diff options
-rw-r--r-- | src/gallium/state_trackers/egl/common/egl_g3d.h | 3 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/common/egl_g3d_api.c | 99 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/common/egl_g3d_st.c | 59 |
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 5a3c80b968..d516d8fe03 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 2ec540a99e..255a1fb730 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 b0c0ec4bba..6bb819336b 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); |