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:
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user