summaryrefslogtreecommitdiff
path: root/src/egl/drivers/glx/egl_glx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/drivers/glx/egl_glx.c')
-rw-r--r--src/egl/drivers/glx/egl_glx.c150
1 files changed, 65 insertions, 85 deletions
diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
index 96292b0e9e..3cbfebe488 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -43,7 +43,7 @@
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
-#include "eglglobals.h"
+#include "eglcurrent.h"
#include "egllog.h"
#include "eglsurface.h"
@@ -54,13 +54,6 @@
#error "GL/glx.h must be equal to or greater than GLX 1.4"
#endif
-/*
- * report OpenGL ES bits because apps usually forget to specify
- * EGL_RENDERABLE_TYPE when choosing configs
- */
-#define GLX_EGL_APIS (EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)
-
-
/** subclass of _EGLDriver */
struct GLX_egl_driver
{
@@ -110,6 +103,8 @@ struct GLX_egl_surface
Drawable drawable;
GLXDrawable glx_drawable;
+
+ void (*destroy)(Display *, GLXDrawable);
};
@@ -121,35 +116,14 @@ struct GLX_egl_config
int index;
};
-/** cast wrapper */
-static struct GLX_egl_driver *
-GLX_egl_driver(_EGLDriver *drv)
-{
- return (struct GLX_egl_driver *) drv;
-}
-
-static struct GLX_egl_display *
-GLX_egl_display(_EGLDisplay *dpy)
-{
- return (struct GLX_egl_display *) dpy->DriverData;
-}
-
-static struct GLX_egl_context *
-GLX_egl_context(_EGLContext *ctx)
-{
- return (struct GLX_egl_context *) ctx;
-}
-
-static struct GLX_egl_surface *
-GLX_egl_surface(_EGLSurface *surf)
-{
- return (struct GLX_egl_surface *) surf;
-}
+/* standard typecasts */
+_EGL_DRIVER_STANDARD_TYPECASTS(GLX_egl)
static int
GLX_egl_config_index(_EGLConfig *conf)
{
- return ((struct GLX_egl_config *) conf)->index;
+ struct GLX_egl_config *GLX_conf = GLX_egl_config(conf);
+ return GLX_conf->index;
}
@@ -244,7 +218,7 @@ convert_fbconfig(Display *dpy, GLXFBConfig fbconfig,
GLX_conf->double_buffered = (mode.doubleBufferMode != 0);
return _eglConfigFromContextModesRec(&GLX_conf->Base, &mode,
- GLX_EGL_APIS, GLX_EGL_APIS);
+ EGL_OPENGL_BIT, EGL_OPENGL_BIT);
}
@@ -364,7 +338,7 @@ convert_visual(Display *dpy, XVisualInfo *vinfo,
GLX_conf->double_buffered = (mode.doubleBufferMode != 0);
return _eglConfigFromContextModesRec(&GLX_conf->Base, &mode,
- GLX_EGL_APIS, GLX_EGL_APIS);
+ EGL_OPENGL_BIT, EGL_OPENGL_BIT);
}
@@ -427,7 +401,7 @@ create_configs(_EGLDisplay *dpy, struct GLX_egl_display *GLX_dpy,
EGLBoolean ok;
memset(&template, 0, sizeof(template));
- _eglInitConfig(&template.Base, id);
+ _eglInitConfig(&template.Base, dpy, id);
if (GLX_dpy->have_fbconfig)
ok = convert_fbconfig(GLX_dpy->dpy, GLX_dpy->fbconfigs[i], &template);
else
@@ -559,7 +533,7 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
}
disp->DriverData = (void *) GLX_dpy;
- disp->ClientAPIsMask = GLX_EGL_APIS;
+ disp->ClientAPIsMask = EGL_OPENGL_BIT;
/* we're supporting EGL 1.4 */
*major = 1;
@@ -610,7 +584,7 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
- if (!_eglInitContext(drv, &GLX_ctx->Base, conf, attrib_list)) {
+ if (!_eglInitContext(&GLX_ctx->Base, disp, conf, attrib_list)) {
free(GLX_ctx);
return NULL;
}
@@ -638,6 +612,21 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
/**
+ * Destroy a surface. The display is allowed to be uninitialized.
+ */
+static void
+destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
+{
+ struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
+
+ if (GLX_surf->destroy)
+ GLX_surf->destroy(disp->NativeDisplay, GLX_surf->glx_drawable);
+
+ free(GLX_surf);
+}
+
+
+/**
* Called via eglMakeCurrent(), drv->API.MakeCurrent().
*/
static EGLBoolean
@@ -650,8 +639,10 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
struct GLX_egl_context *GLX_ctx = GLX_egl_context(ctx);
GLXDrawable ddraw, rdraw;
GLXContext cctx;
+ EGLBoolean ret = EGL_FALSE;
- if (!_eglMakeCurrent(drv, disp, dsurf, rsurf, ctx))
+ /* bind the new context and return the "orphaned" one */
+ if (!_eglBindContext(&ctx, &dsurf, &rsurf))
return EGL_FALSE;
ddraw = (GLX_dsurf) ? GLX_dsurf->glx_drawable : None;
@@ -659,11 +650,21 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
cctx = (GLX_ctx) ? GLX_ctx->context : NULL;
if (GLX_dpy->have_make_current_read)
- return glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx);
+ ret = glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx);
else if (ddraw == rdraw)
- return glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx);
+ ret = glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx);
- return EGL_FALSE;
+ if (ret) {
+ if (dsurf && !_eglIsSurfaceLinked(dsurf))
+ destroy_surface(disp, dsurf);
+ if (rsurf && rsurf != dsurf && !_eglIsSurfaceLinked(rsurf))
+ destroy_surface(disp, rsurf);
+ }
+ else {
+ _eglBindContext(&ctx, &dsurf, &rsurf);
+ }
+
+ return ret;
}
/** Get size of given window */
@@ -684,8 +685,9 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
*/
static _EGLSurface *
-GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
- NativeWindowType window, const EGLint *attrib_list)
+GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLConfig *conf, EGLNativeWindowType window,
+ const EGLint *attrib_list)
{
struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf;
@@ -697,7 +699,7 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
- if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_WINDOW_BIT,
+ if (!_eglInitSurface(&GLX_surf->Base, disp, EGL_WINDOW_BIT,
conf, attrib_list)) {
free(GLX_surf);
return NULL;
@@ -718,6 +720,9 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
+ if (GLX_dpy->have_1_3 && !GLX_dpy->glx_window_quirk)
+ GLX_surf->destroy = glXDestroyWindow;
+
get_drawable_size(GLX_dpy->dpy, window, &width, &height);
GLX_surf->Base.Width = width;
GLX_surf->Base.Height = height;
@@ -726,8 +731,9 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
}
static _EGLSurface *
-GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
- NativePixmapType pixmap, const EGLint *attrib_list)
+GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLConfig *conf, EGLNativePixmapType pixmap,
+ const EGLint *attrib_list)
{
struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf;
@@ -739,7 +745,7 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
- if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PIXMAP_BIT,
+ if (!_eglInitSurface(&GLX_surf->Base, disp, EGL_PIXMAP_BIT,
conf, attrib_list)) {
free(GLX_surf);
return NULL;
@@ -774,6 +780,9 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
+ GLX_surf->destroy = (GLX_dpy->have_1_3) ?
+ glXDestroyPixmap : glXDestroyGLXPixmap;
+
get_drawable_size(GLX_dpy->dpy, pixmap, &width, &height);
GLX_surf->Base.Width = width;
GLX_surf->Base.Height = height;
@@ -796,7 +805,7 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp,
return NULL;
}
- if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PBUFFER_BIT,
+ if (!_eglInitSurface(&GLX_surf->Base, disp, EGL_PBUFFER_BIT,
conf, attrib_list)) {
free(GLX_surf);
return NULL;
@@ -838,47 +847,18 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp,
return NULL;
}
+ GLX_surf->destroy = (GLX_dpy->have_1_3) ?
+ glXDestroyPbuffer : GLX_dpy->glXDestroyGLXPbufferSGIX;
+
return &GLX_surf->Base;
}
+
static EGLBoolean
GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
{
- struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
- if (!_eglIsSurfaceBound(surf)) {
- struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
-
- if (GLX_dpy->have_1_3) {
- switch (surf->Type) {
- case EGL_WINDOW_BIT:
- if (!GLX_dpy->glx_window_quirk)
- glXDestroyWindow(GLX_dpy->dpy, GLX_surf->glx_drawable);
- break;
- case EGL_PBUFFER_BIT:
- glXDestroyPbuffer(GLX_dpy->dpy, GLX_surf->glx_drawable);
- break;
- case EGL_PIXMAP_BIT:
- glXDestroyPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable);
- break;
- default:
- break;
- }
- }
- else {
- switch (surf->Type) {
- case EGL_PBUFFER_BIT:
- GLX_dpy->glXDestroyGLXPbufferSGIX(GLX_dpy->dpy,
- GLX_surf->glx_drawable);
- break;
- case EGL_PIXMAP_BIT:
- glXDestroyGLXPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable);
- break;
- default:
- break;
- }
- }
- free(surf);
- }
+ if (!_eglIsSurfaceBound(surf))
+ destroy_surface(disp, surf);
return EGL_TRUE;
}
@@ -899,7 +879,7 @@ GLX_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
* Called from eglGetProcAddress() via drv->API.GetProcAddress().
*/
static _EGLProc
-GLX_eglGetProcAddress(const char *procname)
+GLX_eglGetProcAddress(_EGLDriver *drv, const char *procname)
{
return (_EGLProc) glXGetProcAddress((const GLubyte *) procname);
}