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

Nicolai Hähnle nhaehnle at gmail.com
Mon Jul 31 10:05:12 UTC 2017


On 28.07.2017 19:38, Marek Olšák wrote:
> 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

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>


> ---
>   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++) {
> 


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list