[Title] apply khr-2does-enabling-libgl-v3.patch and pixmap-enabling-libgl-v3.patch.
authorSooyoung Ha <yoosah.ha@samsung.com>
Mon, 27 Aug 2012 12:53:13 +0000 (21:53 +0900)
committerSooyoung Ha <yoosah.ha@samsung.com>
Mon, 27 Aug 2012 12:53:13 +0000 (21:53 +0900)
[Type] bug fix
[Module] opengl
[Priority]
[CQ#]
[Redmine#]
[Problem]
[Cause]
[Solution]
[TestCase]

tizen/src/hw/gloffscreen.h
tizen/src/hw/gloffscreen_common.c
tizen/src/hw/gloffscreen_xcomposite.c
tizen/src/hw/opengl_exec.c

index fe543ac..88bb2b2 100644 (file)
@@ -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.
index c97b9c1..fef4cb0 100644 (file)
@@ -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;
index 6c3343e..2a1de64 100644 (file)
@@ -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);
 }
index 24ea678..718ece0 100644 (file)
@@ -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: