A follow-up patch enables EGL_KHR_mutable_render_buffer for Android.
This patch is separate from the Android patch because I think it's
easier to review the platform-independent bits separately.
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
_EGL_CHECK_EXTENSION(KHR_image);
_EGL_CHECK_EXTENSION(KHR_image_base);
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
+ _EGL_CHECK_EXTENSION(KHR_mutable_render_buffer);
_EGL_CHECK_EXTENSION(KHR_no_config_context);
_EGL_CHECK_EXTENSION(KHR_partial_update);
_EGL_CHECK_EXTENSION(KHR_reusable_sync);
EGLBoolean
_eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
{
+ _EGLDisplay *disp = conf->Display;
EGLint i, attr, val;
EGLBoolean valid = EGL_TRUE;
EGL_VG_ALPHA_FORMAT_PRE_BIT |
EGL_MULTISAMPLE_RESOLVE_BOX_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+ if (disp->Extensions.KHR_mutable_render_buffer)
+ mask |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
break;
case EGL_RENDERABLE_TYPE:
case EGL_CONFORMANT:
EGLBoolean KHR_image;
EGLBoolean KHR_image_base;
EGLBoolean KHR_image_pixmap;
+ EGLBoolean KHR_mutable_render_buffer;
EGLBoolean KHR_no_config_context;
EGLBoolean KHR_partial_update;
EGLBoolean KHR_reusable_sync;
break;
}
surf->RequestedRenderBuffer = val;
+ if (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) {
+ /* Unlike normal EGLSurfaces, one with a mutable render buffer
+ * uses the application-chosen render buffer.
+ */
+ surf->ActiveRenderBuffer = val;
+ }
break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
if (!dpy->Extensions.NV_post_sub_buffer ||
*value = surface->SwapBehavior;
break;
case EGL_RENDER_BUFFER:
- /* From the EGL 1.5 spec (2014.08.27):
+ /* From the EGL_KHR_mutable_render_buffer spec (v12):
*
* Querying EGL_RENDER_BUFFER returns the buffer which client API
* rendering is requested to use. For a window surface, this is the
- * same attribute value specified when the surface was created. For
- * a pbuffer surface, it is always EGL_BACK_BUFFER . For a pixmap
+ * attribute value specified when the surface was created or last set
+ * via eglSurfaceAttrib.
+ *
+ * In other words, querying a window surface returns the value most
+ * recently *requested* by the user.
+ *
+ * The paragraph continues in the EGL 1.5 spec (2014.08.27):
+ *
+ * For a pbuffer surface, it is always EGL_BACK_BUFFER . For a pixmap
* surface, it is always EGL_SINGLE_BUFFER . To determine the actual
* buffer being rendered to by a context, call eglQueryContext.
*/
break;
surface->MultisampleResolve = value;
break;
+ case EGL_RENDER_BUFFER:
+ if (!dpy->Extensions.KHR_mutable_render_buffer) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) {
+ err = EGL_BAD_PARAMETER;
+ break;
+ }
+
+ /* From the EGL_KHR_mutable_render_buffer spec (v12):
+ *
+ * If attribute is EGL_RENDER_BUFFER, and the EGL_SURFACE_TYPE
+ * attribute of the EGLConfig used to create surface does not contain
+ * EGL_MUTABLE_RENDER_BUFFER_BIT_KHR, [...] an EGL_BAD_MATCH error is
+ * generated [...].
+ */
+ if (!(surface->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR)) {
+ err = EGL_BAD_MATCH;
+ break;
+ }
+
+ surface->RequestedRenderBuffer = value;
+ break;
case EGL_SWAP_BEHAVIOR:
switch (value) {
case EGL_BUFFER_DESTROYED:
{
return EGL_TRUE;
}
+
+EGLBoolean
+_eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf)
+{
+ return surf->Type == EGL_WINDOW_BIT &&
+ surf->Config &&
+ (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR);
+}
+
+EGLBoolean
+_eglSurfaceInSharedBufferMode(_EGLSurface *surf)
+{
+ return _eglSurfaceHasMutableRenderBuffer(surf) &&
+ surf->ActiveRenderBuffer == EGL_SINGLE_BUFFER;
+}
* surfaces, the EGL spec hard-codes the EGL_RENDER_BUFFER value and the
* user must not provide it in the attribute list.
*
- * Refer to eglQuerySurface() in the EGL spec.
+ * Normally, the attribute is immutable and after surface creation.
+ * However, EGL_KHR_mutable_render_buffer allows the user to change it in
+ * window surfaces via eglSurfaceAttrib, in which case
+ * eglQuerySurface(EGL_RENDER_BUFFER) will immediately afterwards return
+ * the requested value but the actual render buffer used by the context
+ * does not change until completion of the next eglSwapBuffers call.
+ *
+ * From the EGL_KHR_mutable_render_buffer spec (v12):
+ *
+ * Querying EGL_RENDER_BUFFER returns the buffer which client API
+ * rendering is requested to use. For a window surface, this is the
+ * attribute value specified when the surface was created or last set
+ * via eglSurfaceAttrib.
+ *
* eglQueryContext(EGL_RENDER_BUFFER) ignores this.
*/
EGLenum RequestedRenderBuffer;
*
* Refer to eglQueryContext(EGL_RENDER_BUFFER) in the EGL spec.
* eglQuerySurface(EGL_RENDER_BUFFER) ignores this.
+ *
+ * If a window surface is bound as the draw surface and has a pending,
+ * user-requested change to EGL_RENDER_BUFFER, then the next eglSwapBuffers
+ * will flush the pending change. (The flush of EGL_RENDER_BUFFER state may
+ * occur without the implicit glFlush induced by eglSwapBuffers). The spec
+ * requires that the flush occur at that time and nowhere else. During the
+ * state-flush, we copy RequestedRenderBuffer to ActiveRenderBuffer.
+ *
+ * From the EGL_KHR_mutable_render_buffer spec (v12):
+ *
+ * If [...] there is a pending change to the EGL_RENDER_BUFFER
+ * attribute, eglSwapBuffers performs an implicit flush operation on the
+ * context and effects the attribute change.
*/
EGLenum ActiveRenderBuffer;
extern EGLBoolean
_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval);
+extern EGLBoolean
+_eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf);
+
+extern EGLBoolean
+_eglSurfaceInSharedBufferMode(_EGLSurface *surf);
/**
* Increment reference count for the surface.