X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fegl%2Fdrivers%2Fglx%2Fegl_glx.c;h=3c8f8b6a6845f9b42d227c1c047ade64bf175a33;hb=4cfb1b880b52d6bba32f4ebec78040ff6bf6737f;hp=4274493a5b566337da151572704c1f12b201ac42;hpb=8015f3ae3b96d93e8b1338b8254bcbead45bb91a;p=mesa.git diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 4274493a5b5..3c8f8b6a684 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -36,8 +36,6 @@ /* * TODO: * - * Add GLXFBConfig support - * Pbuffer & Pixmap support * test eglBind/ReleaseTexImage */ @@ -59,7 +57,6 @@ #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" -#include "eglhash.h" #include "egllog.h" #include "eglsurface.h" @@ -67,10 +64,10 @@ #define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T)) -static const EGLint all_apis = (EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT | - EGL_OPENGL_BIT); +static const EGLint all_apis = (EGL_OPENGL_ES_BIT + | EGL_OPENGL_ES2_BIT + | EGL_OPENVG_BIT + /* | EGL_OPENGL_BIT */); /* can't do */ struct visual_attribs { @@ -110,8 +107,9 @@ struct GLX_egl_driver _EGLDriver Base; /**< base class */ XVisualInfo *visuals; + GLXFBConfig *fbconfigs; - /* GLXFBConfig *fbconfigs - todo */ + int glx_maj, glx_min; }; @@ -158,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) @@ -191,6 +196,9 @@ get_visual_attribs(Display *dpy, XVisualInfo *vInfo, attribs->render_type = GLX_RGBA_BIT; glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer); + if (!attribs->doubleBuffer) + return GL_FALSE; + glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo); glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers); glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize); @@ -242,6 +250,106 @@ get_visual_attribs(Display *dpy, XVisualInfo *vInfo, return GL_TRUE; } +#ifdef GLX_VERSION_1_3 + +static int +glx_token_to_visual_class(int visual_type) +{ + switch (visual_type) { + case GLX_TRUE_COLOR: + return TrueColor; + case GLX_DIRECT_COLOR: + return DirectColor; + case GLX_PSEUDO_COLOR: + return PseudoColor; + case GLX_STATIC_COLOR: + return StaticColor; + case GLX_GRAY_SCALE: + return GrayScale; + case GLX_STATIC_GRAY: + return StaticGray; + case GLX_NONE: + default: + return None; + } +} +static int +get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig, + struct visual_attribs *attribs) +{ + int visual_type; + int fbconfig_id; + + memset(attribs, 0, sizeof(struct visual_attribs)); + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_FBCONFIG_ID, &fbconfig_id); + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_VISUAL_ID, &attribs->id); + +#if 0 + attribs->depth = vInfo->depth; + attribs->redMask = vInfo->red_mask; + attribs->greenMask = vInfo->green_mask; + attribs->blueMask = vInfo->blue_mask; + attribs->colormapSize = vInfo->colormap_size; + attribs->bitsPerRGB = vInfo->bits_per_rgb; +#endif + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_X_VISUAL_TYPE, &visual_type); + attribs->klass = glx_token_to_visual_class(visual_type); + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_BUFFER_SIZE, &attribs->bufferSize); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_LEVEL, &attribs->level); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &attribs->render_type); + if (!(attribs->render_type & GLX_RGBA_BIT)) + return 0; + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &attribs->doubleBuffer); + if (!attribs->doubleBuffer) + return 0; + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_STEREO, &attribs->stereo); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_AUX_BUFFERS, &attribs->auxBuffers); + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_RED_SIZE, &attribs->redSize); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_GREEN_SIZE, &attribs->greenSize); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_BLUE_SIZE, &attribs->blueSize); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ALPHA_SIZE, &attribs->alphaSize); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_DEPTH_SIZE, &attribs->depthSize); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_STENCIL_SIZE, &attribs->stencilSize); + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize); + + /* get transparent pixel stuff */ + glXGetFBConfigAttrib(dpy, fbconfig,GLX_TRANSPARENT_TYPE, &attribs->transparentType); + if (attribs->transparentType == GLX_TRANSPARENT_RGB) { + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue); + } + else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) { + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue); + } + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLE_BUFFERS, &attribs->numMultisample); + glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLES, &attribs->numSamples); + + glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &attribs->visualCaveat); + + if (attribs->id == 0) { + attribs->id = fbconfig_id; + return EGL_PBUFFER_BIT | EGL_PIXMAP_BIT; + } + + return EGL_WINDOW_BIT; +} + +#endif + static EGLBoolean create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv) { @@ -251,6 +359,51 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv) int i; struct visual_attribs attribs; + GLX_drv->fbconfigs = NULL; + +#ifdef GLX_VERSION_1_3 + /* get list of all fbconfigs on this screen */ + GLX_drv->fbconfigs = glXGetFBConfigs(disp->Xdpy, DefaultScreen(disp->Xdpy), &numVisuals); + + if (numVisuals == 0) { + GLX_drv->fbconfigs = NULL; + goto xvisual; + } + + for (i = 0; i < numVisuals; i++) { + struct GLX_egl_config *config; + int bit; + + bit = get_fbconfig_attribs(disp->Xdpy, GLX_drv->fbconfigs[i], &attribs); + if (!bit) + continue; + + config = CALLOC_STRUCT(GLX_egl_config); + + _eglInitConfig(&config->Base, (i+1)); + SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, attribs.id); + SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, attribs.bufferSize); + SET_CONFIG_ATTRIB(&config->Base, EGL_RED_SIZE, attribs.redSize); + SET_CONFIG_ATTRIB(&config->Base, EGL_GREEN_SIZE, attribs.greenSize); + SET_CONFIG_ATTRIB(&config->Base, EGL_BLUE_SIZE, attribs.blueSize); + SET_CONFIG_ATTRIB(&config->Base, EGL_ALPHA_SIZE, attribs.alphaSize); + SET_CONFIG_ATTRIB(&config->Base, EGL_DEPTH_SIZE, attribs.depthSize); + SET_CONFIG_ATTRIB(&config->Base, EGL_STENCIL_SIZE, attribs.stencilSize); + SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLES, attribs.numSamples); + SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLE_BUFFERS, attribs.numMultisample); + SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis); + SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis); + SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, bit); + + /* XXX possibly other things to init... */ + + _eglAddConfig(disp, &config->Base); + } + + goto end; +#endif + +xvisual: /* get list of all visuals on this screen */ theTemplate.screen = DefaultScreen(disp->Xdpy); mask = VisualScreenMask; @@ -262,10 +415,9 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv) if (!get_visual_attribs(disp->Xdpy, &GLX_drv->visuals[i], &attribs)) continue; - if (attribs.doubleBuffer) { config = CALLOC_STRUCT(GLX_egl_config); - _eglInitConfig(&config->Base, i+1); + _eglInitConfig(&config->Base, (i+1)); SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, attribs.id); SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, attribs.bufferSize); SET_CONFIG_ATTRIB(&config->Base, EGL_RED_SIZE, attribs.redSize); @@ -284,9 +436,9 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv) /* XXX possibly other things to init... */ _eglAddConfig(disp, &config->Base); - } } +end: return EGL_TRUE; } @@ -294,24 +446,25 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv) * 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, "XDRI: eglInitialize"); + _eglLog(_EGL_DEBUG, "GLX: eglInitialize"); if (!disp->Xdpy) { disp->Xdpy = XOpenDisplay(NULL); if (!disp->Xdpy) { - _eglLog(_EGL_WARNING, "XDRI: XOpenDisplay failed"); + _eglLog(_EGL_WARNING, "GLX: XOpenDisplay failed"); return EGL_FALSE; } - } + } - GLX_drv->Base.Initialized = EGL_TRUE; + disp->ClientAPIsMask = all_apis; + glXQueryVersion(disp->Xdpy, &GLX_drv->glx_maj, &GLX_drv->glx_min); + GLX_drv->Base.Name = "GLX"; /* we're supporting EGL 1.4 */ @@ -323,18 +476,45 @@ GLX_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, return EGL_TRUE; } +/* + * 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 -GLX_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) +GLX_eglTerminate(_EGLDriver *drv, _EGLDisplay *disp) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _eglLog(_EGL_DEBUG, "GLX: eglTerminate"); - _eglLog(_EGL_DEBUG, "XDRI: eglTerminate"); - -// XCloseDisplay(disp->Xdpy); + _eglReleaseDisplayResources(drv, disp); + FreeDisplayExt(disp->Xdpy); + _eglCleanupDisplay(disp); return EGL_TRUE; } @@ -343,45 +523,47 @@ 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); - - GLX_ctx->context = glXCreateContext(disp->Xdpy, &GLX_drv->visuals[(int)config-1], GLX_ctx_shared ? GLX_ctx_shared->context : NULL, GL_TRUE); +#ifdef GLX_VERSION_1_3 + if (GLX_drv->fbconfigs) + 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[GLX_egl_config_id(conf)], + GLX_ctx_shared ? GLX_ctx_shared->context : NULL, + GL_TRUE); if (!GLX_ctx->context) return EGL_FALSE; - /* need to have a direct rendering context */ +#if 1 + /* (maybe?) need to have a direct rendering context */ if (!glXIsDirect(disp->Xdpy, GLX_ctx->context)) return EGL_FALSE; +#endif - return _eglGetContextHandle(&GLX_ctx->Base); + return &GLX_ctx->Base; } @@ -389,23 +571,21 @@ 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; -// if (!glXMakeContextCurrent(disp->Xdpy, GLX_dsurf->drawable, GLX_rsurf->drawable, GLX_ctx->context)) - if (!glXMakeCurrent(disp->Xdpy, GLX_dsurf ? GLX_dsurf->drawable : 0, GLX_ctx ? GLX_ctx->context : NULL)) - return EGL_FALSE; +#ifdef GLX_VERSION_1_3 + if (!glXMakeContextCurrent(disp->Xdpy, GLX_dsurf ? GLX_dsurf->drawable : 0, GLX_rsurf ? GLX_rsurf->drawable : 0, GLX_ctx ? GLX_ctx->context : NULL)) +#endif + if (!glXMakeCurrent(disp->Xdpy, GLX_dsurf ? GLX_dsurf->drawable : 0, GLX_ctx ? GLX_ctx->context : NULL)) + return EGL_FALSE; return EGL_TRUE; } @@ -427,64 +607,135 @@ 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; } -static EGLBoolean -GLX_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +#ifdef GLX_VERSION_1_3 +static _EGLSurface * +GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, + NativePixmapType pixmap, const EGLint *attrib_list) { - _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); + struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv); + struct GLX_egl_surface *GLX_surf; + int i; + + GLX_surf = CALLOC_STRUCT(GLX_egl_surface); + if (!GLX_surf) + return NULL; + + if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PIXMAP_BIT, + conf, attrib_list)) { + free(GLX_surf); + return NULL; + } + + 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 NULL; } + } - return EGL_TRUE; + GLX_surf->drawable = + glXCreatePixmap(disp->Xdpy, + GLX_drv->fbconfigs[GLX_egl_config_id(conf)], + pixmap, NULL); + + return &GLX_surf->Base; +} + +static _EGLSurface * +GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, + const EGLint *attrib_list) +{ + struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv); + 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 NULL; + + if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PBUFFER_BIT, + conf, attrib_list)) { + free(GLX_surf); + return NULL; } - else { - _eglError(EGL_BAD_SURFACE, "eglDestroySurface"); - return EGL_FALSE; + + while(attrib_list[i] != EGL_NONE) { + switch (attrib_list[i]) { + case EGL_WIDTH: + attribs[j++] = GLX_PBUFFER_WIDTH; + attribs[j++] = attrib_list[i+1]; + break; + case EGL_HEIGHT: + attribs[j++] = GLX_PBUFFER_HEIGHT; + attribs[j++] = attrib_list[i+1]; + break; + } + i++; } + attribs[j++] = 0; + + GLX_surf->drawable = + glXCreatePbuffer(disp->Xdpy, + GLX_drv->fbconfigs[GLX_egl_config_id(conf)], attribs); + + return &GLX_surf->Base; +} +#endif + +static EGLBoolean +GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *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; + } + 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 ?? */ @@ -495,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 ?? */ @@ -510,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, "XDRI: EGL SwapBuffers 0x%x",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); @@ -533,7 +780,29 @@ GLX_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) static _EGLProc GLX_eglGetProcAddress(const char *procname) { - return (_EGLProc)glXGetProcAddress((const GLubyte *)procname); + /* 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 (*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); + + 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); } @@ -542,9 +811,11 @@ GLX_eglGetProcAddress(const char *procname) * 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; + if (!GLX_drv) return NULL; @@ -554,21 +825,37 @@ _eglMain(_EGLDisplay *disp, const char *args) GLX_drv->Base.API.CreateContext = GLX_eglCreateContext; GLX_drv->Base.API.MakeCurrent = GLX_eglMakeCurrent; GLX_drv->Base.API.CreateWindowSurface = GLX_eglCreateWindowSurface; +#ifdef GLX_VERSION_1_3 + if (GLX_drv->glx_maj == 1 && GLX_drv->glx_min >= 3) { + GLX_drv->Base.API.CreatePixmapSurface = GLX_eglCreatePixmapSurface; + GLX_drv->Base.API.CreatePbufferSurface = GLX_eglCreatePbufferSurface; + printf("GLX: Pbuffer and Pixmap support\n"); + } else { + printf("GLX: No pbuffer or pixmap support\n"); + } +#endif GLX_drv->Base.API.DestroySurface = GLX_eglDestroySurface; GLX_drv->Base.API.BindTexImage = GLX_eglBindTexImage; GLX_drv->Base.API.ReleaseTexImage = GLX_eglReleaseTexImage; 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); - /* set new DRI path to pick up EGL version (no mesa code), but don't - * override if one is already set. + /* set new DRI path to pick up EGL version (which doesn't contain any mesa + * code), but don't override if one is already set. */ - setenv("LIBGL_DRIVERS_PATH", DEFAULT_DRIVER_DIR"/egl", 0); + env = getenv("LIBGL_DRIVERS_PATH"); + if (env) { + if (!strstr(env, "egl")) { + sprintf(env, "%s/egl", env); + setenv("LIBGL_DRIVERS_PATH", env, 1); + } + } else + setenv("LIBGL_DRIVERS_PATH", DEFAULT_DRIVER_DIR"/egl", 0); return &GLX_drv->Base; }