st/egl: Unify surface creation.
authorChia-I Wu <olv@lunarg.com>
Mon, 22 Feb 2010 13:56:58 +0000 (21:56 +0800)
committerChia-I Wu <olv@lunarg.com>
Tue, 23 Feb 2010 14:42:41 +0000 (22:42 +0800)
Add a new function egl_g3d_create_surface and use it to create window,
pixmap, buffer, and screen surfaces.

src/gallium/state_trackers/egl/common/egl_g3d.c

index d769d253ac5c727834f0bd1947ca8d88239eeec4..13a7487ea835e3ab79f6b14e18319eb7cca5a8aa 100644 (file)
@@ -687,131 +687,143 @@ egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
    return EGL_TRUE;
 }
 
-static EGLBoolean
-init_surface_geometry(_EGLSurface *surf)
-{
-   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
-
-   return gsurf->native->validate(gsurf->native, 0x0,
-         &gsurf->sequence_number, NULL,
-         &gsurf->base.Width, &gsurf->base.Height);
-}
+struct egl_g3d_create_surface_arg {
+   EGLint type;
+   union {
+      EGLNativeWindowType win;
+      EGLNativePixmapType pix;
+   } u;
+};
 
 static _EGLSurface *
-egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
-                              _EGLConfig *conf, EGLNativeWindowType win,
-                              const EGLint *attribs)
+egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+                       struct egl_g3d_create_surface_arg *arg,
+                       const EGLint *attribs)
 {
    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
    struct egl_g3d_config *gconf = egl_g3d_config(conf);
    struct egl_g3d_surface *gsurf;
+   struct native_surface *nsurf;
+   const char *err;
+
+   switch (arg->type) {
+   case EGL_WINDOW_BIT:
+      err = "eglCreateWindowSurface";
+      break;
+   case EGL_PIXMAP_BIT:
+      err = "eglCreatePixmapSurface";
+      break;
+   case EGL_PBUFFER_BIT:
+      err = "eglCreatePBufferSurface";
+      break;
+#ifdef EGL_MESA_screen_surface
+   case EGL_SCREEN_BIT_MESA:
+      err = "eglCreateScreenSurface";
+      break;
+#endif
+   default:
+      err = "eglCreateUnknownSurface";
+      break;
+   }
 
    gsurf = CALLOC_STRUCT(egl_g3d_surface);
    if (!gsurf) {
-      _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+      _eglError(EGL_BAD_ALLOC, err);
       return NULL;
    }
 
-   if (!_eglInitSurface(&gsurf->base, dpy, EGL_WINDOW_BIT, conf, attribs)) {
+   if (!_eglInitSurface(&gsurf->base, dpy, arg->type, conf, attribs)) {
       free(gsurf);
       return NULL;
    }
 
-   gsurf->native =
-      gdpy->native->create_window_surface(gdpy->native, win, gconf->native);
-   if (!gsurf->native) {
+   /* create the native surface */
+   switch (arg->type) {
+   case EGL_WINDOW_BIT:
+      nsurf = gdpy->native->create_window_surface(gdpy->native,
+            arg->u.win, gconf->native);
+      break;
+   case EGL_PIXMAP_BIT:
+      nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
+            arg->u.pix, gconf->native);
+      break;
+   case EGL_PBUFFER_BIT:
+      nsurf = gdpy->native->create_pbuffer_surface(gdpy->native,
+            gconf->native, gsurf->base.Width, gsurf->base.Height);
+      break;
+#ifdef EGL_MESA_screen_surface
+   case EGL_SCREEN_BIT_MESA:
+      /* prefer back buffer (move to _eglInitSurface?) */
+      gsurf->base.RenderBuffer = EGL_BACK_BUFFER;
+      nsurf = gdpy->native->modeset->create_scanout_surface(gdpy->native,
+            gconf->native, gsurf->base.Width, gsurf->base.Height);
+      break;
+#endif
+   default:
+      nsurf = NULL;
+      break;
+   }
+
+   if (!nsurf) {
       free(gsurf);
       return NULL;
    }
-
-   if (!init_surface_geometry(&gsurf->base)) {
-      gsurf->native->destroy(gsurf->native);
+   /* initialize the geometry */
+   if (!nsurf->validate(nsurf, 0x0, &gsurf->sequence_number, NULL,
+            &gsurf->base.Width, &gsurf->base.Height)) {
+      nsurf->destroy(nsurf);
       free(gsurf);
       return NULL;
    }
 
-   gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER ||
-                        !gconf->native->mode.doubleBufferMode) ?
+   gsurf->native = nsurf;
+
+   gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ?
       NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
+   if (!gconf->native->mode.doubleBufferMode)
+      gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
 
    return &gsurf->base;
 }
 
 static _EGLSurface *
-egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
-                              _EGLConfig *conf, EGLNativePixmapType pix,
+egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+                              _EGLConfig *conf, EGLNativeWindowType win,
                               const EGLint *attribs)
 {
-   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
-   struct egl_g3d_config *gconf = egl_g3d_config(conf);
-   struct egl_g3d_surface *gsurf;
+   struct egl_g3d_create_surface_arg arg;
 
-   gsurf = CALLOC_STRUCT(egl_g3d_surface);
-   if (!gsurf) {
-      _eglError(EGL_BAD_ALLOC, "eglCreatePixmapSurface");
-      return NULL;
-   }
+   memset(&arg, 0, sizeof(arg));
+   arg.type = EGL_WINDOW_BIT;
+   arg.u.win = win;
 
-   if (!_eglInitSurface(&gsurf->base, dpy, EGL_PIXMAP_BIT, conf, attribs)) {
-      free(gsurf);
-      return NULL;
-   }
-
-   gsurf->native =
-      gdpy->native->create_pixmap_surface(gdpy->native, pix, gconf->native);
-   if (!gsurf->native) {
-      free(gsurf);
-      return NULL;
-   }
+   return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
+}
 
-   if (!init_surface_geometry(&gsurf->base)) {
-      gsurf->native->destroy(gsurf->native);
-      free(gsurf);
-      return NULL;
-   }
+static _EGLSurface *
+egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+                              _EGLConfig *conf, EGLNativePixmapType pix,
+                              const EGLint *attribs)
+{
+   struct egl_g3d_create_surface_arg arg;
 
-   gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
+   memset(&arg, 0, sizeof(arg));
+   arg.type = EGL_PIXMAP_BIT;
+   arg.u.pix = pix;
 
-   return &gsurf->base;
+   return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
 }
 
 static _EGLSurface *
 egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
                                _EGLConfig *conf, const EGLint *attribs)
 {
-   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
-   struct egl_g3d_config *gconf = egl_g3d_config(conf);
-   struct egl_g3d_surface *gsurf;
-
-   gsurf = CALLOC_STRUCT(egl_g3d_surface);
-   if (!gsurf) {
-      _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
-      return NULL;
-   }
-
-   if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) {
-      free(gsurf);
-      return NULL;
-   }
-
-   gsurf->native =
-      gdpy->native->create_pbuffer_surface(gdpy->native, gconf->native,
-            gsurf->base.Width, gsurf->base.Height);
-   if (!gsurf->native) {
-      free(gsurf);
-      return NULL;
-   }
+   struct egl_g3d_create_surface_arg arg;
 
-   if (!init_surface_geometry(&gsurf->base)) {
-      gsurf->native->destroy(gsurf->native);
-      free(gsurf);
-      return NULL;
-   }
+   memset(&arg, 0, sizeof(arg));
+   arg.type = EGL_PBUFFER_BIT;
 
-   gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ?
-      NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
-
-   return &gsurf->base;
+   return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
 }
 
 /**
@@ -1171,34 +1183,12 @@ static _EGLSurface *
 egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
                               _EGLConfig *conf, const EGLint *attribs)
 {
-   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
-   struct egl_g3d_config *gconf = egl_g3d_config(conf);
-   struct egl_g3d_surface *gsurf;
-
-   gsurf = CALLOC_STRUCT(egl_g3d_surface);
-   if (!gsurf) {
-      _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
-      return NULL;
-   }
+   struct egl_g3d_create_surface_arg arg;
 
-   if (!_eglInitSurface(&gsurf->base, dpy,
-            EGL_SCREEN_BIT_MESA, conf, attribs)) {
-      free(gsurf);
-      return NULL;
-   }
+   memset(&arg, 0, sizeof(arg));
+   arg.type = EGL_SCREEN_BIT_MESA;
 
-   gsurf->native =
-      gdpy->native->modeset->create_scanout_surface(gdpy->native,
-            gconf->native, gsurf->base.Width, gsurf->base.Height);
-   if (!gsurf->native) {
-      free(gsurf);
-      return NULL;
-   }
-
-   gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ?
-      NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
-
-   return &gsurf->base;
+   return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
 }
 
 static EGLBoolean