From caa75a7ce07e4a5d89b0d7cf8823fe02034c1b3b Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 22 Jan 2010 14:28:23 +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 | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src/egl/drivers/xdri/egl_xdri.c') diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index 7602df11a4..f83da6652f 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -62,6 +62,7 @@ struct xdri_egl_driver { _EGLDriver Base; /**< base class */ + void (*FlushCurrentContext)(void); }; @@ -433,13 +434,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(); @@ -450,12 +461,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; @@ -551,9 +559,15 @@ 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_driver->FlushCurrentContext(); + xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable, 0, 0, 0); return EGL_TRUE; @@ -598,5 +612,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(&xdri_drv->Base, "glFlush"); + return &xdri_drv->Base; } -- cgit v1.2.3