From 8c7623de84d13437e951d37ded04dbefdea5c88c Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 29 Oct 2014 13:33:08 +0100 Subject: [PATCH] Cache default gdk visuals in the GDK_VISUALS property on the root window This means we don't have to try to initialize opengl in every gtk instance that is stated. It will only happen for the first one. https://bugzilla.gnome.org/show_bug.cgi?id=738670 --- gdk/x11/gdkdisplay-x11.c | 3 +- gdk/x11/gdkglcontext-x11.c | 88 +++++++++++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index be3ec710a6..358ae84df0 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -165,7 +165,8 @@ static const char *const precache_atoms[] = { "_NET_WM_USER_TIME_WINDOW", "_NET_VIRTUAL_ROOTS", "GDK_SELECTION", - "_NET_WM_STATE_FOCUSED" + "_NET_WM_STATE_FOCUSED", + "GDK_VISUALS" }; static char *gdk_sm_client_id; diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c index 72079afd48..aa4686816a 100644 --- a/gdk/x11/gdkglcontext-x11.c +++ b/gdk/x11/gdkglcontext-x11.c @@ -30,6 +30,8 @@ #include "gdkx11window.h" #include "gdkx11visual.h" #include "gdkvisualprivate.h" +#include "gdkx11property.h" +#include #include "gdkinternals.h" @@ -817,6 +819,66 @@ pick_better_visual_for_gl (GdkX11Screen *x11_screen, return compatible; } +static gboolean +get_cached_gl_visuals (GdkDisplay *display, int *system, int *rgba) +{ + gboolean found; + Atom type_return; + gint format_return; + gulong nitems_return; + gulong bytes_after_return; + guchar *data = NULL; + Display *dpy; + + dpy = gdk_x11_display_get_xdisplay (display); + + found = FALSE; + + gdk_x11_display_error_trap_push (display); + if (XGetWindowProperty (dpy, DefaultRootWindow (dpy), + gdk_x11_get_xatom_by_name_for_display (display, "GDK_VISUALS"), + 0, 2, False, XA_INTEGER, &type_return, + &format_return, &nitems_return, + &bytes_after_return, &data) == Success) + { + if (type_return == XA_INTEGER && + format_return == 32 && + nitems_return == 2 && + data != NULL) + { + long *visuals = (long *) data; + + *system = (int)visuals[0]; + *rgba = (int)visuals[1]; + found = TRUE; + } + } + gdk_x11_display_error_trap_pop_ignored (display); + + if (data) + XFree (data); + + return found; +} + +static void +save_cached_gl_visuals (GdkDisplay *display, int system, int rgba) +{ + long visualdata[2]; + Display *dpy; + + dpy = gdk_x11_display_get_xdisplay (display); + + visualdata[0] = system; + visualdata[1] = rgba; + + gdk_x11_display_error_trap_push (display); + XChangeProperty(dpy, DefaultRootWindow (dpy), gdk_x11_get_xatom_by_name_for_display (display, "GDK_VISUALS"), + XA_INTEGER, 32, PropModeReplace, (unsigned char *)visualdata, 2); + gdk_x11_display_error_trap_pop_ignored (display); +} + + void _gdk_x11_screen_update_visuals_for_gl (GdkScreen *screen) { @@ -826,16 +888,34 @@ _gdk_x11_screen_update_visuals_for_gl (GdkScreen *screen) Display *dpy; struct glvisualinfo *gl_info; int i; + int system_visual_id, rgba_visual_id; x11_screen = GDK_X11_SCREEN (screen); display = x11_screen->display; display_x11 = GDK_X11_DISPLAY (display); + dpy = gdk_x11_display_get_xdisplay (display); + + /* We save the default visuals as a property on the root window to avoid + having to initialize GL each time, as it may not be used later. */ + if (get_cached_gl_visuals (display, &system_visual_id, &rgba_visual_id)) + { + for (i = 0; i < x11_screen->nvisuals; i++) + { + GdkVisual *visual = x11_screen->visuals[i]; + int visual_id = gdk_x11_visual_get_xvisual (visual)->visualid; + + if (visual_id == system_visual_id) + x11_screen->system_visual = visual; + if (visual_id == rgba_visual_id) + x11_screen->rgba_visual = visual; + } + + return; + } if (!gdk_x11_screen_init_gl (screen)) return; - dpy = gdk_x11_display_get_xdisplay (display); - gl_info = g_new0 (struct glvisualinfo, x11_screen->nvisuals); for (i = 0; i < x11_screen->nvisuals; i++) @@ -872,6 +952,10 @@ _gdk_x11_screen_update_visuals_for_gl (GdkScreen *screen) x11_screen->system_visual = pick_better_visual_for_gl (x11_screen, gl_info, x11_screen->system_visual); if (x11_screen->rgba_visual) x11_screen->rgba_visual = pick_better_visual_for_gl (x11_screen, gl_info, x11_screen->rgba_visual); + + save_cached_gl_visuals (display, + gdk_x11_visual_get_xvisual (x11_screen->system_visual)->visualid, + x11_screen->rgba_visual ? gdk_x11_visual_get_xvisual (x11_screen->rgba_visual)->visualid : 0); }