From bbe2d50b589e0d7b7b63d63814a5271b680164ce Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Sat, 31 Mar 2018 01:16:14 -0700 Subject: [PATCH] dri: Define DRI_MutableRenderBuffer extensions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. Reviewed-by: Tapani Pälli --- include/GL/internal/dri_interface.h | 137 ++++++++++++++++++++++++++++++++- 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, 144 insertions(+), 3 deletions(-) diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index c32cdd3..6f9c2c8 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -746,7 +746,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 +1889,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 +1964,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 +2079,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 d257cb6..be7b6e5 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 062c83f..d6c7d07 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 fc5e2d1..86169d5 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 202268e..6c8724d 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.7.4