[Mesa-dev] [PATCH] dri_interface, egl, gallium: only expose RGBA visuals on Android

Marek Olšák maraeo at gmail.com
Fri Jul 28 17:38:44 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

X/GLX can't handle them. This removes almost 500 GLX visuals that were
incorrectly exposed.

Add an optional getCapability callback for querying what the loader can do.

I'm not splitting this patch, because it's already too small.

v2: also add the callback to __DRIimageLoaderExtension
---
 include/GL/internal/dri_interface.h         | 28 ++++++++++++++++++++++++++--
 src/egl/drivers/dri2/platform_android.c     | 18 ++++++++++++++++--
 src/gallium/state_trackers/dri/dri_screen.c | 24 +++++++++++++++++++++++-
 3 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index a8f5af1..c314a43 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -960,21 +960,29 @@ typedef unsigned int
 
 struct __DRIbufferRec {
     unsigned int attachment;
     unsigned int name;
     unsigned int pitch;
     unsigned int cpp;
     unsigned int flags;
 };
 
 #define __DRI_DRI2_LOADER "DRI_DRI2Loader"
-#define __DRI_DRI2_LOADER_VERSION 3
+#define __DRI_DRI2_LOADER_VERSION 4
+
+enum dri_loader_cap {
+   /* Whether the loader handles RGBA channel ordering correctly. If not,
+    * only BGRA ordering can be exposed.
+    */
+   DRI_LOADER_CAP_RGBA_ORDERING,
+};
+
 struct __DRIdri2LoaderExtensionRec {
     __DRIextension base;
 
     __DRIbuffer *(*getBuffers)(__DRIdrawable *driDrawable,
 			       int *width, int *height,
 			       unsigned int *attachments, int count,
 			       int *out_count, void *loaderPrivate);
 
     /**
      * Flush pending front-buffer rendering
@@ -1010,20 +1018,28 @@ struct __DRIdri2LoaderExtensionRec {
      *                       \c attachments.
      * \param loaderPrivate  Loader's private data that was previously passed
      *                       into __DRIdri2ExtensionRec::createNewDrawable.
      *
      * \since 3
      */
     __DRIbuffer *(*getBuffersWithFormat)(__DRIdrawable *driDrawable,
 					 int *width, int *height,
 					 unsigned int *attachments, int count,
 					 int *out_count, void *loaderPrivate);
+
+    /**
+     * Return a loader capability value. If the loader doesn't know the enum,
+     * it will return 0.
+     *
+     * \since 4
+     */
+    unsigned (*getCapability)(void *loaderPrivate, enum dri_loader_cap cap);
 };
 
 /**
  * This extension provides alternative screen, drawable and context
  * constructors for DRI2.
  */
 #define __DRI_DRI2 "DRI_DRI2"
 #define __DRI_DRI2_VERSION 4
 
 #define __DRI_API_OPENGL	0	/**< OpenGL compatibility profile */
@@ -1704,21 +1720,21 @@ enum __DRIimageBufferMask {
    __DRI_IMAGE_BUFFER_FRONT = (1 << 1)
 };
 
 struct __DRIimageList {
    uint32_t image_mask;
    __DRIimage *back;
    __DRIimage *front;
 };
 
 #define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
-#define __DRI_IMAGE_LOADER_VERSION 1
+#define __DRI_IMAGE_LOADER_VERSION 2
 
 struct __DRIimageLoaderExtensionRec {
     __DRIextension base;
 
    /**
     * Allocate color buffers.
     *
     * \param driDrawable
     * \param width              Width of allocated buffers
     * \param height             Height of allocated buffers
@@ -1740,20 +1756,28 @@ struct __DRIimageLoaderExtensionRec {
      * Flush pending front-buffer rendering
      *
      * Any rendering that has been performed to the
      * fake front will be flushed to the front
      *
      * \param driDrawable    Drawable whose front-buffer is to be flushed
      * \param loaderPrivate  Loader's private data that was previously passed
      *                       into __DRIdri2ExtensionRec::createNewDrawable
      */
     void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void *loaderPrivate);
+
+    /**
+     * Return a loader capability value. If the loader doesn't know the enum,
+     * it will return 0.
+     *
+     * \since 2
+     */
+    unsigned (*getCapability)(void *loaderPrivate, enum dri_loader_cap cap);
 };
 
 /**
  * DRI extension.
  */
 
 #define __DRI_IMAGE_DRIVER           "DRI_IMAGE_DRIVER"
 #define __DRI_IMAGE_DRIVER_VERSION   1
 
 struct __DRIimageDriverExtensionRec {
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index 300e2d9..bae4241 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -1006,20 +1006,32 @@ droid_get_buffers_with_format(__DRIdrawable * driDrawable,
    *out_count = droid_get_buffers_parse_attachments(dri2_surf, attachments, count);
 
    if (width)
       *width = dri2_surf->base.Width;
    if (height)
       *height = dri2_surf->base.Height;
 
    return dri2_surf->buffers;
 }
 
+static unsigned
+droid_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
+{
+   /* Note: loaderPrivate is _EGLDisplay* */
+   switch (cap) {
+   case DRI_LOADER_CAP_RGBA_ORDERING:
+      return 1;
+   default:
+      return 0;
+   }
+}
+
 static EGLBoolean
 droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
    static const struct {
       int format;
       unsigned int rgba_masks[4];
    } visuals[] = {
       { HAL_PIXEL_FORMAT_RGBA_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 } },
       { HAL_PIXEL_FORMAT_RGBX_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 } },
@@ -1118,32 +1130,34 @@ static const struct dri2_egl_display_vtbl droid_display_vtbl = {
    .post_sub_buffer = dri2_fallback_post_sub_buffer,
    .copy_buffers = dri2_fallback_copy_buffers,
    .query_buffer_age = droid_query_buffer_age,
    .query_surface = droid_query_surface,
    .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
    .get_sync_values = dri2_fallback_get_sync_values,
    .get_dri_drawable = dri2_surface_get_dri_drawable,
 };
 
 static const __DRIdri2LoaderExtension droid_dri2_loader_extension = {
-   .base = { __DRI_DRI2_LOADER, 3 },
+   .base = { __DRI_DRI2_LOADER, 4 },
 
    .getBuffers           = NULL,
    .flushFrontBuffer     = droid_flush_front_buffer,
    .getBuffersWithFormat = droid_get_buffers_with_format,
+   .getCapability        = droid_get_capability;
 };
 
 static const __DRIimageLoaderExtension droid_image_loader_extension = {
-   .base = { __DRI_IMAGE_LOADER, 1 },
+   .base = { __DRI_IMAGE_LOADER, 2 },
 
    .getBuffers          = droid_image_get_buffers,
    .flushFrontBuffer    = droid_flush_front_buffer,
+   .getCapability       = droid_get_capability,
 };
 
 static const __DRIextension *droid_dri2_loader_extensions[] = {
    &droid_dri2_loader_extension.base,
    &image_lookup_extension.base,
    &use_invalidate.base,
    NULL,
 };
 
 static const __DRIextension *droid_image_loader_extensions[] = {
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 59a850b..890a8bf 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -117,20 +117,35 @@ dri_fill_st_options(struct dri_screen *screen)
       driQueryOptionb(optionCache, "allow_glsl_builtin_variable_redeclaration");
    options->allow_higher_compat_version =
       driQueryOptionb(optionCache, "allow_higher_compat_version");
    options->glsl_zero_init = driQueryOptionb(optionCache, "glsl_zero_init");
    options->force_glsl_abs_sqrt =
       driQueryOptionb(optionCache, "force_glsl_abs_sqrt");
 
    driComputeOptionsSha1(optionCache, options->config_options_sha1);
 }
 
+static unsigned
+dri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap)
+{
+   const __DRIdri2LoaderExtension *dri2_loader = screen->sPriv->dri2.loader;
+   const __DRIimageLoaderExtension *image_loader = screen->sPriv->image.loader;
+
+   if (dri2_loader && dri2_loader->base.version >= 4)
+      return dri2_loader->getCapability(screen->sPriv->loaderPrivate, cap);
+
+   if (image_loader && image_loader->base.version >= 2)
+      return image_loader->getCapability(screen->sPriv->loaderPrivate, cap);
+
+   return 0;
+}
+
 static const __DRIconfig **
 dri_fill_in_modes(struct dri_screen *screen)
 {
    static const mesa_format mesa_formats[] = {
       MESA_FORMAT_B8G8R8A8_UNORM,
       MESA_FORMAT_B8G8R8X8_UNORM,
       MESA_FORMAT_B8G8R8A8_SRGB,
       MESA_FORMAT_B8G8R8X8_SRGB,
       MESA_FORMAT_B5G6R5_UNORM,
 
@@ -228,22 +243,29 @@ dri_fill_in_modes(struct dri_screen *screen)
    if (pf_z32) {
       depth_bits_array[depth_buffer_factor] = 32;
       stencil_bits_array[depth_buffer_factor++] = 0;
    }
 
    mixed_color_depth =
       p_screen->get_param(p_screen, PIPE_CAP_MIXED_COLOR_DEPTH_BITS);
 
    assert(ARRAY_SIZE(mesa_formats) == ARRAY_SIZE(pipe_formats));
 
+   /* Expose only BGRA ordering if the loader doesn't support RGBA ordering. */
+   unsigned num_formats;
+   if (dri_loader_get_cap(screen, DRI_LOADER_CAP_RGBA_ORDERING))
+      num_formats = ARRAY_SIZE(mesa_formats);
+   else
+      num_formats = 5;
+
    /* Add configs. */
-   for (format = 0; format < ARRAY_SIZE(mesa_formats); format++) {
+   for (format = 0; format < num_formats; format++) {
       __DRIconfig **new_configs = NULL;
       unsigned num_msaa_modes = 0; /* includes a single-sample mode */
       uint8_t msaa_modes[MSAA_VISUAL_MAX_SAMPLES];
 
       if (!p_screen->is_format_supported(p_screen, pipe_formats[format],
                                          PIPE_TEXTURE_2D, 0,
                                          PIPE_BIND_RENDER_TARGET))
          continue;
 
       for (i = 1; i <= msaa_samples_max; i++) {
-- 
2.7.4



More information about the mesa-dev mailing list