From 80f79e0cc7509b79b38193a006b0d98d03432044 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 5 Aug 2019 14:39:21 -0400 Subject: [PATCH] iconcache: Avoid xrender picture formats when creating cairo surface If an application provides its window icon via wmhints, then mutter loads the pixmap specified by the application into a cairo xlib surface. When creating the surface it specifies the visual, indirectly, via an XRender picture format. This is suboptimal, since XRender picture formats don't have a way to specify 16bpp depth, which an application may be using. In particular, applications are likely to use 16bpp depth pixmaps for their icons, if the video card offers a 16bpp framebuffer/root window. This commit drops the XRender middleman, and just tells cairo a visual to use directly. https://gitlab.gnome.org/GNOME/mutter/merge_requests/715 --- src/x11/iconcache.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c index 15d72da65..521c77b8d 100644 --- a/src/x11/iconcache.c +++ b/src/x11/iconcache.c @@ -261,97 +261,78 @@ get_pixmap_geometry (MetaX11Display *x11_display, Pixmap pixmap, int *w, int *h, int *d) { Window root_ignored; int x_ignored, y_ignored; guint width, height; guint border_width_ignored; guint depth; if (w) *w = 1; if (h) *h = 1; if (d) *d = 1; XGetGeometry (x11_display->xdisplay, pixmap, &root_ignored, &x_ignored, &y_ignored, &width, &height, &border_width_ignored, &depth); if (w) *w = width; if (h) *h = height; if (d) *d = depth; } -static int -standard_pict_format_for_depth (int depth) -{ - switch (depth) - { - case 1: - return PictStandardA1; - case 24: - return PictStandardRGB24; - case 32: - return PictStandardARGB32; - default: - g_assert_not_reached (); - } - return 0; -} - -static XRenderPictFormat * -pict_format_for_depth (Display *xdisplay, int depth) -{ - return XRenderFindStandardFormat (xdisplay, standard_pict_format_for_depth (depth)); -} - static cairo_surface_t * surface_from_pixmap (Display *xdisplay, Pixmap xpixmap, int width, int height) { Window root_return; + XVisualInfo visual_info; int x_ret, y_ret; unsigned int w_ret, h_ret, bw_ret, depth_ret; if (!XGetGeometry (xdisplay, xpixmap, &root_return, &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret)) return NULL; - return cairo_xlib_surface_create_with_xrender_format (xdisplay, xpixmap, DefaultScreenOfDisplay (xdisplay), - pict_format_for_depth (xdisplay, depth_ret), w_ret, h_ret); + if (!XMatchVisualInfo (xdisplay, DefaultScreen (xdisplay), + depth_ret, TrueColor, &visual_info)) + return NULL; + + return cairo_xlib_surface_create (xdisplay, xpixmap, visual_info.visual, w_ret, h_ret); } static gboolean try_pixmap_and_mask (MetaX11Display *x11_display, Pixmap src_pixmap, Pixmap src_mask, cairo_surface_t **iconp) { Display *xdisplay = x11_display->xdisplay; cairo_surface_t *icon, *mask = NULL; int w, h, d; if (src_pixmap == None) return FALSE; meta_x11_error_trap_push (x11_display); get_pixmap_geometry (x11_display, src_pixmap, &w, &h, &d); icon = surface_from_pixmap (xdisplay, src_pixmap, w, h); if (icon && src_mask != None) { get_pixmap_geometry (x11_display, src_mask, &w, &h, &d); if (d == 1) mask = surface_from_pixmap (xdisplay, src_mask, w, h); } meta_x11_error_trap_pop (x11_display); -- 2.21.0