alexlarsson / gthree

Gthree is a GObject/Gtk+ port of three.js
MIT License
84 stars 13 forks source link

Gthree apps don't want to work with virtualgl #83

Closed nicholizer closed 2 years ago

nicholizer commented 3 years ago

Hello, Alexander. I've successfully built gthree about two months ago and since then I'm experimenting with it. My laptop has no dedicated gpu, but apps made with gthree worked on it, slowly, but worked. Then, one day I decided to try these apps on a remote machine with Nvidia GTX 1080 ti and good cpu. For this purpose I used TurboVnc and Virtualgl. At first I tried to run glxgears and virtualgl's glxspheres64 and everything was OK, but then there was a problem with gtklogo and other gthree apps:

ubuntu@gc-sleepy-carson:~/Desktop$ vglrun +v ./gtklogo2-app [VGL] Shared memory segment ID for vglconfig: 28 [VGL] VirtualGL v2.6.4 64-bit (Build 20200626) [VGL] NOTICE: Replacing dlopen("libGLX.so.1") with dlopen("libvglfaker.so") [VGL] Opening connection to 3D X server :0 [VGL] NOTICE: Replacing dlopen("libOpenGL.so.0") with dlopen("libvglfaker.so") gtklogo2-app: ../src/dispatch_common.c:863: epoxy_get_proc_address: Assertion `0 && "Couldn't find current GLX or EGL context.\n"' failed. Aborted (core dumped) ubuntu@gc-sleepy-carson:~/Desktop$ vglrun +v glxgears [VGL] Shared memory segment ID for vglconfig: 29 [VGL] VirtualGL v2.6.4 64-bit (Build 20200626) [VGL] Opening connection to 3D X server :0 [VGL] Using Pbuffers for rendering [VGL] Using pixel buffer objects for readback (BGR --> BGRA) 795 frames in 5.0 seconds = 158.815 FPS 790 frames in 5.0 seconds = 157.762 FPS 763 frames in 5.0 seconds = 152.415 FPS 821 frames in 5.0 seconds = 164.191 FPS ubuntu@gc-sleepy-carson:~/Desktop$ vglrun +v /opt/VirtualGL/bin/glxspheres64 Polygons in scene: 62464 (61 spheres * 1024 polys/spheres) [VGL] Shared memory segment ID for vglconfig: 37 [VGL] VirtualGL v2.6.4 64-bit (Build 20200626) [VGL] Opening connection to 3D X server :0 GLX FB config ID of window: 0xad (8/8/8/0) Visual ID of window: 0x21 Context is Direct [VGL] Using Pbuffers for rendering OpenGL Renderer: GeForce GTX 1080 Ti/PCIe/SSE2 [VGL] Using pixel buffer objects for readback (BGR --> BGRA) 303.247910 frames/sec - 232.760966 Mpixels/sec 260.776730 frames/sec - 200.161787 Mpixels/sec 196.662196 frames/sec - 150.950035 Mpixels/sec

As you can see, gtklogo doesn't want to work with virtualgl. I understand, that it is not a gthree's issue, but gthree+virtualgl issue, but maybe you have some idea about it. Can we "workaround" this problem?

nicholizer commented 3 years ago

It seems like Virtualgl does not want to work with GtkGLArea.

nicholizer commented 3 years ago

I solved this issue. The problem was with GtkWindow. As is said in https://github.com/cztomczak/cefcapi/issues/9#issuecomment-349240394, GTK+ > 3.15.1 uses an X11 visual optimized for GTK+'s OpenGL stuff. There, authour of that comment suggests to force GTK to use the default X11 visual instead the GTK's blessed one(I made minor changes in his code):

GtkWidget* create_gtk_window() {
    printf("create_gtk_window\n");
    // Create window.
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    ////...
    // GTK+ > 3.15.1 uses an X11 visual optimized for GTK+'s OpenGL stuff
    // since revid dae447728d: https://github.com/GNOME/gtk/commit/dae447728d
    // However, it breaks CEF: https://github.com/cztomczak/cefcapi/issues/9
    // Let's use the default X11 visual instead the GTK's blessed one.
    GdkScreen* screen = gdk_screen_get_default();
    GList* visuals = gdk_screen_list_visuals(screen);
    printf("n visuals: %u\n", g_list_length(visuals));
    GdkX11Screen* x11_screen = GDK_X11_SCREEN(screen);
    g_assert(x11_screen != NULL);
    Visual* default_xvisual = DefaultVisual(GDK_SCREEN_XDISPLAY(x11_screen),
        GDK_SCREEN_XNUMBER(x11_screen));
    GdkVisual* default_visual = NULL;
    int i = 0;
    while (visuals != NULL) {
    GdkVisual* visual = GDK_X11_VISUAL (visuals->data);
        if (default_xvisual->visualid == gdk_x11_visual_get_xvisual(
           GDK_X11_VISUAL (visuals->data))->visualid) {
           printf("Default visual %d\n", i);
           default_visual = visual;
        }
        i++;
        visuals = visuals->next;
    }
    gtk_widget_set_visual(GTK_WIDGET(window), default_visual);
    ////gtk_widget_show_all(window);
    return window;
}

So, now I add this to my local copy of your utils.c and use create_gtk_window() instead of gtk_window_new(GTK_WINDOW_TOPLEVEL) and gthree-programs(and other gtk-programs too) work with vglrun. Thank you for Gthree, it is wonderful!