st/egl: Hook eglCreatePbufferFromClientBuffer.
authorChia-I Wu <olv@lunarg.com>
Sun, 30 May 2010 02:58:06 +0000 (10:58 +0800)
committerChia-I Wu <olv@lunarg.com>
Sun, 30 May 2010 03:09:30 +0000 (11:09 +0800)
This is some refactoring works.  Creating a pbuffer from an
EGL_OPENVG_IMAGE is still not supported.

src/gallium/state_trackers/egl/common/egl_g3d.h
src/gallium/state_trackers/egl/common/egl_g3d_api.c
src/gallium/state_trackers/egl/common/egl_g3d_st.c

index 5a3c80b968921234cce971f52d5651f1c7375420..d516d8fe03c70a0f608f44b0cf528421e4156240 100644 (file)
@@ -75,6 +75,9 @@ struct egl_g3d_surface {
    struct native_surface *native;
    struct pipe_resource *render_texture;
 
+   EGLenum client_buffer_type;
+   EGLClientBuffer client_buffer;
+
    unsigned int sequence_number;
 };
 
index 2ec540a99e9fa3be74c7efaf19973e8d78f4e575..255a1fb730ad5b87162b6a7dc7da5d707b9c8070 100644 (file)
@@ -267,16 +267,16 @@ egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
    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)
+static struct egl_g3d_surface *
+create_pbuffer_surface(_EGLDisplay *dpy, _EGLConfig *conf,
+                       const EGLint *attribs, const char *func)
 {
    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");
+      _eglError(EGL_BAD_ALLOC, func);
       return NULL;
    }
 
@@ -293,6 +293,96 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
       return NULL;
    }
 
+   return gsurf;
+}
+
+static _EGLSurface *
+egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+                               _EGLConfig *conf, const EGLint *attribs)
+{
+   struct egl_g3d_surface *gsurf;
+   struct pipe_resource *ptex = NULL;
+
+   gsurf = create_pbuffer_surface(dpy, conf, attribs,
+         "eglCreatePbufferSurface");
+   if (!gsurf)
+      return NULL;
+
+   gsurf->client_buffer_type = EGL_NONE;
+
+   if (!gsurf->stfbi->validate(gsurf->stfbi,
+            &gsurf->stvis.render_buffer, 1, &ptex)) {
+      egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
+      FREE(gsurf);
+      return NULL;
+   }
+
+   return &gsurf->base;
+}
+
+static _EGLSurface *
+egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy,
+                                          EGLenum buftype,
+                                          EGLClientBuffer buffer,
+                                          _EGLConfig *conf,
+                                          const EGLint *attribs)
+{
+   struct egl_g3d_surface *gsurf;
+   struct pipe_resource *ptex = NULL;
+   EGLint pbuffer_attribs[32];
+   EGLint count, i;
+
+   switch (buftype) {
+   case EGL_OPENVG_IMAGE:
+      break;
+   default:
+      _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
+      return NULL;
+      break;
+   }
+
+   /* parse the attributes first */
+   count = 0;
+   for (i = 0; attribs && attribs[i] != EGL_NONE; i++) {
+      EGLint attr = attribs[i++];
+      EGLint val = attribs[i];
+      EGLint err = EGL_SUCCESS;
+
+      switch (attr) {
+      case EGL_TEXTURE_FORMAT:
+      case EGL_TEXTURE_TARGET:
+      case EGL_MIPMAP_TEXTURE:
+         pbuffer_attribs[count++] = attr;
+         pbuffer_attribs[count++] = val;
+         break;
+      default:
+         err = EGL_BAD_ATTRIBUTE;
+         break;
+      }
+      /* bail out */
+      if (err != EGL_SUCCESS) {
+         _eglError(err, "eglCreatePbufferFromClientBuffer");
+         return NULL;
+      }
+   }
+
+   pbuffer_attribs[count++] = EGL_NONE;
+
+   gsurf = create_pbuffer_surface(dpy, conf, pbuffer_attribs,
+         "eglCreatePbufferFromClientBuffer");
+   if (!gsurf)
+      return NULL;
+
+   gsurf->client_buffer_type = buftype;
+   gsurf->client_buffer = buffer;
+
+   if (!gsurf->stfbi->validate(gsurf->stfbi,
+            &gsurf->stvis.render_buffer, 1, &ptex)) {
+      egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
+      FREE(gsurf);
+      return NULL;
+   }
+
    return &gsurf->base;
 }
 
@@ -703,6 +793,7 @@ egl_g3d_init_driver_api(_EGLDriver *drv)
    drv->API.CreateWindowSurface = egl_g3d_create_window_surface;
    drv->API.CreatePixmapSurface = egl_g3d_create_pixmap_surface;
    drv->API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface;
+   drv->API.CreatePbufferFromClientBuffer = egl_g3d_create_pbuffer_from_client_buffer;
    drv->API.DestroySurface = egl_g3d_destroy_surface;
    drv->API.MakeCurrent = egl_g3d_make_current;
    drv->API.SwapBuffers = egl_g3d_swap_buffers;
index b0c0ec4bba89008e6ba5c34705b7f9db135ffde3..6bb819336b67a9951f75c54d5faf7e61107360a3 100644 (file)
@@ -29,6 +29,8 @@
 #include "util/u_memory.h"
 #include "util/u_string.h"
 #include "util/u_inlines.h"
+#include "util/u_pointer.h"
+#include "util/u_format.h"
 #include "util/u_dl.h"
 #include "egldriver.h"
 #include "eglimage.h"
@@ -276,7 +278,34 @@ egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_framebuffer_iface *stfbi,
    return TRUE;
 }
 
-static boolean 
+static void
+pbuffer_reference_openvg_image(struct egl_g3d_surface *gsurf)
+{
+   /* TODO */
+}
+
+static void
+pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf)
+{
+   struct egl_g3d_display *gdpy =
+      egl_g3d_display(gsurf->base.Resource.Display);
+   struct pipe_screen *screen = gdpy->native->screen;
+   struct pipe_resource templ, *ptex;
+
+   memset(&templ, 0, sizeof(templ));
+   templ.target = PIPE_TEXTURE_2D;
+   templ.last_level = 0;
+   templ.width0 = gsurf->base.Width;
+   templ.height0 = gsurf->base.Height;
+   templ.depth0 = 1;
+   templ.format = gsurf->stvis.color_format;
+   templ.bind = PIPE_BIND_RENDER_TARGET;
+
+   ptex = screen->resource_create(screen, &templ);
+   gsurf->render_texture = ptex;
+}
+
+static boolean
 egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
                                         const enum st_attachment_type *statts,
                                         unsigned count,
@@ -284,7 +313,6 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
 {
    _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
    struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
-   struct pipe_resource templ;
    unsigned i;
 
    for (i = 0; i < count; i++) {
@@ -294,20 +322,19 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
          continue;
 
       if (!gsurf->render_texture) {
-         struct egl_g3d_display *gdpy =
-            egl_g3d_display(gsurf->base.Resource.Display);
-         struct pipe_screen *screen = gdpy->native->screen;
-
-         memset(&templ, 0, sizeof(templ));
-         templ.target = PIPE_TEXTURE_2D;
-         templ.last_level = 0;
-         templ.width0 = gsurf->base.Width;
-         templ.height0 = gsurf->base.Height;
-         templ.depth0 = 1;
-         templ.format = gsurf->stvis.color_format;
-         templ.bind = PIPE_BIND_RENDER_TARGET;
-
-         gsurf->render_texture = screen->resource_create(screen, &templ);
+         switch (gsurf->client_buffer_type) {
+         case EGL_NONE:
+            pbuffer_allocate_render_texture(gsurf);
+            break;
+         case EGL_OPENVG_IMAGE:
+            pbuffer_reference_openvg_image(gsurf);
+            break;
+         default:
+            break;
+         }
+
+         if (!gsurf->render_texture)
+            return FALSE;
       }
 
       pipe_resource_reference(&out[i], gsurf->render_texture);