gpt4 book ai didi

c++ - X11 和 nVidia 驱动程序的奇怪 EGL 行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:49:56 26 4
gpt4 key购买 nike

我现在有一个奇怪的问题,我有这个使用 GTK2、OpenGL 和 EGL 的示例应用程序。我描述的奇怪行为只发生在带有官方 nVidia 驱动程序的 Linux 上的 nVidia GPU 上。在程序中你看到一条注释,如果你在代码的这个点上不使用 glFlushglGetError,代码将不会绘制三角形,它只会显示红色(清晰的颜色)。如果您调用 glGetErrorglFlush,它会起作用。

有人可以向我解释为什么会这样吗?这是代码:

#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <EGL/egl.h>
#include <GL/gl.h>

static EGLDisplay egl_display;
static EGLSurface egl_surface;
static EGLContext egl_context;

static void realize_cb (GtkWidget *widget)
{
EGLConfig egl_config;
EGLint n_config;
EGLint attributes[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE };
EGLint surf_attrs[] = {
EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
EGL_NONE
};

egl_display = eglGetDisplay ((EGLNativeDisplayType) gdk_x11_display_get_xdisplay (gtk_widget_get_display (widget)));
eglInitialize (egl_display, NULL, NULL);
eglChooseConfig (egl_display, attributes, &egl_config, 1, &n_config);
egl_surface = eglCreateWindowSurface (egl_display, egl_config, GDK_WINDOW_XID (gtk_widget_get_window (widget)), NULL);
eglBindAPI (EGL_OPENGL_API);
egl_context = eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, NULL);
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
printf("GL Version: %s\n", glGetString(GL_VERSION));
}

static gboolean on_configure (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
gtk_widget_queue_draw(widget);
return FALSE;
}

static gboolean draw_cb (GtkWidget *widget, GdkEventExpose *expose, gpointer userdata)
{
eglMakeCurrent (egl_display, egl_surface, egl_surface, egl_context);

GtkAllocation alloc;
gtk_widget_get_allocation(widget, &alloc);
glViewport (0, 0, alloc.width, alloc.height);

glClearColor (1, 0, 0, 1);
glClearDepth(1.0);
glClear (GL_COLOR_BUFFER_BIT);

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, 100, 0, 100, 0, 1);

glBegin (GL_TRIANGLES);
glColor3f (1, 0, 0);
glVertex2f (50, 10);
glColor3f (0, 1, 0);
glVertex2f (90, 90);
glColor3f (0, 0, 1);
glVertex2f (10, 90);
glEnd ();

/****************************
* It does not matter if you call glGetError or glFlush here, if you do, it
* works, if not, it only displays a red surface
****************************/
//glGetError();
//glFlush();
eglSwapBuffers (egl_display, egl_surface);

return TRUE;
}

int main (int argc, char **argv)
{
GtkWidget *w;

gtk_init (&argc, &argv);

w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_double_buffered (GTK_WIDGET (w), FALSE);
g_signal_connect_after (G_OBJECT (w), "realize", G_CALLBACK (realize_cb), NULL);
g_signal_connect (G_OBJECT (w), "expose-event", G_CALLBACK (draw_cb), NULL);
g_signal_connect (G_OBJECT (w), "configure-event", G_CALLBACK (on_configure), NULL);
gtk_widget_show (w);

gtk_main ();

return 0;
}

编译:

g++ -o gtkegl gtkegl.cc -lEGL -lGL $(pkg-config --libs --cflags gtk+-2.0) -lX11

最佳答案

eglSwapBuffers 是特定于线程上下文的。如果您以某种方式从另一个线程更改了渲染上下文,那么它将失败。

我看到几个可能的错误:

  1. 您不检查 eglMakeCurrent 返回值。它可能会失败。
  2. 你没有同步 draw_cb。它可以同时从不同的线程调用。
  3. 您从不同的地方调用 eglMakeCurrent。它们之间可能会发生冲突。

关于c++ - X11 和 nVidia 驱动程序的奇怪 EGL 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56144980/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com