From 77e2b23ea62840b90b4fb8dddf40461d91aa4a04 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 14 Sep 2009 13:32:29 +0800 Subject: egl_xdri: Flush commands on context switch and buffer swap. The corresponding DRI functions does not flush for us. --- src/egl/drivers/xdri/egl_xdri.c | 29 +++++++++++++++++++++++------ 1 file 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; } -- cgit v1.2.3