diff options
Diffstat (limited to 'src/egl')
42 files changed, 3296 insertions, 2757 deletions
diff --git a/src/egl/drivers/demo/demo.c b/src/egl/drivers/demo/demo.c index 1750e976b84..aea4894448b 100644 --- a/src/egl/drivers/demo/demo.c +++ b/src/egl/drivers/demo/demo.c @@ -49,9 +49,8 @@ typedef struct demo_context static EGLBoolean -demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) +demoInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); _EGLScreen *scrn; EGLint i; @@ -85,7 +84,9 @@ demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) _eglAddConfig(disp, config); } - drv->Initialized = EGL_TRUE; + /* enable supported extensions */ + disp->Extensions.MESA_screen_surface = EGL_TRUE; + disp->Extensions.MESA_copy_context = EGL_TRUE; *major = 1; *minor = 0; @@ -95,71 +96,56 @@ demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) static EGLBoolean -demoTerminate(_EGLDriver *drv, EGLDisplay dpy) +demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy) { /*DemoDriver *demo = DEMO_DRIVER(dpy);*/ - free(drv); return EGL_TRUE; } static DemoContext * -LookupDemoContext(EGLContext ctx) +LookupDemoContext(_EGLContext *c) { - _EGLContext *c = _eglLookupContext(ctx); return (DemoContext *) c; } static DemoSurface * -LookupDemoSurface(EGLSurface surf) +LookupDemoSurface(_EGLSurface *s) { - _EGLSurface *s = _eglLookupSurface(surf); return (DemoSurface *) s; } - -static EGLContext -demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) +static _EGLContext * +demoCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list) { - _EGLConfig *conf; DemoContext *c; int i; - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { switch (attrib_list[i]) { /* no attribs defined for now */ default: _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); - return EGL_NO_CONTEXT; + return NULL; } } c = (DemoContext *) calloc(1, sizeof(DemoContext)); if (!c) - return EGL_NO_CONTEXT; + return NULL; - _eglInitContext(drv, dpy, &c->Base, config, attrib_list); + _eglInitContext(drv, &c->Base, conf, attrib_list); c->DemoStuff = 1; printf("demoCreateContext\n"); - /* generate handle and insert into hash table */ - _eglSaveContext(&c->Base); - assert(_eglGetContextHandle(&c->Base)); - - return _eglGetContextHandle(&c->Base); + return &c->Base; } -static EGLSurface -demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) +static _EGLSurface * +demoCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) { int i; for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { @@ -167,107 +153,88 @@ demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nativ /* no attribs at this time */ default: _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface"); - return EGL_NO_SURFACE; + return NULL; } } printf("eglCreateWindowSurface()\n"); /* XXX unfinished */ - return EGL_NO_SURFACE; + return NULL; } -static EGLSurface -demoCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) +static _EGLSurface * +demoCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list) { - _EGLConfig *conf; EGLint i; - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; - } - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { switch (attrib_list[i]) { /* no attribs at this time */ default: _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; + return NULL; } } if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) { _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; + return NULL; } printf("eglCreatePixmapSurface()\n"); - return EGL_NO_SURFACE; + return NULL; } -static EGLSurface -demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +static _EGLSurface * +demoCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list) { DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface)); + if (!surf) - return EGL_NO_SURFACE; + return NULL; - if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_PBUFFER_BIT, - config, attrib_list)) { + if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT, + conf, attrib_list)) { free(surf); - return EGL_NO_SURFACE; + return NULL; } /* a real driver would allocate the pbuffer memory here */ - return surf->Base.Handle; + return &surf->Base; } static EGLBoolean -demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +demoDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) { DemoSurface *fs = LookupDemoSurface(surface); - _eglRemoveSurface(&fs->Base); - if (fs->Base.IsBound) { - fs->Base.DeletePending = EGL_TRUE; - } - else { + if (!_eglIsSurfaceBound(&fs->Base)) free(fs); - } return EGL_TRUE; } static EGLBoolean -demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) +demoDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context) { DemoContext *fc = LookupDemoContext(context); - _eglRemoveContext(&fc->Base); - if (fc->Base.IsBound) { - fc->Base.DeletePending = EGL_TRUE; - } - else { + if (!_eglIsContextBound(&fc->Base)) free(fc); - } return EGL_TRUE; } static EGLBoolean -demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) +demoMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *drawSurf, _EGLSurface *readSurf, _EGLContext *ctx) { /*DemoDriver *demo = DEMO_DRIVER(dpy);*/ - DemoSurface *readSurf = LookupDemoSurface(read); - DemoSurface *drawSurf = LookupDemoSurface(draw); - DemoContext *ctx = LookupDemoContext(context); EGLBoolean b; - b = _eglMakeCurrent(drv, dpy, draw, read, context); + b = _eglMakeCurrent(drv, dpy, drawSurf, readSurf, ctx); if (!b) return EGL_FALSE; @@ -281,12 +248,19 @@ demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface rea } +static void +demoUnload(_EGLDriver *drv) +{ + free(drv); +} + + /** * The bootstrap function. Return a new DemoDriver object and * plug in API functions. */ _EGLDriver * -_eglMain(_EGLDisplay *dpy, const char *args) +_eglMain(const char *args) { DemoDriver *demo; @@ -308,9 +282,8 @@ _eglMain(_EGLDisplay *dpy, const char *args) demo->Base.API.DestroySurface = demoDestroySurface; demo->Base.API.DestroyContext = demoDestroyContext; - /* enable supported extensions */ - demo->Base.Extensions.MESA_screen_surface = EGL_TRUE; - demo->Base.Extensions.MESA_copy_context = EGL_TRUE; + demo->Base.Name = "egl/demo"; + demo->Base.Unload = demoUnload; return &demo->Base; } diff --git a/src/egl/drivers/dri/Makefile b/src/egl/drivers/dri/Makefile index 4041d5c906a..7339c97c77d 100644 --- a/src/egl/drivers/dri/Makefile +++ b/src/egl/drivers/dri/Makefile @@ -50,11 +50,12 @@ $(TOP)/$(LIB_DIR)/libEGLdri.so: $(OBJECTS) install: $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(INSTALL) $(TOP)/$(LIB_DIR)/libEGLdri.so $(DESTDIR)$(INSTALL_LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libEGLdri.so $(DESTDIR)$(INSTALL_LIB_DIR) clean: -rm -f *.o -rm -f *.so + -rm -f depend depend.bak depend: $(SOURCES) $(HEADERS) @ echo "running $(MKDEP)" diff --git a/src/egl/drivers/dri/egldri.c b/src/egl/drivers/dri/egldri.c index 57661cc3ab8..9e400be6248 100644 --- a/src/egl/drivers/dri/egldri.c +++ b/src/egl/drivers/dri/egldri.c @@ -171,7 +171,10 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, if (!c) return EGL_NO_CONTEXT; - if (!_eglInitContext(drv, dpy, &c->Base, config, attrib_list)) { + conf = _eglLookupConfig(drv, dpy, config); + assert(conf); + + if (!_eglInitContext(drv, &c->Base, conf, attrib_list)) { free(c); return EGL_NO_CONTEXT; } @@ -189,8 +192,6 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, else sharePriv = NULL; - conf = _eglLookupConfig(drv, dpy, config); - assert(conf); _eglConfigToContextModesRec(conf, &visMode); c->driContext.private = disp->driScreen.createNewContext(disp, &visMode, @@ -200,8 +201,8 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_FALSE; } - /* generate handle and insert into hash table */ - _eglSaveContext(&c->Base); + /* link to display */ + _eglLinkContext(&c->Base, &disp->Base); return _eglGetContextHandle(&c->Base); } @@ -237,14 +238,18 @@ _eglDRICreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { driSurface *surf; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + assert(conf); surf = (driSurface *) calloc(1, sizeof(*surf)); if (!surf) { return EGL_NO_SURFACE; } - if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_PBUFFER_BIT, - config, attrib_list)) { + if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT, + conf, attrib_list)) { free(surf); return EGL_NO_SURFACE; } @@ -275,7 +280,7 @@ _eglDRICreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, #endif } - _eglSaveSurface(&surf->Base); + _eglLinkSurface(&surf->Base, _eglLookupDisplay(dpy)); return surf->Base.Handle; } @@ -287,16 +292,12 @@ _eglDRIDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) driDisplay *disp = Lookup_driDisplay(dpy); driSurface *fs = Lookup_driSurface(surface); - _eglRemoveSurface(&fs->Base); + _eglUnlinkSurface(&fs->Base); fs->drawable.destroyDrawable(disp, fs->drawable.private); - if (fs->Base.IsBound) { - fs->Base.DeletePending = EGL_TRUE; - } - else { + if (!_eglIsSurfaceBound(&fs->Base)) free(fs); - } return EGL_TRUE; } @@ -307,16 +308,12 @@ _eglDRIDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) driDisplay *disp = Lookup_driDisplay(dpy); driContext *fc = Lookup_driContext(context); - _eglRemoveContext(&fc->Base); + _eglUnlinkContext(&fc->Base); fc->driContext.destroyContext(disp, 0, fc->driContext.private); - if (fc->Base.IsBound) { - fc->Base.DeletePending = EGL_TRUE; - } - else { + if (!_eglIsContextBound(&fc->Base)) free(fc); - } return EGL_TRUE; } @@ -340,13 +337,13 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, } /* init base class, do error checking, etc. */ - if (!_eglInitSurface(drv, dpy, &surface->Base, EGL_SCREEN_BIT_MESA, - cfg, attrib_list)) { + if (!_eglInitSurface(drv, &surface->Base, EGL_SCREEN_BIT_MESA, + config, attrib_list)) { free(surface); return EGL_NO_SURFACE; } - _eglSaveSurface(&surface->Base); + _eglLinkSurface(&surface->Base &disp->Base); /* @@ -363,7 +360,7 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, if (!disp->driScreen.createNewDrawable(disp, &visMode, drawBuf, &surface->drawable, GLX_WINDOW_BIT, empty_attribute_list)) { - _eglRemoveSurface(&surface->Base); + _eglUnlinkSurface(&surface->Base); free(surface); return EGL_NO_SURFACE; } diff --git a/src/egl/drivers/glx/Makefile b/src/egl/drivers/glx/Makefile index 5f041a268f1..20ef0352ad9 100644 --- a/src/egl/drivers/glx/Makefile +++ b/src/egl/drivers/glx/Makefile @@ -58,7 +58,7 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS) install: $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(INSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(DESTDIR)$(INSTALL_LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(DESTDIR)$(INSTALL_LIB_DIR) clean: rm -f *.o diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 155caa413c8..3c8f8b6a684 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -57,7 +57,6 @@ #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" -#include "eglhash.h" #include "egllog.h" #include "eglsurface.h" @@ -157,6 +156,13 @@ GLX_egl_surface(_EGLSurface *surf) return (struct GLX_egl_surface *) surf; } +static int +GLX_egl_config_id(_EGLConfig *conf) +{ + /* see create_configs */ + return (int) _eglPointerToUInt(_eglGetConfigHandle(conf)) - 1; +} + static GLboolean get_visual_attribs(Display *dpy, XVisualInfo *vInfo, struct visual_attribs *attribs) @@ -351,7 +357,6 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv) int numVisuals; long mask; int i; - int egl_configs = 1; struct visual_attribs attribs; GLX_drv->fbconfigs = NULL; @@ -441,11 +446,10 @@ end: * Called via eglInitialize(), GLX_drv->API.Initialize(). */ static EGLBoolean -GLX_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, +GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *minor, EGLint *major) { struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv); - _EGLDisplay *disp = _eglLookupDisplay(dpy); _eglLog(_EGL_DEBUG, "GLX: eglInitialize"); @@ -457,10 +461,10 @@ GLX_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, } } + disp->ClientAPIsMask = all_apis; + glXQueryVersion(disp->Xdpy, &GLX_drv->glx_maj, &GLX_drv->glx_min); - GLX_drv->Base.Initialized = EGL_TRUE; - GLX_drv->Base.Name = "GLX"; /* we're supporting EGL 1.4 */ @@ -504,13 +508,13 @@ FreeDisplayExt(Display *dpy) * Called via eglTerminate(), drv->API.Terminate(). */ static EGLBoolean -GLX_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) +GLX_eglTerminate(_EGLDriver *drv, _EGLDisplay *disp) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - _eglLog(_EGL_DEBUG, "GLX: eglTerminate"); + _eglReleaseDisplayResources(drv, disp); FreeDisplayExt(disp->Xdpy); + _eglCleanupDisplay(disp); return EGL_TRUE; } @@ -519,42 +523,37 @@ GLX_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) /** * Called via eglCreateContext(), drv->API.CreateContext(). */ -static EGLContext -GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, - EGLContext share_list, const EGLint *attrib_list) +static _EGLContext * +GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, + _EGLContext *share_list, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); struct GLX_egl_context *GLX_ctx = CALLOC_STRUCT(GLX_egl_context); struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv); - struct GLX_egl_context *GLX_ctx_shared = NULL; - _EGLConfig *conf; + struct GLX_egl_context *GLX_ctx_shared = GLX_egl_context(share_list); if (!GLX_ctx) - return EGL_NO_CONTEXT; + return NULL; - if (!_eglInitContext(drv, dpy, &GLX_ctx->Base, config, attrib_list)) { + if (!_eglInitContext(drv, &GLX_ctx->Base, conf, attrib_list)) { free(GLX_ctx); - return EGL_NO_CONTEXT; - } - - if (share_list != EGL_NO_CONTEXT) { - _EGLContext *shareCtx = _eglLookupContext(share_list); - if (!shareCtx) { - _eglError(EGL_BAD_CONTEXT, "eglCreateContext(share_list)"); - return EGL_FALSE; - } - GLX_ctx_shared = GLX_egl_context(shareCtx); + return NULL; } - conf = _eglLookupConfig(drv, dpy, config); - assert(conf); - #ifdef GLX_VERSION_1_3 if (GLX_drv->fbconfigs) - GLX_ctx->context = glXCreateNewContext(disp->Xdpy, GLX_drv->fbconfigs[(int)config-1], GLX_RGBA_TYPE, GLX_ctx_shared ? GLX_ctx_shared->context : NULL, GL_TRUE); + GLX_ctx->context = + glXCreateNewContext(disp->Xdpy, + GLX_drv->fbconfigs[GLX_egl_config_id(conf)], + GLX_RGBA_TYPE, + GLX_ctx_shared ? GLX_ctx_shared->context : NULL, + GL_TRUE); else #endif - GLX_ctx->context = glXCreateContext(disp->Xdpy, &GLX_drv->visuals[(int)config-1], GLX_ctx_shared ? GLX_ctx_shared->context : NULL, GL_TRUE); + GLX_ctx->context = + glXCreateContext(disp->Xdpy, + &GLX_drv->visuals[GLX_egl_config_id(conf)], + GLX_ctx_shared ? GLX_ctx_shared->context : NULL, + GL_TRUE); if (!GLX_ctx->context) return EGL_FALSE; @@ -564,7 +563,7 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_FALSE; #endif - return _eglGetContextHandle(&GLX_ctx->Base); + return &GLX_ctx->Base; } @@ -572,18 +571,14 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ static EGLBoolean -GLX_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, - EGLSurface r, EGLContext context) +GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, + _EGLSurface *rsurf, _EGLContext *ctx) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - _EGLContext *ctx = _eglLookupContext(context); - _EGLSurface *dsurf = _eglLookupSurface(d); - _EGLSurface *rsurf = _eglLookupSurface(r); struct GLX_egl_surface *GLX_dsurf = GLX_egl_surface(dsurf); struct GLX_egl_surface *GLX_rsurf = GLX_egl_surface(rsurf); struct GLX_egl_context *GLX_ctx = GLX_egl_context(ctx); - if (!_eglMakeCurrent(drv, dpy, d, r, context)) + if (!_eglMakeCurrent(drv, disp, dsurf, rsurf, ctx)) return EGL_FALSE; #ifdef GLX_VERSION_1_3 @@ -612,92 +607,86 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) /** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ -static EGLSurface -GLX_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +static _EGLSurface * +GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); struct GLX_egl_surface *GLX_surf; uint width, height; GLX_surf = CALLOC_STRUCT(GLX_egl_surface); if (!GLX_surf) - return EGL_NO_SURFACE; + return NULL; - if (!_eglInitSurface(drv, dpy, &GLX_surf->Base, EGL_WINDOW_BIT, - config, attrib_list)) { + if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_WINDOW_BIT, + conf, attrib_list)) { free(GLX_surf); - return EGL_FALSE; + return NULL; } - _eglSaveSurface(&GLX_surf->Base); - GLX_surf->drawable = window; get_drawable_size(disp->Xdpy, window, &width, &height); GLX_surf->Base.Width = width; GLX_surf->Base.Height = height; - return _eglGetSurfaceHandle(&GLX_surf->Base); + return &GLX_surf->Base; } #ifdef GLX_VERSION_1_3 -static EGLSurface -GLX_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +static _EGLSurface * +GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list) { struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv); - _EGLDisplay *disp = _eglLookupDisplay(dpy); struct GLX_egl_surface *GLX_surf; int i; GLX_surf = CALLOC_STRUCT(GLX_egl_surface); if (!GLX_surf) - return EGL_NO_SURFACE; + return NULL; - if (!_eglInitSurface(drv, dpy, &GLX_surf->Base, EGL_PIXMAP_BIT, - config, attrib_list)) { + if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PIXMAP_BIT, + conf, attrib_list)) { free(GLX_surf); - return EGL_FALSE; + return NULL; } - _eglSaveSurface(&GLX_surf->Base); - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { switch (attrib_list[i]) { /* no attribs at this time */ default: _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; + return NULL; } } - GLX_surf->drawable = glXCreatePixmap(disp->Xdpy, GLX_drv->fbconfigs[(int)config-1], pixmap, NULL); + GLX_surf->drawable = + glXCreatePixmap(disp->Xdpy, + GLX_drv->fbconfigs[GLX_egl_config_id(conf)], + pixmap, NULL); - return _eglGetSurfaceHandle(&GLX_surf->Base); + return &GLX_surf->Base; } -static EGLSurface -GLX_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +static _EGLSurface * +GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, const EGLint *attrib_list) { struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv); - _EGLDisplay *disp = _eglLookupDisplay(dpy); struct GLX_egl_surface *GLX_surf; int attribs[5]; int i = 0, j = 0; GLX_surf = CALLOC_STRUCT(GLX_egl_surface); if (!GLX_surf) - return EGL_NO_SURFACE; + return NULL; - if (!_eglInitSurface(drv, dpy, &GLX_surf->Base, EGL_PBUFFER_BIT, - config, attrib_list)) { + if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PBUFFER_BIT, + conf, attrib_list)) { free(GLX_surf); - return EGL_NO_SURFACE; + return NULL; } - _eglSaveSurface(&GLX_surf->Base); - while(attrib_list[i] != EGL_NONE) { switch (attrib_list[i]) { case EGL_WIDTH: @@ -713,42 +702,40 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, } attribs[j++] = 0; - GLX_surf->drawable = glXCreatePbuffer(disp->Xdpy, GLX_drv->fbconfigs[(int)config-1], attribs); + GLX_surf->drawable = + glXCreatePbuffer(disp->Xdpy, + GLX_drv->fbconfigs[GLX_egl_config_id(conf)], attribs); - return _eglGetSurfaceHandle(&GLX_surf->Base); + return &GLX_surf->Base; } #endif static EGLBoolean -GLX_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface); - return EGL_TRUE; - if (surf) { - _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface); - if (surf->IsBound) { - surf->DeletePending = EGL_TRUE; - } - else { - free(surf); + if (!_eglIsSurfaceBound(surf)) { + struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); + switch (surf->Type) { + case EGL_PBUFFER_BIT: + glXDestroyPbuffer(disp->Xdpy, GLX_surf->drawable); + break; + case EGL_PIXMAP_BIT: + glXDestroyPixmap(disp->Xdpy, GLX_surf->drawable); + break; + default: + break; } - - return EGL_TRUE; - } - else { - _eglError(EGL_BAD_SURFACE, "eglDestroySurface"); - return EGL_FALSE; + free(surf); } + + return EGL_TRUE; } static EGLBoolean -GLX_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, +GLX_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface); struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); /* buffer ?? */ @@ -759,11 +746,9 @@ GLX_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, static EGLBoolean -GLX_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, +GLX_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface); struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); /* buffer ?? */ @@ -774,16 +759,14 @@ GLX_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, static EGLBoolean -GLX_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +GLX_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(draw); - struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); + struct GLX_egl_surface *GLX_surf = GLX_egl_surface(draw); _eglLog(_EGL_DEBUG, "GLX: EGL SwapBuffers 0x%x",draw); /* error checking step: */ - if (!_eglSwapBuffers(drv, dpy, draw)) + if (!_eglSwapBuffers(drv, disp, draw)) return EGL_FALSE; glXSwapBuffers(disp->Xdpy, GLX_surf->drawable); @@ -802,28 +785,36 @@ GLX_eglGetProcAddress(const char *procname) * some point. */ _EGLProc (*get_proc_addr)(const char *procname); + _EGLProc proc_addr; get_proc_addr = dlsym(NULL, "st_get_proc_address"); if (get_proc_addr) return get_proc_addr(procname); - get_proc_addr = glXGetProcAddress((const GLubyte *)procname); - if (get_proc_addr) - return get_proc_addr(procname); + proc_addr = glXGetProcAddress((const GLubyte *)procname); + if (proc_addr) + return proc_addr; return (_EGLProc)dlsym(NULL, procname); } +static void +GLX_Unload(_EGLDriver *drv) +{ + struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv); + free(GLX_drv); +} + + /** * This is the main entrypoint into the driver, called by libEGL. * Create a new _EGLDriver object and init its dispatch table. */ _EGLDriver * -_eglMain(_EGLDisplay *disp, const char *args) +_eglMain(const char *args) { struct GLX_egl_driver *GLX_drv = CALLOC_STRUCT(GLX_egl_driver); char *env; - int maj = 0, min = 0; if (!GLX_drv) return NULL; @@ -849,8 +840,8 @@ _eglMain(_EGLDisplay *disp, const char *args) GLX_drv->Base.API.SwapBuffers = GLX_eglSwapBuffers; GLX_drv->Base.API.GetProcAddress = GLX_eglGetProcAddress; - GLX_drv->Base.ClientAPIsMask = all_apis; GLX_drv->Base.Name = "GLX"; + GLX_drv->Base.Unload = GLX_Unload; _eglLog(_EGL_DEBUG, "GLX: main(%s)", args); diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile index eb83867b718..4c1fc9071c5 100644 --- a/src/egl/drivers/xdri/Makefile +++ b/src/egl/drivers/xdri/Makefile @@ -16,19 +16,24 @@ INCLUDE_DIRS = \ $(shell pkg-config --cflags-only-I libdrm) \ -I$(TOP)/include \ -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/drivers/dri/common \ -I$(TOP)/src/egl/main \ -I$(TOP)/src/glx/x11 -SOURCES = egl_xdri.c +HEADERS = glxinit.h driinit.h +SOURCES = egl_xdri.c glxinit.c driinit.c + +DRI_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c +DRI_SOURCES := $(addprefix ../../../glx/x11/,$(DRI_SOURCES)) + +SOURCES += $(DRI_SOURCES) OBJECTS = $(SOURCES:.c=.o) DRM_LIB = `pkg-config --libs libdrm` -MISC_LIBS = -ldl -lXext -lGL - +CFLAGS += -DGLX_DIRECT_RENDERING .c.o: $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ @@ -50,11 +55,11 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS) -major 1 -minor 0 \ -L$(TOP)/$(LIB_DIR) \ -install $(TOP)/$(LIB_DIR) \ - $(OBJECTS) $(DRM_LIB) $(MISC_LIBS) + $(OBJECTS) $(DRM_LIB) $(GL_LIB_DEPS) install: $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(INSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(DESTDIR)$(INSTALL_LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(DESTDIR)$(INSTALL_LIB_DIR) clean: rm -f *.o diff --git a/src/egl/drivers/xdri/driinit.c b/src/egl/drivers/xdri/driinit.c new file mode 100644 index 00000000000..12da1bcd248 --- /dev/null +++ b/src/egl/drivers/xdri/driinit.c @@ -0,0 +1,67 @@ +/** + * DRI initialization. The DRI loaders are defined in src/glx/x11/. + */ + +#include <sys/time.h> + +#include "glxclient.h" +#include "driinit.h" + +/* for __DRI_SYSTEM_TIME extension */ +_X_HIDDEN int +__glXGetUST(int64_t * ust) +{ + struct timeval tv; + + if (ust == NULL) { + return -EFAULT; + } + + if (gettimeofday(&tv, NULL) == 0) { + ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec; + return 0; + } + else { + return -errno; + } +} + +_X_HIDDEN GLboolean +__driGetMscRateOML(__DRIdrawable * draw, + int32_t * numerator, int32_t * denominator, void *private) +{ + return GL_FALSE; +} + +/* ignore glx extensions */ +_X_HIDDEN void +__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name) +{ +} + +_X_HIDDEN __GLXDRIdisplay * +__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version) +{ + __GLXDRIdisplay *driDisplay; + int ver = 0; + + /* try DRI2 first */ + driDisplay = dri2CreateDisplay(dpyPriv->dpy); + if (driDisplay) { + /* fill in the required field */ + dpyPriv->dri2Display = driDisplay; + ver = 2; + } + else { + /* try DRI */ + driDisplay = driCreateDisplay(dpyPriv->dpy); + if (driDisplay) { + dpyPriv->driDisplay = driDisplay; + ver = 1; + } + } + + if (version) + *version = ver; + return driDisplay; +} diff --git a/src/egl/drivers/xdri/driinit.h b/src/egl/drivers/xdri/driinit.h new file mode 100644 index 00000000000..6ea05cebefd --- /dev/null +++ b/src/egl/drivers/xdri/driinit.h @@ -0,0 +1,9 @@ +#ifndef DRIINIT_INCLUDED +#define DRIINIT_INCLUDED + +#include "glxclient.h" + +extern __GLXDRIdisplay * +__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version); + +#endif /* DRIINIT_INCLUDED */ diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index 3b3e312746e..518091a2d14 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -39,63 +39,40 @@ * Authors: Brian Paul */ - #include <assert.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include "dlfcn.h" +#include <stdlib.h> #include <X11/Xlib.h> -#include <GL/gl.h> -#include "xf86dri.h" -#include "glxclient.h" -#include "dri_util.h" -#include "drm_sarea.h" -#define _EGL_PLATFORM_X +#include "glxinit.h" +#include "driinit.h" +#include "glapi/glapi.h" /* for glapi functions */ #include "eglconfig.h" #include "eglcontext.h" #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" -#include "eglhash.h" #include "egllog.h" #include "eglsurface.h" -#include <GL/gl.h> - -typedef void (*glGetIntegerv_t)(GLenum, GLint *); -typedef void (*glBindTexture_t)(GLenum, GLuint); -typedef void (*glCopyTexImage2D_t)(GLenum, GLint, GLenum, GLint, GLint, - GLint, GLint, GLint); - - #define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T)) - /** subclass of _EGLDriver */ struct xdri_egl_driver { _EGLDriver Base; /**< base class */ - - const char *dri_driver_name; /**< name of DRI driver to load */ - void *dri_driver_handle; /**< returned by dlopen(dri_driver_name) */ - - __GLXdisplayPrivate *glx_priv; +}; - /* XXX we're not actually using these at this time: */ - int chipset; - int minor; - int drmFD; +/** driver data of _EGLDisplay */ +struct xdri_egl_display +{ + Display *dpy; + __GLXdisplayPrivate *dpyPriv; + __GLXDRIdisplay *driDisplay; - __DRIframebuffer framebuffer; - drm_handle_t hSAREA; - drmAddress pSAREA; - char *busID; - drm_magic_t magic; + __GLXscreenConfigs *psc; + EGLint scr; }; @@ -104,9 +81,10 @@ struct xdri_egl_context { _EGLContext Base; /**< base class */ - __DRIcontext driContext; + /* just enough info to create dri contexts */ + GLXContext dummy_gc; - GLint bound_tex_object; + __GLXDRIcontext *driContext; }; @@ -115,8 +93,8 @@ struct xdri_egl_surface { _EGLSurface Base; /**< base class */ - __DRIid driDrawable; /**< DRI surface */ - drm_drawable_t hDrawable; + Drawable drawable; + __GLXDRIdrawable *driDrawable; }; @@ -131,46 +109,44 @@ struct xdri_egl_config /** cast wrapper */ -static struct xdri_egl_driver * +static INLINE struct xdri_egl_driver * xdri_egl_driver(_EGLDriver *drv) { return (struct xdri_egl_driver *) drv; } +static INLINE struct xdri_egl_display * +lookup_display(_EGLDisplay *dpy) +{ + return (struct xdri_egl_display *) dpy->DriverData; +} + + /** Map EGLSurface handle to xdri_egl_surface object */ -static struct xdri_egl_surface * -lookup_surface(EGLSurface surf) +static INLINE struct xdri_egl_surface * +lookup_surface(_EGLSurface *surface) { - _EGLSurface *surface = _eglLookupSurface(surf); return (struct xdri_egl_surface *) surface; } /** Map EGLContext handle to xdri_egl_context object */ -static struct xdri_egl_context * -lookup_context(EGLContext c) +static INLINE struct xdri_egl_context * +lookup_context(_EGLContext *context) { - _EGLContext *context = _eglLookupContext(c); return (struct xdri_egl_context *) context; } -static struct xdri_egl_context * -current_context(void) -{ - return (struct xdri_egl_context *) _eglGetCurrentContext(); -} /** Map EGLConfig handle to xdri_egl_config object */ -static struct xdri_egl_config * -lookup_config(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config) +static INLINE struct xdri_egl_config * +lookup_config(_EGLConfig *conf) { - _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); return (struct xdri_egl_config *) conf; } - /** Get size of given window */ static Status get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) @@ -188,22 +164,18 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) /** * Produce a set of EGL configs. - * Note that we get the list of GLcontextModes from the GLX library. - * This dependency on GLX lib will be removed someday. */ -static void -create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv) +static EGLint +create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id) { static const EGLint all_apis = (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENVG_BIT | EGL_OPENGL_BIT); - __GLXscreenConfigs *scrn = glx_priv->screenConfigs; - const __GLcontextModes *m; - int id = 1; + int id = first_id; - for (m = scrn->configs; m; m = m->next) { - /* EGL requires double-buffered configs */ + for (; m; m = m->next) { + /* add double buffered visual */ if (m->doubleBufferMode) { struct xdri_egl_config *config = CALLOC_STRUCT(xdri_egl_config); @@ -222,9 +194,7 @@ create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv) SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_TYPE, m->visualType); SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis); SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis); - /* XXX only window rendering allowed ATM */ - SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, - (EGL_WINDOW_BIT | EGL_PBUFFER_BIT)); + SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT); /* XXX possibly other things to init... */ @@ -234,431 +204,76 @@ create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv) _eglAddConfig(disp, &config->Base); } } -} - - -/** - * Called via __DRIinterfaceMethods object - */ -static __DRIfuncPtr -dri_get_proc_address(const char * proc_name) -{ - return NULL; -} - - -static void -dri_context_modes_destroy(__GLcontextModes *modes) -{ - _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); - - while (modes) { - __GLcontextModes * const next = modes->next; - free(modes); - modes = next; - } -} - - -/** - * Create a linked list of 'count' GLcontextModes. - * These are used during the client/server visual negotiation phase, - * then discarded. - */ -static __GLcontextModes * -dri_context_modes_create(unsigned count, size_t minimum_size) -{ - /* This code copied from libGLX, and modified */ - const size_t size = (minimum_size > sizeof(__GLcontextModes)) - ? minimum_size : sizeof(__GLcontextModes); - __GLcontextModes * head = NULL; - __GLcontextModes ** next; - unsigned i; - - next = & head; - for (i = 0 ; i < count ; i++) { - *next = (__GLcontextModes *) calloc(1, size); - if (*next == NULL) { - dri_context_modes_destroy(head); - head = NULL; - break; - } - - (*next)->doubleBufferMode = 1; - (*next)->visualID = GLX_DONT_CARE; - (*next)->visualType = GLX_DONT_CARE; - (*next)->visualRating = GLX_NONE; - (*next)->transparentPixel = GLX_NONE; - (*next)->transparentRed = GLX_DONT_CARE; - (*next)->transparentGreen = GLX_DONT_CARE; - (*next)->transparentBlue = GLX_DONT_CARE; - (*next)->transparentAlpha = GLX_DONT_CARE; - (*next)->transparentIndex = GLX_DONT_CARE; - (*next)->xRenderable = GLX_DONT_CARE; - (*next)->fbconfigID = GLX_DONT_CARE; - (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; - (*next)->bindToTextureRgb = GLX_DONT_CARE; - (*next)->bindToTextureRgba = GLX_DONT_CARE; - (*next)->bindToMipmapTexture = GLX_DONT_CARE; - (*next)->bindToTextureTargets = 0; - (*next)->yInverted = GLX_DONT_CARE; - - next = & ((*next)->next); - } - - return head; -} - - -static __DRIscreen * -dri_find_dri_screen(__DRInativeDisplay *ndpy, int scrn) -{ - __GLXdisplayPrivate *priv = __glXInitialize(ndpy); - __GLXscreenConfigs *scrnConf = priv->screenConfigs; - return &scrnConf->driScreen; -} - - -static GLboolean -dri_window_exists(__DRInativeDisplay *ndpy, __DRIid draw) -{ - return EGL_TRUE; -} - - -static GLboolean -dri_create_context(__DRInativeDisplay *ndpy, int screenNum, int configID, - void * contextID, drm_context_t * hw_context) -{ - assert(configID >= 0); - return XF86DRICreateContextWithConfig(ndpy, screenNum, - configID, contextID, hw_context); -} - - -static GLboolean -dri_destroy_context(__DRInativeDisplay * ndpy, int screen, __DRIid context) -{ - return XF86DRIDestroyContext(ndpy, screen, context); -} - - -static GLboolean -dri_create_drawable(__DRInativeDisplay * ndpy, int screen, - __DRIid drawable, drm_drawable_t * hHWDrawable) -{ - _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__); - - /* Create DRI drawable for given window ID (drawable) */ - if (!XF86DRICreateDrawable(ndpy, screen, drawable, hHWDrawable)) - return EGL_FALSE; - - return EGL_TRUE; -} - - -static GLboolean -dri_destroy_drawable(__DRInativeDisplay * ndpy, int screen, __DRIid drawable) -{ - _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__); - return XF86DRIDestroyDrawable(ndpy, screen, drawable); -} - - -static GLboolean -dri_get_drawable_info(__DRInativeDisplay *ndpy, int scrn, - __DRIid draw, unsigned int * index, unsigned int * stamp, - int * x, int * y, int * width, int * height, - int * numClipRects, drm_clip_rect_t ** pClipRects, - int * backX, int * backY, - int * numBackClipRects, - drm_clip_rect_t ** pBackClipRects) -{ - _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__); - - if (!XF86DRIGetDrawableInfo(ndpy, scrn, draw, index, stamp, - x, y, width, height, - numClipRects, pClipRects, - backX, backY, - numBackClipRects, pBackClipRects)) { - return EGL_FALSE; - } - return EGL_TRUE; + return id; } /** - * Table of functions exported by the loader to the driver. + * Called via eglInitialize(), xdri_dpy->API.Initialize(). */ -static const __DRIinterfaceMethods interface_methods = { - dri_get_proc_address, - - dri_context_modes_create, - dri_context_modes_destroy, - - dri_find_dri_screen, - dri_window_exists, - - dri_create_context, - dri_destroy_context, - - dri_create_drawable, - dri_destroy_drawable, - dri_get_drawable_info, - - NULL,/*__eglGetUST,*/ - NULL,/*__eglGetMSCRate,*/ -}; - - - static EGLBoolean -init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp) +xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, + EGLint *minor, EGLint *major) { - __DRIversion ddx_version; - __DRIversion dri_version; - __DRIversion drm_version; - drmVersionPtr version; - drm_handle_t hFB; - int newlyopened; - int status; - int scrn = DefaultScreen(disp->Xdpy); - -#if 0 - createNewScreen = (PFNCREATENEWSCREENFUNC) - dlsym(xdri_drv->dri_driver_handle, createNewScreenName); - if (!createNewScreen) { - _eglLog(_EGL_WARNING, "XDRI: Couldn't find %s function in the driver.", - createNewScreenName); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: Found %s", createNewScreenName); - } -#endif - - /* - * Get the DRI X extension version. - */ - dri_version.major = 4; - dri_version.minor = 0; - dri_version.patch = 0; - - if (!XF86DRIOpenConnection(disp->Xdpy, scrn, - &xdri_drv->hSAREA, &xdri_drv->busID)) { - _eglLog(_EGL_WARNING, "XF86DRIOpenConnection failed"); - } - - xdri_drv->drmFD = drmOpenOnce(NULL, xdri_drv->busID, &newlyopened); - if (xdri_drv->drmFD < 0) { - perror("drmOpenOnce failed: "); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: drmOpenOnce returned %d", xdri_drv->drmFD); - } - - - if (drmGetMagic(xdri_drv->drmFD, &xdri_drv->magic)) { - perror("drmGetMagic failed: "); - return EGL_FALSE; - } - - version = drmGetVersion(xdri_drv->drmFD); - if (version) { - drm_version.major = version->version_major; - drm_version.minor = version->version_minor; - drm_version.patch = version->version_patchlevel; - drmFreeVersion(version); - _eglLog(_EGL_DEBUG, "XDRI: Got DRM version %d.%d.%d", - drm_version.major, - drm_version.minor, - drm_version.patch); - } - else { - drm_version.major = -1; - drm_version.minor = -1; - drm_version.patch = -1; - _eglLog(_EGL_WARNING, "XDRI: drmGetVersion() failed"); - return EGL_FALSE; - } - - /* Authenticate w/ server. - */ - if (!XF86DRIAuthConnection(disp->Xdpy, scrn, xdri_drv->magic)) { - _eglLog(_EGL_WARNING, "XDRI: XF86DRIAuthConnection() failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: XF86DRIAuthConnection() success"); - } - - /* Get ddx version. - */ - { - char *driverName; - - /* - * Get device name (like "tdfx") and the ddx version - * numbers. We'll check the version in each DRI driver's - * "createNewScreen" function. - */ - if (!XF86DRIGetClientDriverName(disp->Xdpy, scrn, - &ddx_version.major, - &ddx_version.minor, - &ddx_version.patch, - &driverName)) { - _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetClientDriverName failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetClientDriverName returned %s", driverName); + struct xdri_egl_display *xdri_dpy; + __GLXdisplayPrivate *dpyPriv; + __GLXDRIdisplay *driDisplay; + __GLXscreenConfigs *psc; + EGLint first_id = 1; + int scr; + + xdri_dpy = CALLOC_STRUCT(xdri_egl_display); + if (!xdri_dpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + xdri_dpy->dpy = (Display *) dpy->NativeDisplay; + if (!xdri_dpy->dpy) { + xdri_dpy->dpy = XOpenDisplay(NULL); + if (!xdri_dpy->dpy) { + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } } - /* Get framebuffer info. - */ - { - int junk; - if (!XF86DRIGetDeviceInfo(disp->Xdpy, scrn, - &hFB, - &junk, - &xdri_drv->framebuffer.size, - &xdri_drv->framebuffer.stride, - &xdri_drv->framebuffer.dev_priv_size, - &xdri_drv->framebuffer.dev_priv)) { - _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetDeviceInfo() failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetDeviceInfo() success"); - } - xdri_drv->framebuffer.width = DisplayWidth(disp->Xdpy, scrn); - xdri_drv->framebuffer.height = DisplayHeight(disp->Xdpy, scrn); - } - - /* Map the framebuffer region. (this may not be needed) - */ - status = drmMap(xdri_drv->drmFD, hFB, xdri_drv->framebuffer.size, - (drmAddressPtr) &xdri_drv->framebuffer.base); - if (status != 0) { - _eglLog(_EGL_WARNING, "XDRI: drmMap(framebuffer) failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: drmMap(framebuffer) success"); - } - - /* Map the SAREA region. - */ - status = drmMap(xdri_drv->drmFD, xdri_drv->hSAREA, SAREA_MAX, &xdri_drv->pSAREA); - if (status != 0) { - _eglLog(_EGL_WARNING, "XDRI: drmMap(sarea) failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: drmMap(sarea) success"); - } - - return EGL_TRUE; -} - - -/** - * Load the DRI driver named by "xdri_drv->dri_driver_name". - * Basically, dlopen() the library to set "xdri_drv->dri_driver_handle". - * - * Later, we'll call dlsym(createNewScreenName) to get a pointer to - * the driver's createNewScreen() function which is the bootstrap function. - * - * \return EGL_TRUE for success, EGL_FALSE for failure - */ -static EGLBoolean -load_dri_driver(struct xdri_egl_driver *xdri_drv) -{ - char filename[100]; - int flags = RTLD_NOW; - - /* try "egl_xxx_dri.so" first */ - snprintf(filename, sizeof(filename), "egl_%s.so", xdri_drv->dri_driver_name); - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename); - xdri_drv->dri_driver_handle = dlopen(filename, flags); - if (xdri_drv->dri_driver_handle) { - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename); - return EGL_TRUE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) fail (%s)", filename, dlerror()); + dpyPriv = __glXInitialize(xdri_dpy->dpy); + if (!dpyPriv) { + _eglLog(_EGL_WARNING, "failed to create GLX display"); + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } - /* try regular "xxx_dri.so" next */ - snprintf(filename, sizeof(filename), "%s.so", xdri_drv->dri_driver_name); - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename); - xdri_drv->dri_driver_handle = dlopen(filename, flags); - if (xdri_drv->dri_driver_handle) { - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename); - return EGL_TRUE; + driDisplay = __driCreateDisplay(dpyPriv, NULL); + if (!driDisplay) { + _eglLog(_EGL_WARNING, "failed to create DRI display"); + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } - _eglLog(_EGL_WARNING, "XDRI Could not open %s (%s)", filename, dlerror()); - return EGL_FALSE; -} - - -/** - * Called via eglInitialize(), xdri_drv->API.Initialize(). - */ -static EGLBoolean -xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, - EGLint *minor, EGLint *major) -{ - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - _EGLDisplay *disp = _eglLookupDisplay(dpy); - static char name[100]; + scr = DefaultScreen(xdri_dpy->dpy); + psc = &dpyPriv->screenConfigs[scr]; - _eglLog(_EGL_DEBUG, "XDRI: eglInitialize"); + xdri_dpy->dpyPriv = dpyPriv; + xdri_dpy->driDisplay = driDisplay; + xdri_dpy->psc = psc; + xdri_dpy->scr = scr; - if (!disp->Xdpy) { - disp->Xdpy = XOpenDisplay(NULL); - if (!disp->Xdpy) { - _eglLog(_EGL_WARNING, "XDRI: XOpenDisplay failed"); - return EGL_FALSE; - } + psc->driScreen = driDisplay->createScreen(psc, scr, dpyPriv); + if (!psc->driScreen) { + _eglLog(_EGL_WARNING, "failed to create DRI screen #%d", scr); + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } -#if 0 - /* choose the DRI driver to load */ - xdri_drv->dri_driver_name = _eglChooseDRMDriver(0); - if (!load_dri_driver(xdri_drv)) - return EGL_FALSE; -#else - (void) load_dri_driver; -#endif - -#if 0 - if (!init_drm(xdri_drv, disp)) - return EGL_FALSE; -#else - (void) init_drm; -#endif - - /* - * NOTE: this call to __glXInitialize() bootstraps the whole GLX/DRI - * interface, loads the DRI driver, etc. - * This replaces the load_dri_driver() and init_drm() code above. - */ - xdri_drv->glx_priv = __glXInitialize(disp->Xdpy); - - create_configs(disp, xdri_drv->glx_priv); + /* add visuals and fbconfigs */ + first_id = create_configs(dpy, psc->visuals, first_id); + create_configs(dpy, psc->configs, first_id); - xdri_drv->Base.Initialized = EGL_TRUE; - - if (xdri_drv->dri_driver_name) - snprintf(name, sizeof(name), "X/DRI:%s", xdri_drv->dri_driver_name); - else - snprintf(name, sizeof(name), "X/DRI"); - xdri_drv->Base.Name = name; + 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; @@ -668,57 +283,37 @@ xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, } -/* - * Do some clean-up that normally occurs in XCloseDisplay(). - * We do this here because we're about to unload a dynamic library - * that has added some per-display extension data and callbacks. - * If we don't do this here we'll crash in XCloseDisplay() because it'll - * try to call functions that went away when the driver library was unloaded. - */ -static void -FreeDisplayExt(Display *dpy) -{ - _XExtension *ext, *next; - - for (ext = dpy->ext_procs; ext; ext = next) { - next = ext->next; - if (ext->close_display) { - ext->close_display(dpy, &ext->codes); - ext->close_display = NULL; - } - if (ext->name) - Xfree(ext->name); - Xfree(ext); - } - dpy->ext_procs = NULL; - - _XFreeExtData (dpy->ext_data); - dpy->ext_data = NULL; -} - - /** * Called via eglTerminate(), drv->API.Terminate(). */ static EGLBoolean -xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) +xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) { - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + __GLXscreenConfigs *psc; - _eglLog(_EGL_DEBUG, "XDRI: eglTerminate"); + _eglReleaseDisplayResources(drv, dpy); + _eglCleanupDisplay(dpy); - _eglLog(_EGL_DEBUG, "XDRI: Closing %s", xdri_drv->dri_driver_name); - - FreeDisplayExt(disp->Xdpy); + psc = xdri_dpy->psc; + if (psc->driver_configs) { + unsigned int i; + for (i = 0; psc->driver_configs[i]; i++) + free((__DRIconfig *) psc->driver_configs[i]); + free(psc->driver_configs); + psc->driver_configs = NULL; + } + if (psc->driScreen) { + psc->driScreen->destroyScreen(psc); + free(psc->driScreen); + psc->driScreen = NULL; + } -#if 0 - /* this causes a segfault for some reason */ - dlclose(xdri_drv->dri_driver_handle); -#endif - xdri_drv->dri_driver_handle = NULL; + xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay); + __glXRelease(xdri_dpy->dpyPriv); - free((void*) xdri_drv->dri_driver_name); + free(xdri_dpy); + dpy->DriverData = NULL; return EGL_TRUE; } @@ -730,71 +325,77 @@ xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) static _EGLProc xdri_eglGetProcAddress(const char *procname) { -#if 0 - _EGLDriver *drv = NULL; - - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - /*_EGLDisplay *disp = _eglLookupDisplay(dpy);*/ - _EGLProc *proc = xdri_drv->driScreen.getProcAddress(procname); - return proc; -#elif 1 - /* This is a bit of a hack to get at the gallium/Mesa state tracker - * function st_get_proc_address(). This will probably change at - * some point. - */ - _EGLProc (*st_get_proc_addr)(const char *procname); - st_get_proc_addr = dlsym(NULL, "st_get_proc_address"); - if (st_get_proc_addr) { - return st_get_proc_addr(procname); - } - return NULL; -#else - return NULL; -#endif + /* the symbol is defined in libGL.so */ + return (_EGLProc) _glapi_get_proc_address(procname); } /** * Called via eglCreateContext(), drv->API.CreateContext(). */ -static EGLContext -xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, - EGLContext share_list, const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config); - void *shared = NULL; +static _EGLContext * +xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + _EGLContext *share_list, const EGLint *attrib_list) +{ + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_config *xdri_config = lookup_config(conf); + struct xdri_egl_context *shared = lookup_context(share_list); + __GLXscreenConfigs *psc = xdri_dpy->psc; int renderType = GLX_RGBA_BIT; + struct xdri_egl_context *xdri_ctx; - struct xdri_egl_context *xdri_ctx = CALLOC_STRUCT(xdri_egl_context); - if (!xdri_ctx) - return EGL_NO_CONTEXT; + xdri_ctx = CALLOC_STRUCT(xdri_egl_context); + if (!xdri_ctx) { + _eglError(EGL_BAD_ALLOC, "eglCreateContext"); + return NULL; + } - if (!_eglInitContext(drv, dpy, &xdri_ctx->Base, config, attrib_list)) { + xdri_ctx->dummy_gc = CALLOC_STRUCT(__GLXcontextRec); + if (!xdri_ctx->dummy_gc) { + _eglError(EGL_BAD_ALLOC, "eglCreateContext"); free(xdri_ctx); - return EGL_NO_CONTEXT; + return NULL; } - assert(xdri_config); - - { - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; - xdri_ctx->driContext.private = - scrnConf->driScreen.createNewContext(disp->Xdpy, - xdri_config->mode, renderType, - shared, &xdri_ctx->driContext); + if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) { + free(xdri_ctx->dummy_gc); + free(xdri_ctx); + return NULL; } - if (!xdri_ctx->driContext.private) { - _eglLog(_EGL_DEBUG, "driScreen.createNewContext failed"); + xdri_ctx->driContext = + psc->driScreen->createContext(psc, + xdri_config->mode, + xdri_ctx->dummy_gc, + (shared) ? shared->dummy_gc : NULL, + renderType); + if (!xdri_ctx->driContext) { + free(xdri_ctx->dummy_gc); free(xdri_ctx); - return EGL_NO_CONTEXT; + return NULL; } - xdri_ctx->driContext.mode = xdri_config->mode; + /* fill in the required field */ + xdri_ctx->dummy_gc->driContext = xdri_ctx->driContext; - return _eglGetContextHandle(&xdri_ctx->Base); + return &xdri_ctx->Base; +} + + +static EGLBoolean +xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_context *xdri_ctx = lookup_context(ctx); + + if (!_eglIsContextBound(ctx)) { + xdri_ctx->driContext->destroyContext(xdri_ctx->driContext, + xdri_dpy->psc, xdri_dpy->dpy); + free(xdri_ctx->dummy_gc); + free(xdri_ctx); + } + + return EGL_TRUE; } @@ -802,25 +403,32 @@ xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ static EGLBoolean -xdri_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, - EGLSurface r, EGLContext context) +xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, + _EGLSurface *r, _EGLContext *context) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); struct xdri_egl_context *xdri_ctx = lookup_context(context); - struct xdri_egl_surface *xdri_draw = lookup_surface(d); - struct xdri_egl_surface *xdri_read = lookup_surface(r); - __DRIid draw = xdri_draw ? xdri_draw->driDrawable : 0; - __DRIid read = xdri_read ? xdri_read->driDrawable : 0; - int scrn = DefaultScreen(disp->Xdpy); + struct xdri_egl_surface *draw = lookup_surface(d); + struct xdri_egl_surface *read = lookup_surface(r); if (!_eglMakeCurrent(drv, dpy, d, r, context)) return EGL_FALSE; + /* the symbol is defined in libGL.so */ + _glapi_check_multithread(); - if (xdri_ctx && - !xdri_ctx->driContext.bindContext(disp->Xdpy, scrn, draw, read, - &xdri_ctx->driContext)) { - return EGL_FALSE; + if (xdri_ctx) { + if (!xdri_ctx->driContext->bindContext(xdri_ctx->driContext, + draw->driDrawable, + read->driDrawable)) { + return EGL_FALSE; + } + } + else { + _EGLContext *old = _eglGetCurrentContext(); + if (old) { + xdri_ctx = lookup_context(old); + xdri_ctx->driContext->unbindContext(xdri_ctx->driContext); + } } return EGL_TRUE; @@ -830,309 +438,106 @@ xdri_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, /** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ -static EGLSurface -xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +static _EGLSurface * +xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_config *xdri_config = lookup_config(conf); struct xdri_egl_surface *xdri_surf; - int scrn = DefaultScreen(disp->Xdpy); uint width, height; xdri_surf = CALLOC_STRUCT(xdri_egl_surface); - if (!xdri_surf) - return EGL_NO_SURFACE; + if (!xdri_surf) { + _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); + return NULL; + } - if (!_eglInitSurface(drv, dpy, &xdri_surf->Base, EGL_WINDOW_BIT, - config, attrib_list)) { + if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT, + &xdri_config->Base, attrib_list)) { free(xdri_surf); - return EGL_FALSE; + return NULL; } - if (!XF86DRICreateDrawable(disp->Xdpy, scrn, window, &xdri_surf->hDrawable)) { + xdri_surf->driDrawable = + xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc, + (XID) window, + (GLXDrawable) window, + xdri_config->mode); + if (!xdri_surf->driDrawable) { free(xdri_surf); - return EGL_FALSE; + return NULL; } - xdri_surf->driDrawable = window; + xdri_surf->drawable = (Drawable) window; - _eglSaveSurface(&xdri_surf->Base); - - get_drawable_size(disp->Xdpy, window, &width, &height); + get_drawable_size(xdri_dpy->dpy, window, &width, &height); xdri_surf->Base.Width = width; xdri_surf->Base.Height = height; - _eglLog(_EGL_DEBUG, - "XDRI: CreateWindowSurface win 0x%x handle %d hDrawable %d", - (int) window, _eglGetSurfaceHandle(&xdri_surf->Base), - (int) xdri_surf->hDrawable); - - return _eglGetSurfaceHandle(&xdri_surf->Base); + return &xdri_surf->Base; } /** * Called via eglCreatePbufferSurface(), drv->API.CreatePbufferSurface(). */ -static EGLSurface -xdri_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +static _EGLSurface * +xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct xdri_egl_surface *xdri_surf; - struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config); - int scrn = DefaultScreen(disp->Xdpy); - Window window; - - xdri_surf = CALLOC_STRUCT(xdri_egl_surface); - if (!xdri_surf) - return EGL_NO_SURFACE; - - if (!_eglInitSurface(drv, dpy, &xdri_surf->Base, EGL_PBUFFER_BIT, - config, attrib_list)) { - free(xdri_surf); - return EGL_FALSE; - } - - /* Create a dummy X window */ - { - Window root = RootWindow(disp->Xdpy, scrn); - XSetWindowAttributes attr; - XVisualInfo *visInfo, visTemplate; - unsigned mask; - int nvis; - - visTemplate.visualid = xdri_config->mode->visualID; - visInfo = XGetVisualInfo(disp->Xdpy, VisualIDMask, &visTemplate, &nvis); - if (!visInfo) { - return EGL_NO_SURFACE; - } - - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap(disp->Xdpy, root, - visInfo->visual, AllocNone); - attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - - window = XCreateWindow(disp->Xdpy, root, 0, 0, - xdri_surf->Base.Width, xdri_surf->Base.Height, - 0, visInfo->depth, InputOutput, - visInfo->visual, mask, &attr); - - /*XMapWindow(disp->Xdpy, window);*/ - XFree(visInfo); - - /* set hints and properties */ - /* - sizehints.width = xdri_surf->Base.Width; - sizehints.height = xdri_surf->Base.Height; - sizehints.flags = USPosition; - XSetNormalHints(disp->Xdpy, window, &sizehints); - */ - } - - if (!XF86DRICreateDrawable(disp->Xdpy, scrn, window, &xdri_surf->hDrawable)) { - free(xdri_surf); - return EGL_FALSE; - } - - xdri_surf->driDrawable = window; - - _eglSaveSurface(&xdri_surf->Base); - - _eglLog(_EGL_DEBUG, - "XDRI: CreatePbufferSurface handle %d hDrawable %d", - _eglGetSurfaceHandle(&xdri_surf->Base), - (int) xdri_surf->hDrawable); - - return _eglGetSurfaceHandle(&xdri_surf->Base); + return NULL; } static EGLBoolean -xdri_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) { struct xdri_egl_surface *xdri_surf = lookup_surface(surface); - if (xdri_surf) { - _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface); - if (xdri_surf->Base.IsBound) { - xdri_surf->Base.DeletePending = EGL_TRUE; - } - else { - /* - st_unreference_framebuffer(surf->Framebuffer); - */ - free(xdri_surf); - } - return EGL_TRUE; - } - else { - _eglError(EGL_BAD_SURFACE, "eglDestroySurface"); - return EGL_FALSE; + + if (!_eglIsSurfaceBound(&xdri_surf->Base)) { + xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable); + free(xdri_surf); } + + return EGL_TRUE; } static EGLBoolean -xdri_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, +xdri_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer) { - typedef int (*bind_teximage)(__DRInativeDisplay *dpy, - __DRIid surface, __DRIscreen *psc, - int buffer, int target, int format, - int level, int mipmap); - - bind_teximage egl_dri_bind_teximage; - - _EGLDisplay *disp = _eglLookupDisplay(dpy); - - struct xdri_egl_context *xdri_ctx = current_context(); - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - struct xdri_egl_surface *xdri_surf = lookup_surface(surface); - - __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0; - - __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; - __DRIscreen *psc = &scrnConf->driScreen; - - /* this call just does error checking */ - if (!_eglBindTexImage(drv, dpy, surface, buffer)) { - return EGL_FALSE; - } - - egl_dri_bind_teximage = - (bind_teximage) dlsym(NULL, "egl_dri_bind_teximage"); - if (egl_dri_bind_teximage) { - return egl_dri_bind_teximage(disp->Xdpy, dri_surf, psc, - buffer, - xdri_surf->Base.TextureTarget, - xdri_surf->Base.TextureFormat, - xdri_surf->Base.MipmapLevel, - xdri_surf->Base.MipmapTexture); - } - else { - /* fallback path based on glCopyTexImage() */ - /* Get/save currently bound 2D texobj name */ - glGetIntegerv_t glGetIntegerv_func = - (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv"); - GLint curTexObj = 0; - if (glGetIntegerv_func) { - (*glGetIntegerv_func)(GL_TEXTURE_BINDING_2D, &curTexObj); - } - xdri_ctx->bound_tex_object = curTexObj; - } - return EGL_FALSE; } static EGLBoolean -xdri_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, +xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer) { - typedef int (*release_teximage)(__DRInativeDisplay *dpy, - __DRIid surface, __DRIscreen *psc, - int buffer, int target, int format, - int level, int mipmap); - release_teximage egl_dri_release_teximage; - - _EGLDisplay *disp = _eglLookupDisplay(dpy); - - struct xdri_egl_context *xdri_ctx = current_context(); - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - struct xdri_egl_surface *xdri_surf = lookup_surface(surface); - - __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0; - - __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; - __DRIscreen *psc = &scrnConf->driScreen; - - /* this call just does error checking */ - if (!_eglReleaseTexImage(drv, dpy, surface, buffer)) { - return EGL_FALSE; - } - - egl_dri_release_teximage = - (release_teximage) dlsym(NULL, "egl_dri_release_teximage"); - if (egl_dri_release_teximage) { - return egl_dri_release_teximage(disp->Xdpy, dri_surf, psc, - buffer, - xdri_surf->Base.TextureTarget, - xdri_surf->Base.TextureFormat, - xdri_surf->Base.MipmapLevel, - xdri_surf->Base.MipmapTexture); - } - else { - /* fallback path based on glCopyTexImage() */ - glGetIntegerv_t glGetIntegerv_func = - (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv"); - glBindTexture_t glBindTexture_func = - (glBindTexture_t) dlsym(NULL, "glBindTexture"); - glCopyTexImage2D_t glCopyTexImage2D_func = - (glCopyTexImage2D_t) dlsym(NULL, "glCopyTexImage2D"); - GLint curTexObj; - GLenum intFormat; - GLint level, width, height; - - if (xdri_surf->Base.TextureFormat == EGL_TEXTURE_RGBA) - intFormat = GL_RGBA; - else - intFormat = GL_RGB; - level = xdri_surf->Base.MipmapLevel; - width = xdri_surf->Base.Width >> level; - height = xdri_surf->Base.Height >> level; - - if (width > 0 && height > 0 && - glGetIntegerv_func && glBindTexture_func && glCopyTexImage2D_func) { - glGetIntegerv_func(GL_TEXTURE_BINDING_2D, &curTexObj); - /* restore texobj from time of eglBindTexImage() call */ - if (curTexObj != xdri_ctx->bound_tex_object) - glBindTexture_func(GL_TEXTURE_2D, xdri_ctx->bound_tex_object); - /* copy pbuffer image to texture */ - glCopyTexImage2D_func(GL_TEXTURE_2D, - level, - intFormat, - 0, 0, width, height, 0); - /* restore current texture */ - if (curTexObj != xdri_ctx->bound_tex_object) - glBindTexture_func(GL_TEXTURE_2D, curTexObj); - } - xdri_ctx->bound_tex_object = -1; - } - return EGL_FALSE; } static EGLBoolean -xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_surface *xdri_surf = lookup_surface(draw); - _eglLog(_EGL_DEBUG, "XDRI: EGL SwapBuffers"); + xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable); - /* error checking step: */ - if (!_eglSwapBuffers(drv, dpy, draw)) - return EGL_FALSE; + return EGL_TRUE; +} - { - struct xdri_egl_surface *xdri_surf = lookup_surface(draw); - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; - __DRIscreen *psc = &scrnConf->driScreen; - __DRIdrawable * const pdraw = psc->getDrawable(disp->Xdpy, - xdri_surf->driDrawable, - psc->private); - - if (pdraw) - pdraw->swapBuffers(disp->Xdpy, pdraw->private); - else - _eglLog(_EGL_WARNING, "pdraw is null in SwapBuffers"); - } - return EGL_TRUE; +static void +xdri_Unload(_EGLDriver *drv) +{ + struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); + free(xdri_drv); } @@ -1141,15 +546,12 @@ xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) * Create a new _EGLDriver object and init its dispatch table. */ _EGLDriver * -_eglMain(_EGLDisplay *disp, const char *args) +_eglMain(const char *args) { struct xdri_egl_driver *xdri_drv = CALLOC_STRUCT(xdri_egl_driver); if (!xdri_drv) return NULL; - /* Tell libGL to prefer the EGL drivers over regular DRI drivers */ - __glXPreferEGL(1); - _eglInitDriverFallbacks(&xdri_drv->Base); xdri_drv->Base.API.Initialize = xdri_eglInitialize; xdri_drv->Base.API.Terminate = xdri_eglTerminate; @@ -1157,6 +559,7 @@ _eglMain(_EGLDisplay *disp, const char *args) xdri_drv->Base.API.GetProcAddress = xdri_eglGetProcAddress; xdri_drv->Base.API.CreateContext = xdri_eglCreateContext; + xdri_drv->Base.API.DestroyContext = xdri_eglDestroyContext; xdri_drv->Base.API.MakeCurrent = xdri_eglMakeCurrent; xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface; xdri_drv->Base.API.CreatePbufferSurface = xdri_eglCreatePbufferSurface; @@ -1165,13 +568,8 @@ _eglMain(_EGLDisplay *disp, const char *args) xdri_drv->Base.API.ReleaseTexImage = xdri_eglReleaseTexImage; xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers; - xdri_drv->Base.ClientAPIsMask = (EGL_OPENGL_BIT | - EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT); xdri_drv->Base.Name = "X/DRI"; - - _eglLog(_EGL_DEBUG, "XDRI: main(%s)", args); + xdri_drv->Base.Unload = xdri_Unload; return &xdri_drv->Base; } diff --git a/src/egl/drivers/xdri/glxinit.c b/src/egl/drivers/xdri/glxinit.c new file mode 100644 index 00000000000..77750093944 --- /dev/null +++ b/src/egl/drivers/xdri/glxinit.c @@ -0,0 +1,626 @@ +/** + * GLX initialization. Code based on glxext.c, glx_query.c, and + * glcontextmodes.c under src/glx/x11/. The major difference is that no DRI + * related code here. + * + */ + +#include <assert.h> +#include <X11/Xlib.h> +#include <X11/Xproto.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include <sys/time.h> + +#include "glxinit.h" + +typedef struct GLXGenericGetString +{ + CARD8 reqType; + CARD8 glxCode; + CARD16 length B16; + CARD32 for_whom B32; + CARD32 name B32; +} xGLXGenericGetStringReq; + +#define sz_xGLXGenericGetStringReq 12 +#define X_GLXGenericGetString 0 + +/* Extension required boiler plate */ + +static char *__glXExtensionName = GLX_EXTENSION_NAME; +static XExtensionInfo *__glXExtensionInfo = NULL; + +static /* const */ XExtensionHooks __glXExtensionHooks = { NULL }; +static +XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, + __glXExtensionName, &__glXExtensionHooks, + __GLX_NUMBER_EVENTS, NULL) + +static GLint +_gl_convert_from_x_visual_type(int visualType) +{ +#define NUM_VISUAL_TYPES 6 + static const int glx_visual_types[NUM_VISUAL_TYPES] = { + GLX_STATIC_GRAY, GLX_GRAY_SCALE, + GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, GLX_DIRECT_COLOR + }; + + return ((unsigned) visualType < NUM_VISUAL_TYPES) + ? glx_visual_types[visualType] : GLX_NONE; +} + +static __GLcontextModes * +_gl_context_modes_create(unsigned count, size_t minimum_size) +{ + const size_t size = (minimum_size > sizeof(__GLcontextModes)) + ? minimum_size : sizeof(__GLcontextModes); + __GLcontextModes *base = NULL; + __GLcontextModes **next; + unsigned i; + + next = &base; + for (i = 0; i < count; i++) { + *next = (__GLcontextModes *) Xmalloc(size); + if (*next == NULL) { + _gl_context_modes_destroy(base); + base = NULL; + break; + } + + memset(*next, 0, size); + (*next)->visualID = GLX_DONT_CARE; + (*next)->visualType = GLX_DONT_CARE; + (*next)->visualRating = GLX_NONE; + (*next)->transparentPixel = GLX_NONE; + (*next)->transparentRed = GLX_DONT_CARE; + (*next)->transparentGreen = GLX_DONT_CARE; + (*next)->transparentBlue = GLX_DONT_CARE; + (*next)->transparentAlpha = GLX_DONT_CARE; + (*next)->transparentIndex = GLX_DONT_CARE; + (*next)->xRenderable = GLX_DONT_CARE; + (*next)->fbconfigID = GLX_DONT_CARE; + (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; + (*next)->bindToTextureRgb = GLX_DONT_CARE; + (*next)->bindToTextureRgba = GLX_DONT_CARE; + (*next)->bindToMipmapTexture = GLX_DONT_CARE; + (*next)->bindToTextureTargets = GLX_DONT_CARE; + (*next)->yInverted = GLX_DONT_CARE; + + next = &((*next)->next); + } + + return base; +} + +_X_HIDDEN void +_gl_context_modes_destroy(__GLcontextModes * modes) +{ + while (modes != NULL) { + __GLcontextModes *const next = modes->next; + + Xfree(modes); + modes = next; + } +} + +_X_HIDDEN char * +__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name) +{ + xGLXGenericGetStringReq *req; + xGLXSingleReply reply; + int length; + int numbytes; + char *buf; + CARD32 for_whom = screen; + CARD32 glxCode = X_GLXQueryServerString; + + + LockDisplay(dpy); + + + /* All of the GLX protocol requests for getting a string from the server + * look the same. The exact meaning of the for_whom field is usually + * either the screen number (for glXQueryServerString) or the context tag + * (for GLXSingle). + */ + + GetReq(GLXGenericGetString, req); + req->reqType = opcode; + req->glxCode = glxCode; + req->for_whom = for_whom; + req->name = name; + + _XReply(dpy, (xReply *) & reply, 0, False); + + length = reply.length * 4; + numbytes = reply.size; + + buf = (char *) Xmalloc(numbytes); + if (buf != NULL) { + _XRead(dpy, buf, numbytes); + length -= numbytes; + } + + _XEatData(dpy, length); + + UnlockDisplay(dpy); + SyncHandle(); + + return buf; +} + +/************************************************************************/ +/* +** Free the per screen configs data as well as the array of +** __glXScreenConfigs. +*/ +static void +FreeScreenConfigs(__GLXdisplayPrivate * priv) +{ + __GLXscreenConfigs *psc; + GLint i, screens; + + /* Free screen configuration information */ + psc = priv->screenConfigs; + screens = ScreenCount(priv->dpy); + for (i = 0; i < screens; i++, psc++) { + if (psc->configs) { + _gl_context_modes_destroy(psc->configs); + psc->configs = NULL; /* NOTE: just for paranoia */ + } + if (psc->visuals) { + _gl_context_modes_destroy(psc->visuals); + psc->visuals = NULL; /* NOTE: just for paranoia */ + } + Xfree((char *) psc->serverGLXexts); + } + XFree((char *) priv->screenConfigs); + priv->screenConfigs = NULL; +} + +/************************************************************************/ + +/* +** Query the version of the GLX extension. This procedure works even if +** the client extension is not completely set up. +*/ +static Bool +QueryVersion(Display * dpy, int opcode, int *major, int *minor) +{ + xGLXQueryVersionReq *req; + xGLXQueryVersionReply reply; + + /* Send the glXQueryVersion request */ + LockDisplay(dpy); + GetReq(GLXQueryVersion, req); + req->reqType = opcode; + req->glxCode = X_GLXQueryVersion; + req->majorVersion = GLX_MAJOR_VERSION; + req->minorVersion = GLX_MINOR_VERSION; + _XReply(dpy, (xReply *) & reply, 0, False); + UnlockDisplay(dpy); + SyncHandle(); + + if (reply.majorVersion != GLX_MAJOR_VERSION) { + /* + ** The server does not support the same major release as this + ** client. + */ + return GL_FALSE; + } + *major = reply.majorVersion; + *minor = min(reply.minorVersion, GLX_MINOR_VERSION); + return GL_TRUE; +} + +_X_HIDDEN void +__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count, + const INT32 * bp, Bool tagged_only, + Bool fbconfig_style_tags) +{ + int i; + + if (!tagged_only) { + /* Copy in the first set of properties */ + config->visualID = *bp++; + + config->visualType = _gl_convert_from_x_visual_type(*bp++); + + config->rgbMode = *bp++; + + config->redBits = *bp++; + config->greenBits = *bp++; + config->blueBits = *bp++; + config->alphaBits = *bp++; + config->accumRedBits = *bp++; + config->accumGreenBits = *bp++; + config->accumBlueBits = *bp++; + config->accumAlphaBits = *bp++; + + config->doubleBufferMode = *bp++; + config->stereoMode = *bp++; + + config->rgbBits = *bp++; + config->depthBits = *bp++; + config->stencilBits = *bp++; + config->numAuxBuffers = *bp++; + config->level = *bp++; + + count -= __GLX_MIN_CONFIG_PROPS; + } + + /* + ** Additional properties may be in a list at the end + ** of the reply. They are in pairs of property type + ** and property value. + */ + +#define FETCH_OR_SET(tag) \ + config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1 + + for (i = 0; i < count; i += 2) { + switch (*bp++) { + case GLX_RGBA: + FETCH_OR_SET(rgbMode); + break; + case GLX_BUFFER_SIZE: + config->rgbBits = *bp++; + break; + case GLX_LEVEL: + config->level = *bp++; + break; + case GLX_DOUBLEBUFFER: + FETCH_OR_SET(doubleBufferMode); + break; + case GLX_STEREO: + FETCH_OR_SET(stereoMode); + break; + case GLX_AUX_BUFFERS: + config->numAuxBuffers = *bp++; + break; + case GLX_RED_SIZE: + config->redBits = *bp++; + break; + case GLX_GREEN_SIZE: + config->greenBits = *bp++; + break; + case GLX_BLUE_SIZE: + config->blueBits = *bp++; + break; + case GLX_ALPHA_SIZE: + config->alphaBits = *bp++; + break; + case GLX_DEPTH_SIZE: + config->depthBits = *bp++; + break; + case GLX_STENCIL_SIZE: + config->stencilBits = *bp++; + break; + case GLX_ACCUM_RED_SIZE: + config->accumRedBits = *bp++; + break; + case GLX_ACCUM_GREEN_SIZE: + config->accumGreenBits = *bp++; + break; + case GLX_ACCUM_BLUE_SIZE: + config->accumBlueBits = *bp++; + break; + case GLX_ACCUM_ALPHA_SIZE: + config->accumAlphaBits = *bp++; + break; + case GLX_VISUAL_CAVEAT_EXT: + config->visualRating = *bp++; + break; + case GLX_X_VISUAL_TYPE: + config->visualType = *bp++; + break; + case GLX_TRANSPARENT_TYPE: + config->transparentPixel = *bp++; + break; + case GLX_TRANSPARENT_INDEX_VALUE: + config->transparentIndex = *bp++; + break; + case GLX_TRANSPARENT_RED_VALUE: + config->transparentRed = *bp++; + break; + case GLX_TRANSPARENT_GREEN_VALUE: + config->transparentGreen = *bp++; + break; + case GLX_TRANSPARENT_BLUE_VALUE: + config->transparentBlue = *bp++; + break; + case GLX_TRANSPARENT_ALPHA_VALUE: + config->transparentAlpha = *bp++; + break; + case GLX_VISUAL_ID: + config->visualID = *bp++; + break; + case GLX_DRAWABLE_TYPE: + config->drawableType = *bp++; + break; + case GLX_RENDER_TYPE: + config->renderType = *bp++; + break; + case GLX_X_RENDERABLE: + config->xRenderable = *bp++; + break; + case GLX_FBCONFIG_ID: + config->fbconfigID = *bp++; + break; + case GLX_MAX_PBUFFER_WIDTH: + config->maxPbufferWidth = *bp++; + break; + case GLX_MAX_PBUFFER_HEIGHT: + config->maxPbufferHeight = *bp++; + break; + case GLX_MAX_PBUFFER_PIXELS: + config->maxPbufferPixels = *bp++; + break; + case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: + config->optimalPbufferWidth = *bp++; + break; + case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: + config->optimalPbufferHeight = *bp++; + break; + case GLX_VISUAL_SELECT_GROUP_SGIX: + config->visualSelectGroup = *bp++; + break; + case GLX_SWAP_METHOD_OML: + config->swapMethod = *bp++; + break; + case GLX_SAMPLE_BUFFERS_SGIS: + config->sampleBuffers = *bp++; + break; + case GLX_SAMPLES_SGIS: + config->samples = *bp++; + break; + case GLX_BIND_TO_TEXTURE_RGB_EXT: + config->bindToTextureRgb = *bp++; + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + config->bindToTextureRgba = *bp++; + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + config->bindToMipmapTexture = *bp++; + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + config->bindToTextureTargets = *bp++; + break; + case GLX_Y_INVERTED_EXT: + config->yInverted = *bp++; + break; + case None: + i = count; + break; + default: + break; + } + } + + config->renderType = + (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + + config->haveAccumBuffer = ((config->accumRedBits + + config->accumGreenBits + + config->accumBlueBits + + config->accumAlphaBits) > 0); + config->haveDepthBuffer = (config->depthBits > 0); + config->haveStencilBuffer = (config->stencilBits > 0); +} + +static __GLcontextModes * +createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, + int screen, GLboolean tagged_only) +{ + INT32 buf[__GLX_TOTAL_CONFIG], *props; + unsigned prop_size; + __GLcontextModes *modes, *m; + int i; + + if (nprops == 0) + return NULL; + + /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */ + + /* Check number of properties */ + if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS) + return NULL; + + /* Allocate memory for our config structure */ + modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes)); + if (!modes) + return NULL; + + prop_size = nprops * __GLX_SIZE_INT32; + if (prop_size <= sizeof(buf)) + props = buf; + else + props = Xmalloc(prop_size); + + /* Read each config structure and convert it into our format */ + m = modes; + for (i = 0; i < nvisuals; i++) { + _XRead(dpy, (char *) props, prop_size); + /* Older X servers don't send this so we default it here. */ + m->drawableType = GLX_WINDOW_BIT; + __glXInitializeVisualConfigFromTags(m, nprops, props, + tagged_only, GL_TRUE); + m->screen = screen; + m = m->next; + } + + if (props != buf) + Xfree(props); + + return modes; +} + +static GLboolean +getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) +{ + xGLXGetVisualConfigsReq *req; + __GLXscreenConfigs *psc; + xGLXGetVisualConfigsReply reply; + + LockDisplay(dpy); + + psc = priv->screenConfigs + screen; + psc->visuals = NULL; + GetReq(GLXGetVisualConfigs, req); + req->reqType = priv->majorOpcode; + req->glxCode = X_GLXGetVisualConfigs; + req->screen = screen; + + if (!_XReply(dpy, (xReply *) & reply, 0, False)) + goto out; + + psc->visuals = createConfigsFromProperties(dpy, + reply.numVisuals, + reply.numProps, + screen, GL_FALSE); + + out: + UnlockDisplay(dpy); + return psc->visuals != NULL; +} + +static GLboolean +getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) +{ + xGLXGetFBConfigsReq *fb_req; + xGLXGetFBConfigsSGIXReq *sgi_req; + xGLXVendorPrivateWithReplyReq *vpreq; + xGLXGetFBConfigsReply reply; + __GLXscreenConfigs *psc; + + psc = priv->screenConfigs + screen; + psc->serverGLXexts = + __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS); + + LockDisplay(dpy); + + psc->configs = NULL; + if (atof(priv->serverGLXversion) >= 1.3) { + GetReq(GLXGetFBConfigs, fb_req); + fb_req->reqType = priv->majorOpcode; + fb_req->glxCode = X_GLXGetFBConfigs; + fb_req->screen = screen; + } + else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) { + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXGetFBConfigsSGIXReq + + sz_xGLXVendorPrivateWithReplyReq, vpreq); + sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; + sgi_req->reqType = priv->majorOpcode; + sgi_req->glxCode = X_GLXVendorPrivateWithReply; + sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; + sgi_req->screen = screen; + } + else + goto out; + + if (!_XReply(dpy, (xReply *) & reply, 0, False)) + goto out; + + psc->configs = createConfigsFromProperties(dpy, + reply.numFBConfigs, + reply.numAttribs * 2, + screen, GL_TRUE); + + out: + UnlockDisplay(dpy); + return psc->configs != NULL; +} + +static GLboolean +AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) +{ + __GLXscreenConfigs *psc; + GLint i, screens; + + /* + ** First allocate memory for the array of per screen configs. + */ + screens = ScreenCount(dpy); + psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs)); + if (!psc) { + return GL_FALSE; + } + memset(psc, 0, screens * sizeof(__GLXscreenConfigs)); + priv->screenConfigs = psc; + + priv->serverGLXversion = + __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION); + if (priv->serverGLXversion == NULL) { + FreeScreenConfigs(priv); + return GL_FALSE; + } + + for (i = 0; i < screens; i++, psc++) { + getFBConfigs(dpy, priv, i); + getVisualConfigs(dpy, priv, i); + psc->scr = i; + psc->dpy = dpy; + } + + SyncHandle(); + + return GL_TRUE; +} + +_X_HIDDEN void +__glXRelease(__GLXdisplayPrivate *dpyPriv) +{ + FreeScreenConfigs(dpyPriv); + + if (dpyPriv->serverGLXvendor) { + Xfree((char *) dpyPriv->serverGLXvendor); + dpyPriv->serverGLXvendor = NULL; + } + if (dpyPriv->serverGLXversion) { + Xfree((char *) dpyPriv->serverGLXversion); + dpyPriv->serverGLXversion = NULL; + } + + Xfree(dpyPriv); +} + +_X_HIDDEN __GLXdisplayPrivate * +__glXInitialize(Display * dpy) +{ + XExtDisplayInfo *info = __glXFindDisplay(dpy); + __GLXdisplayPrivate *dpyPriv; + int major, minor; + + if (!XextHasExtension(info)) + return NULL; + + /* See if the versions are compatible */ + if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) + return NULL; + + dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate)); + if (!dpyPriv) + return NULL; + + /* + ** Init the display private and then read in the screen config + ** structures from the server. + */ + dpyPriv->majorOpcode = info->codes->major_opcode; + dpyPriv->majorVersion = major; + dpyPriv->minorVersion = minor; + dpyPriv->dpy = dpy; + + dpyPriv->serverGLXvendor = NULL; + dpyPriv->serverGLXversion = NULL; + + if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { + Xfree(dpyPriv); + return NULL; + } + + return dpyPriv; +} diff --git a/src/egl/drivers/xdri/glxinit.h b/src/egl/drivers/xdri/glxinit.h new file mode 100644 index 00000000000..57206e627b2 --- /dev/null +++ b/src/egl/drivers/xdri/glxinit.h @@ -0,0 +1,14 @@ +#ifndef GLXINIT_INCLUDED +#define GLXINIT_INCLUDED + +#include <X11/Xlib.h> +#include "glxclient.h" + +/* this is used by DRI loaders */ +extern void +_gl_context_modes_destroy(__GLcontextModes * modes); + +extern void +__glXRelease(__GLXdisplayPrivate *dpyPriv); + +#endif /* GLXINIT_INCLUDED */ diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index fab8f160891..c951b070f1f 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -7,38 +7,38 @@ include $(TOP)/configs/current INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi $(X11_INCLUDES) HEADERS = \ + eglcompiler.h \ eglconfig.h \ eglconfigutil.h \ eglcontext.h \ + eglcurrent.h \ egldefines.h \ egldisplay.h \ egldriver.h \ eglglobals.h \ egllog.h \ - eglhash.h \ eglmisc.h \ eglmode.h \ + eglmutex.h \ eglscreen.h \ eglstring.h \ - eglsurface.h \ - eglx.h + eglsurface.h SOURCES = \ eglapi.c \ eglconfig.c \ eglconfigutil.c \ eglcontext.c \ + eglcurrent.c \ egldisplay.c \ egldriver.c \ eglglobals.c \ egllog.c \ - eglhash.c \ eglmisc.c \ eglmode.c \ eglscreen.c \ eglstring.c \ - eglsurface.c \ - eglx.c + eglsurface.c OBJECTS = $(SOURCES:.c=.o) @@ -66,11 +66,12 @@ $(TOP)/$(LIB_DIR)/libEGL.so: $(OBJECTS) install: default $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(INSTALL) $(TOP)/$(LIB_DIR)/libEGL.so* $(DESTDIR)$(INSTALL_LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libEGL.so* $(DESTDIR)$(INSTALL_LIB_DIR) clean: -rm -f *.o *.so* -rm -f core.* + -rm -f depend depend.bak depend: $(SOURCES) $(HEADERS) diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 9df938e1887..29617b7afff 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -29,7 +29,6 @@ */ - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -39,7 +38,9 @@ #include "eglglobals.h" #include "egldriver.h" #include "eglsurface.h" - +#include "eglconfig.h" +#include "eglscreen.h" +#include "eglmode.h" /** @@ -50,8 +51,12 @@ EGLDisplay EGLAPIENTRY eglGetDisplay(NativeDisplayType nativeDisplay) { _EGLDisplay *dpy; - _eglInitGlobals(); - dpy = _eglNewDisplay(nativeDisplay); + dpy = _eglFindDisplay(nativeDisplay); + if (!dpy) { + dpy = _eglNewDisplay(nativeDisplay); + if (dpy) + _eglLinkDisplay(dpy); + } return _eglGetDisplayHandle(dpy); } @@ -63,232 +68,484 @@ eglGetDisplay(NativeDisplayType nativeDisplay) EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDriver *drv; EGLint major_int, minor_int; - if (dpy) { - EGLBoolean retVal; - _EGLDisplay *dpyPriv = _eglLookupDisplay(dpy); - if (!dpyPriv) { - return EGL_FALSE; - } - dpyPriv->Driver = _eglOpenDriver(dpyPriv, - dpyPriv->DriverName, - dpyPriv->DriverArgs); - if (!dpyPriv->Driver) { - return EGL_FALSE; - } - /* Initialize the particular driver now */ - retVal = dpyPriv->Driver->API.Initialize(dpyPriv->Driver, dpy, - &major_int, &minor_int); - - dpyPriv->Driver->APImajor = major_int; - dpyPriv->Driver->APIminor = minor_int; - snprintf(dpyPriv->Driver->Version, sizeof(dpyPriv->Driver->Version), - "%d.%d (%s)", major_int, minor_int, dpyPriv->Driver->Name); - - /* Update applications version of major and minor if not NULL */ - if((major != NULL) && (minor != NULL)) - { - *major = major_int; - *minor = minor_int; + if (!disp) + return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + + drv = disp->Driver; + if (!drv) { + drv = _eglOpenDriver(disp); + if (!drv) + return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); + + /* Initialize the particular display now */ + if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) { + _eglCloseDriver(drv, disp); + return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); } - return retVal; + disp->APImajor = major_int; + disp->APIminor = minor_int; + snprintf(disp->Version, sizeof(disp->Version), + "%d.%d (%s)", major_int, minor_int, drv->Name); + + /* update the global notion of supported APIs */ + _eglGlobal.ClientAPIsMask |= disp->ClientAPIsMask; + + disp->Driver = drv; + } else { + major_int = disp->APImajor; + minor_int = disp->APIminor; + } + + /* Update applications version of major and minor if not NULL */ + if ((major != NULL) && (minor != NULL)) { + *major = major_int; + *minor = minor_int; } - return EGL_FALSE; + + return EGL_TRUE; } EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy) { - _EGLDriver *drv = _eglLookupDriver(dpy); - if (drv) - return _eglCloseDriver(drv, dpy); - else - return EGL_FALSE; + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDriver *drv; + + if (!disp) + return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + + drv = disp->Driver; + if (drv) { + drv->API.Terminate(drv, disp); + _eglCloseDriver(drv, disp); + disp->Driver = NULL; + } + + return EGL_TRUE; +} + + +/** + * A bunch of check functions and declare macros to simply error checking. + */ +static INLINE _EGLDriver * +_eglCheckDisplay(_EGLDisplay *disp, const char *msg) +{ + if (!disp) { + _eglError(EGL_BAD_DISPLAY, msg); + return NULL; + } + if (!disp->Driver) { + _eglError(EGL_NOT_INITIALIZED, msg); + return NULL; + } + return disp->Driver; +} + + +static INLINE _EGLDriver * +_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg) +{ + _EGLDriver *drv = _eglCheckDisplay(disp, msg); + if (!drv) + return NULL; + if (!surf) { + _eglError(EGL_BAD_SURFACE, msg); + return NULL; + } + return drv; +} + + +static INLINE _EGLDriver * +_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg) +{ + _EGLDriver *drv = _eglCheckDisplay(disp, msg); + if (!drv) + return NULL; + if (!context) { + _eglError(EGL_BAD_CONTEXT, msg); + return NULL; + } + return drv; +} + + +static INLINE _EGLDriver * +_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) +{ + _EGLDriver *drv = _eglCheckDisplay(disp, msg); + if (!drv) + return NULL; + if (!conf) { + _eglError(EGL_BAD_CONFIG, msg); + return NULL; + } + return drv; } +#define _EGL_DECLARE_DD(dpy) \ + _EGLDisplay *disp = _eglLookupDisplay(dpy); \ + _EGLDriver *drv; \ + do { \ + drv = _eglCheckDisplay(disp, __FUNCTION__); \ + if (!drv) \ + return EGL_FALSE; \ + } while (0) + + +#define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface) \ + _EGLDisplay *disp = _eglLookupDisplay(dpy); \ + _EGLSurface *surf = _eglLookupSurface((surface), disp); \ + _EGLDriver *drv; \ + do { \ + drv = _eglCheckSurface(disp, surf, __FUNCTION__); \ + if (!drv) \ + return EGL_FALSE; \ + } while (0) + + +#define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx) \ + _EGLDisplay *disp = _eglLookupDisplay(dpy); \ + _EGLContext *context = _eglLookupContext((ctx), disp); \ + _EGLDriver *drv; \ + do { \ + drv = _eglCheckContext(disp, context, __FUNCTION__); \ + if (!drv) \ + return EGL_FALSE; \ + } while (0) + + +#ifdef EGL_MESA_screen_surface + + +static INLINE _EGLDriver * +_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg) +{ + _EGLDriver *drv = _eglCheckDisplay(disp, msg); + if (!drv) + return NULL; + if (!scrn) { + _eglError(EGL_BAD_SCREEN_MESA, msg); + return NULL; + } + return drv; +} + + +static INLINE _EGLDriver * +_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg) +{ + _EGLDriver *drv = _eglCheckDisplay(disp, msg); + if (!drv) + return NULL; + if (!m) { + _eglError(EGL_BAD_MODE_MESA, msg); + return NULL; + } + return drv; +} + + +#define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen) \ + _EGLDisplay *disp = _eglLookupDisplay(dpy); \ + _EGLScreen *scrn = _eglLookupScreen((screen), disp); \ + _EGLDriver *drv; \ + do { \ + drv = _eglCheckScreen(disp, scrn, __FUNCTION__); \ + if (!drv) \ + return EGL_FALSE; \ + } while (0) + + +#define _EGL_DECLARE_DD_AND_MODE(dpy, mode) \ + _EGLDisplay *disp = _eglLookupDisplay(dpy); \ + _EGLMode *m = _eglLookupMode((mode), disp); \ + _EGLDriver *drv; \ + do { \ + drv = _eglCheckMode(disp, m, __FUNCTION__); \ + if (!drv) \ + return EGL_FALSE; \ + } while (0) + + +#endif /* EGL_MESA_screen_surface */ + + const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name) { - _EGLDriver *drv = _eglLookupDriver(dpy); - if (drv) - return drv->API.QueryString(drv, dpy, name); - else - return NULL; + _EGL_DECLARE_DD(dpy); + return drv->API.QueryString(drv, disp, name); } EGLBoolean EGLAPIENTRY -eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) +eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, + EGLint config_size, EGLint *num_config) { - _EGLDriver *drv = _eglLookupDriver(dpy); - /* XXX check drv for null in remaining functions */ - return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config); + _EGL_DECLARE_DD(dpy); + return drv->API.GetConfigs(drv, disp, configs, config_size, num_config); } EGLBoolean EGLAPIENTRY -eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) +eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, + EGLint config_size, EGLint *num_config) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config); + _EGL_DECLARE_DD(dpy); + return drv->API.ChooseConfig(drv, disp, attrib_list, configs, + config_size, num_config); } EGLBoolean EGLAPIENTRY -eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) +eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, + EGLint attribute, EGLint *value) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(config, disp); + _EGLDriver *drv; + + drv = _eglCheckConfig(disp, conf, __FUNCTION__); + if (!drv) + return EGL_FALSE; + + return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); } EGLContext EGLAPIENTRY -eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) -{ - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list); +eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, + const EGLint *attrib_list) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(config, disp); + _EGLContext *share = _eglLookupContext(share_list, disp); + _EGLDriver *drv; + _EGLContext *context; + + drv = _eglCheckConfig(disp, conf, __FUNCTION__); + if (!drv) + return EGL_NO_CONTEXT; + if (!share && share_list != EGL_NO_CONTEXT) { + _eglError(EGL_BAD_CONTEXT, __FUNCTION__); + return EGL_NO_CONTEXT; + } + + context = drv->API.CreateContext(drv, disp, conf, share, attrib_list); + if (context) + return _eglLinkContext(context, disp); + else + return EGL_NO_CONTEXT; } EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.DestroyContext(drv, dpy, ctx); + _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx); + _eglUnlinkContext(context); + return drv->API.DestroyContext(drv, disp, context); } EGLBoolean EGLAPIENTRY -eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) +eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, + EGLContext ctx) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.MakeCurrent(drv, dpy, draw, read, ctx); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLContext *context = _eglLookupContext(ctx, disp); + _EGLSurface *draw_surf = _eglLookupSurface(draw, disp); + _EGLSurface *read_surf = _eglLookupSurface(read, disp); + _EGLDriver *drv; + + drv = _eglCheckDisplay(disp, __FUNCTION__); + if (!drv) + return EGL_FALSE; + if (!context && ctx != EGL_NO_CONTEXT) + return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); + if ((!draw_surf && draw != EGL_NO_SURFACE) || + (!read_surf && read != EGL_NO_SURFACE)) + return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + + return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); } EGLBoolean EGLAPIENTRY -eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) +eglQueryContext(EGLDisplay dpy, EGLContext ctx, + EGLint attribute, EGLint *value) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.QueryContext(drv, dpy, ctx, attribute, value); + _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx); + return drv->API.QueryContext(drv, disp, context, attribute, value); } EGLSurface EGLAPIENTRY -eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) +eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, + NativeWindowType window, const EGLint *attrib_list) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(config, disp); + _EGLDriver *drv; + _EGLSurface *surf; + + drv = _eglCheckConfig(disp, conf, __FUNCTION__); + if (!drv) + return EGL_NO_SURFACE; + + surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list); + if (surf) + return _eglLinkSurface(surf, disp); + else + return EGL_NO_SURFACE; } EGLSurface EGLAPIENTRY -eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) +eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, + NativePixmapType pixmap, const EGLint *attrib_list) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(config, disp); + _EGLDriver *drv; + _EGLSurface *surf; + + drv = _eglCheckConfig(disp, conf, __FUNCTION__); + if (!drv) + return EGL_NO_SURFACE; + + surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list); + if (surf) + return _eglLinkSurface(surf, disp); + else + return EGL_NO_SURFACE; } EGLSurface EGLAPIENTRY -eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) +eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(config, disp); + _EGLDriver *drv; + _EGLSurface *surf; + + drv = _eglCheckConfig(disp, conf, __FUNCTION__); + if (!drv) + return EGL_NO_SURFACE; + + surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list); + if (surf) + return _eglLinkSurface(surf, disp); + else + return EGL_NO_SURFACE; } EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.DestroySurface(drv, dpy, surface); + _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + _eglUnlinkSurface(surf); + return drv->API.DestroySurface(drv, disp, surf); } - EGLBoolean EGLAPIENTRY -eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) +eglQuerySurface(EGLDisplay dpy, EGLSurface surface, + EGLint attribute, EGLint *value) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.QuerySurface(drv, dpy, surface, attribute, value); + _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + return drv->API.QuerySurface(drv, disp, surf, attribute, value); } - EGLBoolean EGLAPIENTRY -eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) +eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, + EGLint attribute, EGLint value) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value); + _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); } EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.BindTexImage(drv, dpy, surface, buffer); + _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + return drv->API.BindTexImage(drv, disp, surf, buffer); } EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.ReleaseTexImage(drv, dpy, surface, buffer); + _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + return drv->API.ReleaseTexImage(drv, disp, surf, buffer); } EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.SwapInterval(drv, dpy, interval); + _EGL_DECLARE_DD(dpy); + return drv->API.SwapInterval(drv, disp, interval); } EGLBoolean EGLAPIENTRY -eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) +eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.SwapBuffers(drv, dpy, draw); + _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + return drv->API.SwapBuffers(drv, disp, surf); } EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.CopyBuffers(drv, dpy, surface, target); + _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + return drv->API.CopyBuffers(drv, disp, surf, target); } EGLBoolean EGLAPIENTRY eglWaitGL(void) { - EGLDisplay dpy = eglGetCurrentDisplay(); - if (dpy != EGL_NO_DISPLAY) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.WaitGL(drv, dpy); - } - else - return EGL_FALSE; + _EGLDisplay *disp = _eglGetCurrentDisplay(); + _EGLDriver *drv; + + if (!disp) + return EGL_TRUE; + + /* a current display is always initialized */ + drv = disp->Driver; + + return drv->API.WaitGL(drv, disp); } EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) { - EGLDisplay dpy = eglGetCurrentDisplay(); - if (dpy != EGL_NO_DISPLAY) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.WaitNative(drv, dpy, engine); - } - else - return EGL_FALSE; + _EGLDisplay *disp = _eglGetCurrentDisplay(); + _EGLDriver *drv; + + if (!disp) + return EGL_TRUE; + + /* a current display is always initialized */ + drv = disp->Driver; + + return drv->API.WaitNative(drv, disp, engine); } @@ -321,7 +578,8 @@ eglGetError(void) { _EGLThreadInfo *t = _eglGetCurrentThread(); EGLint e = t->LastError; - t->LastError = EGL_SUCCESS; + if (!_eglIsCurrentThreadDummy()) + t->LastError = EGL_SUCCESS; return e; } @@ -415,111 +673,168 @@ eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes) { - _EGLDriver *drv = _eglLookupDriver(dpy); - if (drv) - return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes); - else - return EGL_FALSE; + _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); + return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, + modes, modes_size, num_modes); } EGLBoolean EGLAPIENTRY -eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode) +eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, + EGLint mode_size, EGLint *num_mode) { - _EGLDriver *drv = _eglLookupDriver(dpy); - if (drv) - return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode); - else - return EGL_FALSE; + _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); + return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); } EGLBoolean EGLAPIENTRY -eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value) +eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, + EGLint attribute, EGLint *value) { - _EGLDriver *drv = _eglLookupDriver(dpy); - if (drv) - return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value); - else - return EGL_FALSE; + _EGL_DECLARE_DD_AND_MODE(dpy, mode); + return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); } EGLBoolean EGLAPIENTRY -eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask) -{ - _EGLDriver *drv = _eglLookupDriver(dpy); - if (drv) - return drv->API.CopyContextMESA(drv, dpy, source, dest, mask); - else +eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, + EGLint mask) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLContext *source_context = _eglLookupContext(source, disp); + _EGLContext *dest_context = _eglLookupContext(dest, disp); + _EGLDriver *drv; + + drv = _eglCheckContext(disp, source_context, __FUNCTION__); + if (!drv || !dest_context) { + if (drv) + _eglError(EGL_BAD_CONTEXT, __FUNCTION__); return EGL_FALSE; + } + + return drv->API.CopyContextMESA(drv, disp, source_context, dest_context, + mask); } EGLBoolean -eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens) +eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, + EGLint max_screens, EGLint *num_screens) { - _EGLDriver *drv = _eglLookupDriver(dpy); - if (drv) - return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens); - else - return EGL_FALSE; + _EGL_DECLARE_DD(dpy); + return drv->API.GetScreensMESA(drv, disp, screens, + max_screens, num_screens); } EGLSurface -eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) +eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(config, disp); + _EGLDriver *drv; + _EGLSurface *surf; + + drv = _eglCheckConfig(disp, conf, __FUNCTION__); + if (!drv) + return EGL_NO_SURFACE; + + surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list); + if (surf) + return _eglLinkSurface(surf, disp); + else + return EGL_NO_SURFACE; } EGLBoolean -eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode) +eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, + EGLSurface surface, EGLModeMESA mode) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLMode *m = _eglLookupMode(mode, disp); + _EGLDriver *drv; + + drv = _eglCheckScreen(disp, scrn, __FUNCTION__); + if (!drv) + return EGL_FALSE; + if (!surf && surface != EGL_NO_SURFACE) + return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + if (!m && mode != EGL_NO_MODE_MESA) + return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__); + + return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); } EGLBoolean eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y); + _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); + return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); } EGLBoolean -eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value) +eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, + EGLint attribute, EGLint *value) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value); + _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); + return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); } EGLBoolean -eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface) +eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, + EGLSurface *surface) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); + _EGLDriver *drv; + _EGLSurface *surf; + + drv = _eglCheckScreen(disp, scrn, __FUNCTION__); + if (!drv) + return EGL_FALSE; + + if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE) + surf = NULL; + if (surface) + *surface = _eglGetSurfaceHandle(surf); + return (surf != NULL); } EGLBoolean eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); + _EGLDriver *drv; + _EGLMode *m; + + drv = _eglCheckScreen(disp, scrn, __FUNCTION__); + if (!drv) + return EGL_FALSE; + + if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE) + m = NULL; + if (mode) + *mode = m->Handle; + + return (m != NULL); } const char * eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.QueryModeStringMESA(drv, dpy, mode); + _EGL_DECLARE_DD_AND_MODE(dpy, mode); + return drv->API.QueryModeStringMESA(drv, disp, m); } @@ -546,11 +861,17 @@ eglBindAPI(EGLenum api) { _EGLThreadInfo *t = _eglGetCurrentThread(); + if (_eglIsCurrentThreadDummy()) + return _eglError(EGL_BAD_ALLOC, "eglBindAPI"); + + if (!_eglIsApiValid(api)) + return _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); + switch (api) { #ifdef EGL_VERSION_1_4 case EGL_OPENGL_API: if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) { - t->CurrentAPI = api; + t->CurrentAPIIndex = _eglConvertApiToIndex(api); return EGL_TRUE; } _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); @@ -558,14 +879,14 @@ eglBindAPI(EGLenum api) #endif case EGL_OPENGL_ES_API: if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) { - t->CurrentAPI = api; + t->CurrentAPIIndex = _eglConvertApiToIndex(api); return EGL_TRUE; } _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); return EGL_FALSE; case EGL_OPENVG_API: if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) { - t->CurrentAPI = api; + t->CurrentAPIIndex = _eglConvertApiToIndex(api); return EGL_TRUE; } _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); @@ -585,7 +906,7 @@ eglQueryAPI(void) { /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ _EGLThreadInfo *t = _eglGetCurrentThread(); - return t->CurrentAPI; + return _eglConvertApiFromIndex(t->CurrentAPIIndex); } @@ -594,24 +915,38 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer, - config, attrib_list); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(config, disp); + _EGLDriver *drv; + _EGLSurface *surf; + + drv = _eglCheckConfig(disp, conf, __FUNCTION__); + if (!drv) + return EGL_NO_SURFACE; + + surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer, + conf, attrib_list); + if (surf) + return _eglLinkSurface(surf, disp); + else + return EGL_NO_SURFACE; } EGLBoolean eglReleaseThread(void) { - _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLDisplay dpy = eglGetCurrentDisplay(); - if (dpy) { - _EGLDriver *drv = _eglLookupDriver(dpy); - /* unbind context */ - (void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); + /* unbind current context */ + if (!_eglIsCurrentThreadDummy()) { + _EGLDisplay *disp = _eglGetCurrentDisplay(); + _EGLDriver *drv; + if (disp) { + drv = disp->Driver; + (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); + } } - _eglDeleteThreadData(t); + + _eglDestroyCurrentThread(); return EGL_TRUE; } @@ -619,13 +954,17 @@ eglReleaseThread(void) EGLBoolean eglWaitClient(void) { - EGLDisplay dpy = eglGetCurrentDisplay(); - if (dpy != EGL_NO_DISPLAY) { - _EGLDriver *drv = _eglLookupDriver(dpy); - return drv->API.WaitClient(drv, dpy); - } - else - return EGL_FALSE; + _EGLDisplay *disp = _eglGetCurrentDisplay(); + _EGLDriver *drv; + + if (!disp) + return EGL_TRUE; + + /* a current display is always initialized */ + drv = disp->Driver; + + return drv->API.WaitClient(drv, disp); } + #endif /* EGL_VERSION_1_2 */ diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index f6163a0c7a8..6081e588928 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -12,61 +12,61 @@ typedef void (*_EGLProc)(); */ /* driver funcs */ -typedef EGLBoolean (*Initialize_t)(_EGLDriver *, EGLDisplay dpy, EGLint *major, EGLint *minor); -typedef EGLBoolean (*Terminate_t)(_EGLDriver *, EGLDisplay dpy); +typedef EGLBoolean (*Initialize_t)(_EGLDriver *, _EGLDisplay *dpy, EGLint *major, EGLint *minor); +typedef EGLBoolean (*Terminate_t)(_EGLDriver *, _EGLDisplay *dpy); /* config funcs */ -typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); -typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); -typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, EGLint attribute, EGLint *value); /* context funcs */ -typedef EGLContext (*CreateContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list); -typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx); -typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); -typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +typedef _EGLContext *(*CreateContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, _EGLContext *share_list, const EGLint *attrib_list); +typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx); +typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx); +typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value); /* surface funcs */ -typedef EGLSurface (*CreateWindowSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list); -typedef EGLSurface (*CreatePixmapSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list); -typedef EGLSurface (*CreatePbufferSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); -typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface); -typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); -typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); -typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer); -typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer); -typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint interval); -typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw); -typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target); +typedef _EGLSurface *(*CreateWindowSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativeWindowType window, const EGLint *attrib_list); +typedef _EGLSurface *(*CreatePixmapSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativePixmapType pixmap, const EGLint *attrib_list); +typedef _EGLSurface *(*CreatePbufferSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list); +typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface); +typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value); +typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint value); +typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer); +typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer); +typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval); +typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw); +typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, NativePixmapType target); /* misc funcs */ -typedef const char *(*QueryString_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint name); -typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, EGLDisplay dpy); -typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint engine); +typedef const char *(*QueryString_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name); +typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, _EGLDisplay *dpy); +typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine); typedef _EGLProc (*GetProcAddress_t)(const char *procname); #ifdef EGL_MESA_screen_surface -typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); -typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode); -typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value); -typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask); -typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); -typedef EGLSurface (*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); -typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode); -typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y); -typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value); -typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface); -typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode); -typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode); +typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); +typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode); +typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode, EGLint attribute, EGLint *value); +typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *source, _EGLContext *dest, EGLint mask); +typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); +typedef _EGLSurface *(*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list); +typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode); +typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint x, EGLint y); +typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint attribute, EGLint *value); +typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface **surface); +typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLMode **mode); +typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode); #endif /* EGL_MESA_screen_surface */ #ifdef EGL_VERSION_1_2 -typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, EGLDisplay dpy); -typedef EGLSurface (*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, _EGLDisplay *dpy); +typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum buftype, EGLClientBuffer buffer, _EGLConfig *config, const EGLint *attrib_list); #endif /* EGL_VERSION_1_2 */ diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h new file mode 100644 index 00000000000..6b639b75c66 --- /dev/null +++ b/src/egl/main/eglcompiler.h @@ -0,0 +1,64 @@ +#ifndef EGLCOMPILER_INCLUDED +#define EGLCOMPILER_INCLUDED + + +/** + * Get standard integer types + */ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) +# include <stdint.h> +#elif defined(_MSC_VER) + typedef __int8 int8_t; + typedef unsigned __int8 uint8_t; + typedef __int16 int16_t; + typedef unsigned __int16 uint16_t; +# ifndef __eglplatform_h_ + typedef __int32 int32_t; +# endif + typedef unsigned __int32 uint32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + +# if defined(_WIN64) + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +# else + typedef __int32 intptr_t; + typedef unsigned __int32 uintptr_t; +# endif + +# define INT64_C(__val) __val##i64 +# define UINT64_C(__val) __val##ui64 +#else +/* hope the best instead of adding a bunch of ifdef's */ +# include <stdint.h> +#endif + + +/** + * Function inlining + */ +#if defined(__GNUC__) +# define INLINE __inline__ +#elif defined(__MSC__) +# define INLINE __inline +#elif defined(_MSC_VER) +# define INLINE __inline +#elif defined(__ICL) +# define INLINE __inline +#elif defined(__INTEL_COMPILER) +# define INLINE inline +#elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) +# define INLINE __inline +#elif defined(__SUNPRO_C) && defined(__C99FEATURES__) +# define INLINE inline +# define __inline inline +# define __inline__ inline +#elif (__STDC_VERSION__ >= 199901L) /* C99 */ +# define INLINE inline +#else +# define INLINE +#endif + + +#endif /* EGLCOMPILER_INCLUDED */ diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index f2f32585c73..d47b99eed4b 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -34,7 +34,7 @@ void _eglInitConfig(_EGLConfig *config, EGLint id) { memset(config, 0, sizeof(*config)); - config->Handle = (EGLConfig) id; + config->Handle = (EGLConfig) _eglUIntToPointer((unsigned int) id); _eglSetConfigAttrib(config, EGL_CONFIG_ID, id); _eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE); _eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE); @@ -71,10 +71,9 @@ _eglGetConfigHandle(_EGLConfig *config) * This is the inverse of _eglGetConfigHandle(). */ _EGLConfig * -_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config) +_eglLookupConfig(EGLConfig config, _EGLDisplay *disp) { EGLint i; - _EGLDisplay *disp = _eglLookupDisplay(dpy); for (i = 0; i < disp->NumConfigs; i++) { if (disp->Configs[i]->Handle == config) { return disp->Configs[i]; @@ -319,10 +318,9 @@ _eglCompareConfigs(const void *a, const void *b) * Typical fallback routine for eglChooseConfig */ EGLBoolean -_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, +_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_configs) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); _EGLConfig **configList, criteria; EGLint i, count; @@ -367,10 +365,9 @@ _eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, * Fallback for eglGetConfigAttrib. */ EGLBoolean -_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLint attribute, EGLint *value) { - const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); const EGLint k = attribute - FIRST_ATTRIB; if (k >= 0 && k < MAX_ATTRIBS) { *value = conf->Attrib[k]; @@ -387,16 +384,9 @@ _eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, * Fallback for eglGetConfigs. */ EGLBoolean -_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, +_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - - if (!drv->Initialized) { - _eglError(EGL_NOT_INITIALIZED, "eglGetConfigs"); - return EGL_FALSE; - } - if (configs) { EGLint i; *num_config = MIN2(disp->NumConfigs, config_size); diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h index db1c4c10e08..36ed96ae956 100644 --- a/src/egl/main/eglconfig.h +++ b/src/egl/main/eglconfig.h @@ -34,7 +34,7 @@ _eglGetConfigHandle(_EGLConfig *config); extern _EGLConfig * -_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config); +_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy); extern _EGLConfig * @@ -46,15 +46,15 @@ _eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list); extern EGLBoolean -_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); extern EGLBoolean -_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLint attribute, EGLint *value); extern EGLBoolean -_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); extern void diff --git a/src/egl/main/eglconfigutil.c b/src/egl/main/eglconfigutil.c index 138dc729e74..c9d00e79826 100644 --- a/src/egl/main/eglconfigutil.c +++ b/src/egl/main/eglconfigutil.c @@ -156,6 +156,7 @@ _eglFillInConfigs(_EGLConfig * configs, {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */ }; +#if 0 static const uint32_t masks_table_bgr[8][4] = { {0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -177,6 +178,7 @@ _eglFillInConfigs(_EGLConfig * configs, {0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */ }; +#endif static const uint8_t bytes_per_pixel[8] = { 0, 0, 0, 2, 2, 4, 0, 4 diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 461679db090..b094f49bfc1 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -14,11 +14,9 @@ * in the attrib_list. */ EGLBoolean -_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx, - EGLConfig config, const EGLint *attrib_list) +_eglInitContext(_EGLDriver *drv, _EGLContext *ctx, + _EGLConfig *conf, const EGLint *attrib_list) { - _EGLConfig *conf; - _EGLDisplay *display = _eglLookupDisplay(dpy); EGLint i; const EGLenum api = eglQueryAPI(); @@ -27,12 +25,6 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx, return EGL_FALSE; } - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "_eglInitContext"); - return EGL_FALSE; - } - memset(ctx, 0, sizeof(_EGLContext)); ctx->ClientVersion = 1; /* the default, per EGL spec */ @@ -49,7 +41,6 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx, } } - ctx->Display = display; ctx->Config = conf; ctx->DrawSurface = EGL_NO_SURFACE; ctx->ReadSurface = EGL_NO_SURFACE; @@ -60,88 +51,27 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx, /** - * Save a new _EGLContext into the hash table. - */ -void -_eglSaveContext(_EGLContext *ctx) -{ - /* no-op. - * Public EGLContext handle and private _EGLContext are the same. - */ -} - - -/** - * Remove the given _EGLContext object from the hash table. - */ -void -_eglRemoveContext(_EGLContext *ctx) -{ - /* no-op. - * Public EGLContext handle and private _EGLContext are the same. - */ -} - - -/** - * Return the public handle for the given private context ptr. - * This is the inverse of _eglLookupContext(). - */ -EGLContext -_eglGetContextHandle(_EGLContext *ctx) -{ - /* just a cast! */ - return (EGLContext) ctx; -} - - -/** - * Return the _EGLContext object that corresponds to the given - * EGLContext handle. - * This is the inverse of _eglGetContextHandle(). - */ -_EGLContext * -_eglLookupContext(EGLContext ctx) -{ - /* just a cast since EGLContext is just a void ptr */ - return (_EGLContext *) ctx; -} - - -/** - * Return the currently bound _EGLContext object, or NULL. - */ -_EGLContext * -_eglGetCurrentContext(void) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - return t->CurrentContext; -} - - -/** * Just a placeholder/demo function. Real driver will never use this! */ -EGLContext -_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, - EGLContext share_list, const EGLint *attrib_list) +_EGLContext * +_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + _EGLContext *share_list, const EGLint *attrib_list) { #if 0 /* example code */ _EGLContext *context; context = (_EGLContext *) calloc(1, sizeof(_EGLContext)); if (!context) - return EGL_NO_CONTEXT; + return NULL; - if (!_eglInitContext(drv, dpy, context, config, attrib_list)) { + if (!_eglInitContext(drv, context, conf, attrib_list)) { free(context); - return EGL_NO_CONTEXT; + return NULL; } - _eglSaveContext(context); - return (EGLContext) context; + return context; #endif - return EGL_NO_CONTEXT; + return NULL; } @@ -149,39 +79,21 @@ _eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, * Default fallback routine - drivers should usually override this. */ EGLBoolean -_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) +_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) { - _EGLContext *context = _eglLookupContext(ctx); - if (context) { - if (context->IsBound) { - context->DeletePending = EGL_TRUE; - } - else { - free(context); - } - return EGL_TRUE; - } - else { - _eglError(EGL_BAD_CONTEXT, "eglDestroyContext"); - return EGL_TRUE; - } + if (!_eglIsContextBound(ctx)) + free(ctx); + return EGL_TRUE; } EGLBoolean -_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, +_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c, EGLint attribute, EGLint *value) { - _EGLContext *c = _eglLookupContext(ctx); - (void) drv; (void) dpy; - if (!c) { - _eglError(EGL_BAD_CONTEXT, "eglQueryContext"); - return EGL_FALSE; - } - switch (attribute) { case EGL_CONFIG_ID: *value = GET_CONFIG_ATTRIB(c->Config, EGL_CONFIG_ID); @@ -203,90 +115,100 @@ _eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, /** * Drivers will typically call this to do the error checking and - * update the various IsBound and DeletePending flags. + * update the various flags. * Then, the driver will do its device-dependent Make-Current stuff. */ EGLBoolean -_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, - EGLSurface r, EGLContext context) +_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, + _EGLSurface *read, _EGLContext *ctx) { _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *ctx = _eglLookupContext(context); - _EGLSurface *draw = _eglLookupSurface(d); - _EGLSurface *read = _eglLookupSurface(r); + _EGLContext *oldContext = NULL; + _EGLSurface *oldDrawSurface = NULL; + _EGLSurface *oldReadSurface = NULL; + EGLint apiIndex; - _EGLContext *oldContext = _eglGetCurrentContext(); - _EGLSurface *oldDrawSurface = _eglGetCurrentSurface(EGL_DRAW); - _EGLSurface *oldReadSurface = _eglGetCurrentSurface(EGL_READ); + if (_eglIsCurrentThreadDummy()) + return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); - /* error checking */ if (ctx) { - if (draw == NULL || read == NULL) { - _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - return EGL_FALSE; - } - if (draw->Config != ctx->Config) { - _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - return EGL_FALSE; - } - if (read->Config != ctx->Config) { - _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - return EGL_FALSE; + /* error checking */ + if (ctx->Binding && ctx->Binding != t) + return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); + if (draw == NULL || read == NULL) + return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); + if (draw->Config != ctx->Config || read->Config != ctx->Config) + return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); + if ((draw->Binding && draw->Binding->Binding != t) || + (read->Binding && read->Binding->Binding != t)) + return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); + +#ifdef EGL_VERSION_1_4 + /* OpenGL and OpenGL ES are conflicting */ + switch (ctx->ClientAPI) { + case EGL_OPENGL_ES_API: + if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)]) + return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); + break; + case EGL_OPENGL_API: + if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_ES_API)]) + return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); + break; + default: + break; } +#endif + apiIndex = _eglConvertApiToIndex(ctx->ClientAPI); + } + else { + if (draw != NULL || read != NULL) + return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); + apiIndex = t->CurrentAPIIndex; } - /* - * check if the old context or surfaces need to be deleted - */ - if (oldDrawSurface != NULL) { - oldDrawSurface->IsBound = EGL_FALSE; - if (oldDrawSurface->DeletePending) { - /* make sure we don't try to rebind a deleted surface */ - if (draw == oldDrawSurface || draw == oldReadSurface) { - draw = NULL; - } - /* really delete surface now */ - drv->API.DestroySurface(drv, dpy, oldDrawSurface->Handle); + oldContext = t->CurrentContexts[apiIndex]; + if (oldContext) { + oldDrawSurface = oldContext->DrawSurface; + oldReadSurface = oldContext->ReadSurface; + assert(oldDrawSurface); + assert(oldReadSurface); + + /* break old bindings */ + t->CurrentContexts[apiIndex] = NULL; + oldContext->Binding = NULL; + oldContext->DrawSurface = NULL; + oldContext->ReadSurface = NULL; + oldDrawSurface->Binding = NULL; + oldReadSurface->Binding = NULL; + + /* + * check if the old context or surfaces need to be deleted + */ + if (!_eglIsSurfaceLinked(oldDrawSurface)) { + assert(draw != oldDrawSurface && read != oldDrawSurface); + drv->API.DestroySurface(drv, dpy, oldDrawSurface); } - } - if (oldReadSurface != NULL && oldReadSurface != oldDrawSurface) { - oldReadSurface->IsBound = EGL_FALSE; - if (oldReadSurface->DeletePending) { - /* make sure we don't try to rebind a deleted surface */ - if (read == oldDrawSurface || read == oldReadSurface) { - read = NULL; - } - /* really delete surface now */ - drv->API.DestroySurface(drv, dpy, oldReadSurface->Handle); + if (oldReadSurface != oldDrawSurface && + !_eglIsSurfaceLinked(oldReadSurface)) { + assert(draw != oldReadSurface && read != oldReadSurface); + drv->API.DestroySurface(drv, dpy, oldReadSurface); } - } - if (oldContext != NULL) { - oldContext->IsBound = EGL_FALSE; - if (oldContext->DeletePending) { - /* make sure we don't try to rebind a deleted context */ - if (ctx == oldContext) { - ctx = NULL; - } - /* really delete context now */ - drv->API.DestroyContext(drv, dpy, _eglGetContextHandle(oldContext)); + if (!_eglIsContextLinked(oldContext)) { + assert(ctx != oldContext); + drv->API.DestroyContext(drv, dpy, oldContext); } } + /* build new bindings */ if (ctx) { - /* check read/draw again, in case we deleted them above */ - if (draw == NULL || read == NULL) { - _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - return EGL_FALSE; - } + t->CurrentContexts[apiIndex] = ctx; + ctx->Binding = t; ctx->DrawSurface = draw; ctx->ReadSurface = read; - ctx->IsBound = EGL_TRUE; - draw->IsBound = EGL_TRUE; - read->IsBound = EGL_TRUE; + draw->Binding = ctx; + read->Binding = ctx; } - t->CurrentContext = ctx; - return EGL_TRUE; } diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index 34fee9c6376..647f24488ff 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -11,15 +11,16 @@ */ struct _egl_context { - _EGLDisplay *Display; /* who do I belong to? */ - - _EGLConfig *Config; + /* Managed by EGLDisplay for linking */ + _EGLDisplay *Display; + _EGLContext *Next; + /* The bound status of the context */ + _EGLThreadInfo *Binding; _EGLSurface *DrawSurface; _EGLSurface *ReadSurface; - EGLBoolean IsBound; - EGLBoolean DeletePending; + _EGLConfig *Config; EGLint ClientAPI; /**< EGL_OPENGL_ES_API, EGL_OPENGL_API, EGL_OPENVG_API */ EGLint ClientVersion; /**< 1 = OpenGLES 1.x, 2 = OpenGLES 2.x */ @@ -27,47 +28,38 @@ struct _egl_context extern EGLBoolean -_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx, - EGLConfig config, const EGLint *attrib_list); - - -extern void -_eglSaveContext(_EGLContext *ctx); - - -extern void -_eglRemoveContext(_EGLContext *ctx); - - -extern EGLContext -_eglGetContextHandle(_EGLContext *ctx); +_eglInitContext(_EGLDriver *drv, _EGLContext *ctx, + _EGLConfig *config, const EGLint *attrib_list); extern _EGLContext * -_eglLookupContext(EGLContext ctx); - - -extern _EGLContext * -_eglGetCurrentContext(void); - - -extern EGLContext -_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list); +_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list); extern EGLBoolean -_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx); +_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx); extern EGLBoolean -_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value); extern EGLBoolean -_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx); extern EGLBoolean _eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask); + +/** + * Return true if the context is bound to a thread. + */ +static INLINE EGLBoolean +_eglIsContextBound(_EGLContext *ctx) +{ + return (ctx->Binding != NULL); +} + + #endif /* EGLCONTEXT_INCLUDED */ diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c new file mode 100644 index 00000000000..4431f964f69 --- /dev/null +++ b/src/egl/main/eglcurrent.c @@ -0,0 +1,342 @@ +#include <stdlib.h> +#include <string.h> +#include "eglcurrent.h" +#include "eglcontext.h" +#include "egllog.h" +#include "eglmutex.h" +#include "eglglobals.h" + + +/* This should be kept in sync with _eglInitThreadInfo() */ +#define _EGL_THREAD_INFO_INITIALIZER \ + { EGL_SUCCESS, { NULL }, 1 } + +/* a fallback thread info to guarantee that every thread always has one */ +static _EGLThreadInfo dummy_thread = _EGL_THREAD_INFO_INITIALIZER; + + +#ifdef GLX_USE_TLS +static __thread const _EGLThreadInfo *_egl_TSD; + __attribute__ ((tls_model("initial-exec"))); + +static INLINE void _eglSetTSD(const _EGLThreadInfo *t) +{ + _egl_TSD = t; +} + +static INLINE _EGLThreadInfo *_eglGetTSD(void) +{ + return (_EGLThreadInfo *) _egl_TSD; +} + +static INLINE void _eglFiniTSD(void) +{ +} + +static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *)) +{ + /* TODO destroy TSD */ + (void) dtor; + (void) _eglFiniTSD; + return EGL_TRUE; +} + +#elif PTHREADS +#include <pthread.h> + +static _EGL_DECLARE_MUTEX(_egl_TSDMutex); +static EGLBoolean _egl_TSDInitialized; +static pthread_key_t _egl_TSD; +static void (*_egl_FreeTSD)(_EGLThreadInfo *); + +static INLINE void _eglSetTSD(const _EGLThreadInfo *t) +{ + pthread_setspecific(_egl_TSD, (const void *) t); +} + +static INLINE _EGLThreadInfo *_eglGetTSD(void) +{ + return (_EGLThreadInfo *) pthread_getspecific(_egl_TSD); +} + +static INLINE void _eglFiniTSD(void) +{ + _eglLockMutex(&_egl_TSDMutex); + if (_egl_TSDInitialized) { + _EGLThreadInfo *t = _eglGetTSD(); + + _egl_TSDInitialized = EGL_FALSE; + if (t && _egl_FreeTSD) + _egl_FreeTSD((void *) t); + pthread_key_delete(_egl_TSD); + } + _eglUnlockMutex(&_egl_TSDMutex); +} + +static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *)) +{ + if (!_egl_TSDInitialized) { + _eglLockMutex(&_egl_TSDMutex); + + /* check again after acquiring lock */ + if (!_egl_TSDInitialized) { + if (pthread_key_create(&_egl_TSD, (void (*)(void *)) dtor) != 0) { + _eglUnlockMutex(&_egl_TSDMutex); + return EGL_FALSE; + } + _egl_FreeTSD = dtor; + _eglAddAtExitCall(_eglFiniTSD); + _egl_TSDInitialized = EGL_TRUE; + } + + _eglUnlockMutex(&_egl_TSDMutex); + } + + return EGL_TRUE; +} + +#else /* PTHREADS */ +static const _EGLThreadInfo *_egl_TSD; +static void (*_egl_FreeTSD)(_EGLThreadInfo *); + +static INLINE void _eglSetTSD(const _EGLThreadInfo *t) +{ + _egl_TSD = t; +} + +static INLINE _EGLThreadInfo *_eglGetTSD(void) +{ + return (_EGLThreadInfo *) _egl_TSD; +} + +static INLINE void _eglFiniTSD(void) +{ + if (_egl_FreeTSD && _egl_TSD) + _egl_FreeTSD((_EGLThreadInfo *) _egl_TSD); +} + +static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *)) +{ + if (!_egl_FreeTSD && dtor) { + _egl_FreeTSD = dtor; + _eglAddAtExitCall(_eglFiniTSD); + } + return EGL_TRUE; +} + +#endif /* !PTHREADS */ + + +static void +_eglInitThreadInfo(_EGLThreadInfo *t) +{ + memset(t, 0, sizeof(*t)); + t->LastError = EGL_SUCCESS; + /* default, per EGL spec */ + t->CurrentAPIIndex = _eglConvertApiToIndex(EGL_OPENGL_ES_API); +} + + +/** + * Allocate and init a new _EGLThreadInfo object. + */ +static _EGLThreadInfo * +_eglCreateThreadInfo(void) +{ + _EGLThreadInfo *t = (_EGLThreadInfo *) calloc(1, sizeof(_EGLThreadInfo)); + if (t) + _eglInitThreadInfo(t); + else + t = &dummy_thread; + return t; +} + + +/** + * Delete/free a _EGLThreadInfo object. + */ +static void +_eglDestroyThreadInfo(_EGLThreadInfo *t) +{ + if (t != &dummy_thread) + free(t); +} + + +/** + * Make sure TSD is initialized and return current value. + */ +static INLINE _EGLThreadInfo * +_eglCheckedGetTSD(void) +{ + if (_eglInitTSD(&_eglDestroyThreadInfo) != EGL_TRUE) { + _eglLog(_EGL_FATAL, "failed to initialize \"current\" system"); + return NULL; + } + + return _eglGetTSD(); +} + + +/** + * Return the calling thread's thread info. + * If the calling thread nevers calls this function before, or if its thread + * info was destroyed, a new one is created. This function never returns NULL. + * In the case allocation fails, a dummy one is returned. See also + * _eglIsCurrentThreadDummy. + */ +_EGLThreadInfo * +_eglGetCurrentThread(void) +{ + _EGLThreadInfo *t = _eglCheckedGetTSD(); + if (!t) { + t = _eglCreateThreadInfo(); + _eglSetTSD(t); + } + + return t; +} + + +/** + * Destroy the calling thread's thread info. + */ +void +_eglDestroyCurrentThread(void) +{ + _EGLThreadInfo *t = _eglCheckedGetTSD(); + if (t) { + _eglDestroyThreadInfo(t); + _eglSetTSD(NULL); + } +} + + +/** + * Return true if the calling thread's thread info is dummy. + * A dummy thread info is shared by all threads and should not be modified. + * Functions like eglBindAPI or eglMakeCurrent should check for dummy-ness + * before updating the thread info. + */ +EGLBoolean +_eglIsCurrentThreadDummy(void) +{ + _EGLThreadInfo *t = _eglCheckedGetTSD(); + return (!t || t == &dummy_thread); +} + + +/** + * Return the currently bound context, or NULL. + */ +_EGLContext * +_eglGetCurrentContext(void) +{ + _EGLThreadInfo *t = _eglGetCurrentThread(); + return t->CurrentContexts[t->CurrentAPIIndex]; +} + + +/** + * Return the display of the currently bound context, or NULL. + */ +_EGLDisplay * +_eglGetCurrentDisplay(void) +{ + _EGLThreadInfo *t = _eglGetCurrentThread(); + _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex]; + if (ctx) + return ctx->Display; + else + return NULL; +} + + +/** + * Return the read or write surface of the currently bound context, or NULL. + */ +_EGLSurface * +_eglGetCurrentSurface(EGLint readdraw) +{ + _EGLThreadInfo *t = _eglGetCurrentThread(); + _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex]; + if (ctx) { + switch (readdraw) { + case EGL_DRAW: + return ctx->DrawSurface; + case EGL_READ: + return ctx->ReadSurface; + default: + return NULL; + } + } + return NULL; +} + + +/** + * Record EGL error code. + */ +EGLBoolean +_eglError(EGLint errCode, const char *msg) +{ + _EGLThreadInfo *t = _eglGetCurrentThread(); + const char *s; + + if (t == &dummy_thread) + return EGL_FALSE; + + if (t->LastError == EGL_SUCCESS) { + t->LastError = errCode; + + switch (errCode) { + case EGL_BAD_ACCESS: + s = "EGL_BAD_ACCESS"; + break; + case EGL_BAD_ALLOC: + s = "EGL_BAD_ALLOC"; + break; + case EGL_BAD_ATTRIBUTE: + s = "EGL_BAD_ATTRIBUTE"; + break; + case EGL_BAD_CONFIG: + s = "EGL_BAD_CONFIG"; + break; + case EGL_BAD_CONTEXT: + s = "EGL_BAD_CONTEXT"; + break; + case EGL_BAD_CURRENT_SURFACE: + s = "EGL_BAD_CURRENT_SURFACE"; + break; + case EGL_BAD_DISPLAY: + s = "EGL_BAD_DISPLAY"; + break; + case EGL_BAD_MATCH: + s = "EGL_BAD_MATCH"; + break; + case EGL_BAD_NATIVE_PIXMAP: + s = "EGL_BAD_NATIVE_PIXMAP"; + break; + case EGL_BAD_NATIVE_WINDOW: + s = "EGL_BAD_NATIVE_WINDOW"; + break; + case EGL_BAD_PARAMETER: + s = "EGL_BAD_PARAMETER"; + break; + case EGL_BAD_SURFACE: + s = "EGL_BAD_SURFACE"; + break; + case EGL_BAD_SCREEN_MESA: + s = "EGL_BAD_SCREEN_MESA"; + break; + case EGL_BAD_MODE_MESA: + s = "EGL_BAD_MODE_MESA"; + break; + default: + s = "other"; + } + _eglLog(_EGL_DEBUG, "EGL user error 0x%x (%s) in %s\n", errCode, s, msg); + } + + return EGL_FALSE; +} diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h new file mode 100644 index 00000000000..8eb241029ec --- /dev/null +++ b/src/egl/main/eglcurrent.h @@ -0,0 +1,84 @@ +#ifndef EGLCURRENT_INCLUDED +#define EGLCURRENT_INCLUDED + +#include "egltypedefs.h" + + +#define _EGL_API_NUM_INDICES \ + (EGL_OPENGL_API - EGL_OPENGL_ES_API + 2) /* idx 0 is for EGL_NONE */ + + +/** + * Per-thread info + */ +struct _egl_thread_info +{ + EGLint LastError; + _EGLContext *CurrentContexts[_EGL_API_NUM_INDICES]; + /* use index for fast access to current context */ + EGLint CurrentAPIIndex; +}; + + +/** + * Return true if a client API enum can be converted to an index. + */ +static INLINE EGLBoolean +_eglIsApiValid(EGLenum api) +{ + return ((api >= EGL_OPENGL_ES_API && api <= EGL_OPENGL_API) || + api == EGL_NONE); +} + + +/** + * Convert a client API enum to an index, for use by thread info. + * The client API enum is assumed to be valid. + */ +static INLINE EGLint +_eglConvertApiToIndex(EGLenum api) +{ + return (api != EGL_NONE) ? api - EGL_OPENGL_ES_API + 1 : 0; +} + + +/** + * Convert an index, used by thread info, to a client API enum. + * The index is assumed to be valid. + */ +static INLINE EGLenum +_eglConvertApiFromIndex(EGLint idx) +{ + return (idx) ? EGL_OPENGL_ES_API + idx - 1 : EGL_NONE; +} + + +extern _EGLThreadInfo * +_eglGetCurrentThread(void); + + +extern void +_eglDestroyCurrentThread(void); + + +extern EGLBoolean +_eglIsCurrentThreadDummy(void); + + +extern _EGLContext * +_eglGetCurrentContext(void); + + +extern _EGLDisplay * +_eglGetCurrentDisplay(void); + + +extern _EGLSurface * +_eglGetCurrentSurface(EGLint readdraw); + + +extern EGLBoolean +_eglError(EGLint errCode, const char *msg); + + +#endif /* EGLCURRENT_INCLUDED */ diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 47a2323eafb..2c271efd670 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -1,4 +1,3 @@ - /** * Functions related to EGLDisplay. */ @@ -7,11 +6,67 @@ #include <stdlib.h> #include <string.h> #include "eglcontext.h" +#include "eglsurface.h" #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" -#include "eglhash.h" #include "eglstring.h" +#include "eglmutex.h" +#include "egllog.h" + + +/** + * Finish display management. + */ +void +_eglFiniDisplay(void) +{ + _EGLDisplay *dpyList, *dpy; + + /* atexit function is called with global mutex locked */ + dpyList = _eglGlobal.DisplayList; + while (dpyList) { + /* pop list head */ + dpy = dpyList; + dpyList = dpyList->Next; + + if (dpy->ContextList || dpy->SurfaceList) + _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy); + + free(dpy); + } + _eglGlobal.DisplayList = NULL; +} + + +/** + * If the first character is '!' we interpret it as specific driver name + * (i.e. "!r200" or "!i830"). Whatever follows ':' is interpreted as + * arguments. + * + * The caller may free() the returned driver name. + */ +char * +_eglSplitDisplayString(const char *dpyString, const char **args) +{ + char *drv, *p; + + if (!dpyString || dpyString[0] != '!') + return NULL; + drv = _eglstrdup(dpyString + 1); + if (!drv) + return NULL; + + p = strchr(dpyString, ':'); + if (p) { + drv[p - dpyString] = '\0'; + p++; + } + if (args) + *args = p; + + return drv; +} /** @@ -25,17 +80,12 @@ _eglNewDisplay(NativeDisplayType nativeDisplay) { _EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay)); if (dpy) { - EGLuint key = _eglHashGenKey(_eglGlobal.Displays); - - dpy->Handle = (EGLDisplay) key; - _eglHashInsert(_eglGlobal.Displays, key, dpy); - dpy->NativeDisplay = nativeDisplay; #if defined(_EGL_PLATFORM_X) dpy->Xdpy = (Display *) nativeDisplay; #endif - dpy->DriverName = _eglChooseDriver(dpy); + dpy->DriverName = _eglPreloadDriver(dpy); if (!dpy->DriverName) { free(dpy); return NULL; @@ -46,54 +96,107 @@ _eglNewDisplay(NativeDisplayType nativeDisplay) /** - * Return the public handle for an internal _EGLDisplay. - * This is the inverse of _eglLookupDisplay(). + * Link a display to itself and return the handle of the link. + * The handle can be passed to client directly. */ EGLDisplay -_eglGetDisplayHandle(_EGLDisplay *display) +_eglLinkDisplay(_EGLDisplay *dpy) { - if (display) - return display->Handle; - else - return EGL_NO_DISPLAY; + _eglLockMutex(_eglGlobal.Mutex); + + dpy->Next = _eglGlobal.DisplayList; + _eglGlobal.DisplayList = dpy; + + _eglUnlockMutex(_eglGlobal.Mutex); + + return (EGLDisplay) dpy; } - + /** - * Return the _EGLDisplay object that corresponds to the given public/ - * opaque display handle. - * This is the inverse of _eglGetDisplayHandle(). + * Unlink a linked display from itself. + * Accessing an unlinked display should generate EGL_BAD_DISPLAY error. */ -_EGLDisplay * -_eglLookupDisplay(EGLDisplay dpy) +void +_eglUnlinkDisplay(_EGLDisplay *dpy) { - EGLuint key = (EGLuint) dpy; - if (!_eglGlobal.Displays) - return NULL; - return (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key); + _EGLDisplay *prev; + + _eglLockMutex(_eglGlobal.Mutex); + + prev = _eglGlobal.DisplayList; + if (prev != dpy) { + while (prev) { + if (prev->Next == dpy) + break; + prev = prev->Next; + } + assert(prev); + prev->Next = dpy->Next; + } + else { + _eglGlobal.DisplayList = dpy->Next; + } + + _eglUnlockMutex(_eglGlobal.Mutex); } -void -_eglSaveDisplay(_EGLDisplay *dpy) +/** + * Find the display corresponding to the specified native display id in all + * linked displays. + */ +_EGLDisplay * +_eglFindDisplay(NativeDisplayType nativeDisplay) { - EGLuint key = _eglHashGenKey(_eglGlobal.Displays); - assert(dpy); - assert(!dpy->Handle); - dpy->Handle = (EGLDisplay) key; - assert(dpy->Handle); - _eglHashInsert(_eglGlobal.Displays, key, dpy); + _EGLDisplay *dpy; + + _eglLockMutex(_eglGlobal.Mutex); + + dpy = _eglGlobal.DisplayList; + while (dpy) { + if (dpy->NativeDisplay == nativeDisplay) { + _eglUnlockMutex(_eglGlobal.Mutex); + return dpy; + } + dpy = dpy->Next; + } + + _eglUnlockMutex(_eglGlobal.Mutex); + + return NULL; } -_EGLDisplay * -_eglGetCurrentDisplay(void) +/** + * Destroy the contexts and surfaces that are linked to the display. + */ +void +_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display) { - _EGLContext *ctx = _eglGetCurrentContext(); - if (ctx) - return ctx->Display; - else - return NULL; + _EGLContext *contexts; + _EGLSurface *surfaces; + + contexts = display->ContextList; + surfaces = display->SurfaceList; + + while (contexts) { + _EGLContext *ctx = contexts; + contexts = contexts->Next; + + _eglUnlinkContext(ctx); + drv->API.DestroyContext(drv, display, ctx); + } + assert(!display->ContextList); + + while (surfaces) { + _EGLSurface *surf = surfaces; + surfaces = surfaces->Next; + + _eglUnlinkSurface(surf); + drv->API.DestroySurface(drv, display, surf); + } + assert(!display->SurfaceList); } @@ -106,16 +209,166 @@ _eglCleanupDisplay(_EGLDisplay *disp) { EGLint i; - for (i = 0; i < disp->NumConfigs; i++) { - free(disp->Configs[i]); + if (disp->Configs) { + for (i = 0; i < disp->NumConfigs; i++) + free(disp->Configs[i]); + free(disp->Configs); + disp->Configs = NULL; + disp->NumConfigs = 0; } - free(disp->Configs); - disp->Configs = NULL; /* XXX incomplete */ +} - free((void *) disp->DriverName); - disp->DriverName = NULL; - /* driver deletes the _EGLDisplay object */ +/** + * Link a context to a display and return the handle of the link. + * The handle can be passed to client directly. + */ +EGLContext +_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy) +{ + ctx->Display = dpy; + ctx->Next = dpy->ContextList; + dpy->ContextList = ctx; + return (EGLContext) ctx; +} + + +/** + * Unlink a linked context from its display. + * Accessing an unlinked context should generate EGL_BAD_CONTEXT error. + */ +void +_eglUnlinkContext(_EGLContext *ctx) +{ + _EGLContext *prev; + + prev = ctx->Display->ContextList; + if (prev != ctx) { + while (prev) { + if (prev->Next == ctx) + break; + prev = prev->Next; + } + assert(prev); + prev->Next = ctx->Next; + } + else { + ctx->Display->ContextList = ctx->Next; + } + + ctx->Next = NULL; + ctx->Display = NULL; +} + + +/** + * Link a surface to a display and return the handle of the link. + * The handle can be passed to client directly. + */ +EGLSurface +_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy) +{ + surf->Display = dpy; + surf->Next = dpy->SurfaceList; + dpy->SurfaceList = surf; + return (EGLSurface) surf; } + + +/** + * Unlink a linked surface from its display. + * Accessing an unlinked surface should generate EGL_BAD_SURFACE error. + */ +void +_eglUnlinkSurface(_EGLSurface *surf) +{ + _EGLSurface *prev; + + prev = surf->Display->SurfaceList; + if (prev != surf) { + while (prev) { + if (prev->Next == surf) + break; + prev = prev->Next; + } + assert(prev); + prev->Next = surf->Next; + } + else { + prev = NULL; + surf->Display->SurfaceList = surf->Next; + } + + surf->Next = NULL; + surf->Display = NULL; +} + + +#ifndef _EGL_SKIP_HANDLE_CHECK + + +/** + * Return EGL_TRUE if the given handle is a valid handle to a display. + */ +EGLBoolean +_eglCheckDisplayHandle(EGLDisplay dpy) +{ + _EGLDisplay *cur; + + _eglLockMutex(_eglGlobal.Mutex); + cur = _eglGlobal.DisplayList; + while (cur) { + if (cur == (_EGLDisplay *) dpy) + break; + cur = cur->Next; + } + _eglUnlockMutex(_eglGlobal.Mutex); + return (cur != NULL); +} + + +/** + * Return EGL_TRUE if the given handle is a valid handle to a context. + */ +EGLBoolean +_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy) +{ + _EGLContext *cur = NULL; + + if (dpy) + cur = dpy->ContextList; + while (cur) { + if (cur == (_EGLContext *) ctx) { + assert(cur->Display == dpy); + break; + } + cur = cur->Next; + } + return (cur != NULL); +} + + +/** + * Return EGL_TRUE if the given handle is a valid handle to a surface. + */ +EGLBoolean +_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy) +{ + _EGLSurface *cur = NULL; + + if (dpy) + cur = dpy->SurfaceList; + while (cur) { + if (cur == (_EGLSurface *) surf) { + assert(cur->Display == dpy); + break; + } + cur = cur->Next; + } + return (cur != NULL); +} + + +#endif /* !_EGL_SKIP_HANDLE_CHECK */ diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index ff623ee1c66..c7a41cd5883 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -6,16 +6,44 @@ #endif #include "egltypedefs.h" +#include "egldefines.h" +#include "eglcontext.h" +#include "eglsurface.h" + + +/** + * Optional EGL extensions info. + */ +struct _egl_extensions +{ + EGLBoolean MESA_screen_surface; + EGLBoolean MESA_copy_context; + + char String[_EGL_MAX_EXTENSIONS_LEN]; +}; struct _egl_display { + /* used to link displays */ + _EGLDisplay *Next; + EGLNativeDisplayType NativeDisplay; - EGLDisplay Handle; const char *DriverName; - const char *DriverArgs; _EGLDriver *Driver; + void *DriverData; /* private to driver */ + + int APImajor, APIminor; /**< as returned by eglInitialize() */ + char Version[1000]; /**< initialized from APImajor/minor, DriverName */ + + /** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */ + EGLint ClientAPIsMask; + char ClientAPIs[1000]; /**< updated by eglQueryString */ + + _EGLExtensions Extensions; + + int LargestPbuffer; EGLint NumScreens; _EGLScreen **Screens; /* array [NumScreens] */ @@ -23,39 +51,230 @@ struct _egl_display EGLint NumConfigs; _EGLConfig **Configs; /* array [NumConfigs] of ptr to _EGLConfig */ + /* lists of linked contexts and surface */ + _EGLContext *ContextList; + _EGLSurface *SurfaceList; + #ifdef _EGL_PLATFORM_X Display *Xdpy; #endif }; -extern _EGLDisplay * -_eglNewDisplay(NativeDisplayType displayName); +extern void +_eglFiniDisplay(void); -EGLDisplay -_eglGetDisplayHandle(_EGLDisplay *display); +extern char * +_eglSplitDisplayString(const char *dpyString, const char **args); extern _EGLDisplay * -_eglLookupDisplay(EGLDisplay dpy); +_eglNewDisplay(NativeDisplayType displayName); + + +extern EGLDisplay +_eglLinkDisplay(_EGLDisplay *dpy); extern void -_eglSaveDisplay(_EGLDisplay *dpy); +_eglUnlinkDisplay(_EGLDisplay *dpy); extern _EGLDisplay * -_eglGetCurrentDisplay(void); +_eglFindDisplay(NativeDisplayType nativeDisplay); + + +extern void +_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *dpy); extern void _eglCleanupDisplay(_EGLDisplay *disp); -extern EGLBoolean -_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attrib, EGLint *value); +extern EGLContext +_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy); + + +extern void +_eglUnlinkContext(_EGLContext *ctx); + + +extern EGLSurface +_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy); + + +extern void +_eglUnlinkSurface(_EGLSurface *surf); + + +#ifndef _EGL_SKIP_HANDLE_CHECK + + +extern EGLBoolean +_eglCheckDisplayHandle(EGLDisplay dpy); + + +extern EGLBoolean +_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy); + + +extern EGLBoolean +_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy); + + +#else /* !_EGL_SKIP_HANDLE_CHECK */ + +/* Only do a quick check. This is NOT standard compliant. */ + +static INLINE EGLBoolean +_eglCheckDisplayHandle(EGLDisplay dpy) +{ + return ((_EGLDisplay *) dpy != NULL); +} +static INLINE EGLBoolean +_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy) +{ + _EGLContext *c = (_EGLContext *) ctx; + return (dpy && c && c->Display == dpy); +} + + +static INLINE EGLBoolean +_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy) +{ + _EGLSurface *s = (_EGLSurface *) surf; + return (dpy && s && s->Display == dpy); +} + + +#endif /* _EGL_SKIP_HANDLE_CHECK */ + + +/** + * Lookup a handle to find the linked display. + * Return NULL if the handle has no corresponding linked display. + */ +static INLINE _EGLDisplay * +_eglLookupDisplay(EGLDisplay display) +{ + _EGLDisplay *dpy = (_EGLDisplay *) display; + if (!_eglCheckDisplayHandle(display)) + dpy = NULL; + return dpy; +} + + +/** + * Return the handle of a linked display, or EGL_NO_DISPLAY. + */ +static INLINE EGLDisplay +_eglGetDisplayHandle(_EGLDisplay *dpy) +{ + return (EGLDisplay) ((dpy) ? dpy : EGL_NO_DISPLAY); +} + + +/** + * Return true if the display is linked. + */ +static INLINE EGLBoolean +_eglIsDisplayLinked(_EGLDisplay *dpy) +{ + return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY); +} + + +/** + * Lookup a handle to find the linked context. + * Return NULL if the handle has no corresponding linked context. + */ +static INLINE _EGLContext * +_eglLookupContext(EGLContext context, _EGLDisplay *dpy) +{ + _EGLContext *ctx = (_EGLContext *) context; + if (!_eglCheckContextHandle(context, dpy)) + ctx = NULL; + return ctx; +} + + +/** + * Return the handle of a linked context, or EGL_NO_CONTEXT. + */ +static INLINE EGLContext +_eglGetContextHandle(_EGLContext *ctx) +{ + return (EGLContext) ((ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT); +} + + +/** + * Return true if the context is linked to a display. + */ +static INLINE EGLBoolean +_eglIsContextLinked(_EGLContext *ctx) +{ + return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT); +} + + +/** + * Lookup a handle to find the linked surface. + * Return NULL if the handle has no corresponding linked surface. + */ +static INLINE _EGLSurface * +_eglLookupSurface(EGLSurface surface, _EGLDisplay *dpy) +{ + _EGLSurface *surf = (_EGLSurface *) surface; + if (!_eglCheckSurfaceHandle(surf, dpy)) + surf = NULL; + return surf; +} + + +/** + * Return the handle of a linked surface, or EGL_NO_SURFACE. + */ +static INLINE EGLSurface +_eglGetSurfaceHandle(_EGLSurface *surf) +{ + return (EGLSurface) ((surf && surf->Display) ? surf : EGL_NO_SURFACE); +} + + +/** + * Return true if the surface is linked to a display. + */ +static INLINE EGLBoolean +_eglIsSurfaceLinked(_EGLSurface *surf) +{ + return (EGLBoolean) (_eglGetSurfaceHandle(surf) != EGL_NO_SURFACE); +} + + +/** + * Cast an unsigned int to a pointer. + */ +static INLINE void * +_eglUIntToPointer(unsigned int v) +{ + return (void *) ((uintptr_t) v); +} + + +/** + * Cast a pointer to an unsigned int. The pointer must be one that is + * returned by _eglUIntToPointer. + */ +static INLINE unsigned int +_eglPointerToUInt(const void *p) +{ + return (unsigned int) ((uintptr_t) p); +} + #endif /* EGLDISPLAY_INCLUDED */ diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 43b1f519034..87786e36bbf 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -22,7 +22,6 @@ #if defined(_EGL_PLATFORM_X) #include <dlfcn.h> -#include "eglx.h" #elif defined(_EGL_PLATFORM_WINDOWS) /* Use static linking on Windows for now */ #define WINDOWS_STATIC_LINK @@ -38,7 +37,6 @@ /* XXX Need to decide how to do dynamic name lookup on Windows */ static const char *DefaultDriverName = "TBD"; #endif - static const char *SysFS = NULL; typedef HMODULE lib_handle; static HMODULE @@ -61,8 +59,7 @@ } #elif defined(_EGL_PLATFORM_X) - static const char *DefaultDriverName = ":0"; - static const char *SysFS = "/sys/class"; + static const char *DefaultDriverName = "egl_softpipe"; typedef void * lib_handle; @@ -80,142 +77,69 @@ #endif -/** - * Given a card number, use sysfs to determine the DRI driver name. - */ -const char * -_eglChooseDRMDriver(int card) -{ -#if 0 - return _eglstrdup("libEGLdri"); -#else - char path[2000], driverName[2000]; - FILE *f; - int length; - - snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", SysFS, card); - - f = fopen(path, "r"); - if (!f) - return NULL; - - fgets(driverName, sizeof(driverName), f); - fclose(f); - - if ((length = strlen(driverName)) > 1) { - /* remove the trailing newline from sysfs */ - driverName[length - 1] = '\0'; - strncat(driverName, "_dri", sizeof(driverName)); - return _eglstrdup(driverName); - } - else { - return NULL; - } -#endif -} /** - * XXX this function is totally subject change!!! - * - * - * Determine/return the name of the driver to use for the given _EGLDisplay. - * - * Try to be clever and determine if nativeDisplay is an Xlib Display - * ptr or a string (naming a driver or screen number, etc). - * - * If the first character is ':' we interpret it as a screen or card index - * number (i.e. ":0" or ":1", etc) - * Else if the first character is '!' we interpret it as specific driver name - * (i.e. "!r200" or "!i830". - * - * Whatever follows ':' is copied and put into dpy->DriverArgs. - * - * The caller may free() the returned string. + * Choose a driver for a given display. + * The caller may free() the returned strings. */ -const char * -_eglChooseDriver(_EGLDisplay *dpy) +static char * +_eglChooseDriver(_EGLDisplay *dpy, char **argsRet) { - /* Under Windows, the NativeDisplay is an HDC handle, therefore */ - /* it can't be interpreted as a string or a pointer. */ -#if defined(_EGL_PLATFORM_WINDOWS) - const char *displayString = NULL; -#else - const char *displayString = (const char *) dpy->NativeDisplay; -#endif - const char *driverName = NULL; + char *path = NULL; + const char *args = NULL; + const char *suffix = NULL; + const char *p; - (void) DefaultDriverName; + path = getenv("EGL_DRIVER"); + if (path) + path = _eglstrdup(path); #if defined(_EGL_PLATFORM_X) - /* First, if the EGL_DRIVER env var is set, use that */ - driverName = getenv("EGL_DRIVER"); - if (driverName) - return _eglstrdup(driverName); -#endif - -#if 0 - if (!displayString) { - /* choose a default */ - displayString = DefaultDriverName; + if (!path && dpy->NativeDisplay) { + /* assume (wrongly!) that the native display is a display string */ + path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args); } -#endif - /* extract default DriverArgs = whatever follows ':' */ - if (displayString && - (displayString[0] == '!' || - displayString[0] == ':')) { - const char *args = strchr(displayString, ':'); - if (args) - dpy->DriverArgs = _eglstrdup(args + 1); - } - - /* determine driver name now */ - if (displayString && displayString[0] == ':' && - (displayString[1] >= '0' && displayString[1] <= '9') && - !displayString[2]) { - int card = atoi(displayString + 1); - driverName = _eglChooseDRMDriver(card); - } - else if (displayString && displayString[0] == '!') { - /* use user-specified driver name */ - driverName = _eglstrdup(displayString + 1); - /* truncate driverName at ':' if present */ - { - char *args = strchr(driverName, ':'); - if (args) { - *args = 0; - } + suffix = "so"; +#elif defined(_EGL_PLATFORM_WINDOWS) + suffix = "dll"; +#endif /* _EGL_PLATFORM_X */ + + if (!path) + path = _eglstrdup(DefaultDriverName); + + /* append suffix if there isn't */ + p = strrchr(path, '.'); + if (!p && suffix) { + size_t len = strlen(path); + char *tmp = malloc(len + strlen(suffix) + 2); + if (tmp) { + memcpy(tmp, path, len); + tmp[len++] = '.'; + tmp[len] = '\0'; + strcat(tmp + len, suffix); + + free(path); + path = tmp; } } - else - { - /* NativeDisplay is not a string! */ -#if defined(_EGL_PLATFORM_X) - driverName = _xeglChooseDriver(dpy); -#else - driverName = DefaultDriverName; -#endif - } - return driverName; + if (argsRet) + *argsRet = (args) ? _eglstrdup(args) : NULL; + + return path; } /** - * Open/load the named driver and call its bootstrap function: _eglMain(). - * By the time this function is called, the dpy->DriverName should have - * been determined. - * - * \return new _EGLDriver object. + * Open the named driver and find its bootstrap function: _eglMain(). */ -_EGLDriver * -_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args) +static _EGLMain_t +_eglOpenLibrary(const char *driverPath, lib_handle *handle) { - _EGLDriver *drv; _EGLMain_t mainFunc; lib_handle lib; - char driverFilename[1000]; - assert(driverName); + assert(driverPath); #if defined(_EGL_PLATFORM_WINDOWS) /* Use static linking on Windows for now */ @@ -224,85 +148,190 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args) mainFunc = (_EGLMain_t)_eglMain; #else /* XXX untested */ - sprintf(driverFilename, "%s.dll", driverName); - _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename); - lib = open_library(driverFilename); + _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath); + lib = open_library(driverPath); if (!lib) { _eglLog(_EGL_WARNING, "Could not open %s", - driverFilename); + driverPath); return NULL; } mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain"); #endif #elif defined(_EGL_PLATFORM_X) - /* XXX also prepend a directory path??? */ - sprintf(driverFilename, "%s.so", driverName); - _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename); - lib = open_library(driverFilename); + _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath); + lib = open_library(driverPath); if (!lib) { _eglLog(_EGL_WARNING, "Could not open %s (%s)", - driverFilename, dlerror()); + driverPath, dlerror()); + if (!getenv("EGL_DRIVER")) + _eglLog(_EGL_WARNING, + "The driver can be overridden by setting EGL_DRIVER"); return NULL; } mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain"); #endif if (!mainFunc) { - _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename); - close_library(lib); + _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverPath); + if (lib) + close_library(lib); return NULL; } - drv = mainFunc(dpy, args); + *handle = lib; + return mainFunc; +} + + +/** + * Load the named driver. The path and args passed will be + * owned by the driver and freed. + */ +static _EGLDriver * +_eglLoadDriver(char *path, char *args) +{ + _EGLMain_t mainFunc; + lib_handle lib; + _EGLDriver *drv = NULL; + + mainFunc = _eglOpenLibrary(path, &lib); + if (!mainFunc) + return NULL; + + drv = mainFunc(args); if (!drv) { - close_library(lib); + if (lib) + close_library(lib); return NULL; } - /* with a recurvise open you want the inner most handle */ - if (!drv->LibHandle) { - drv->LibHandle = lib; - } - else { - close_library(lib); + if (!drv->Name) { + _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path); + drv->Name = "UNNAMED"; } - /* update the global notion of supported APIs */ - _eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask; - - _eglSaveDriver(drv); + drv->Path = path; + drv->Args = args; + drv->LibHandle = lib; return drv; } -EGLBoolean -_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy) +/** + * Match a display to a preloaded driver. + */ +static _EGLDriver * +_eglMatchDriver(_EGLDisplay *dpy) { - void *handle = drv->LibHandle; - EGLBoolean b; + _EGLDriver *defaultDriver = NULL; + EGLint i; - _eglLog(_EGL_DEBUG, "Closing %s", drv->Name); + for (i = 0; i < _eglGlobal.NumDrivers; i++) { + _EGLDriver *drv = _eglGlobal.Drivers[i]; - /* - * XXX check for currently bound context/surfaces and delete them? - */ + /* display specifies a driver */ + if (dpy->DriverName) { + if (strcmp(dpy->DriverName, drv->Name) == 0) + return drv; + } + else if (drv->Probe) { + if (drv->Probe(drv, dpy)) + return drv; + } + else { + if (!defaultDriver) + defaultDriver = drv; + } + } + + return defaultDriver; +} + + +/** + * Load a driver and save it. + */ +const char * +_eglPreloadDriver(_EGLDisplay *dpy) +{ + char *path, *args; + _EGLDriver *drv; + EGLint i; + + path = _eglChooseDriver(dpy, &args); + if (!path) + return NULL; + + for (i = 0; i < _eglGlobal.NumDrivers; i++) { + drv = _eglGlobal.Drivers[i]; + if (strcmp(drv->Path, path) == 0) { + _eglLog(_EGL_DEBUG, "Driver %s is already preloaded", + drv->Name); + free(path); + if (args) + free(args); + return drv->Name; + } + } + + drv = _eglLoadDriver(path, args); + if (!drv) + return NULL; - b = drv->API.Terminate(drv, dpy); + _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv; + + return drv->Name; +} + + +/** + * Open a preloaded driver. + */ +_EGLDriver * +_eglOpenDriver(_EGLDisplay *dpy) +{ + _EGLDriver *drv = _eglMatchDriver(dpy); + return drv; +} - close_library(handle); - return b; +/** + * Close a preloaded driver. + */ +EGLBoolean +_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy) +{ + return EGL_TRUE; } /** - * Save the given driver pointer in the list of all known drivers. + * Unload preloaded drivers. */ void -_eglSaveDriver(_EGLDriver *drv) +_eglUnloadDrivers(void) { - _eglGlobal.Drivers[ _eglGlobal.NumDrivers++ ] = drv; + EGLint i; + for (i = 0; i < _eglGlobal.NumDrivers; i++) { + _EGLDriver *drv = _eglGlobal.Drivers[i]; + lib_handle handle = drv->LibHandle; + + if (drv->Path) + free((char *) drv->Path); + if (drv->Args) + free((char *) drv->Args); + + /* destroy driver */ + if (drv->Unload) + drv->Unload(drv); + + if (handle) + close_library(handle); + _eglGlobal.Drivers[i] = NULL; + } + + _eglGlobal.NumDrivers = 0; } diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h index 4066c6ec1df..6c848eb35ea 100644 --- a/src/egl/main/egldriver.h +++ b/src/egl/main/egldriver.h @@ -4,19 +4,6 @@ #include "egltypedefs.h" #include "eglapi.h" -#include "egldefines.h" - - -/** - * Optional EGL extensions info. - */ -struct _egl_extensions -{ - EGLBoolean MESA_screen_surface; - EGLBoolean MESA_copy_context; - - char String[_EGL_MAX_EXTENSIONS_LEN]; -}; /** @@ -24,46 +11,37 @@ struct _egl_extensions */ struct _egl_driver { - EGLBoolean Initialized; /**< set by driver after initialized */ - void *LibHandle; /**< dlopen handle */ + const char *Path; /**< path to this driver */ + const char *Args; /**< args to load this driver */ const char *Name; /**< name of this driver */ - - int APImajor, APIminor; /**< as returned by eglInitialize() */ - char Version[1000]; /**< initialized from APImajor/minor, Name */ - - /** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */ - EGLint ClientAPIsMask; + /**< probe a display to see if it is supported */ + EGLBoolean (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy); + /**< called before dlclose to release this driver */ + void (*Unload)(_EGLDriver *drv); _EGLAPI API; /**< EGL API dispatch table */ - - _EGLExtensions Extensions; - - int LargestPbuffer; }; -extern _EGLDriver *_eglMain(_EGLDisplay *dpy, const char *args); +extern _EGLDriver *_eglMain(const char *args); extern const char * -_eglChooseDRMDriver(int card); - -extern const char * -_eglChooseDriver(_EGLDisplay *dpy); +_eglPreloadDriver(_EGLDisplay *dpy); extern _EGLDriver * -_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args); +_eglOpenDriver(_EGLDisplay *dpy); extern EGLBoolean -_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy); +_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy); -extern void -_eglSaveDriver(_EGLDriver *drv); +void +_eglUnloadDrivers(void); extern _EGLDriver * diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index b770e55dbdf..3ae4c1ad3a3 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -1,146 +1,56 @@ -#include <stdio.h> #include <stdlib.h> +#include <assert.h> #include "eglglobals.h" +#include "egldriver.h" +#include "egllog.h" +#include "eglmutex.h" -struct _egl_global _eglGlobal = -{ - EGL_FALSE -}; - -/** - * Init the fields in the _eglGlobal struct - * May be safely called more than once. - */ -void -_eglInitGlobals(void) -{ - if (!_eglGlobal.Initialized) { - _eglGlobal.Displays = _eglNewHashTable(); - _eglGlobal.Surfaces = _eglNewHashTable(); - _eglGlobal.FreeScreenHandle = 1; - _eglGlobal.Initialized = EGL_TRUE; - - _eglGlobal.ClientAPIsMask = 0x0; - /* XXX temporary */ - _eglGlobal.ThreadInfo = _eglNewThreadInfo(); - } -} +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -/** - * Should call this via an atexit handler. - */ -void -_eglDestroyGlobals(void) +static _EGL_DECLARE_MUTEX(_eglGlobalMutex); +struct _egl_global _eglGlobal = { - /* XXX TODO walk over table entries, deleting each */ - _eglDeleteHashTable(_eglGlobal.Displays); - _eglDeleteHashTable(_eglGlobal.Surfaces); -} + &_eglGlobalMutex, /* Mutex */ + NULL, /* DisplayList */ + 1, /* FreeScreenHandle */ + 0x0, /* ClientAPIsMask */ + 0, /* NumDrivers */ + { NULL }, /* Drivers */ + 2, /* NumAtExitCalls */ + { /* AtExitCalls */ + _eglFiniDisplay, + _eglUnloadDrivers + }, +}; -/** - * Allocate and init a new _EGLThreadInfo object. - */ -_EGLThreadInfo * -_eglNewThreadInfo(void) +static void +_eglAtExit(void) { - _EGLThreadInfo *t = (_EGLThreadInfo *) calloc(1, sizeof(_EGLThreadInfo)); - if (t) { - t->CurrentContext = EGL_NO_CONTEXT; - t->LastError = EGL_SUCCESS; - t->CurrentAPI = EGL_OPENGL_ES_API; /* default, per EGL spec */ - } - return t; + EGLint i; + for (i = _eglGlobal.NumAtExitCalls - 1; i >= 0; i--) + _eglGlobal.AtExitCalls[i](); } -/** - * Delete/free a _EGLThreadInfo object. - */ void -_eglDeleteThreadData(_EGLThreadInfo *t) +_eglAddAtExitCall(void (*func)(void)) { - free(t); -} - - + if (func) { + static EGLBoolean registered = EGL_FALSE; -/** - * Return pointer to calling thread's _EGLThreadInfo object. - * Create a new one if needed. - * Should never return NULL. - */ -_EGLThreadInfo * -_eglGetCurrentThread(void) -{ - _eglInitGlobals(); - - /* XXX temporary */ - return _eglGlobal.ThreadInfo; -} + _eglLockMutex(_eglGlobal.Mutex); + if (!registered) { + atexit(_eglAtExit); + registered = EGL_TRUE; + } -/** - * Record EGL error code. - */ -void -_eglError(EGLint errCode, const char *msg) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - const char *s; - - if (t->LastError == EGL_SUCCESS) { - t->LastError = errCode; + assert(_eglGlobal.NumAtExitCalls < ARRAY_SIZE(_eglGlobal.AtExitCalls)); + _eglGlobal.AtExitCalls[_eglGlobal.NumAtExitCalls++] = func; - switch (errCode) { - case EGL_BAD_ACCESS: - s = "EGL_BAD_ACCESS"; - break; - case EGL_BAD_ALLOC: - s = "EGL_BAD_ALLOC"; - break; - case EGL_BAD_ATTRIBUTE: - s = "EGL_BAD_ATTRIBUTE"; - break; - case EGL_BAD_CONFIG: - s = "EGL_BAD_CONFIG"; - break; - case EGL_BAD_CONTEXT: - s = "EGL_BAD_CONTEXT"; - break; - case EGL_BAD_CURRENT_SURFACE: - s = "EGL_BAD_CURRENT_SURFACE"; - break; - case EGL_BAD_DISPLAY: - s = "EGL_BAD_DISPLAY"; - break; - case EGL_BAD_MATCH: - s = "EGL_BAD_MATCH"; - break; - case EGL_BAD_NATIVE_PIXMAP: - s = "EGL_BAD_NATIVE_PIXMAP"; - break; - case EGL_BAD_NATIVE_WINDOW: - s = "EGL_BAD_NATIVE_WINDOW"; - break; - case EGL_BAD_PARAMETER: - s = "EGL_BAD_PARAMETER"; - break; - case EGL_BAD_SURFACE: - s = "EGL_BAD_SURFACE"; - break; - case EGL_BAD_SCREEN_MESA: - s = "EGL_BAD_SCREEN_MESA"; - break; - case EGL_BAD_MODE_MESA: - s = "EGL_BAD_MODE_MESA"; - break; - default: - s = "other"; - } - /* XXX temporary */ - fprintf(stderr, "EGL user error 0x%x (%s) in %s\n", errCode, s, msg); + _eglUnlockMutex(_eglGlobal.Mutex); } } diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h index 14d8ea487af..58511076d45 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -2,18 +2,9 @@ #define EGLGLOBALS_INCLUDED #include "egltypedefs.h" -#include "eglhash.h" - - -/** - * Per-thread info - */ -struct _egl_thread_info -{ - EGLint LastError; - _EGLContext *CurrentContext; - EGLenum CurrentAPI; -}; +#include "egldisplay.h" +#include "eglcurrent.h" +#include "eglmutex.h" /** @@ -21,23 +12,21 @@ struct _egl_thread_info */ struct _egl_global { - EGLBoolean Initialized; + _EGLMutex *Mutex; - _EGLHashtable *Displays; - _EGLHashtable *Surfaces; + /* the list of all displays */ + _EGLDisplay *DisplayList; EGLScreenMESA FreeScreenHandle; /* bitmaks of supported APIs (supported by _some_ driver) */ EGLint ClientAPIsMask; - char ClientAPIs[1000]; /**< updated by eglQueryString */ - - /* XXX temporary - should be thread-specific data (TSD) */ - _EGLThreadInfo *ThreadInfo; - EGLint NumDrivers; _EGLDriver *Drivers[10]; + + EGLint NumAtExitCalls; + void (*AtExitCalls[10])(void); }; @@ -45,27 +34,7 @@ extern struct _egl_global _eglGlobal; extern void -_eglInitGlobals(void); - - -extern void -_eglDestroyGlobals(void); - - -extern _EGLThreadInfo * -_eglNewThreadInfo(void); - - -extern void -_eglDeleteThreadData(_EGLThreadInfo *t); - - -extern _EGLThreadInfo * -_eglGetCurrentThread(void); - - -extern void -_eglError(EGLint errCode, const char *msg); +_eglAddAtExitCall(void (*func)(void)); #endif /* EGLGLOBALS_INCLUDED */ diff --git a/src/egl/main/eglhash.c b/src/egl/main/eglhash.c deleted file mode 100644 index 8e3da2e9061..00000000000 --- a/src/egl/main/eglhash.c +++ /dev/null @@ -1,347 +0,0 @@ -/** - * \file hash.c - * Generic hash table. - * - * This code taken from Mesa and adapted. - */ - -#include <assert.h> -#include <stdlib.h> -#include <stdio.h> -#include "eglhash.h" - - -#define TABLE_SIZE 1023 /**< Size of lookup table/array */ - -#define HASH_FUNC(K) ((K) % TABLE_SIZE) - - -/* - * Unfinished mutex stuff - */ - -typedef int _EGLMutex; - -static void -_eglInitMutex(_EGLMutex m) -{ -} - -static void -_eglDestroyMutex(_EGLMutex m) -{ -} - -static void -_eglLockMutex(_EGLMutex m) -{ -} - -static void -_eglUnlockMutex(_EGLMutex m) -{ -} - - - -typedef struct _egl_hashentry _EGLHashentry; - -struct _egl_hashentry -{ - EGLuint Key; /**< the entry's key */ - void *Data; /**< the entry's data */ - _EGLHashentry *Next; /**< pointer to next entry */ -}; - - -struct _egl_hashtable -{ - _EGLHashentry *Table[TABLE_SIZE]; /**< the lookup table */ - EGLuint MaxKey; /**< highest key inserted so far */ - _EGLMutex Mutex; /**< mutual exclusion lock */ -}; - - -/** - * Create a new hash table. - * - * \return pointer to a new, empty hash table. - */ -_EGLHashtable * -_eglNewHashTable(void) -{ - _EGLHashtable *table = (_EGLHashtable *) calloc(1, sizeof(_EGLHashtable)); - if (table) { - _eglInitMutex(table->Mutex); - table->MaxKey = 1; - } - return table; -} - - - -/** - * Delete a hash table. - * Frees each entry on the hash table and then the hash table structure itself. - * Note that the caller should have already traversed the table and deleted - * the objects in the table (i.e. We don't free the entries' data pointer). - * - * \param table the hash table to delete. - */ -void -_eglDeleteHashTable(_EGLHashtable *table) -{ - EGLuint i; - assert(table); - for (i = 0; i < TABLE_SIZE; i++) { - _EGLHashentry *entry = table->Table[i]; - while (entry) { - _EGLHashentry *next = entry->Next; - free(entry); - entry = next; - } - } - _eglDestroyMutex(table->Mutex); - free(table); -} - - - -/** - * Lookup an entry in the hash table. - * - * \param table the hash table. - * \param key the key. - * - * \return pointer to user's data or NULL if key not in table - */ -void * -_eglHashLookup(const _EGLHashtable *table, EGLuint key) -{ - EGLuint pos; - const _EGLHashentry *entry; - - assert(table); - - if (!key) - return NULL; - - pos = HASH_FUNC(key); - entry = table->Table[pos]; - while (entry) { - if (entry->Key == key) { - return entry->Data; - } - entry = entry->Next; - } - return NULL; -} - - - -/** - * Insert a key/pointer pair into the hash table. - * If an entry with this key already exists we'll replace the existing entry. - * - * \param table the hash table. - * \param key the key (not zero). - * \param data pointer to user data. - */ -void -_eglHashInsert(_EGLHashtable *table, EGLuint key, void *data) -{ - /* search for existing entry with this key */ - EGLuint pos; - _EGLHashentry *entry; - - assert(table); - assert(key); - - _eglLockMutex(table->Mutex); - - if (key > table->MaxKey) - table->MaxKey = key; - - pos = HASH_FUNC(key); - entry = table->Table[pos]; - while (entry) { - if (entry->Key == key) { - /* replace entry's data */ - entry->Data = data; - _eglUnlockMutex(table->Mutex); - return; - } - entry = entry->Next; - } - - /* alloc and insert new table entry */ - entry = (_EGLHashentry *) malloc(sizeof(_EGLHashentry)); - entry->Key = key; - entry->Data = data; - entry->Next = table->Table[pos]; - table->Table[pos] = entry; - - _eglUnlockMutex(table->Mutex); -} - - - -/** - * Remove an entry from the hash table. - * - * \param table the hash table. - * \param key key of entry to remove. - * - * While holding the hash table's lock, searches the entry with the matching - * key and unlinks it. - */ -void -_eglHashRemove(_EGLHashtable *table, EGLuint key) -{ - EGLuint pos; - _EGLHashentry *entry, *prev; - - assert(table); - assert(key); - - _eglLockMutex(table->Mutex); - - pos = HASH_FUNC(key); - prev = NULL; - entry = table->Table[pos]; - while (entry) { - if (entry->Key == key) { - /* found it! */ - if (prev) { - prev->Next = entry->Next; - } - else { - table->Table[pos] = entry->Next; - } - free(entry); - _eglUnlockMutex(table->Mutex); - return; - } - prev = entry; - entry = entry->Next; - } - - _eglUnlockMutex(table->Mutex); -} - - - -/** - * Get the key of the "first" entry in the hash table. - * - * This is used in the course of deleting all display lists when - * a context is destroyed. - * - * \param table the hash table - * - * \return key for the "first" entry in the hash table. - * - * While holding the lock, walks through all table positions until finding - * the first entry of the first non-empty one. - */ -EGLuint -_eglHashFirstEntry(_EGLHashtable *table) -{ - EGLuint pos; - assert(table); - _eglLockMutex(table->Mutex); - for (pos = 0; pos < TABLE_SIZE; pos++) { - if (table->Table[pos]) { - _eglUnlockMutex(table->Mutex); - return table->Table[pos]->Key; - } - } - _eglUnlockMutex(table->Mutex); - return 0; -} - - -/** - * Given a hash table key, return the next key. This is used to walk - * over all entries in the table. Note that the keys returned during - * walking won't be in any particular order. - * \return next hash key or 0 if end of table. - */ -EGLuint -_eglHashNextEntry(const _EGLHashtable *table, EGLuint key) -{ - const _EGLHashentry *entry; - EGLuint pos; - - assert(table); - assert(key); - - /* Find the entry with given key */ - pos = HASH_FUNC(key); - entry = table->Table[pos]; - while (entry) { - if (entry->Key == key) { - break; - } - entry = entry->Next; - } - - if (!entry) { - /* the key was not found, we can't find next entry */ - return 0; - } - - if (entry->Next) { - /* return next in linked list */ - return entry->Next->Key; - } - else { - /* look for next non-empty table slot */ - pos++; - while (pos < TABLE_SIZE) { - if (table->Table[pos]) { - return table->Table[pos]->Key; - } - pos++; - } - return 0; - } -} - - -/** - * Dump contents of hash table for debugging. - * - * \param table the hash table. - */ -void -_eglHashPrint(const _EGLHashtable *table) -{ - EGLuint i; - assert(table); - for (i = 0; i < TABLE_SIZE; i++) { - const _EGLHashentry *entry = table->Table[i]; - while (entry) { - printf("%u %p\n", entry->Key, entry->Data); - entry = entry->Next; - } - } -} - - - -/** - * Return a new, unused hash key. - */ -EGLuint -_eglHashGenKey(_EGLHashtable *table) -{ - EGLuint k; - - _eglLockMutex(table->Mutex); - k = table->MaxKey; - table->MaxKey++; - _eglUnlockMutex(table->Mutex); - return k; -} - diff --git a/src/egl/main/eglhash.h b/src/egl/main/eglhash.h deleted file mode 100644 index 1d6db9598ce..00000000000 --- a/src/egl/main/eglhash.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * \file eglhash.h - * Generic hash table. - */ - - -#ifndef EGLHASH_INCLUDED -#define EGLHASH_INCLUDED - - -/* XXX move this? */ -typedef unsigned int EGLuint; - - -typedef struct _egl_hashtable _EGLHashtable; - - -extern _EGLHashtable *_eglNewHashTable(void); - -extern void _eglDeleteHashTable(_EGLHashtable *table); - -extern void *_eglHashLookup(const _EGLHashtable *table, EGLuint key); - -extern void _eglHashInsert(_EGLHashtable *table, EGLuint key, void *data); - -extern void _eglHashRemove(_EGLHashtable *table, EGLuint key); - -extern EGLuint _eglHashFirstEntry(_EGLHashtable *table); - -extern EGLuint _eglHashNextEntry(const _EGLHashtable *table, EGLuint key); - -extern void _eglHashPrint(const _EGLHashtable *table); - -extern EGLuint _eglHashGenKey(_EGLHashtable *table); - -extern void _egltest_hash_functions(void); - - -#endif /* EGLHASH_INCLUDED */ diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c index b5bdc3ea4bf..b37213faf10 100644 --- a/src/egl/main/eglmisc.c +++ b/src/egl/main/eglmisc.c @@ -35,6 +35,7 @@ #include <string.h> #include "eglglobals.h" #include "eglmisc.h" +#include "egldisplay.h" /** @@ -42,42 +43,47 @@ * the driver's Extensions string. */ static void -_eglUpdateExtensionsString(_EGLDriver *drv) +_eglUpdateExtensionsString(_EGLDisplay *dpy) { - drv->Extensions.String[0] = 0; + char *exts = dpy->Extensions.String; - if (drv->Extensions.MESA_screen_surface) - strcat(drv->Extensions.String, "EGL_MESA_screen_surface "); - if (drv->Extensions.MESA_copy_context) - strcat(drv->Extensions.String, "EGL_MESA_copy_context "); - assert(strlen(drv->Extensions.String) < _EGL_MAX_EXTENSIONS_LEN); + if (exts[0]) + return; + + if (dpy->Extensions.MESA_screen_surface) + strcat(exts, "EGL_MESA_screen_surface "); + if (dpy->Extensions.MESA_copy_context) + strcat(exts, "EGL_MESA_copy_context "); + assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN); } static void -_eglUpdateAPIsString(_EGLDriver *drv) +_eglUpdateAPIsString(_EGLDisplay *dpy) { - _eglGlobal.ClientAPIs[0] = 0; + char *apis = dpy->ClientAPIs; - if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) - strcat(_eglGlobal.ClientAPIs, "OpenGL "); + if (apis[0] || !dpy->ClientAPIsMask) + return; - if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES_BIT) - strcat(_eglGlobal.ClientAPIs, "OpenGL_ES "); + if (dpy->ClientAPIsMask & EGL_OPENGL_BIT) + strcat(apis, "OpenGL "); - if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES2_BIT) - strcat(_eglGlobal.ClientAPIs, "OpenGL_ES2 "); + if (dpy->ClientAPIsMask & EGL_OPENGL_ES_BIT) + strcat(apis, "OpenGL_ES "); - if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) - strcat(_eglGlobal.ClientAPIs, "OpenVG "); + if (dpy->ClientAPIsMask & EGL_OPENGL_ES2_BIT) + strcat(apis, "OpenGL_ES2 "); - assert(strlen(_eglGlobal.ClientAPIs) < sizeof(_eglGlobal.ClientAPIs)); -} + if (dpy->ClientAPIsMask & EGL_OPENVG_BIT) + strcat(apis, "OpenVG "); + assert(strlen(apis) < sizeof(dpy->ClientAPIs)); +} const char * -_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name) +_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name) { (void) drv; (void) dpy; @@ -85,14 +91,14 @@ _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name) case EGL_VENDOR: return _EGL_VENDOR_STRING; case EGL_VERSION: - return drv->Version; + return dpy->Version; case EGL_EXTENSIONS: - _eglUpdateExtensionsString(drv); - return drv->Extensions.String; + _eglUpdateExtensionsString(dpy); + return dpy->Extensions.String; #ifdef EGL_VERSION_1_2 case EGL_CLIENT_APIS: - _eglUpdateAPIsString(drv); - return _eglGlobal.ClientAPIs; + _eglUpdateAPIsString(dpy); + return dpy->ClientAPIs; #endif default: _eglError(EGL_BAD_PARAMETER, "eglQueryString"); @@ -102,7 +108,7 @@ _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name) EGLBoolean -_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy) +_eglWaitGL(_EGLDriver *drv, _EGLDisplay *dpy) { /* just a placeholder */ (void) drv; @@ -112,7 +118,7 @@ _eglWaitGL(_EGLDriver *drv, EGLDisplay dpy) EGLBoolean -_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine) +_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine) { /* just a placeholder */ (void) drv; diff --git a/src/egl/main/eglmisc.h b/src/egl/main/eglmisc.h index 4e2a40ea991..a15c839be2b 100644 --- a/src/egl/main/eglmisc.h +++ b/src/egl/main/eglmisc.h @@ -33,15 +33,15 @@ extern const char * -_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name); +_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name); extern EGLBoolean -_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy); +_eglWaitGL(_EGLDriver *drv, _EGLDisplay *dpy); extern EGLBoolean -_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine); +_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine); #endif /* EGLMISC_INCLUDED */ diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c index 786432234bb..0f3ba6e5c08 100644 --- a/src/egl/main/eglmode.c +++ b/src/egl/main/eglmode.c @@ -34,9 +34,8 @@ my_strdup(const char *s) * or null if non-existant. */ _EGLMode * -_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode) +_eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp) { - const _EGLDisplay *disp = _eglLookupDisplay(dpy); EGLint scrnum; /* loop over all screens on the display */ @@ -272,19 +271,13 @@ _eglCompareModes(const void *a, const void *b) * Called via eglChooseModeMESA API function. */ EGLBoolean -_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, +_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes) { - const _EGLScreen *scrn = _eglLookupScreen(dpy, screen); _EGLMode **modeList, min; EGLint i, count; - if (!scrn) { - _eglError(EGL_BAD_SCREEN_MESA, "eglChooseModeMESA"); - return EGL_FALSE; - } - if (!_eglParseModeAttribs(&min, attrib_list)) { /* error code will have been recorded */ return EGL_FALSE; @@ -326,16 +319,9 @@ _eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, * Called via eglGetModesMESA() API function. */ EGLBoolean -_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, +_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes) { - _EGLScreen *scrn = _eglLookupScreen(dpy, screen); - - if (!scrn) { - _eglError(EGL_BAD_SCREEN_MESA, "eglGetModesMESA"); - return EGL_FALSE; - } - if (modes) { EGLint i; *num_modes = MIN2(scrn->NumModes, modes_size); @@ -356,17 +342,11 @@ _eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, * Query an attribute of a mode. */ EGLBoolean -_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy, - EGLModeMESA mode, EGLint attribute, EGLint *value) +_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLMode *m, EGLint attribute, EGLint *value) { - _EGLMode *m = _eglLookupMode(dpy, mode); EGLint v; - if (!m) { - _eglError(EGL_BAD_MODE_MESA, "eglGetModeAttribMESA"); - return EGL_FALSE; - } - v = getModeAttrib(m, attribute); if (v < 0) { _eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttribMESA"); @@ -382,13 +362,8 @@ _eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy, * This is the default function called by eglQueryModeStringMESA(). */ const char * -_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode) +_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m) { - _EGLMode *m = _eglLookupMode(dpy, mode); - if (!m) { - _eglError(EGL_BAD_MODE_MESA, "eglQueryModeStringMESA"); - return NULL; - } return m->Name; } diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h index 52d4875676d..af7c2c56d33 100644 --- a/src/egl/main/eglmode.h +++ b/src/egl/main/eglmode.h @@ -26,7 +26,7 @@ struct _egl_mode extern _EGLMode * -_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode); +_eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy); extern _EGLMode * @@ -35,23 +35,23 @@ _eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height, extern EGLBoolean -_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, +_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); extern EGLBoolean -_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, +_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); extern EGLBoolean -_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode, +_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m, EGLint attribute, EGLint *value); extern const char * -_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode); +_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m); #endif /* EGLMODE_INCLUDED */ diff --git a/src/egl/main/eglmutex.h b/src/egl/main/eglmutex.h new file mode 100644 index 00000000000..29faba0f241 --- /dev/null +++ b/src/egl/main/eglmutex.h @@ -0,0 +1,52 @@ +#ifndef EGLMUTEX_INCLUDED +#define EGLMUTEX_INCLUDED + +#include "eglcompiler.h" + +#ifdef PTHREADS +#include <pthread.h> + +typedef pthread_mutex_t _EGLMutex; + +static INLINE void _eglInitMutex(_EGLMutex *m) +{ + pthread_mutex_init(m, NULL); +} + +static INLINE void +_eglDestroyMutex(_EGLMutex *m) +{ + pthread_mutex_destroy(m); +} + +static INLINE void +_eglLockMutex(_EGLMutex *m) +{ + pthread_mutex_lock(m); +} + +static INLINE void +_eglUnlockMutex(_EGLMutex *m) +{ + pthread_mutex_unlock(m); +} + +#define _EGL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define _EGL_DECLARE_MUTEX(m) \ + _EGLMutex m = _EGL_MUTEX_INITIALIZER + +#else + +typedef int _EGLMutex; +static INLINE void _eglInitMutex(_EGLMutex *m) { (void) m; } +static INLINE void _eglDestroyMutex(_EGLMutex *m) { (void) m; } +static INLINE void _eglLockMutex(_EGLMutex *m) { (void) m; } +static INLINE void _eglUnlockMutex(_EGLMutex *m) { (void) m; } + +#define _EGL_MUTEX_INITIALIZER 0 +#define _EGL_DECLARE_MUTEX(m) \ + _EGLMutex m = _EGL_MUTEX_INITIALIZER + +#endif + +#endif /* EGLMUTEX_INCLUDED */ diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c index 9c9a8377bf2..14a1e9f8fe3 100644 --- a/src/egl/main/eglscreen.c +++ b/src/egl/main/eglscreen.c @@ -52,13 +52,9 @@ _eglInitScreen(_EGLScreen *screen) * Given a public screen handle, return the internal _EGLScreen object. */ _EGLScreen * -_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen) +_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display) { EGLint i; - _EGLDisplay *display = _eglLookupDisplay(dpy); - - if (!display) - return NULL; for (i = 0; i < display->NumScreens; i++) { if (display->Screens[i]->Handle == screen) @@ -89,17 +85,11 @@ _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen) EGLBoolean -_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, +_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens) { - _EGLDisplay *display = _eglLookupDisplay(dpy); EGLint n; - if (!display) { - _eglError(EGL_BAD_DISPLAY, "eglGetScreensMESA"); - return EGL_FALSE; - } - if (display->NumScreens > max_screens) { n = max_screens; } @@ -122,8 +112,8 @@ _eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, /** * Example function - drivers should do a proper implementation. */ -EGLSurface -_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +_EGLSurface * +_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list) { #if 0 /* THIS IS JUST EXAMPLE CODE */ @@ -131,19 +121,17 @@ _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); if (!surf) - return EGL_NO_SURFACE; + return NULL; - if (!_eglInitSurface(drv, dpy, surf, EGL_SCREEN_BIT_MESA, - config, attrib_list)) { + if (!_eglInitSurface(drv, surf, EGL_SCREEN_BIT_MESA, + conf, attrib_list)) { free(surf); - return EGL_NO_SURFACE; + return NULL; } - _eglSaveSurface(surf); - - return surf->Handle; + return surf; #endif - return EGL_NO_SURFACE; + return NULL; } @@ -155,28 +143,15 @@ _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, * this with code that _really_ shows the surface. */ EGLBoolean -_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, - EGLScreenMESA screen, EGLSurface surface, - EGLModeMESA m) +_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLScreen *scrn, _EGLSurface *surf, + _EGLMode *mode) { - _EGLScreen *scrn = _eglLookupScreen(dpy, screen); - _EGLMode *mode = _eglLookupMode(dpy, m); - - if (!scrn) { - _eglError(EGL_BAD_SCREEN_MESA, "eglShowSurfaceMESA"); - return EGL_FALSE; - } - if (!mode && (m != EGL_NO_MODE_MESA )) { - _eglError(EGL_BAD_MODE_MESA, "eglShowSurfaceMESA"); - return EGL_FALSE; - } - - if (surface == EGL_NO_SURFACE) { + if (!surf) { scrn->CurrentSurface = NULL; } else { - _EGLSurface *surf = _eglLookupSurface(surface); - if (!surf || surf->Type != EGL_SCREEN_BIT_MESA) { + if (surf->Type != EGL_SCREEN_BIT_MESA) { _eglError(EGL_BAD_SURFACE, "eglShowSurfaceMESA"); return EGL_FALSE; } @@ -201,18 +176,10 @@ _eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, * this with code that _really_ sets the mode. */ EGLBoolean -_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, - EGLModeMESA mode) +_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, + _EGLMode *m) { - _EGLScreen *scrn = _eglLookupScreen(dpy, screen); - - if (!scrn) { - _eglError(EGL_BAD_SCREEN_MESA, "eglScreenModeMESA"); - return EGL_FALSE; - } - - scrn->CurrentMode = _eglLookupMode(dpy, mode); - + scrn->CurrentMode = m; return EGL_TRUE; } @@ -221,15 +188,9 @@ _eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, * Set a screen's surface origin. */ EGLBoolean -_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy, - EGLScreenMESA screen, EGLint x, EGLint y) +_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLScreen *scrn, EGLint x, EGLint y) { - _EGLScreen *scrn = _eglLookupScreen(dpy, screen); - if (!scrn) { - _eglError(EGL_BAD_SCREEN_MESA, "eglScreenPositionMESA"); - return EGL_FALSE; - } - scrn->OriginX = x; scrn->OriginY = y; @@ -241,14 +202,10 @@ _eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy, * Query a screen's current surface. */ EGLBoolean -_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, - EGLScreenMESA screen, EGLSurface *surface) +_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLScreen *scrn, _EGLSurface **surf) { - const _EGLScreen *scrn = _eglLookupScreen(dpy, screen); - if (scrn->CurrentSurface) - *surface = scrn->CurrentSurface->Handle; - else - *surface = EGL_NO_SURFACE; + *surf = scrn->CurrentSurface; return EGL_TRUE; } @@ -257,29 +214,18 @@ _eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, * Query a screen's current mode. */ EGLBoolean -_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, - EGLModeMESA *mode) +_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, + _EGLMode **m) { - const _EGLScreen *scrn = _eglLookupScreen(dpy, screen); - if (scrn->CurrentMode) - *mode = scrn->CurrentMode->Handle; - else - *mode = EGL_NO_MODE_MESA; + *m = scrn->CurrentMode; return EGL_TRUE; } EGLBoolean -_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, +_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint attribute, EGLint *value) { - const _EGLScreen *scrn = _eglLookupScreen(dpy, screen); - - if (!scrn) { - _eglError(EGL_BAD_SCREEN_MESA, "eglQueryScreenMESA"); - return EGL_FALSE; - } - switch (attribute) { case EGL_SCREEN_POSITION_MESA: value[0] = scrn->OriginX; diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h index 833439b4107..8860a2aa7f6 100644 --- a/src/egl/main/eglscreen.h +++ b/src/egl/main/eglscreen.h @@ -35,7 +35,7 @@ _eglInitScreen(_EGLScreen *screen); extern _EGLScreen * -_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen); +_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *dpy); extern void @@ -43,40 +43,40 @@ _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen); extern EGLBoolean -_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); +_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); -extern EGLSurface -_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +extern _EGLSurface * +_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list); extern EGLBoolean -_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode); +_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLSurface *surf, _EGLMode *m); extern EGLBoolean -_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA mode); +_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode *m); extern EGLBoolean -_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y); +_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint x, EGLint y); extern EGLBoolean -_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attribute, EGLint *value); +_eglQueryDisplayMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLint attribute, EGLint *value); extern EGLBoolean -_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, - EGLScreenMESA screen, EGLSurface *surface); +_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLScreen *scrn, _EGLSurface **surface); extern EGLBoolean -_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode); +_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode **m); extern EGLBoolean -_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value); +_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint attribute, EGLint *value); extern void diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index 6905acac50b..e7a1a8329e1 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -6,11 +6,11 @@ #include <assert.h> #include <stdlib.h> #include <string.h> +#include "egldisplay.h" #include "eglcontext.h" #include "eglconfig.h" #include "egldriver.h" #include "eglglobals.h" -#include "eglhash.h" #include "egllog.h" #include "eglsurface.h" @@ -20,14 +20,13 @@ * \return EGL_TRUE if no errors, EGL_FALSE otherwise. */ EGLBoolean -_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy, - _EGLSurface *surf, EGLint type, EGLConfig config, - const EGLint *attrib_list) +_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type, + _EGLConfig *conf, const EGLint *attrib_list) { const char *func; - _EGLConfig *conf; EGLint width = 0, height = 0, largest = 0; - EGLint texFormat = 0, texTarget = 0, mipmapTex = 0; + EGLint texFormat = EGL_NO_TEXTURE, texTarget = EGL_NO_TEXTURE; + EGLint mipmapTex = EGL_FALSE; EGLint renderBuffer = EGL_BACK_BUFFER; #ifdef EGL_VERSION_1_2 EGLint colorspace = EGL_COLORSPACE_sRGB; @@ -55,7 +54,6 @@ _eglInitSurface(_EGLDriver *drv, EGLDisplay dpy, return EGL_FALSE; } - conf = _eglLookupConfig(drv, dpy, config); if (!conf) { _eglError(EGL_BAD_CONFIG, func); return EGL_FALSE; @@ -211,89 +209,16 @@ _eglInitSurface(_EGLDriver *drv, EGLDisplay dpy, } -void -_eglSaveSurface(_EGLSurface *surf) -{ - EGLuint key = _eglHashGenKey(_eglGlobal.Surfaces); - assert(surf); - assert(!surf->Handle); - surf->Handle = (EGLSurface) key; - assert(surf->Handle); - _eglHashInsert(_eglGlobal.Surfaces, key, surf); -} - - -void -_eglRemoveSurface(_EGLSurface *surf) -{ - _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle); -} - - - -/** - * Return the public handle for an internal _EGLSurface. - * This is the inverse of _eglLookupSurface(). - */ -EGLSurface -_eglGetSurfaceHandle(_EGLSurface *surface) -{ - if (surface) - return surface->Handle; - else - return EGL_NO_SURFACE; -} - - -/** - * Return the private _EGLSurface which corresponds to a public EGLSurface - * handle. - * This is the inverse of _eglGetSurfaceHandle(). - */ -_EGLSurface * -_eglLookupSurface(EGLSurface surf) -{ - _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces, - (EGLuint) surf); - return c; -} - - -_EGLSurface * -_eglGetCurrentSurface(EGLint readdraw) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - if (ctx) { - switch (readdraw) { - case EGL_DRAW: - return ctx->DrawSurface; - case EGL_READ: - return ctx->ReadSurface; - default: - return NULL; - } - } - return NULL; -} - - EGLBoolean -_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) { - /* Basically just do error checking here. Drivers have to do the - * actual buffer swap. - */ - _EGLSurface *surface = _eglLookupSurface(draw); - if (surface == NULL) { - _eglError(EGL_BAD_SURFACE, "eglSwapBuffers"); - return EGL_FALSE; - } + /* Drivers have to do the actual buffer swap. */ return EGL_TRUE; } EGLBoolean -_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, +_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, NativePixmapType target) { /* copy surface to native pixmap */ @@ -303,14 +228,9 @@ _eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLBoolean -_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, +_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value) { - _EGLSurface *surface = _eglLookupSurface(surf); - if (surface == NULL) { - _eglError(EGL_BAD_SURFACE, "eglQuerySurface"); - return EGL_FALSE; - } switch (attribute) { case EGL_WIDTH: *value = surface->Width; @@ -322,7 +242,7 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID); return EGL_TRUE; case EGL_LARGEST_PBUFFER: - *value = drv->LargestPbuffer; + *value = dpy->LargestPbuffer; return EGL_TRUE; case EGL_SURFACE_TYPE: *value = surface->Type; @@ -379,8 +299,8 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, /** * Example function - drivers should do a proper implementation. */ -EGLSurface -_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +_EGLSurface * +_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) { #if 0 /* THIS IS JUST EXAMPLE CODE */ @@ -388,26 +308,24 @@ _eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); if (!surf) - return EGL_NO_SURFACE; + return NULL; - if (!_eglInitSurface(drv, dpy, surf, EGL_WINDOW_BIT, config, attrib_list)) { + if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) { free(surf); - return EGL_NO_SURFACE; + return NULL; } - _eglSaveSurface(surf); - - return surf->Handle; + return surf; #endif - return EGL_NO_SURFACE; + return NULL; } /** * Example function - drivers should do a proper implementation. */ -EGLSurface -_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +_EGLSurface * +_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list) { #if 0 /* THIS IS JUST EXAMPLE CODE */ @@ -415,26 +333,24 @@ _eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); if (!surf) - return EGL_NO_SURFACE; + return NULL; - if (!_eglInitSurface(drv, dpy, surf, EGL_PIXMAP_BIT, config, attrib_list)) { + if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) { free(surf); - return EGL_NO_SURFACE; + return NULL; } - _eglSaveSurface(surf); - - return surf->Handle; + return surf; #endif - return EGL_NO_SURFACE; + return NULL; } /** * Example function - drivers should do a proper implementation. */ -EGLSurface -_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +_EGLSurface * +_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list) { #if 0 /* THIS IS JUST EXAMPLE CODE */ @@ -442,18 +358,16 @@ _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); if (!surf) - return EGL_NO_SURFACE; + return NULL; - if (!_eglInitSurface(drv, dpy, surf, EGL_PBUFFER_BIT, config, attrib_list)) { + if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) { free(surf); - return EGL_NO_SURFACE; + return NULL; } - _eglSaveSurface(surf); - - return surf->Handle; + return NULL; #endif - return EGL_NO_SURFACE; + return NULL; } @@ -461,23 +375,11 @@ _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, * Default fallback routine - drivers should usually override this. */ EGLBoolean -_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) { - _EGLSurface *surf = _eglLookupSurface(surface); - if (surf) { - _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface); - if (surf->IsBound) { - surf->DeletePending = EGL_TRUE; - } - else { - free(surf); - } - return EGL_TRUE; - } - else { - _eglError(EGL_BAD_SURFACE, "eglDestroySurface"); - return EGL_FALSE; - } + if (!_eglIsSurfaceBound(surf)) + free(surf); + return EGL_TRUE; } @@ -485,16 +387,9 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) * Default fallback routine - drivers might override this. */ EGLBoolean -_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, +_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint value) { - _EGLSurface *surface = _eglLookupSurface(surf); - - if (surface == NULL) { - _eglError(EGL_BAD_SURFACE, "eglSurfaceAttrib"); - return EGL_FALSE; - } - switch (attribute) { case EGL_MIPMAP_LEVEL: surface->MipmapLevel = value; @@ -508,15 +403,14 @@ _eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLBoolean -_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, +_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer) { /* Just do basic error checking and return success/fail. * Drivers must implement the real stuff. */ - _EGLSurface *surface = _eglLookupSurface(surf); - if (!surface || surface->Type != EGL_PBUFFER_BIT) { + if (surface->Type != EGL_PBUFFER_BIT) { _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); return EGL_FALSE; } @@ -538,15 +432,14 @@ _eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLBoolean -_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, +_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer) { /* Just do basic error checking and return success/fail. * Drivers must implement the real stuff. */ - _EGLSurface *surface = _eglLookupSurface(surf); - if (!surface || surface->Type != EGL_PBUFFER_BIT) { + if (surface->Type != EGL_PBUFFER_BIT) { _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); return EGL_FALSE; } @@ -573,14 +466,11 @@ _eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLBoolean -_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval) +_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval) { _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW); - if (surf == NULL) { - _eglError(EGL_BAD_SURFACE, "eglSwapInterval"); - return EGL_FALSE; - } - surf->SwapInterval = interval; + if (surf) + surf->SwapInterval = interval; return EGL_TRUE; } @@ -590,17 +480,17 @@ _eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval) /** * Example function - drivers should do a proper implementation. */ -EGLSurface -_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy, +_EGLSurface * +_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum buftype, EGLClientBuffer buffer, - EGLConfig config, const EGLint *attrib_list) + _EGLConfig *conf, const EGLint *attrib_list) { if (buftype != EGL_OPENVG_IMAGE) { _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer"); - return EGL_NO_SURFACE; + return NULL; } - return EGL_NO_SURFACE; + return NULL; } #endif /* EGL_VERSION_1_2 */ diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index 50f965b5cb7..f6d44b5922e 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -10,14 +10,16 @@ */ struct _egl_surface { - EGLSurface Handle; /* The public/opaque handle which names this object */ - _EGLConfig *Config; + /* Managed by EGLDisplay for linking */ + _EGLDisplay *Display; + _EGLSurface *Next; - /* May need reference counting here */ - EGLBoolean IsBound; - EGLBoolean DeletePending; + /* The bound status of the surface */ + _EGLContext *Binding; EGLBoolean BoundToTexture; + _EGLConfig *Config; + EGLint Type; /* one of EGL_WINDOW_BIT, EGL_PIXMAP_BIT or EGL_PBUFFER_BIT */ EGLint Width, Height; EGLint TextureFormat, TextureTarget; @@ -39,84 +41,74 @@ struct _egl_surface extern EGLBoolean -_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy, - _EGLSurface *surf, EGLint type, EGLConfig config, - const EGLint *attrib_list); - - -extern void -_eglSaveSurface(_EGLSurface *surf); - - -extern void -_eglRemoveSurface(_EGLSurface *surf); - - -extern EGLSurface -_eglGetSurfaceHandle(_EGLSurface *surface); - - -extern _EGLSurface * -_eglLookupSurface(EGLSurface surf); - - -extern _EGLSurface * -_eglGetCurrentSurface(EGLint readdraw); +_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type, + _EGLConfig *config, const EGLint *attrib_list); extern EGLBoolean -_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw); +_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf); extern EGLBoolean -_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target); +_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, NativePixmapType target); extern EGLBoolean -_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint *value); -extern EGLSurface -_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list); +extern _EGLSurface * +_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list); -extern EGLSurface -_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list); +extern _EGLSurface * +_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list); -extern EGLSurface -_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +extern _EGLSurface * +_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list); extern EGLBoolean -_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface); +_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf); extern EGLBoolean -_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint value); extern EGLBoolean -_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer); +_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer); extern EGLBoolean -_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer); +_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer); extern EGLBoolean -_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval); +_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval); #ifdef EGL_VERSION_1_2 -extern EGLSurface -_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy, +extern _EGLSurface * +_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum buftype, EGLClientBuffer buffer, - EGLConfig config, const EGLint *attrib_list); + _EGLConfig *conf, const EGLint *attrib_list); #endif /* EGL_VERSION_1_2 */ +/** + * Return true if the surface is bound to a thread. + * A surface bound to a texutre is not considered bound by + * this function. + */ +static INLINE EGLBoolean +_eglIsSurfaceBound(_EGLSurface *surf) +{ + return (surf->Binding != NULL); +} + #endif /* EGLSURFACE_INCLUDED */ diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h index 9fbc55352c2..4461440b9b7 100644 --- a/src/egl/main/egltypedefs.h +++ b/src/egl/main/egltypedefs.h @@ -6,6 +6,7 @@ #include <EGL/egl.h> #include <EGL/eglext.h> +#include "eglcompiler.h" typedef struct _egl_api _EGLAPI; @@ -28,7 +29,7 @@ typedef struct _egl_surface _EGLSurface; typedef struct _egl_thread_info _EGLThreadInfo; -typedef _EGLDriver *(*_EGLMain_t)(_EGLDisplay *dpy, const char *args); +typedef _EGLDriver *(*_EGLMain_t)(const char *args); #endif /* EGLTYPEDEFS_INCLUDED */ diff --git a/src/egl/main/eglx.c b/src/egl/main/eglx.c deleted file mode 100644 index 50acc3a24f9..00000000000 --- a/src/egl/main/eglx.c +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * X-specific EGL code. - * - * Any glue code needed to make EGL work with X is placed in this file. - */ - - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <X11/Xlib.h> - -#include "egldriver.h" -#include "egllog.h" -#include "eglstring.h" -#include "eglx.h" - - -static const char *DefaultGLXDriver = "egl_glx"; -static const char *DefaultSoftDriver = "egl_softpipe"; - - -/** - * Given an X Display ptr (at dpy->Xdpy) try to determine the appropriate - * device driver. Return its name. - * - * This boils down to whether to use the egl_glx.so driver which will - * load a DRI driver or the egl_softpipe.so driver that'll do software - * rendering on Xlib. - */ -const char * -_xeglChooseDriver(_EGLDisplay *dpy) -{ -#ifdef _EGL_PLATFORM_X - _XPrivDisplay xdpy; - int screen; - const char *driverName; - - assert(dpy); - - if (!dpy->Xdpy) { - dpy->Xdpy = XOpenDisplay(NULL); - if (!dpy->Xdpy) { - /* can't open X display -> can't use X-based driver */ - return NULL; - } - } - xdpy = (_XPrivDisplay) dpy->Xdpy; - - assert(dpy->Xdpy); - - screen = DefaultScreen(dpy->Xdpy); - - /* See if we can choose a DRI/DRM driver */ - driverName = _eglChooseDRMDriver(screen); - if (driverName) { - free((void *) driverName); - driverName = _eglstrdup(DefaultGLXDriver); - } - else { - driverName = _eglstrdup(DefaultSoftDriver); - } - - _eglLog(_EGL_DEBUG, "_xeglChooseDriver: %s", driverName); - - return driverName; -#else - return NULL; -#endif -} - - diff --git a/src/egl/main/eglx.h b/src/egl/main/eglx.h deleted file mode 100644 index 4323d558381..00000000000 --- a/src/egl/main/eglx.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef EGLX_INCLUDED -#define EGLX_INCLUDED - - -#include "egldisplay.h" - - -extern const char * -_xeglChooseDriver(_EGLDisplay *dpy); - - -#endif /* EGLX_INCLUDED */ |