#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
-#include "eglglobals.h"
+#include "eglcurrent.h"
#include "egllog.h"
#include "eglsurface.h"
-/** cast wrapper */
-static INLINE struct xdri_egl_driver *
-xdri_egl_driver(_EGLDriver *drv)
-{
- return (struct xdri_egl_driver *) drv;
-}
-
-
-static INLINE struct xdri_egl_display *
-lookup_display(_EGLDisplay *dpy)
-{
- return (struct xdri_egl_display *) dpy->DriverData;
-}
+/* standard typecasts */
+_EGL_DRIVER_STANDARD_TYPECASTS(xdri_egl)
-
-/** Map EGLSurface handle to xdri_egl_surface object */
-static INLINE struct xdri_egl_surface *
-lookup_surface(_EGLSurface *surface)
-{
- return (struct xdri_egl_surface *) surface;
-}
-
-
-/** Map EGLContext handle to xdri_egl_context object */
-static INLINE struct xdri_egl_context *
-lookup_context(_EGLContext *context)
-{
- return (struct xdri_egl_context *) context;
-}
-
-
-/** Map EGLConfig handle to xdri_egl_config object */
-static INLINE struct xdri_egl_config *
-lookup_config(_EGLConfig *conf)
-{
- return (struct xdri_egl_config *) conf;
-}
+#define lookup_display(dpy) xdri_egl_display(dpy)
+#define lookup_context(ctx) xdri_egl_context(ctx)
+#define lookup_surface(surf) xdri_egl_surface(surf)
+#define lookup_config(conf) xdri_egl_config(conf)
/** Get size of given window */
{
EGLint val;
- _eglInitConfig(conf, id);
if (!_eglConfigFromContextModesRec(conf, m, EGL_OPENGL_BIT, EGL_OPENGL_BIT))
return EGL_FALSE;
_EGLConfig conf;
EGLint rb;
+ _eglInitConfig(&conf, disp, id);
if (!convert_config(&conf, id, m))
continue;
if (m->doubleBufferMode) {
return NULL;
}
- if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) {
+ if (!_eglInitContext(&xdri_ctx->Base, dpy, &xdri_config->Base, attrib_list)) {
free(xdri_ctx->dummy_gc);
free(xdri_ctx);
return NULL;
}
-static EGLBoolean
-xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+/**
+ * Destroy a context.
+ */
+static void
+destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
{
struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
struct xdri_egl_context *xdri_ctx = lookup_context(ctx);
- if (!_eglIsContextBound(ctx)) {
- xdri_ctx->driContext->destroyContext(xdri_ctx->driContext,
- xdri_dpy->psc, xdri_dpy->dpy);
- free(xdri_ctx->dummy_gc);
- free(xdri_ctx);
- }
+ /* FIXME a context might live longer than its display */
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
+
+ xdri_ctx->driContext->destroyContext(xdri_ctx->driContext,
+ xdri_dpy->psc, xdri_dpy->dpy);
+ free(xdri_ctx->dummy_gc);
+ free(xdri_ctx);
+}
+
+
+/**
+ * Destroy a surface.
+ */
+static void
+destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
+{
+ struct xdri_egl_surface *xdri_surf = lookup_surface(surf);
+
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
+ xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable);
+ free(xdri_surf);
+}
+
+
+static EGLBoolean
+xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+ if (!_eglIsContextBound(ctx))
+ destroy_context(dpy, ctx);
return EGL_TRUE;
}
struct xdri_egl_context *xdri_ctx = lookup_context(context);
struct xdri_egl_surface *draw = lookup_surface(d);
struct xdri_egl_surface *read = lookup_surface(r);
- _EGLContext *old = _eglGetCurrentContext();
-
- /* an unlinked context will be invalid after context switch */
- if (!_eglIsContextLinked(old))
- old = NULL;
- if (!_eglMakeCurrent(drv, dpy, d, r, context))
+ /* bind the new context and return the "orphaned" one */
+ if (!_eglBindContext(&context, &d, &r))
return EGL_FALSE;
/* flush before context switch */
- if (old && old != context && xdri_driver->FlushCurrentContext)
+ if (context && xdri_driver->FlushCurrentContext)
xdri_driver->FlushCurrentContext();
/* the symbol is defined in libGL.so */
return EGL_FALSE;
}
}
- else if (old) {
- xdri_ctx = lookup_context(old);
+ else if (context) {
+ xdri_ctx = lookup_context(context);
xdri_ctx->driContext->unbindContext(xdri_ctx->driContext);
}
+ if (context && !_eglIsContextLinked(context))
+ destroy_context(dpy, context);
+ if (d && !_eglIsSurfaceLinked(d))
+ destroy_surface(dpy, d);
+ if (r && r != d && !_eglIsSurfaceLinked(r))
+ destroy_surface(dpy, r);
+
return EGL_TRUE;
}
return NULL;
}
- if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT,
+ if (!_eglInitSurface(&xdri_surf->Base, dpy, EGL_WINDOW_BIT,
&xdri_config->Base, attrib_list)) {
free(xdri_surf);
return NULL;
static EGLBoolean
xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
{
- struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
-
- if (!_eglIsSurfaceBound(&xdri_surf->Base)) {
- xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable);
- free(xdri_surf);
- }
-
+ if (!_eglIsSurfaceBound(surface))
+ destroy_surface(dpy, surface);
return EGL_TRUE;
}
struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
/* swapBuffers does not flush commands */
- if (draw->Binding && xdri_driver->FlushCurrentContext)
+ if (draw->CurrentContext && xdri_driver->FlushCurrentContext)
xdri_driver->FlushCurrentContext();
xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable, 0, 0, 0);