egl: Convert drivers to use typecast macros.
[mesa.git] / src / egl / drivers / xdri / egl_xdri.c
index e13d884e71573e6141e9062d82567050c8ba9ae8..555473c00a59e8d9e2c0ea5306879b3d7f93ab37 100644 (file)
@@ -52,7 +52,7 @@
 #include "eglcontext.h"
 #include "egldisplay.h"
 #include "egldriver.h"
-#include "eglglobals.h"
+#include "eglcurrent.h"
 #include "egllog.h"
 #include "eglsurface.h"
 
@@ -112,43 +112,13 @@ struct xdri_egl_config
 
 
 
-/** 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 */
@@ -171,7 +141,6 @@ convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m)
 {
    EGLint val;
 
-   _eglInitConfig(conf, id);
    if (!_eglConfigFromContextModesRec(conf, m, EGL_OPENGL_BIT, EGL_OPENGL_BIT))
       return EGL_FALSE;
 
@@ -221,6 +190,7 @@ create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id)
       _EGLConfig conf;
       EGLint rb;
 
+      _eglInitConfig(&conf, disp, id);
       if (!convert_config(&conf, id, m))
          continue;
       if (m->doubleBufferMode) {
@@ -391,7 +361,7 @@ xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
       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;
@@ -419,19 +389,47 @@ xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
 }
 
 
-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;
 }
 
@@ -447,17 +445,13 @@ xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
    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 */
@@ -470,11 +464,18 @@ xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
          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;
 }
 
@@ -498,7 +499,7 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
       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;
@@ -539,13 +540,8 @@ xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf
 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;
 }
 
@@ -574,7 +570,7 @@ xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
    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);