summaryrefslogtreecommitdiff
path: root/src/egl/drivers/dri2/egl_dri2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/drivers/dri2/egl_dri2.c')
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 9c98858fd06..0a9ef86a2c3 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -300,7 +300,10 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
_eglSetConfigKey(&base, EGL_MAX_PBUFFER_HEIGHT,
_EGL_MAX_PBUFFER_HEIGHT);
break;
-
+ case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER:
+ if (disp->Extensions.KHR_mutable_render_buffer)
+ surface_type |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
+ break;
default:
key = dri2_to_egl_attribute_map[attrib];
if (key != 0)
@@ -460,6 +463,7 @@ static const struct dri2_extension_match optional_core_extensions[] = {
{ __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) },
{ __DRI2_FLUSH_CONTROL, 1, offsetof(struct dri2_egl_display, flush_control) },
{ __DRI2_BLOB, 1, offsetof(struct dri2_egl_display, blob) },
+ { __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1, offsetof(struct dri2_egl_display, mutable_render_buffer) },
{ NULL, 0, 0 }
};
@@ -1487,6 +1491,8 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+ _EGLDisplay *old_disp = NULL;
+ struct dri2_egl_display *old_dri2_dpy = NULL;
_EGLContext *old_ctx;
_EGLSurface *old_dsurf, *old_rsurf;
_EGLSurface *tmp_dsurf, *tmp_rsurf;
@@ -1503,6 +1509,11 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
return EGL_FALSE;
}
+ if (old_ctx) {
+ old_disp = old_ctx->Resource.Display;
+ old_dri2_dpy = dri2_egl_display(old_disp);
+ }
+
/* flush before context switch */
if (old_ctx)
dri2_gl_flush();
@@ -1516,6 +1527,13 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
if (old_dsurf)
dri2_surf_update_fence_fd(old_ctx, disp, old_dsurf);
+
+ /* Disable shared buffer mode */
+ if (old_dsurf && _eglSurfaceInSharedBufferMode(old_dsurf) &&
+ old_dri2_dpy->vtbl->set_shared_buffer_mode) {
+ old_dri2_dpy->vtbl->set_shared_buffer_mode(old_disp, old_dsurf, false);
+ }
+
dri2_dpy->core->unbindContext(old_cctx);
}
@@ -1528,6 +1546,11 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
tmp_dsurf == dsurf &&
tmp_rsurf == rsurf);
+ if (old_dsurf && _eglSurfaceInSharedBufferMode(old_dsurf) &&
+ old_dri2_dpy->vtbl->set_shared_buffer_mode) {
+ old_dri2_dpy->vtbl->set_shared_buffer_mode(old_disp, old_dsurf, true);
+ }
+
_eglPutSurface(dsurf);
_eglPutSurface(rsurf);
_eglPutContext(ctx);
@@ -1550,11 +1573,22 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
dri2_dpy->ref_count++;
if (old_ctx) {
- EGLDisplay old_disp = _eglGetDisplayHandle(old_ctx->Resource.Display);
dri2_destroy_context(drv, disp, old_ctx);
dri2_display_release(old_disp);
}
+ if (dsurf && _eglSurfaceHasMutableRenderBuffer(dsurf) &&
+ dri2_dpy->vtbl->set_shared_buffer_mode) {
+ /* Always update the shared buffer mode. This is obviously needed when
+ * the active EGL_RENDER_BUFFER is EGL_SINGLE_BUFFER. When
+ * EGL_RENDER_BUFFER is EGL_BACK_BUFFER, the update protects us in the
+ * case where external non-EGL API may have changed window's shared
+ * buffer mode since we last saw it.
+ */
+ bool mode = (dsurf->ActiveRenderBuffer == EGL_SINGLE_BUFFER);
+ dri2_dpy->vtbl->set_shared_buffer_mode(disp, dsurf, mode);
+ }
+
return EGL_TRUE;
}