diff options
Diffstat (limited to 'src/egl')
-rw-r--r-- | src/egl/drivers/demo/demo.c | 29 | ||||
-rw-r--r-- | src/egl/drivers/dri/egldri.c | 45 | ||||
-rw-r--r-- | src/egl/drivers/glx/egl_glx.c | 48 | ||||
-rw-r--r-- | src/egl/drivers/xdri/egl_xdri.c | 24 | ||||
-rw-r--r-- | src/egl/main/Makefile | 3 | ||||
-rw-r--r-- | src/egl/main/eglapi.c | 34 | ||||
-rw-r--r-- | src/egl/main/eglcompiler.h | 31 | ||||
-rw-r--r-- | src/egl/main/eglcontext.c | 136 | ||||
-rw-r--r-- | src/egl/main/eglcontext.h | 29 | ||||
-rw-r--r-- | src/egl/main/egldisplay.c | 253 | ||||
-rw-r--r-- | src/egl/main/egldisplay.h | 79 | ||||
-rw-r--r-- | src/egl/main/egldriver.c | 4 | ||||
-rw-r--r-- | src/egl/main/eglglobals.c | 113 | ||||
-rw-r--r-- | src/egl/main/eglglobals.h | 32 | ||||
-rw-r--r-- | src/egl/main/eglscreen.c | 15 | ||||
-rw-r--r-- | src/egl/main/eglsurface.c | 121 | ||||
-rw-r--r-- | src/egl/main/eglsurface.h | 32 | ||||
-rw-r--r-- | src/egl/main/egltypedefs.h | 1 |
18 files changed, 545 insertions, 484 deletions
diff --git a/src/egl/drivers/demo/demo.c b/src/egl/drivers/demo/demo.c index 1750e976b8..f316974d83 100644 --- a/src/egl/drivers/demo/demo.c +++ b/src/egl/drivers/demo/demo.c @@ -146,12 +146,12 @@ demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext if (!c) return EGL_NO_CONTEXT; - _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); + /* link to display */ + _eglLinkContext(&c->Base, _eglLookupDisplay(dpy)); assert(_eglGetContextHandle(&c->Base)); return _eglGetContextHandle(&c->Base); @@ -213,11 +213,14 @@ demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface)); + _EGLConfig *conf; + if (!surf) return EGL_NO_SURFACE; - if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_PBUFFER_BIT, - config, attrib_list)) { + conf = _eglLookupConfig(drv, dpy, config); + if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT, + conf, attrib_list)) { free(surf); return EGL_NO_SURFACE; } @@ -232,13 +235,9 @@ static EGLBoolean demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) { DemoSurface *fs = LookupDemoSurface(surface); - _eglRemoveSurface(&fs->Base); - if (fs->Base.IsBound) { - fs->Base.DeletePending = EGL_TRUE; - } - else { + _eglUnlinkSurface(&fs->Base); + if (!fs->Base.IsBound) free(fs); - } return EGL_TRUE; } @@ -247,13 +246,9 @@ static EGLBoolean demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) { DemoContext *fc = LookupDemoContext(context); - _eglRemoveContext(&fc->Base); - if (fc->Base.IsBound) { - fc->Base.DeletePending = EGL_TRUE; - } - else { + _eglUnlinkContext(&fc->Base); + if (!fc->Base.IsBound) free(fc); - } return EGL_TRUE; } diff --git a/src/egl/drivers/dri/egldri.c b/src/egl/drivers/dri/egldri.c index 57661cc3ab..3f9617a8f9 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 (!fs->Base.IsBound) 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 (!fc->Base.IsBound) 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/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 155caa413c..207b1ea779 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -532,7 +532,10 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, if (!GLX_ctx) return EGL_NO_CONTEXT; - if (!_eglInitContext(drv, dpy, &GLX_ctx->Base, config, attrib_list)) { + conf = _eglLookupConfig(drv, dpy, config); + assert(conf); + + if (!_eglInitContext(drv, &GLX_ctx->Base, conf, attrib_list)) { free(GLX_ctx); return EGL_NO_CONTEXT; } @@ -546,9 +549,6 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, GLX_ctx_shared = GLX_egl_context(shareCtx); } - 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); @@ -564,7 +564,7 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_FALSE; #endif - return _eglGetContextHandle(&GLX_ctx->Base); + return _eglLinkContext(&GLX_ctx->Base, disp); } @@ -619,18 +619,22 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, _EGLDisplay *disp = _eglLookupDisplay(dpy); struct GLX_egl_surface *GLX_surf; uint width, height; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + assert(conf); GLX_surf = CALLOC_STRUCT(GLX_egl_surface); if (!GLX_surf) return EGL_NO_SURFACE; - 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; } - _eglSaveSurface(&GLX_surf->Base); + _eglLinkSurface(&GLX_surf->Base, disp); GLX_surf->drawable = window; get_drawable_size(disp->Xdpy, window, &width, &height); @@ -648,19 +652,23 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv); _EGLDisplay *disp = _eglLookupDisplay(dpy); struct GLX_egl_surface *GLX_surf; + _EGLConfig *conf; int i; + conf = _eglLookupConfig(drv, dpy, config); + assert(conf); + GLX_surf = CALLOC_STRUCT(GLX_egl_surface); if (!GLX_surf) return EGL_NO_SURFACE; - 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; } - _eglSaveSurface(&GLX_surf->Base); + _eglLinkSurface(&GLX_surf->Base, disp); for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { switch (attrib_list[i]) { @@ -683,20 +691,24 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv); _EGLDisplay *disp = _eglLookupDisplay(dpy); struct GLX_egl_surface *GLX_surf; + _EGLConfig *conf; int attribs[5]; int i = 0, j = 0; + conf = _eglLookupConfig(drv, dpy, config); + assert(conf); + GLX_surf = CALLOC_STRUCT(GLX_egl_surface); if (!GLX_surf) return EGL_NO_SURFACE; - 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; } - _eglSaveSurface(&GLX_surf->Base); + _eglLinkSurface(&GLX_surf->Base, disp); while(attrib_list[i] != EGL_NONE) { switch (attrib_list[i]) { @@ -726,13 +738,9 @@ GLX_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) _EGLSurface *surf = _eglLookupSurface(surface); return EGL_TRUE; if (surf) { - _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface); - if (surf->IsBound) { - surf->DeletePending = EGL_TRUE; - } - else { + _eglUnlinkSurface(surf); + if (!surf->IsBound) free(surf); - } return EGL_TRUE; } diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index 3b3e312746..e040efdd43 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -770,7 +770,7 @@ xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, if (!xdri_ctx) return EGL_NO_CONTEXT; - if (!_eglInitContext(drv, dpy, &xdri_ctx->Base, config, attrib_list)) { + if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) { free(xdri_ctx); return EGL_NO_CONTEXT; } @@ -794,7 +794,7 @@ xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, xdri_ctx->driContext.mode = xdri_config->mode; - return _eglGetContextHandle(&xdri_ctx->Base); + return _eglLinkContext(&xdri_ctx->Base, &disp); } @@ -835,6 +835,7 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) { _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config); struct xdri_egl_surface *xdri_surf; int scrn = DefaultScreen(disp->Xdpy); uint width, height; @@ -843,8 +844,8 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, if (!xdri_surf) return EGL_NO_SURFACE; - 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; } @@ -856,7 +857,7 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, xdri_surf->driDrawable = window; - _eglSaveSurface(&xdri_surf->Base); + _eglLinkSurface(&xdri_surf->Base, disp); get_drawable_size(disp->Xdpy, window, &width, &height); xdri_surf->Base.Width = width; @@ -888,8 +889,8 @@ xdri_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, if (!xdri_surf) return EGL_NO_SURFACE; - if (!_eglInitSurface(drv, dpy, &xdri_surf->Base, EGL_PBUFFER_BIT, - config, attrib_list)) { + if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_PBUFFER_BIT, + &xdri_config->Base, attrib_list)) { free(xdri_surf); return EGL_FALSE; } @@ -939,7 +940,7 @@ xdri_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, xdri_surf->driDrawable = window; - _eglSaveSurface(&xdri_surf->Base); + _eglLinkSurface(&xdri_surf->Base, disp); _eglLog(_EGL_DEBUG, "XDRI: CreatePbufferSurface handle %d hDrawable %d", @@ -956,11 +957,8 @@ 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 { + _eglUnlinkSurface(&xdri_surf->Base); + if (!xdri_surf->Base.IsBound) { /* st_unreference_framebuffer(surf->Framebuffer); */ diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index cddba9f088..e1ff8794b3 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -7,9 +7,11 @@ include $(TOP)/configs/current INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi HEADERS = \ + eglcompiler.h \ eglconfig.h \ eglconfigutil.h \ eglcontext.h \ + eglcurrent.h \ egldefines.h \ egldisplay.h \ egldriver.h \ @@ -28,6 +30,7 @@ SOURCES = \ eglconfig.c \ eglconfigutil.c \ eglcontext.c \ + eglcurrent.c \ egldisplay.c \ egldriver.c \ eglglobals.c \ diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 9df938e188..f0a6f7f935 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -51,7 +51,12 @@ eglGetDisplay(NativeDisplayType nativeDisplay) { _EGLDisplay *dpy; _eglInitGlobals(); - dpy = _eglNewDisplay(nativeDisplay); + dpy = _eglFindDisplay(nativeDisplay); + if (!dpy) { + dpy = _eglNewDisplay(nativeDisplay); + if (dpy) + _eglLinkDisplay(dpy); + } return _eglGetDisplayHandle(dpy); } @@ -321,7 +326,8 @@ eglGetError(void) { _EGLThreadInfo *t = _eglGetCurrentThread(); EGLint e = t->LastError; - t->LastError = EGL_SUCCESS; + if (!_eglIsCurrentThreadDummy()) + t->LastError = EGL_SUCCESS; return e; } @@ -546,11 +552,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 +570,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 +597,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); } @@ -603,15 +615,19 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLBoolean eglReleaseThread(void) { - _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLDisplay dpy = eglGetCurrentDisplay(); + EGLDisplay dpy; + + if (_eglIsCurrentThreadDummy()) + return EGL_TRUE; + + 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); } - _eglDeleteThreadData(t); + _eglDestroyCurrentThread(); return EGL_TRUE; } diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h new file mode 100644 index 0000000000..0b19afedfd --- /dev/null +++ b/src/egl/main/eglcompiler.h @@ -0,0 +1,31 @@ +#ifndef EGLCOMPILER_INCLUDED +#define EGLCOMPILER_INCLUDED + + +/** + * 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/eglcontext.c b/src/egl/main/eglcontext.c index 461679db09..9ab4286d3a 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,7 +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; @@ -49,7 +46,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,66 +56,6 @@ _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 @@ -128,18 +64,24 @@ _eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, { #if 0 /* example code */ _EGLContext *context; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreateContext"); + return EGL_NO_CONTEXT; + } context = (_EGLContext *) calloc(1, sizeof(_EGLContext)); if (!context) return EGL_NO_CONTEXT; - if (!_eglInitContext(drv, dpy, context, config, attrib_list)) { + if (!_eglInitContext(drv, context, conf, attrib_list)) { free(context); return EGL_NO_CONTEXT; } - _eglSaveContext(context); - return (EGLContext) context; + return _eglLinkContext(context, _eglLookupDisplay(dpy)); #endif return EGL_NO_CONTEXT; } @@ -153,12 +95,9 @@ _eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) { _EGLContext *context = _eglLookupContext(ctx); if (context) { - if (context->IsBound) { - context->DeletePending = EGL_TRUE; - } - else { + _eglUnlinkContext(context); + if (!context->IsBound) free(context); - } return EGL_TRUE; } else { @@ -203,7 +142,7 @@ _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 @@ -214,10 +153,13 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, _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) { @@ -233,6 +175,32 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); return EGL_FALSE; } + +#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 { + apiIndex = t->CurrentAPIIndex; + } + + oldContext = t->CurrentContexts[apiIndex]; + if (oldContext) { + oldDrawSurface = oldContext->DrawSurface; + oldReadSurface = oldContext->ReadSurface; } /* @@ -240,7 +208,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, */ if (oldDrawSurface != NULL) { oldDrawSurface->IsBound = EGL_FALSE; - if (oldDrawSurface->DeletePending) { + if (!_eglIsSurfaceLinked(oldDrawSurface)) { /* make sure we don't try to rebind a deleted surface */ if (draw == oldDrawSurface || draw == oldReadSurface) { draw = NULL; @@ -251,7 +219,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, } if (oldReadSurface != NULL && oldReadSurface != oldDrawSurface) { oldReadSurface->IsBound = EGL_FALSE; - if (oldReadSurface->DeletePending) { + if (!_eglIsSurfaceLinked(oldReadSurface)) { /* make sure we don't try to rebind a deleted surface */ if (read == oldDrawSurface || read == oldReadSurface) { read = NULL; @@ -262,7 +230,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, } if (oldContext != NULL) { oldContext->IsBound = EGL_FALSE; - if (oldContext->DeletePending) { + if (!_eglIsContextLinked(oldContext)) { /* make sure we don't try to rebind a deleted context */ if (ctx == oldContext) { ctx = NULL; @@ -283,9 +251,11 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, ctx->IsBound = EGL_TRUE; draw->IsBound = EGL_TRUE; read->IsBound = EGL_TRUE; + t->CurrentContexts[apiIndex] = ctx; + } + else { + t->CurrentContexts[apiIndex] = NULL; } - - t->CurrentContext = ctx; return EGL_TRUE; } diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index 34fee9c637..2fb28d38b9 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -11,7 +11,9 @@ */ struct _egl_context { - _EGLDisplay *Display; /* who do I belong to? */ + /* Managed by EGLDisplay for linking */ + _EGLDisplay *Display; + _EGLContext *Next; _EGLConfig *Config; @@ -19,7 +21,6 @@ struct _egl_context _EGLSurface *ReadSurface; EGLBoolean IsBound; - EGLBoolean DeletePending; EGLint ClientAPI; /**< EGL_OPENGL_ES_API, EGL_OPENGL_API, EGL_OPENVG_API */ EGLint ClientVersion; /**< 1 = OpenGLES 1.x, 2 = OpenGLES 2.x */ @@ -27,28 +28,8 @@ 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); - - -extern _EGLContext * -_eglLookupContext(EGLContext ctx); - - -extern _EGLContext * -_eglGetCurrentContext(void); +_eglInitContext(_EGLDriver *drv, _EGLContext *ctx, + _EGLConfig *config, const EGLint *attrib_list); extern EGLContext diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 47a2323eaf..89de609d0b 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -7,6 +7,7 @@ #include <stdlib.h> #include <string.h> #include "eglcontext.h" +#include "eglsurface.h" #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" @@ -25,11 +26,6 @@ _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; @@ -46,8 +42,37 @@ _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 +_eglLinkDisplay(_EGLDisplay *dpy) +{ + EGLuint key; + key = _eglHashGenKey(_eglGlobal.Displays); + assert(key); + /* "link" the display to the hash table */ + _eglHashInsert(_eglGlobal.Displays, key, dpy); + dpy->Handle = (EGLDisplay) key; + + return dpy->Handle; +} + + +/** + * Unlink a linked display from itself. + * Accessing an unlinked display should generate EGL_BAD_DISPLAY error. + */ +void +_eglUnlinkDisplay(_EGLDisplay *dpy) +{ + _eglHashRemove(_eglGlobal.Displays, (EGLuint) dpy->Handle); + dpy->Handle = EGL_NO_DISPLAY; +} + + +/** + * Return the handle of a linked display, or EGL_NO_DISPLAY. */ EGLDisplay _eglGetDisplayHandle(_EGLDisplay *display) @@ -60,40 +85,70 @@ _eglGetDisplayHandle(_EGLDisplay *display) /** - * Return the _EGLDisplay object that corresponds to the given public/ - * opaque display handle. - * This is the inverse of _eglGetDisplayHandle(). + * Lookup a handle to find the linked display. + * Return NULL if the handle has no corresponding linked display. */ _EGLDisplay * _eglLookupDisplay(EGLDisplay dpy) { EGLuint key = (EGLuint) dpy; - if (!_eglGlobal.Displays) - return NULL; return (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key); } -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); + EGLuint key = _eglHashFirstEntry(_eglGlobal.Displays); + + /* Walk the hash table. Should switch to list if it is a problem. */ + while (key) { + _EGLDisplay *dpy = (_EGLDisplay *) + _eglHashLookup(_eglGlobal.Displays, key); + assert(dpy); + + if (dpy->NativeDisplay == nativeDisplay) + return dpy; + key = _eglHashNextEntry(_eglGlobal.Displays, key); + } + + return NULL; } -_EGLDisplay * -_eglGetCurrentDisplay(void) +/** + * Destroy the contexts and surfaces that are linked to the display. + */ +void +_eglReleaseDisplayResources(_EGLDriver *drv, EGLDisplay dpy) { - _EGLContext *ctx = _eglGetCurrentContext(); - if (ctx) - return ctx->Display; - else - return NULL; + _EGLDisplay *display; + _EGLContext *contexts; + _EGLSurface *surfaces; + + display = _eglLookupDisplay(dpy); + if (!display) + return; + contexts = display->ContextList; + surfaces = display->SurfaceList; + + while (contexts) { + EGLContext handle = _eglGetContextHandle(contexts); + contexts = contexts->Next; + drv->API.DestroyContext(drv, dpy, handle); + } + assert(!display->ContextList); + + while (surfaces) { + EGLSurface handle = _eglGetSurfaceHandle(surfaces); + surfaces = surfaces->Next; + drv->API.DestroySurface(drv, dpy, handle); + } + assert(!display->SurfaceList); } @@ -119,3 +174,147 @@ _eglCleanupDisplay(_EGLDisplay *disp) /* 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; +} + + +/** + * Return the handle of a linked context, or EGL_NO_CONTEXT. + */ +EGLContext +_eglGetContextHandle(_EGLContext *ctx) +{ + return (EGLContext) (ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT; +} + + +/** + * Lookup a handle to find the linked context. + * Return NULL if the handle has no corresponding linked context. + */ +_EGLContext * +_eglLookupContext(EGLContext ctx) +{ + _EGLContext *context = (_EGLContext *) ctx; + return (context && context->Display) ? context : 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) +{ + EGLuint key; + + surf->Display = dpy; + surf->Next = dpy->SurfaceList; + dpy->SurfaceList = surf; + + key = _eglHashGenKey(_eglGlobal.Surfaces); + assert(key); + _eglHashInsert(_eglGlobal.Surfaces, key, surf); + + surf->Handle = (EGLSurface) key; + return surf->Handle; +} + + +/** + * Unlink a linked surface from its display. + * Accessing an unlinked surface should generate EGL_BAD_SURFACE error. + */ +void +_eglUnlinkSurface(_EGLSurface *surf) +{ + _EGLSurface *prev; + + _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle); + surf->Handle = EGL_NO_SURFACE; + + 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; +} + + +/** + * Return the handle of a linked surface, or EGL_NO_SURFACE. + */ +EGLSurface +_eglGetSurfaceHandle(_EGLSurface *surface) +{ + if (surface) + return surface->Handle; + else + return EGL_NO_SURFACE; +} + + +/** + * Lookup a handle to find the linked surface. + * Return NULL if the handle has no corresponding linked surface. + */ +_EGLSurface * +_eglLookupSurface(EGLSurface surf) +{ + _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces, + (EGLuint) surf); + return c; +} diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index ff623ee1c6..372ed3cd79 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -23,6 +23,9 @@ 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 @@ -33,7 +36,15 @@ extern _EGLDisplay * _eglNewDisplay(NativeDisplayType displayName); -EGLDisplay +extern EGLDisplay +_eglLinkDisplay(_EGLDisplay *dpy); + + +extern void +_eglUnlinkDisplay(_EGLDisplay *dpy); + + +extern EGLDisplay _eglGetDisplayHandle(_EGLDisplay *display); @@ -41,21 +52,77 @@ extern _EGLDisplay * _eglLookupDisplay(EGLDisplay dpy); -extern void -_eglSaveDisplay(_EGLDisplay *dpy); +/** + * Return true if the display is linked. + */ +static INLINE EGLBoolean +_eglIsDisplayLinked(_EGLDisplay *dpy) +{ + return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY); +} 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 EGLContext +_eglGetContextHandle(_EGLContext *ctx); +extern _EGLContext * +_eglLookupContext(EGLContext ctx); + + +/** + * Return true if the context is linked to a display. + */ +static INLINE EGLBoolean +_eglIsContextLinked(_EGLContext *ctx) +{ + return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT); +} + +extern EGLSurface +_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy); + + +extern void +_eglUnlinkSurface(_EGLSurface *surf); + + +extern EGLSurface +_eglGetSurfaceHandle(_EGLSurface *); + + +extern _EGLSurface * +_eglLookupSurface(EGLSurface surf); + + +/** + * Return true if the surface is linked to a display. + */ +static INLINE EGLBoolean +_eglIsSurfaceLinked(_EGLSurface *surf) +{ + return (EGLBoolean) (_eglGetSurfaceHandle(surf) != EGL_NO_SURFACE); +} + #endif /* EGLDISPLAY_INCLUDED */ diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 43b1f51903..f2a864cd8a 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -284,9 +284,7 @@ _eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy) _eglLog(_EGL_DEBUG, "Closing %s", drv->Name); - /* - * XXX check for currently bound context/surfaces and delete them? - */ + _eglReleaseDisplayResources(drv, dpy); b = drv->API.Terminate(drv, dpy); diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index b770e55dbd..55de394ef5 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -1,6 +1,6 @@ -#include <stdio.h> #include <stdlib.h> #include "eglglobals.h" +#include "egllog.h" struct _egl_global _eglGlobal = { @@ -22,8 +22,8 @@ _eglInitGlobals(void) _eglGlobal.ClientAPIsMask = 0x0; - /* XXX temporary */ - _eglGlobal.ThreadInfo = _eglNewThreadInfo(); + if (!_eglInitCurrent()) + _eglLog(_EGL_FATAL, "failed to initialize \"current\" system"); } } @@ -34,113 +34,8 @@ _eglInitGlobals(void) void _eglDestroyGlobals(void) { + _eglFiniCurrent(); /* XXX TODO walk over table entries, deleting each */ _eglDeleteHashTable(_eglGlobal.Displays); _eglDeleteHashTable(_eglGlobal.Surfaces); } - - -/** - * Allocate and init a new _EGLThreadInfo object. - */ -_EGLThreadInfo * -_eglNewThreadInfo(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; -} - - -/** - * Delete/free a _EGLThreadInfo object. - */ -void -_eglDeleteThreadData(_EGLThreadInfo *t) -{ - free(t); -} - - - -/** - * 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; -} - - -/** - * 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; - - 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); - } -} diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h index 14d8ea487a..a9443cfbdd 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -3,17 +3,7 @@ #include "egltypedefs.h" #include "eglhash.h" - - -/** - * Per-thread info - */ -struct _egl_thread_info -{ - EGLint LastError; - _EGLContext *CurrentContext; - EGLenum CurrentAPI; -}; +#include "eglcurrent.h" /** @@ -23,6 +13,7 @@ struct _egl_global { EGLBoolean Initialized; + /* these are private to egldisplay.c */ _EGLHashtable *Displays; _EGLHashtable *Surfaces; @@ -33,9 +24,6 @@ struct _egl_global char ClientAPIs[1000]; /**< updated by eglQueryString */ - /* XXX temporary - should be thread-specific data (TSD) */ - _EGLThreadInfo *ThreadInfo; - EGLint NumDrivers; _EGLDriver *Drivers[10]; }; @@ -52,20 +40,4 @@ 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); - - #endif /* EGLGLOBALS_INCLUDED */ diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c index 9c9a8377bf..b6bde65e8b 100644 --- a/src/egl/main/eglscreen.c +++ b/src/egl/main/eglscreen.c @@ -128,20 +128,25 @@ _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, { #if 0 /* THIS IS JUST EXAMPLE CODE */ _EGLSurface *surf; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreateScreenSurfaceMESA"); + return EGL_NO_SURFACE; + } surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); if (!surf) return EGL_NO_SURFACE; - 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; } - _eglSaveSurface(surf); - - return surf->Handle; + return _eglLinkSurface(surf, _eglLookupDisplay(dpy)); #endif return EGL_NO_SURFACE; } diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index 6905acac50..9821e63628 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -6,6 +6,7 @@ #include <assert.h> #include <stdlib.h> #include <string.h> +#include "egldisplay.h" #include "eglcontext.h" #include "eglconfig.h" #include "egldriver.h" @@ -20,12 +21,10 @@ * \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 renderBuffer = EGL_BACK_BUFFER; @@ -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,72 +209,6 @@ _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) { @@ -385,19 +317,24 @@ _eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, { #if 0 /* THIS IS JUST EXAMPLE CODE */ _EGLSurface *surf; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreateWindowSurface"); + return EGL_NO_SURFACE; + } surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); if (!surf) return EGL_NO_SURFACE; - 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; } - _eglSaveSurface(surf); - - return surf->Handle; + return _eglLinkSurface(surf, _eglLookupDisplay(dpy)); #endif return EGL_NO_SURFACE; } @@ -412,19 +349,24 @@ _eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, { #if 0 /* THIS IS JUST EXAMPLE CODE */ _EGLSurface *surf; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface"); + return EGL_NO_SURFACE; + } surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); if (!surf) return EGL_NO_SURFACE; - 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; } - _eglSaveSurface(surf); - - return surf->Handle; + return _eglLinkSurface(surf, _eglLookupDisplay(dpy)); #endif return EGL_NO_SURFACE; } @@ -439,19 +381,24 @@ _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, { #if 0 /* THIS IS JUST EXAMPLE CODE */ _EGLSurface *surf; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); if (!surf) return EGL_NO_SURFACE; - 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; } - _eglSaveSurface(surf); - - return surf->Handle; + return _eglLinkSurface(surf, _eglLookupDisplay(dpy)); #endif return EGL_NO_SURFACE; } @@ -465,13 +412,9 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) { _EGLSurface *surf = _eglLookupSurface(surface); if (surf) { - _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface); - if (surf->IsBound) { - surf->DeletePending = EGL_TRUE; - } - else { + _eglUnlinkSurface(surf); + if (!surf->IsBound) free(surf); - } return EGL_TRUE; } else { diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index 50f965b5cb..f9413eb9d7 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -10,12 +10,15 @@ */ struct _egl_surface { - EGLSurface Handle; /* The public/opaque handle which names this object */ + /* Managed by EGLDisplay for linking */ + _EGLDisplay *Display; + _EGLSurface *Next; + EGLSurface Handle; + _EGLConfig *Config; /* May need reference counting here */ EGLBoolean IsBound; - EGLBoolean DeletePending; EGLBoolean BoundToTexture; EGLint Type; /* one of EGL_WINDOW_BIT, EGL_PIXMAP_BIT or EGL_PBUFFER_BIT */ @@ -39,29 +42,8 @@ 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 diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h index 9fbc55352c..0a770dec0c 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; |