summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-05-30 10:58:06 +0800
committerChia-I Wu <[email protected]>2010-05-30 11:09:30 +0800
commita5183a38c293249dad36a7230ff872ea7485eee0 (patch)
tree4645c39964f5c8769638a5a4ecba8bd9dce1dc41 /src/gallium/state_trackers
parent9d7219c560d468e1329d6867cff5033e979f535f (diff)
st/egl: Hook eglCreatePbufferFromClientBuffer.
This is some refactoring works. Creating a pbuffer from an EGL_OPENVG_IMAGE is still not supported.
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h3
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c99
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c59
3 files changed, 141 insertions, 20 deletions
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index 5a3c80b9689..d516d8fe03c 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -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;
};
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 2ec540a99e9..255a1fb730a 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -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;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
index b0c0ec4bba8..6bb819336b6 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -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);