Enable pbuffer surface.
authorSangjin Kim <sangjin3.kim@samsung.com>
Wed, 20 Mar 2013 07:38:14 +0000 (16:38 +0900)
committerSangjin Kim <sangjin3.kim@samsung.com>
Wed, 20 Mar 2013 07:38:14 +0000 (16:38 +0900)
Signed-off-by: Zhai Edwin <edwin.zhai@intel.com>
tizen/src/hw/gl_func_perso.h
tizen/src/hw/gloffscreen.h
tizen/src/hw/gloffscreen_agl.c
tizen/src/hw/gloffscreen_wgl.c
tizen/src/hw/gloffscreen_xcomposite.c
tizen/src/hw/opengl_exec.c
tizen/src/hw/opengl_func.h

index 1488343..4d7ad9e 100644 (file)
@@ -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),
 
index 806db14..11547c7 100644 (file)
@@ -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);
index 4a42907..c950c28 100644 (file)
@@ -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)
index 0290d76..0ab2ea5 100644 (file)
@@ -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;
index 4389749..1a54e0a 100644 (file)
@@ -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);
index 43c1f35..5be4192 100644 (file)
@@ -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);
                     }
                 }
index 3b30217..e29f0d9 100644 (file)
@@ -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[] =