dri: Define DRI_MutableRenderBuffer extensions

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 <tapani.palli@intel.com>
This commit is contained in:
Chad Versace 2018-03-31 01:16:14 -07:00
parent eabf59791e
commit bbe2d50b58
5 changed files with 144 additions and 3 deletions

View File

@ -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

View File

@ -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];
}
}

View File

@ -216,6 +216,10 @@ struct __DRIscreenRec {
const __DRIimageLoaderExtension *loader;
} image;
struct {
const __DRImutableRenderBufferLoaderExtension *loader;
} mutableRenderBuffer;
driOptionCache optionInfo;
driOptionCache optionCache;

View File

@ -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

View File

@ -213,6 +213,9 @@ struct gl_config
/* EXT_framebuffer_sRGB */
GLint sRGBCapable;
/* EGL_KHR_mutable_render_buffer */
GLuint mutableRenderBuffer; /* bool */
};