[Mesa-dev] [PATCH 3/3] egl/x11: Handle both depth 30 formats for eglCreateImage().

Mario Kleiner mario.kleiner.de at gmail.com
Mon Mar 12 20:45:45 UTC 2018


We need to distinguish if a backing pixmap of a window is
XRGB2101010 or XBGR2101010, as different gpu hw supports
different formats. NVidia hw prefers XBGR, whereas AMD and
Intel are happy with XRGB.

We use the red channel mask of the visual to distinguish at
depth 30, but because we can't easily get the associated
visual of a Pixmap, we use the visual of the x-screens root
window instead as a proxy.

This fixes desktop composition of color depth 30 windows
when the X11 compositor uses EGL.

Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
---
 src/egl/drivers/dri2/egl_dri2.h          |  7 ++++++
 src/egl/drivers/dri2/platform_x11.c      | 37 +++++++++++++++++++++++++++++++-
 src/egl/drivers/dri2/platform_x11_dri3.c |  7 +++++-
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index d36d02c..a399b06 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -402,6 +402,8 @@ EGLBoolean
 dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp);
 void
 dri2_teardown_x11(struct dri2_egl_display *dri2_dpy);
+unsigned int
+dri2_x11_get_red_mask(struct dri2_egl_display *dri2_dpy);
 #else
 static inline EGLBoolean
 dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
@@ -410,6 +412,11 @@ dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
 }
 static inline void
 dri2_teardown_x11(struct dri2_egl_display *dri2_dpy) {}
+static inline unsigned int
+dri2_x11_get_red_mask(struct dri2_egl_display *dri2_dpy)
+{
+   return 0;
+}
 #endif
 
 #ifdef HAVE_DRM_PLATFORM
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index 6c287b4..da28981 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -209,6 +209,37 @@ get_xcb_screen(xcb_screen_iterator_t iter, int screen)
     return NULL;
 }
 
+static xcb_visualtype_t *
+get_xcb_visualtype(struct dri2_egl_display *dri2_dpy)
+{
+   xcb_visualtype_iterator_t visual_iter;
+   xcb_screen_t *screen = dri2_dpy->screen;
+   xcb_visualid_t visual_id = screen->root_visual;
+   xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen);
+
+   for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
+      visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
+
+      for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
+         if (visual_iter.data->visual_id == visual_id)
+            return visual_iter.data;
+      }
+   }
+
+   return NULL;
+}
+
+/* Get red channel mask of the root windows visual for our x-screen */
+unsigned int
+dri2_x11_get_red_mask(struct dri2_egl_display *dri2_dpy)
+{
+   unsigned int red_mask = 0;
+   xcb_visualtype_t *visual = get_xcb_visualtype(dri2_dpy);
+   if (visual)
+      red_mask = visual->red_mask;
+
+   return red_mask;
+}
 
 /**
  * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
@@ -1050,7 +1081,11 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
       format = __DRI_IMAGE_FORMAT_XRGB8888;
       break;
    case 30:
-      format = __DRI_IMAGE_FORMAT_XRGB2101010;
+      /* Different preferred formats for different hw */
+      if (dri2_x11_get_red_mask(dri2_dpy) == 0x3ff)
+         format = __DRI_IMAGE_FORMAT_XBGR2101010;
+      else
+         format = __DRI_IMAGE_FORMAT_XRGB2101010;
       break;
    case 32:
       format = __DRI_IMAGE_FORMAT_ARGB8888;
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
index 2073c59..667c845 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -282,7 +282,12 @@ dri3_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
       format = __DRI_IMAGE_FORMAT_XRGB8888;
       break;
    case 30:
-      format = __DRI_IMAGE_FORMAT_XRGB2101010;
+      /* Different preferred formats for different hw */
+      if (dri2_x11_get_red_mask(dri2_dpy) == 0x3ff)
+         format = __DRI_IMAGE_FORMAT_XBGR2101010;
+      else
+         format = __DRI_IMAGE_FORMAT_XRGB2101010;
+
       break;
    case 32:
       format = __DRI_IMAGE_FORMAT_ARGB8888;
-- 
2.7.4



More information about the mesa-dev mailing list