From 5f7c005a0b675d7dbcf46e5b2bca3143759ce2ca Mon Sep 17 00:00:00 2001 From: Sangjin Kim Date: Wed, 20 Mar 2013 16:38:14 +0900 Subject: [PATCH] Enable pbuffer surface. Signed-off-by: Zhai Edwin --- tizen/src/hw/gl_func_perso.h | 4 + tizen/src/hw/gloffscreen.h | 6 +- tizen/src/hw/gloffscreen_agl.c | 8 +- tizen/src/hw/gloffscreen_wgl.c | 5 +- tizen/src/hw/gloffscreen_xcomposite.c | 2 +- tizen/src/hw/opengl_exec.c | 147 ++++++++++++++++++++++---- tizen/src/hw/opengl_func.h | 4 +- 7 files changed, 148 insertions(+), 28 deletions(-) diff --git a/tizen/src/hw/gl_func_perso.h b/tizen/src/hw/gl_func_perso.h index 1488343e9c..4d7ad9eff3 100644 --- a/tizen/src/hw/gl_func_perso.h +++ b/tizen/src/hw/gl_func_perso.h @@ -60,6 +60,10 @@ MAGIC_MACRO(glXGetDriverConfig), MAGIC_MACRO(glXSwapIntervalSGI), MAGIC_MACRO(glXCreatePixmap), MAGIC_MACRO(glXDestroyPixmap), +MAGIC_MACRO(glXBindTexImageARB_fake), +MAGIC_MACRO(glXReleaseTexImageARB_fake), +MAGIC_MACRO(glXCreatePbuffer), +MAGIC_MACRO(glXDestroyPbuffer), MAGIC_MACRO(glGetString), diff --git a/tizen/src/hw/gloffscreen.h b/tizen/src/hw/gloffscreen.h index 806db14b68..11547c71be 100644 --- a/tizen/src/hw/gloffscreen.h +++ b/tizen/src/hw/gloffscreen.h @@ -83,8 +83,10 @@ extern void glo_context_destroy(GloContext *context); /* Update the context in surface and free previous light-weight context */ extern void glo_surface_update_context(GloSurface *surface, GloContext *context, int free_flags); -/* Link the pixmap associated with surface as texture */ -extern void glo_surface_as_texture(GloSurface *surface); +/* Link the pixmap/pbuffer associated with surface as texture. + * ctxt is the target context for the texture operation + */ +extern void glo_surface_as_texture(GloContext *ctxt, GloSurface *surface); /* Create a surface with given width and height, */ extern GloSurface *glo_surface_create(int width, int height, GloContext *context); diff --git a/tizen/src/hw/gloffscreen_agl.c b/tizen/src/hw/gloffscreen_agl.c index 4a42907681..c950c281d3 100644 --- a/tizen/src/hw/gloffscreen_agl.c +++ b/tizen/src/hw/gloffscreen_agl.c @@ -334,8 +334,9 @@ void glo_surface_get_size(GloSurface *surface, int *width, int *height) } /* Bind the surface as texture */ -void glo_surface_as_texture(GloSurface *surface) +void glo_surface_as_texture(GloContext *ctxt, GloSurface *surface) { +#if 0 //Not QUit sure about this function; int glFormat, glType; glo_surface_updatecontents(surface); @@ -345,8 +346,11 @@ void glo_surface_as_texture(GloSurface *surface) /* glTexImage2D use different RGB order than the contexts in the pixmap surface */ /* glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface->width, surface->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->image->data);*/ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface->width, surface->height, 0, glFormat, glType, surface->pbuffer); +#else + if (aglTexImagePBuffer(ctxt->context, surface->pbuffer, GL_BACK) == GL_FALSE) + fprintf(stderr, "aglTexImagePBuffer failed: %s", aglErrorString(aglGetError())); - +#endif } void glo_surface_release_texture(GloSurface *surface) diff --git a/tizen/src/hw/gloffscreen_wgl.c b/tizen/src/hw/gloffscreen_wgl.c index 0290d76474..0ab2ea53b2 100644 --- a/tizen/src/hw/gloffscreen_wgl.c +++ b/tizen/src/hw/gloffscreen_wgl.c @@ -659,6 +659,9 @@ static const char *STANDARD_GL_FUNCTIONS ={ "glXGetVisualFromFBConfig\0" "glXIsDirect\0" "glXCreatePixmap\0" +"glXDestroyPixmap\0" +"glXCreatePbuffer\n" +"glXDestroyPbuffer\n" "\0" }; @@ -964,7 +967,7 @@ void glo_surface_get_size(GloSurface *surface, int *width, int *height) { } /* Bind the surface as texture */ -void glo_surface_as_texture(GloSurface *surface) +void glo_surface_as_texture(GloContext *ctxt, GloSurface *surface) { #if 0 int glFormat, glType; diff --git a/tizen/src/hw/gloffscreen_xcomposite.c b/tizen/src/hw/gloffscreen_xcomposite.c index 4389749f6f..1a54e0a0c6 100644 --- a/tizen/src/hw/gloffscreen_xcomposite.c +++ b/tizen/src/hw/gloffscreen_xcomposite.c @@ -475,7 +475,7 @@ void glo_surface_get_size(GloSurface *surface, int *width, int *height) { } /* Bind the surface as texture */ -void glo_surface_as_texture(GloSurface *surface) +void glo_surface_as_texture(GloContext *ctxt, GloSurface *surface) { #if 0 void (*ptr_func_glXBindTexImageEXT) (Display *dpy, GLXDrawable draw, int buffer, int *attrib_list); diff --git a/tizen/src/hw/opengl_exec.c b/tizen/src/hw/opengl_exec.c index 43c1f353dd..5be4192ee0 100644 --- a/tizen/src/hw/opengl_exec.c +++ b/tizen/src/hw/opengl_exec.c @@ -628,17 +628,12 @@ static void unbind_qsurface(GLState *state, state->current_qsurface = NULL; } -/* Find the qsurface with required drawable in active & pending qsurfaces */ +/* Find the qsurface with required drawable in all pixmap/pbuffer surfaces */ QGloSurface* find_qsurface_from_client_drawable(ProcessState *process, ClientGLXDrawable client_drawable) { - /* search for surfaces in current conetxt */ int i; - QGloSurface *qsurface = get_qsurface_from_client_drawable(process->current_state, client_drawable); - - if (qsurface) - return qsurface; + QGloSurface *qsurface; - /* search the pending surfaces */ for ( i = 0; i < process->nb_qsurf; i++ ) { qsurface = process->pending_qsurfaces[i]; @@ -700,14 +695,13 @@ static int link_drawable(ProcessState *process, ClientGLXDrawable drawable) return 0; } -/* Need to create pixmap surface when guest do so, as guest may use it before - * MakeCurrent. As no context available at this point, we do the follwoing: +/* Need to create pixmap/pbuffer surface when guest do so, as guest may use it + * before MakeCurrent. As no context available at this point, do the following: * 1. Create one light-weight context just for surface creation. * 2. Store this qsurface, and link it with right context when MakeCurrent */ static void keep_qsurface(ProcessState *process, QGloSurface *qsurface) { - int i; process->pending_qsurfaces = g_realloc(process->pending_qsurfaces, (process->nb_qsurf + 1) * sizeof(QGloSurface*)); @@ -760,8 +754,9 @@ static int link_qsurface(ProcessState *process, GLState *glstate, ClientGLXDrawa return 0; } -/* Pixmap can be used as texture via glEGLImageTargetTexture2DOES, so need keep - * the mapping between them to add proper action when bind the texture again +/* Pixmap and Pbuffer can be used as texture via glEGLImageTargetTexture2DOES + * and glXBindTexImage, so need keep the mapping between them to add proper + * action when bind the texture again */ static void del_pixmap_texture_mapping(GLState *state, unsigned int texture) @@ -780,6 +775,23 @@ static void del_pixmap_texture_mapping(GLState *state, } } +static void remove_pixmap_texture_mapping(GLState *state, + ClientGLXDrawable drawable) +{ + int i; + for ( i = 0; i < MAX_PIXMAP_TEXTURE; i++ ) + { + if ( state->pixmapTextures[i].used && + state->pixmapTextures[i].drawable == drawable ) + { + state->pixmapTextures[i].used = 0; + state->pixmapTextures[i].texture = 0; + state->pixmapTextures[i].drawable = 0; + return; + } + } +} + static int add_pixmap_texture_mapping(GLState *state, unsigned int texture, ClientGLXDrawable drawable) { @@ -796,8 +808,7 @@ static int add_pixmap_texture_mapping(GLState *state, } } - if ( i >= MAX_PIXMAP_TEXTURE ) - return 0; + return 0; } static ClientGLXDrawable find_pixmap_texture(GLState *state, @@ -1759,7 +1770,7 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args ret.i = glo_surface_makecurrent(glstate->current_qsurface->surface); /* if (reset_texture)*/ -/* glo_surface_as_texture(old_glstate->current_qsurface->surface);*/ +/* glo_surface_as_texture(process->current_state->context, old_glstate->current_qsurface->surface);*/ } } break; @@ -2030,8 +2041,10 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args keep_qsurface(process, qsurface); /* If this pixmap is linked as texture previously */ - if (link_drawable(process, client_drawable)) - glo_surface_as_texture(qsurface->surface); + if (link_drawable(process, client_drawable)) + glo_surface_as_texture(process->current_state->context, + qsurface->surface); + ret.i = client_drawable; @@ -2040,6 +2053,17 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args } case glXDestroyPixmap_func: { + /* glXPixmap same as input Pixmap */ + ClientGLXDrawable client_drawable = to_drawable(args[1]); + QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable); + if ( qsurface && + qsurface != process->current_state->current_qsurface && + qsurface->glstate == NULL && + qsurface->type == SURFACE_PIXMAP ) + { + glo_surface_destroy(qsurface->surface); + g_free(qsurface); + } break; } case glEGLImageTargetTexture2DOES_fake_func: @@ -2063,10 +2087,93 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args } } else - glo_surface_as_texture(qsurface->surface); + glo_surface_as_texture(process->current_state->context, qsurface->surface); + + break; + } + case glXBindTexImageARB_fake_func: + { + ClientGLXDrawable client_drawable = to_drawable(args[1]); + QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable); + ret.i = 0; + + + if ( qsurface ) + { + add_pixmap_texture_mapping(process->current_state, + process->current_state->bindTexture2D, + client_drawable); + glo_surface_as_texture(process->current_state->context, qsurface->surface); + ret.i = 1; + } + else + DEBUGF( "Not found pbuffer surface for BindTexImage!\n"); + + break; + } + case glXReleaseTexImageARB_fake_func: + { + ClientGLXDrawable client_drawable = to_drawable(args[1]); + QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable); + + if ( qsurface ) + { + remove_pixmap_texture_mapping(process->current_state, + client_drawable); + glo_surface_release_texture(qsurface->surface); + } + + break; + } + case glXCreatePbuffer_func: + { + int client_fbconfig = args[1]; + + ret.i = 0; + const GLXFBConfig *fbconfig = get_fbconfig(process, client_fbconfig); + + if (fbconfig) { + + /* Create a light-weight context just for creating surface */ + GloContext *context = __glo_context_create(fbconfig->formatFlags); + + QGloSurface *qsurface = calloc(1, sizeof(QGloSurface)); + /* get the width and height */ + int width, height; + glo_geometry_get_from_glx((int*)args[2], &width, &height); + + DEBUGF( "glXCreatePbuffer: %dX%d.\n", width, height); + qsurface->surface = glo_surface_create(width, height, context); + /* Use GloSurface handler as no input client_drawable, and + * keep only low 32bit of handler on x86_64 host. */ + qsurface->client_drawable = (int)qsurface->surface; + qsurface->type = SURFACE_PBUFFER; + qsurface->status = SURFACE_PENDING; + /* qsurface->ref = 1;*/ + + /* Keep this surface, will link it with context in MakeCurrent */ + keep_qsurface(process, qsurface); + + ret.i = qsurface->client_drawable; + + } + break; + } + case glXDestroyPbuffer_func: + { + ClientGLXDrawable client_drawable = to_drawable(args[1]); + QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable); + if ( qsurface && + qsurface != process->current_state->current_qsurface && + qsurface->glstate == NULL && + qsurface->type == SURFACE_PBUFFER ) + { + glo_surface_destroy(qsurface->surface); + g_free(qsurface); + } break; - } + } /* Begin of texture stuff */ case glBindTexture_func: @@ -2102,7 +2209,7 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args if ( qsurface ) { - glo_surface_as_texture(qsurface->surface); + glo_surface_as_texture(process->current_state->context, qsurface->surface); fprintf(stderr, "edwin:bindtexture: drawable=0x%x,qsurface=%p.\n", drawable, qsurface); } } diff --git a/tizen/src/hw/opengl_func.h b/tizen/src/hw/opengl_func.h index 3b302175ab..e29f0d901f 100644 --- a/tizen/src/hw/opengl_func.h +++ b/tizen/src/hw/opengl_func.h @@ -428,9 +428,9 @@ static const int glXBindTexImageATI_signature[] = { TYPE_NONE, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT }; static const int glXReleaseTexImageATI_signature[] = { TYPE_NONE, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT }; -static const int glXBindTexImageARB_signature[] = +static const int glXBindTexImageARB_fake_signature[] = { TYPE_INT, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT }; -static const int glXReleaseTexImageARB_signature[] = +static const int glXReleaseTexImageARB_fake_signature[] = { TYPE_INT, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT }; static const int glEGLImageTargetTexture2DOES_fake_signature[] = -- 2.34.1