summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2009-09-14 13:32:29 +0800
committerChia-I Wu <olvaffe@gmail.com>2009-09-14 13:39:19 +0800
commit77e2b23ea62840b90b4fb8dddf40461d91aa4a04 (patch)
treeee1d08d7044d198a40461fff5b9a8964f8a331a6
parent5f32756254034ee162f3b17e7488c660c9fa90b0 (diff)
egl_xdri: Flush commands on context switch and buffer swap.
The corresponding DRI functions does not flush for us.
-rw-r--r--src/egl/drivers/xdri/egl_xdri.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c
index 42d8726d71..682a2c3a31 100644
--- a/src/egl/drivers/xdri/egl_xdri.c
+++ b/src/egl/drivers/xdri/egl_xdri.c
@@ -65,6 +65,7 @@
struct xdri_egl_driver
{
_EGLDriver Base; /**< base class */
+ void (*FlushCurrentContext)(void);
};
@@ -495,13 +496,23 @@ static EGLBoolean
xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
_EGLSurface *r, _EGLContext *context)
{
+ struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv);
struct xdri_egl_context *xdri_ctx = lookup_context(context);
struct xdri_egl_surface *draw = lookup_surface(d);
struct xdri_egl_surface *read = lookup_surface(r);
+ _EGLContext *old = _eglGetCurrentContext();
+
+ /* an unlinked context will be invalid after context switch */
+ if (!_eglIsContextLinked(old))
+ old = NULL;
if (!_eglMakeCurrent(drv, dpy, d, r, context))
return EGL_FALSE;
+ /* flush before context switch */
+ if (old && old != context && xdri_driver->FlushCurrentContext)
+ xdri_driver->FlushCurrentContext();
+
/* the symbol is defined in libGL.so */
_glapi_check_multithread();
@@ -512,12 +523,9 @@ xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
return EGL_FALSE;
}
}
- else {
- _EGLContext *old = _eglGetCurrentContext();
- if (old) {
- xdri_ctx = lookup_context(old);
- xdri_ctx->driContext->unbindContext(xdri_ctx->driContext);
- }
+ else if (old) {
+ xdri_ctx = lookup_context(old);
+ xdri_ctx->driContext->unbindContext(xdri_ctx->driContext);
}
return EGL_TRUE;
@@ -613,9 +621,14 @@ xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
static EGLBoolean
xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
{
+ struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv);
struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
+ /* swapBuffers does not flush commands */
+ if (draw == _eglGetCurrentSurface(EGL_DRAW))
+ xdri_driver->FlushCurrentContext();
+
xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable);
return EGL_TRUE;
@@ -762,5 +775,9 @@ _eglMain(const char *args)
xdri_drv->Base.Name = "X/DRI";
xdri_drv->Base.Unload = xdri_Unload;
+ /* we need a way to flush commands */
+ xdri_drv->FlushCurrentContext =
+ (void (*)(void)) xdri_eglGetProcAddress("glFlush");
+
return &xdri_drv->Base;
}