st/egl: Hook eglCreatePbufferFromClientBuffer.

This is some refactoring works.  Creating a pbuffer from an
EGL_OPENVG_IMAGE is still not supported.
This commit is contained in:
Chia-I Wu
2010-05-30 10:58:06 +08:00
parent 9d7219c560
commit a5183a38c2
3 changed files with 140 additions and 19 deletions

View 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;
};

View 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;

View 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;
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;
}
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);
if (!gsurf->render_texture)
return FALSE;
}
pipe_resource_reference(&out[i], gsurf->render_texture);