[Mesa-dev] [PATCH 3/7] dri: Define DRI_MutableRenderBuffer extensions

Chad Versace chadversary at chromium.org
Tue Jul 31 18:18:05 UTC 2018


Define extensions DRI_MutableRenderBufferDriver and
DRI_MutableRenderBufferLoader. These are the two halves for
EGL_KHR_mutable_render_buffer.

Outside the DRI code there is one additional change.  Add
gl_config::mutableRenderBuffer to match
__DRI_ATTRIB_MUTABLE_RENDER_BUFFER. Neither are used yet.
---
 include/GL/internal/dri_interface.h    | 138 ++++++++++++++++++++++++-
 src/mesa/drivers/dri/common/dri_util.c |   2 +
 src/mesa/drivers/dri/common/dri_util.h |   4 +
 src/mesa/drivers/dri/common/utils.c    |   1 +
 src/mesa/main/mtypes.h                 |   3 +
 5 files changed, 145 insertions(+), 3 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index c32cdd3767a..245c845832b 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -48,6 +48,7 @@ typedef unsigned int drm_drawable_t;
 typedef struct drm_clip_rect drm_clip_rect_t;
 #endif
 
+#include <stdbool.h>
 #include <stdint.h>
 
 /**
@@ -746,7 +747,8 @@ struct __DRIuseInvalidateExtensionRec {
 #define __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS	46
 #define __DRI_ATTRIB_YINVERTED			47
 #define __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE	48
-#define __DRI_ATTRIB_MAX			(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE + 1)
+#define __DRI_ATTRIB_MUTABLE_RENDER_BUFFER	49 /* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR */
+#define __DRI_ATTRIB_MAX			50
 
 /* __DRI_ATTRIB_RENDER_TYPE */
 #define __DRI_ATTRIB_RGBA_BIT			0x01	
@@ -1888,9 +1890,57 @@ struct __DRI2rendererQueryExtensionRec {
  * Image Loader extension. Drivers use this to allocate color buffers
  */
 
+/**
+ * See __DRIimageLoaderExtensionRec::getBuffers::buffer_mask.
+ */
 enum __DRIimageBufferMask {
    __DRI_IMAGE_BUFFER_BACK = (1 << 0),
-   __DRI_IMAGE_BUFFER_FRONT = (1 << 1)
+   __DRI_IMAGE_BUFFER_FRONT = (1 << 1),
+
+   /**
+    * A buffer shared between application and compositor. The buffer may be
+    * simultaneously accessed by each.
+    *
+    * A shared buffer is equivalent to an EGLSurface whose EGLConfig contains
+    * EGL_MUTABLE_RENDER_BUFFER_BIT_KHR and whose active EGL_RENDER_BUFFER (as
+    * opposed to any pending, requested change to EGL_RENDER_BUFFER) is
+    * EGL_SINGLE_BUFFER.
+    *
+    * If buffer_mask contains __DRI_IMAGE_BUFFER_SHARED, then must contains no
+    * other bits. As a corollary, a __DRIdrawable that has a "shared" buffer
+    * has no front nor back buffer.
+    *
+    * The loader returns __DRI_IMAGE_BUFFER_SHARED in buffer_mask if and only
+    * if:
+    *     - The loader supports __DRI_MUTABLE_RENDER_BUFFER_LOADER.
+    *     - The driver supports __DRI_MUTABLE_RENDER_BUFFER_DRIVER.
+    *     - The EGLConfig of the drawable EGLSurface contains
+    *       EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.
+    *     - The EGLContext's EGL_RENDER_BUFFER is EGL_SINGLE_BUFFER.
+    *       Equivalently, the EGLSurface's active EGL_RENDER_BUFFER (as
+    *       opposed to any pending, requested change to EGL_RENDER_BUFFER) is
+    *       EGL_SINGLE_BUFFER. (See the EGL 1.5 and
+    *       EGL_KHR_mutable_render_buffer spec for details about "pending" vs
+    *       "active" EGL_RENDER_BUFFER state).
+    *
+    * A shared buffer is similar to a front buffer in that all rendering to the
+    * buffer should appear promptly on the screen. It is different from
+    * a front buffer in that its behavior is independent from the
+    * GL_DRAW_BUFFER state. Specifically, if GL_DRAW_FRAMEBUFFER is 0 and the
+    * __DRIdrawable's buffer_mask is __DRI_IMAGE_BUFFER_SHARED, then all
+    * rendering should appear promptly on the screen if GL_DRAW_BUFFER is not
+    * GL_NONE.
+    *
+    * The difference between a shared buffer and a front buffer is motivated
+    * by the constraints of Android and OpenGL ES. OpenGL ES does not support
+    * front-buffer rendering. Android's SurfaceFlinger protocol provides the
+    * EGL driver only a back buffer and no front buffer. The shared buffer
+    * mode introduced by EGL_KHR_mutable_render_buffer is a backdoor though
+    * EGL that allows Android OpenGL ES applications to render to what is
+    * effectively the front buffer, a backdoor that required no change to the
+    * OpenGL ES API and little change to the SurfaceFlinger API.
+    */
+   __DRI_IMAGE_BUFFER_SHARED = (1 << 2),
 };
 
 struct __DRIimageList {
@@ -1915,7 +1965,8 @@ struct __DRIimageLoaderExtensionRec {
     * \param stamp              Address of variable to be updated when
     *                           getBuffers must be called again
     * \param loaderPrivate      The loaderPrivate for driDrawable
-    * \param buffer_mask        Set of buffers to allocate
+    * \param buffer_mask        Set of buffers to allocate. A bitmask of
+    *                           __DRIimageBufferMask.
     * \param buffers            Returned buffers
     */
    int (*getBuffers)(__DRIdrawable *driDrawable,
@@ -2029,4 +2080,85 @@ struct __DRIbackgroundCallableExtensionRec {
    GLboolean (*isThreadSafe)(void *loaderPrivate);
 };
 
+/**
+ * The driver portion of EGL_KHR_mutable_render_buffer.
+ *
+ * If the driver creates a __DRIconfig with
+ * __DRI_ATTRIB_MUTABLE_RENDER_BUFFER, then it must support this extension.
+ *
+ * To support this extension:
+ *
+ *    - The driver should create at least one __DRIconfig with
+ *      __DRI_ATTRIB_MUTABLE_RENDER_BUFFER. This is strongly recommended but
+ *      not required.
+ *
+ *    - The driver must be able to handle __DRI_IMAGE_BUFFER_SHARED if
+ *      returned by __DRIimageLoaderExtension:getBuffers().
+ *
+ *    - When rendering to __DRI_IMAGE_BUFFER_SHARED, it must call
+ *      __DRImutableRenderBufferLoaderExtension::displaySharedBuffer() in
+ *      response to glFlush and glFinish.  (This requirement is not documented
+ *      in EGL_KHR_mutable_render_buffer, but is a de-facto requirement in the
+ *      Android ecosystem. Android applications expect that glFlush will
+ *      immediately display the buffer when in shared buffer mode, and Android
+ *      drivers comply with this expectation).  It :may: call
+ *      displaySharedBuffer() more often than required.
+ *
+ *    - When rendering to __DRI_IMAGE_BUFFER_SHARED, it must ensure that the
+ *      buffer is always in a format compatible for display because the
+ *      display engine (usually SurfaceFlinger or hwcomposer) may display the
+ *      image at any time, even concurrently with 3D rendering. For example,
+ *      display hardware and the GL hardware may be able to access the buffer
+ *      simultaneously. In particular, if the buffer is compressed then take
+ *      care that SurfaceFlinger and hwcomposer can consume the compression
+ *      format.
+ *
+ * \see __DRI_IMAGE_BUFFER_SHARED
+ * \see __DRI_ATTRIB_MUTABLE_RENDER_BUFFER
+ * \see __DRI_MUTABLE_RENDER_BUFFER_LOADER
+ */
+#define __DRI_MUTABLE_RENDER_BUFFER_DRIVER "DRI_MutableRenderBufferDriver"
+#define __DRI_MUTABLE_RENDER_BUFFER_DRIVER_VERSION 1
+
+typedef struct __DRImutableRenderBufferDriverExtensionRec __DRImutableRenderBufferDriverExtension;
+struct __DRImutableRenderBufferDriverExtensionRec {
+   __DRIextension base;
+};
+
+/**
+ * The loader portion of EGL_KHR_mutable_render_buffer.
+ *
+ * Requires loader extension DRI_IMAGE_LOADER, through which the loader sends
+ * __DRI_IMAGE_BUFFER_SHARED to the driver.
+ *
+ * \see __DRI_MUTABLE_RENDER_BUFFER_DRIVER
+ */
+#define __DRI_MUTABLE_RENDER_BUFFER_LOADER "DRI_MutableRenderBufferLoader"
+#define __DRI_MUTABLE_RENDER_BUFFER_LOADER_VERSION 1
+
+typedef struct __DRImutableRenderBufferLoaderExtensionRec __DRImutableRenderBufferLoaderExtension;
+struct __DRImutableRenderBufferLoaderExtensionRec {
+   __DRIextension base;
+
+   /**
+    * Inform the display engine (that is, SurfaceFlinger and/or hwcomposer)
+    * that the __DRIdrawable has new content.
+    *
+    * The display engine may ignore this call, for example, if it continually
+    * refreshes and displays the buffer on every frame, as in
+    * EGL_ANDROID_front_buffer_auto_refresh. On the other extreme, the display
+    * engine may refresh and display the buffer only in frames in which the
+    * driver calls this.
+    *
+    * If the fence_fd is not -1, then the display engine will display the
+    * buffer only after the fence signals.
+    *
+    * The drawable's current __DRIimageBufferMask, as returned by
+    * __DRIimageLoaderExtension::getBuffers(), must be
+    * __DRI_IMAGE_BUFFER_SHARED.
+    */
+   void (*displaySharedBuffer)(__DRIdrawable *drawable, int fence_fd,
+                               void *loaderPrivate);
+};
+
 #endif
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index d257cb644c8..be7b6e5535d 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -81,6 +81,8 @@ setupLoaderExtensions(__DRIscreen *psp,
 	    psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
         if (strcmp(extensions[i]->name, __DRI_IMAGE_LOADER) == 0)
            psp->image.loader = (__DRIimageLoaderExtension *) extensions[i];
+        if (strcmp(extensions[i]->name, __DRI_MUTABLE_RENDER_BUFFER_LOADER) == 0)
+           psp->mutableRenderBuffer.loader = (__DRImutableRenderBufferLoaderExtension *) extensions[i];
     }
 }
 
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 062c83f79ec..d6c7d07d4e0 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -216,6 +216,10 @@ struct __DRIscreenRec {
         const __DRIimageLoaderExtension *loader;
     } image;
 
+    struct {
+       const __DRImutableRenderBufferLoaderExtension *loader;
+    } mutableRenderBuffer;
+
     driOptionCache optionInfo;
     driOptionCache optionCache;
 
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index fc5e2d19f34..86169d5c214 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -409,6 +409,7 @@ static const struct { unsigned int attrib, offset; } attribMap[] = {
     __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS,	bindToTextureTargets),
     __ATTRIB(__DRI_ATTRIB_YINVERTED,			yInverted),
     __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE,	sRGBCapable),
+    __ATTRIB(__DRI_ATTRIB_MUTABLE_RENDER_BUFFER,	mutableRenderBuffer),
 
     /* The struct field doesn't matter here, these are handled by the
      * switch in driGetConfigAttribIndex.  We need them in the array
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d71872835d1..7f7aab09adb 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -213,6 +213,9 @@ struct gl_config
 
    /* EXT_framebuffer_sRGB */
    GLint sRGBCapable;
+
+   /* EGL_KHR_mutable_render_buffer */
+   GLuint mutableRenderBuffer; /* bool */
 };
 
 
-- 
2.18.0.345.g5c9ce644c3-goog



More information about the mesa-dev mailing list