/*
* TODO:
*
- * Add GLXFBConfig support
- * Pbuffer & Pixmap support
* test eglBind/ReleaseTexImage
*/
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
-#include "eglhash.h"
#include "egllog.h"
#include "eglsurface.h"
#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
{
_EGLDriver Base; /**< base class */
XVisualInfo *visuals;
+ GLXFBConfig *fbconfigs;
- /* GLXFBConfig *fbconfigs - todo */
+ int glx_maj, glx_min;
};
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)
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);
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)
{
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;
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);
/* XXX possibly other things to init... */
_eglAddConfig(disp, &config->Base);
- }
}
+end:
return EGL_TRUE;
}
* 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 */
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;
}
/**
* 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;
}
* 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;
}
/**
* 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 ?? */
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 ?? */
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);
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);
}
* 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;
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;
}