diff options
Diffstat (limited to 'src/egl/drivers/xdri/egl_xdri.c')
-rw-r--r-- | src/egl/drivers/xdri/egl_xdri.c | 65 |
1 files changed, 42 insertions, 23 deletions
diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index d2affc66dd..b133939155 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); }; @@ -71,6 +72,7 @@ struct xdri_egl_display Display *dpy; __GLXdisplayPrivate *dpyPriv; __GLXDRIdisplay *driDisplay; + int driVersion; __GLXscreenConfigs *psc; EGLint scr; @@ -167,14 +169,10 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) static EGLBoolean convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m) { - static const EGLint all_apis = (EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT | - EGL_OPENGL_BIT); EGLint val; _eglInitConfig(conf, id); - if (!_eglConfigFromContextModesRec(conf, m, all_apis, all_apis)) + if (!_eglConfigFromContextModesRec(conf, m, EGL_OPENGL_BIT, EGL_OPENGL_BIT)) return EGL_FALSE; if (m->doubleBufferMode) { @@ -215,6 +213,7 @@ convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m) static EGLint create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id) { + struct xdri_egl_display *xdri_dpy = lookup_display(disp); int id = first_id; for (; m; m = m->next) { @@ -224,8 +223,15 @@ create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id) if (!convert_config(&conf, id, m)) continue; - - rb = (m->doubleBufferMode) ? EGL_BACK_BUFFER : EGL_SINGLE_BUFFER; + if (m->doubleBufferMode) { + rb = EGL_BACK_BUFFER; + } + else { + /* ignore single-buffered mode for DRISW */ + if (xdri_dpy->driVersion == 0) + continue; + rb = EGL_SINGLE_BUFFER; + } xdri_conf = CALLOC_STRUCT(xdri_egl_config); if (xdri_conf) { @@ -275,7 +281,7 @@ xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } - driDisplay = __driCreateDisplay(dpyPriv, NULL); + driDisplay = __driCreateDisplay(dpyPriv, &xdri_dpy->driVersion); if (!driDisplay) { _eglLog(_EGL_WARNING, "failed to create DRI display"); free(xdri_dpy); @@ -297,16 +303,13 @@ xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } + dpy->DriverData = xdri_dpy; + dpy->ClientAPIsMask = EGL_OPENGL_BIT; + /* add visuals and fbconfigs */ first_id = create_configs(dpy, psc->visuals, first_id); create_configs(dpy, psc->configs, first_id); - dpy->DriverData = xdri_dpy; - dpy->ClientAPIsMask = (EGL_OPENGL_BIT | - EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT); - /* we're supporting EGL 1.4 */ *minor = 1; *major = 4; @@ -342,7 +345,6 @@ xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) } xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay); - __glXRelease(xdri_dpy->dpyPriv); free(xdri_dpy); dpy->DriverData = NULL; @@ -355,7 +357,7 @@ xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) * Called from eglGetProcAddress() via drv->API.GetProcAddress(). */ static _EGLProc -xdri_eglGetProcAddress(const char *procname) +xdri_eglGetProcAddress(_EGLDriver *drv, const char *procname) { /* the symbol is defined in libGL.so */ return (_EGLProc) _glapi_get_proc_address(procname); @@ -441,13 +443,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(); @@ -458,12 +470,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; @@ -559,10 +568,16 @@ 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); - xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable); + /* 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; } @@ -606,5 +621,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; } |