From 56456bd2b45996a6135ca2069b77c9d52c59e16f Mon Sep 17 00:00:00 2001 From: Sooyoung Ha Date: Mon, 27 Aug 2012 21:53:13 +0900 Subject: [PATCH] [Title] apply khr-2does-enabling-libgl-v3.patch and pixmap-enabling-libgl-v3.patch. [Type] bug fix [Module] opengl [Priority] [CQ#] [Redmine#] [Problem] [Cause] [Solution] [TestCase] --- tizen/src/hw/gloffscreen.h | 2 + tizen/src/hw/gloffscreen_common.c | 21 ++++ tizen/src/hw/gloffscreen_xcomposite.c | 34 ++++++- tizen/src/hw/opengl_exec.c | 140 ++++++++++++++++++++++++-- 4 files changed, 189 insertions(+), 8 deletions(-) diff --git a/tizen/src/hw/gloffscreen.h b/tizen/src/hw/gloffscreen.h index fe543ac2b2..88bb2b2fdf 100644 --- a/tizen/src/hw/gloffscreen.h +++ b/tizen/src/hw/gloffscreen.h @@ -120,6 +120,8 @@ extern int glo_flags_get_from_glx(const int *fbConfig, int assumeBooleans); /* Use in place of glxGetConfig - returns information from flags based on a GLX enum */ extern int glo_get_glx_from_flags(int formatFlags, int glxEnum); +/* Get the width and height from attrib_list */ +extern void glo_geometry_get_from_glx(const int* attrib_list, int* width, int* height); /* In terms of speed, glReadPixels actually seems the best we can do. * * On Windows PFB_DRAW_TO_BITMAP is software-only. diff --git a/tizen/src/hw/gloffscreen_common.c b/tizen/src/hw/gloffscreen_common.c index c97b9c195c..fef4cb046c 100644 --- a/tizen/src/hw/gloffscreen_common.c +++ b/tizen/src/hw/gloffscreen_common.c @@ -89,6 +89,8 @@ void g_free(void *ptr); #define GLX_MAX_PBUFFER_HEIGHT 0x8017 #define GLX_MAX_PBUFFER_PIXELS 0x8018 #define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E #define GLX_RGBA_BIT 0x00000001 // --------------------------------------------------- @@ -340,6 +342,25 @@ int glo_flags_get_from_glx(const int *fbConfig, int assumeBooleans) { return flags; } +void glo_geometry_get_from_glx(const int* attrib_list, int* width, int* height) +{ + while ( *attrib_list ) + { + switch (*attrib_list) + { + case GLX_WIDTH: + *width = attrib_list[1]; + break; + case GLX_HEIGHT: + *height = attrib_list[1]; + break; + default: + fprintf(stderr, "Should not pass any attribs except for width and height for glXCreiatePixmap. \n"); + } + attrib_list += 2; + } +} + void glo_surface_getcontents_readpixels(int formatFlags, int stride, int bpp, int width, int height, void *data) { int glFormat, glType, rl, pa; diff --git a/tizen/src/hw/gloffscreen_xcomposite.c b/tizen/src/hw/gloffscreen_xcomposite.c index 6c3343ea6f..2a1de64f6b 100644 --- a/tizen/src/hw/gloffscreen_xcomposite.c +++ b/tizen/src/hw/gloffscreen_xcomposite.c @@ -266,6 +266,9 @@ GloSurface *glo_surface_create(int width, int height, GloContext *context) { XSetWindowAttributes attr = { 0 }; unsigned long mask; XVisualInfo *vis; + int pixmapAttribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, + None }; if (!context) return 0; @@ -376,6 +379,24 @@ int glo_surface_makecurrent(GloSurface *surface) { return ret; } +void glo_surface_updatecontents(GloSurface *surface) { + XImage *img; + if (!surface) + return; + + if(glo.use_ximage) { + glXWaitGL(); + + if(surface->image) { + XShmGetImage (glo.dpy, surface->pixmap, surface->image, 0, 0, AllPlanes); + } + else { + img = XGetImage(glo.dpy, surface->pixmap, 0, 0, surface->width, surface->height, AllPlanes, ZPixmap); + } + } + +} + /* Get the contents of the given surface */ void glo_surface_getcontents(GloSurface *surface, int stride, int bpp, void *data) { static int once; @@ -449,6 +470,7 @@ void glo_surface_get_size(GloSurface *surface, int *width, int *height) { /* Bind the surface as texture */ void glo_surface_as_texture(GloSurface *surface) { +#if 0 void (*ptr_func_glXBindTexImageEXT) (Display *dpy, GLXDrawable draw, int buffer, int *attrib_list); ptr_func_glXBindTexImageEXT = (void(*)(Display*, GLXDrawable, int, int*))glo_getprocaddress((const char*)"glXBindTexImageEXT"); @@ -459,10 +481,20 @@ void glo_surface_as_texture(GloSurface *surface) fprintf (stderr, "glXBindTexImageEXT not supported! Can't emulate glEGLImageTargetTexture2DOES!\n"); } + fprintf(stderr, "surface_as_texture:error=%d.\n", glGetError()); ptr_func_glXBindTexImageEXT(glo.dpy, surface->glxPixmap, GLX_FRONT_LEFT_EXT, NULL); + fprintf(stderr, "surface_as_texture:2:error=%d.\n", glGetError()); +#else + glo_surface_updatecontents(surface); + /*XXX: changet the fixed target: GL_TEXTURE_2D*/ + fprintf(stderr, "surface_as_texture:teximage:width=%d,height=%d.\n", surface->width, surface->height); + /* 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, GL_BGRA, GL_UNSIGNED_BYTE, surface->image->data); +#endif } -/* Abstract glXQueryExtensionString() */ + /* Abstract glXQueryExtensionString() */ const char *glo_glXQueryExtensionsString(void) { return glXQueryExtensionsString(glo.dpy, 0); } diff --git a/tizen/src/hw/opengl_exec.c b/tizen/src/hw/opengl_exec.c index 24ea6788ba..718ece0a86 100644 --- a/tizen/src/hw/opengl_exec.c +++ b/tizen/src/hw/opengl_exec.c @@ -114,7 +114,7 @@ void *g_malloc(size_t size); void *g_realloc(void *ptr, size_t size); void g_free(void *ptr); -#define glGetError() 0 +/*#define glGetError() 0*/ #define GET_EXT_PTR(type, funcname, args_decl) \ static int detect_##funcname = 0; \ @@ -203,15 +203,29 @@ typedef void *ClientGLXDrawable; typedef struct GLState GLState; +enum { + SURFACE_WINDOW, + SURFACE_PIXMAP, + SURFACE_PBUFFER, +}; + typedef struct QGloSurface { GLState *glstate; GloSurface *surface; ClientGLXDrawable *client_drawable; + int type; /* window, pixmap or pbuffer */ int ready; int ref; QTAILQ_ENTRY(QGloSurface) next; } QGloSurface; +#define MAX_PIXMAP_TEXTURE 32 +typedef struct PixmapTexture { + unsigned int used; + unsigned int texture; + ClientGLXDrawable drawable; +} PixmapTexture; + struct GLState { int ref; int fake_ctxt; @@ -265,6 +279,9 @@ struct GLState { unsigned int ownTabTextures[32768]; unsigned int *tabTextures; + /* The mapping between the texture and pixmap used as texture */ + PixmapTexture pixmapTextures[MAX_PIXMAP_TEXTURE]; + unsigned int bindTexture2D; RangeAllocator ownTextureAllocator; RangeAllocator *textureAllocator; @@ -690,7 +707,8 @@ static int link_qsurface(ProcessState *process, GLState *glstate, ClientGLXDrawa qsurface = process->pending_qsurfaces[i]; if ( qsurface && qsurface->client_drawable == client_drawable ) { - process->pending_qsurfaces[i] = NULL; + /* Do not reset, as need it in another context */ +/* process->pending_qsurfaces[i] = NULL;*/ qsurface->ref = 1; /* qsurface->surface->context = glstate->context;*/ glo_surface_update_context(qsurface->surface, glstate->context); @@ -702,7 +720,59 @@ 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 + */ +static void del_pixmap_texture_mapping(GLState *state, + unsigned int texture) +{ + int i; + for ( i = 0; i < MAX_PIXMAP_TEXTURE; i++ ) + { + if ( state->pixmapTextures[i].used && + state->pixmapTextures[i].texture == texture ) + { + 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) +{ + int i; + for ( i = 0; i < MAX_PIXMAP_TEXTURE; i++ ) + { + if ( state->pixmapTextures[i].texture == texture || + !state->pixmapTextures[i].used ) + { + state->pixmapTextures[i].used = 1; + state->pixmapTextures[i].texture = texture; + state->pixmapTextures[i].drawable = drawable; + return 1; + } + } + + if ( i >= MAX_PIXMAP_TEXTURE ) + return 0; +} + +static ClientGLXDrawable find_pixmap_texture(GLState *state, + unsigned int texture) +{ + int i; + for ( i = 0; i < MAX_PIXMAP_TEXTURE; i++ ) + { + if ( state->pixmapTextures[i].used && + state->pixmapTextures[i].texture == texture ) + return state->pixmapTextures[i].drawable; + } + return 0; +} static int get_server_texture(ProcessState *process, unsigned int client_texture) @@ -1574,10 +1644,30 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args else { // DEBUGF( " --Client drawable found, using surface: %16x %16lx\n", (unsigned int)glstate->current_qsurface, (unsigned long int)client_drawable); } - + /*Test old surface contents */ + int reset_texture = 0; + GLState *old_glstate = NULL; + /* Switch from pixmap */ + if (process->current_state->current_qsurface && SURFACE_PIXMAP == process->current_state->current_qsurface->type ) + { + glo_surface_updatecontents(process->current_state->current_qsurface->surface); + reset_texture = 1; + old_glstate = process->current_state; + } + fprintf(stderr, "edwin:MakeCurrent: drawable=0x%x,qsurface=%p.\n", client_drawable, glstate->current_qsurface); + + /* Switch to pixmap */ + if (glstate->current_qsurface && SURFACE_PIXMAP == glstate->current_qsurface->type ) + { + /* get the windows contents */ + if ( process->current_state->current_qsurface ) + glo_surface_updatecontents(process->current_state->current_qsurface->surface); + } process->current_state = glstate; ret.i = glo_surface_makecurrent(glstate->current_qsurface->surface); +/* if (reset_texture)*/ +/* glo_surface_as_texture(old_glstate->current_qsurface->surface);*/ } } break; @@ -1832,9 +1922,15 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args ClientGLXDrawable client_drawable = to_drawable(args[2]); QGloSurface *qsurface = calloc(1, sizeof(QGloSurface)); - /*FIXME: need pass w,h from simulator-opengl */ - qsurface->surface = glo_surface_create(512, 512, context); + + /* get the width and height */ + int width, height; + glo_geometry_get_from_glx((int*)args[3], &width, &height); + + DEBUGF( "glXCreatePixmap: %dX%d.\n", width, height); + qsurface->surface = glo_surface_create(width, height, context); qsurface->client_drawable = client_drawable; + qsurface->type = SURFACE_PIXMAP; /* qsurface->ref = 1;*/ /* Keep this surface, will link it with context in MakeCurrent */ @@ -1864,6 +1960,12 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args ClientGLXDrawable client_drawable = to_drawable(args[1]); QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable); + /* Only support GL_TEXTURE_2D according to spec */ + if ( target == GL_TEXTURE_2D ) + add_pixmap_texture_mapping(process->current_state, + process->current_state->bindTexture2D, + client_drawable); + if ( !qsurface ) { if ( !keep_drawable(process, client_drawable) ) @@ -1900,7 +2002,26 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args } glBindTexture(target, server_texture); } - break; + + if ( target == GL_TEXTURE_2D ) { + QGloSurface *qsurface = NULL; + ClientGLXDrawable drawable = + find_pixmap_texture(process->current_state, client_texture); + + if ( drawable ) + { + qsurface = find_qsurface_from_client_drawable(process, drawable); + + if ( qsurface ) + { + glo_surface_as_texture(qsurface->surface); + fprintf(stderr, "edwin:bindtexture: drawable=0x%x,qsurface=%p.\n", drawable, qsurface); + } + } + + process->current_state->bindTexture2D = client_texture; + } + break; } case glGenTextures_fake_func: @@ -1950,7 +2071,12 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args process->current_state->tabTextures[clientTabTextures[i]] = 0; } g_free(serverTabTextures); - break; + + for ( i = 0; i < n; i++ ) + { + del_pixmap_texture_mapping(process->current_state, clientTabTextures[i]); + } + break; } case glPrioritizeTextures_func: -- 2.34.1