Skip to content

Commit

Permalink
Faker: Thwart GTK's X visual cache
Browse files Browse the repository at this point in the history
Starting with
GNOME/gtk@dae4477
(v3.15.2) and ending with
GNOME/gtk@1c55b32
(v4.3.2), GTK used glXGetConfig() to probe the OpenGL rendering
attributes of all X visuals, it picked "system" (opaque) and "RGBA"
(transparent) visuals based on those attributes, and it expected to find
a GLX FB config with a GLX_VISUAL_ID attribute corresponding to one of
those visuals.  (The purpose of this was to ensure that GTK windows can
always be used for OpenGL rendering, since the decision to enable OpenGL
rendering may occur after the window is created.)

Starting with
GNOME/gtk@8c7623d
(GTK v3.15.2) and ending with
GNOME/gtk@62bac44
(GTK v4.3.2), GTK cached the system and RGBA visual IDs in an X root
window property to avoid re-picking the visuals every time GTK was
initialized on a particular X display.

These mechanisms only worked reliably if there was a 1:1 correspondence
between 2D X server visuals and GLX FB configs, which isn't the case
with VirtualGL.  More specifically, if GTK was initialized on the 2D X
server without VirtualGL, then GTK used the 2D X server's GLX
implementation to probe the OpenGL rendering attributes of the 2D X
server visuals.  That caused GTK to pick and cache different visuals
than it would have picked had VirtualGL been active, and it was likely
that none of the GLX FB configs returned by VirtualGL had a
GLX_VISUAL_ID attribute corresponding to one of those visuals.

The easiest workaround is for the VirtualGL Faker to delete the
GDK_VISUALS X root window property in the body of XOpenDisplay(), thus
forcing GTK to re-pick the system and RGBA visuals using VirtualGL's
interposed version of glXGetConfig().

Fixes #158
  • Loading branch information
dcommander committed Feb 15, 2024
1 parent 2975d46 commit 398e941
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
1. The EGL back end now supports OpenGL applications, including ANSYS Fluent,
that use multiple X11 Display handles to render to the same GLX drawable.

2. The VirtualGL Faker now works around an issue whereby applications using the
GtkGLArea widget with GTK v3.15.2 through v4.3.1 failed with "No available
configurations for the given [RGBA] pixel format" if GTK v3.15.2 through v4.3.1
had previously been initialized on the 2D X server without VirtualGL.


3.1
===
Expand Down
17 changes: 16 additions & 1 deletion server/faker-x11.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (C)2004 Landmark Graphics Corporation
// Copyright (C)2005, 2006 Sun Microsystems, Inc.
// Copyright (C)2009, 2011-2016, 2018-2023 D. R. Commander
// Copyright (C)2009, 2011-2016, 2018-2024 D. R. Commander
//
// This library is free software and may be redistributed and/or modified under
// the terms of the wxWindows Library License, Version 3.1 or (at your option)
Expand Down Expand Up @@ -548,6 +548,21 @@ static void setupXDisplay(Display *dpy)
_XFree(ServerVendor(dpy));
ServerVendor(dpy) = strdup(fconfig.vendor);
}

// GTK v3.15.2 through v4.3.1 used glXGetConfig() to probe the OpenGL
// rendering attributes of all X visuals, picked "system" (opaque) and "RGBA"
// (transparent) visuals based on those attributes, cached the visual IDs of
// those visuals in an X root window property, and expected to find a GLX FB
// config with a GLX_VISUAL_ID attribute matching one of those visual IDs.
// If the visuals are picked without VirtualGL (i.e. using the 2D X server's
// GLX implementation), then it is likely that none of the GLX FB configs
// returned by VirtualGL will have a GLX_VISUAL_ID attribute corresponding
// to one of the visuals. We delete the GDK_VISUALS X root window property
// here in order to force GTK to re-pick the visuals using VirtualGL's
// interposed version of glXGetConfig().
Atom atom = None;
if((atom = XInternAtom(dpy, "GDK_VISUALS", True)) != None)
XDeleteProperty(dpy, DefaultRootWindow(dpy), atom);
}


Expand Down

0 comments on commit 398e941

Please sign in to comment.