be able to free and alloc gl surface when asked to dump
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 26 Aug 2010 09:40:48 +0000 (09:40 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 26 Aug 2010 09:40:48 +0000 (09:40 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@51654 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/modules/engines/gl_common/evas_gl_image.c
src/modules/engines/gl_x11/evas_engine.c
src/modules/engines/gl_x11/evas_engine.h
src/modules/engines/gl_x11/evas_x_main.c

index 4fca685..c9ebc75 100644 (file)
@@ -9,8 +9,14 @@ evas_gl_common_image_all_unload(Evas_GL_Context *gc)
    EINA_LIST_FOREACH(gc->shared->images, l, im)
      {
         if (im->im) evas_cache_image_unload_data(&im->im->cache_entry);
-        if (im->tex) evas_gl_common_texture_free(im->tex);
-        im->tex = NULL;
+        if (im->tex)
+          {
+             if (!im->tex->pt->dyn.img)
+               {
+                  evas_gl_common_texture_free(im->tex);
+                  im->tex = NULL;
+               }
+          }
      }
 }
 
index bb4e1ce..aab524c 100644 (file)
@@ -25,6 +25,8 @@ struct _Render_Engine
    struct { // xres - dpi
       int        dpi; // xres - dpi
    } xr; // xres - dpi
+   
+   int w, h;
 };
 
 static int initted = 0;
@@ -204,6 +206,25 @@ eng_info_free(Evas *e __UNUSED__, void *info)
 }
 
 static int
+_re_wincheck(Render_Engine *re)
+{
+   if (re->win->surf) return 1;
+   eng_window_resurf(re->win);
+   if (!re->win->surf)
+     {
+        fprintf(stderr, "ERROR: GL engine can't re-create window surface!\n");
+     }
+   return 0;
+}
+
+static void
+_re_winfree(Render_Engine *re)
+{
+   if (!re->win->surf) return;
+   eng_window_unsurf(re->win);
+}
+
+static int
 eng_setup(Evas *e, void *in)
 {
    Render_Engine *re;
@@ -223,17 +244,19 @@ eng_setup(Evas *e, void *in)
         re->info = info;
         re->evas = e;
        e->engine.data.output = re;
-       re->win = eng_window_new(info->info.display,
-                                info->info.drawable,
-                                 info->info.screen,
-                                info->info.visual,
-                                info->info.colormap,
-                                info->info.depth,
-                                e->output.w,
-                                e->output.h,
-                                 info->indirect,
-                                 info->info.destination_alpha,
-                                 info->info.rotation);
+        re->w = e->output.w;
+        re->h = e->output.h;
+       re->win = eng_window_new(re->info->info.display,
+                                re->info->info.drawable,
+                                 re->info->info.screen,
+                                re->info->info.visual,
+                                re->info->info.colormap,
+                                re->info->info.depth,
+                                 re->w,
+                                 re->h,
+                                 re->info->indirect,
+                                 re->info->info.destination_alpha,
+                                 re->info->info.rotation);
        if (!re->win)
          {
             free(re);
@@ -252,7 +275,7 @@ eng_setup(Evas *e, void *in)
             status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
             if ((!status) || (!type))
               {
-                 if (!re->xrdb) re->xrdb = XrmGetDatabase(info->info.display);
+                 if (!re->xrdb) re->xrdb = XrmGetDatabase(re->info->info.display);
                  if (re->xrdb)
                    status = XrmGetResource(re->xrdb,
                                            "Xft.dpi", "Xft.Dpi", &type, &val);
@@ -316,48 +339,54 @@ eng_setup(Evas *e, void *in)
    else
      {
        re = e->engine.data.output;
-        if ((info->info.display != re->win->disp) ||
-            (info->info.drawable != re->win->win) ||
-            (info->info.screen != re->win->screen) ||
-            (info->info.visual != re->win->visual) ||
-            (info->info.colormap != re->win->colormap) ||
-            (info->info.depth != re->win->depth) ||
-            (info->info.destination_alpha != re->win->alpha) ||
-            (info->info.rotation != re->win->rot))
+        if (_re_wincheck(re))
           {
-             int inc = 0;
-             
-             if (re->win)
+             if ((re->info->info.display != re->win->disp) ||
+                 (re->info->info.drawable != re->win->win) ||
+                 (re->info->info.screen != re->win->screen) ||
+                 (re->info->info.visual != re->win->visual) ||
+                 (re->info->info.colormap != re->win->colormap) ||
+                 (re->info->info.depth != re->win->depth) ||
+                 (re->info->info.destination_alpha != re->win->alpha) ||
+                 (re->info->info.rotation != re->win->rot))
                {
-                  re->win->gl_context->references++;
-                  eng_window_free(re->win);
-                  inc = 1;
-                  gl_wins--;
+                  int inc = 0;
+                  
+                  if (re->win)
+                    {
+                       re->win->gl_context->references++;
+                       eng_window_free(re->win);
+                       inc = 1;
+                       gl_wins--;
+                    }
+                  re->w = e->output.w;
+                  re->h = e->output.h;
+                  re->win = eng_window_new(re->info->info.display,
+                                           re->info->info.drawable,
+                                           re->info->info.screen,
+                                           re->info->info.visual,
+                                           re->info->info.colormap,
+                                           re->info->info.depth,
+                                           re->w,
+                                           re->h,
+                                           re->info->indirect,
+                                           re->info->info.destination_alpha,
+                                           re->info->info.rotation);
+                  if (re->win) gl_wins++;
+                  if ((re->win) && (inc))
+                     re->win->gl_context->references--;
+               }
+             else if ((re->win->w != e->output.w) ||
+                      (re->win->h != e->output.h))
+               {
+                  re->w = e->output.w;
+                  re->h = e->output.h;
+                  re->win->w = e->output.w;
+                  re->win->h = e->output.h;
+                  eng_window_use(re->win);
+                  evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
                }
-             re->win = eng_window_new(info->info.display,
-                                      info->info.drawable,
-                                      info->info.screen,
-                                      info->info.visual,
-                                      info->info.colormap,
-                                      info->info.depth,
-                                      e->output.w,
-                                      e->output.h,
-                                      info->indirect,
-                                      info->info.destination_alpha,
-                                      info->info.rotation);
-             if (re->win) gl_wins++;
-             if ((re->win) && (inc))
-                re->win->gl_context->references--;
-          }
-        else if ((re->win->w != e->output.w) ||
-                 (re->win->h != e->output.h))
-          {
-             re->win->w = e->output.w;
-             re->win->h = e->output.h;
-             eng_window_use(re->win);
-             evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
           }
-        
      }
    if (!re->win)
      {
@@ -501,6 +530,7 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i
    re = (Render_Engine *)data;
    /* get the upate rect surface - return engine data as dummy */
    if (!re->win->draw.redraw) return NULL;
+   if (!_re_wincheck(re)) return NULL;
    evas_gl_common_context_flush(re->win->gl_context);
    eng_window_use(re->win);
    evas_gl_common_context_newframe(re->win->gl_context);
@@ -539,6 +569,7 @@ eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x
    
    re = (Render_Engine *)data;
    /* put back update surface.. in this case just unflag redraw */
+   if (!_re_wincheck(re)) return;
    re->win->draw.redraw = 0;
    re->win->draw.drew = 1;
    evas_gl_common_context_flush(re->win->gl_context);
@@ -572,6 +603,7 @@ eng_output_flush(void *data)
    Render_Engine *re;
 
    re = (Render_Engine *)data;
+   if (!_re_wincheck(re)) return;
    if (!re->win->draw.drew) return;
 //x//   printf("frame -> flush\n");
    re->win->draw.drew = 0;
@@ -674,6 +706,7 @@ eng_output_dump(void *data)
    evas_common_image_image_all_unload();
    evas_common_font_font_all_unload();
    evas_gl_common_image_all_unload(re->win->gl_context);
+   _re_winfree(re);
 }
 
 static void
@@ -1062,6 +1095,7 @@ eng_image_native_set(void *data, void *image, void *native)
    uint32_t pmid;
    
    if (!im) return NULL;
+   
    if (ns)
      {
         vis = ns->data.x11.visual;
@@ -1337,9 +1371,6 @@ eng_image_free(void *data, void *image)
 static void
 eng_image_size_get(void *data, void *image, int *w, int *h)
 {
-//   Render_Engine *re;
-//
-//   re = (Render_Engine *)data;
    if (!image)
      {
        *w = 0;
index b83dc87..715676f 100644 (file)
@@ -108,7 +108,7 @@ struct _Evas_GL_X11_Window
       unsigned int loose_binding : 1;
    } detected;
 #endif
-
+   int             surf : 1;
 };
 
 Evas_GL_X11_Window *eng_window_new(Display *disp, Window win, int screen,
@@ -117,6 +117,9 @@ Evas_GL_X11_Window *eng_window_new(Display *disp, Window win, int screen,
                                    int alpha, int rot);
 void      eng_window_free(Evas_GL_X11_Window *gw);
 void      eng_window_use(Evas_GL_X11_Window *gw);
+void      eng_window_unsurf(Evas_GL_X11_Window *gw);
+void      eng_window_resurf(Evas_GL_X11_Window *gw);
+
 Visual   *eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo);
 Colormap  eng_best_colormap_get(Evas_Engine_Info_GL_X11 *einfo);
 int       eng_best_depth_get(Evas_Engine_Info_GL_X11 *einfo);
index cbe1a98..03fe725 100644 (file)
@@ -59,7 +59,7 @@ eng_window_new(Display *disp,
    gw->rot = rot;
 
    vi_use = _evas_gl_x11_vi;
-   if (alpha)
+   if (gw->alpha)
      {
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
         if (_evas_gl_x11_rgba_vi)
@@ -135,7 +135,7 @@ eng_window_new(Display *disp,
    config_attrs[n++] = 1;
 // FIXME: end n900 breakage   
 #endif
-   if (alpha)
+   if (gw->alpha)
      {
         config_attrs[n++] = EGL_ALPHA_SIZE;
         config_attrs[n++] = 1;
@@ -222,38 +222,38 @@ eng_window_new(Display *disp,
      {
 #ifdef NEWGL        
         if (indirect)
-          context = glXCreateNewContext(disp, fbconf, 
+          context = glXCreateNewContext(gw->disp, fbconf, 
                                         GLX_RGBA_TYPE, NULL, 
                                         GL_TRUE);
         else
-          context = glXCreateNewContext(disp, fbconf, 
+          context = glXCreateNewContext(gw->disp, fbconf, 
                                         GLX_RGBA_TYPE, NULL, 
                                         GL_FALSE);
 #else
         if (indirect)
-          context = glXCreateContext(disp, gw->visualinfo, NULL, GL_FALSE);
+          context = glXCreateContext(gw->disp, gw->visualinfo, NULL, GL_FALSE);
         else
-          context = glXCreateContext(disp, gw->visualinfo, NULL, GL_TRUE);
+          context = glXCreateContext(gw->disp, gw->visualinfo, NULL, GL_TRUE);
 #endif
      }
 #ifdef NEWGL
-   if ((alpha) && (!rgba_context))
+   if ((gw->alpha) && (!rgba_context))
      {
         if (indirect)
-          rgba_context = glXCreateNewContext(disp, rgba_fbconf, 
+          rgba_context = glXCreateNewContext(gw->disp, rgba_fbconf, 
                                              GLX_RGBA_TYPE, context, 
                                              GL_TRUE);
         else
-          rgba_context = glXCreateNewContext(disp, rgba_fbconf, 
+          rgba_context = glXCreateNewContext(gw->disp, rgba_fbconf, 
                                              GLX_RGBA_TYPE, context, 
                                              GL_FALSE);
      }
-   if (alpha)
-     gw->glxwin = glXCreateWindow(disp, rgba_fbconf, gw->win, NULL);
+   if (gw->alpha)
+     gw->glxwin = glXCreateWindow(gw->disp, rgba_fbconf, gw->win, NULL);
    else
-     gw->glxwin = glXCreateWindow(disp, fbconf, gw->win, NULL);
+     gw->glxwin = glXCreateWindow(gw->disp, fbconf, gw->win, NULL);
    
-   if (alpha) gw->context = rgba_context;
+   if (gw->alpha) gw->context = rgba_context;
    else gw->context = context;
 #else   
    gw->context = context;
@@ -311,7 +311,7 @@ eng_window_new(Display *disp,
              // noothing yet. add more cases and options over time
           }
         
-        fbc = glXGetFBConfigs(disp, screen, &num);
+        fbc = glXGetFBConfigs(gw->disp, screen, &num);
         if (!fbc)
           {
              printf("Error: glXGetFBConfigs() returned no fb configs\n");
@@ -322,27 +322,27 @@ eng_window_new(Display *disp,
                {
                   XVisualInfo *vi;
                   int vd;
-                  int alpha, val, dbuf, stencil, depth;
+                  int alph, val, dbuf, stencil, depth;
                   int rgba;
                   
-                  vi = glXGetVisualFromFBConfig(disp, fbc[j]);
+                  vi = glXGetVisualFromFBConfig(gw->disp, fbc[j]);
                   if (!vi) continue;
                   vd = vi->depth;
                   XFree(vi);
                   
                   if (vd != i) continue;
                   
-                  glXGetFBConfigAttrib(disp, fbc[j], GLX_ALPHA_SIZE, &alpha);
-                  glXGetFBConfigAttrib(disp, fbc[j], GLX_BUFFER_SIZE, &val);
+                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_ALPHA_SIZE, &alph);
+                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BUFFER_SIZE, &val);
                   
-                  if ((val != i) && ((val - alpha) != i)) continue;
+                  if ((val != i) && ((val - alph) != i)) continue;
                   
                   val = 0;
                   rgba = 0;
                   
                   if (i == 32)
                     {
-                       glXGetFBConfigAttrib(disp, fbc[j], GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
+                       glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
                        if (val)
                          {
                             rgba = 1;
@@ -352,41 +352,41 @@ eng_window_new(Display *disp,
                   if (!val)
                     {
                        if (rgba) continue;
-                       glXGetFBConfigAttrib(disp, fbc[j], GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
+                       glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
                        if (!val) continue;
                        gw->depth_cfg[i].tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
                     }
                   
                   dbuf = 0x7fff;
-                  glXGetFBConfigAttrib(disp, fbc[j], GLX_DOUBLEBUFFER, &val);
+                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_DOUBLEBUFFER, &val);
                   if (val > dbuf) continue;
                   dbuf = val;
                   
                   stencil = 0x7fff;
-                  glXGetFBConfigAttrib(disp, fbc[j], GLX_STENCIL_SIZE, &val);
+                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_STENCIL_SIZE, &val);
                   if (val > stencil) continue;
                   stencil = val;
                   
                   depth = 0x7fff;
-                  glXGetFBConfigAttrib(disp, fbc[j], GLX_DEPTH_SIZE, &val);
+                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_DEPTH_SIZE, &val);
                   if (val > depth) continue;
                   depth = val;
                   
-                  glXGetFBConfigAttrib(disp, fbc[j], GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
+                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
                   if (val < 0) continue;
                   gw->depth_cfg[i].mipmap = val;
                   
-                  glXGetFBConfigAttrib(disp, fbc[j], GLX_Y_INVERTED_EXT, &val);
+                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_Y_INVERTED_EXT, &val);
                   gw->depth_cfg[i].yinvert = val;
                   
-                  glXGetFBConfigAttrib(disp, fbc[j], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &val);
+                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &val);
                   gw->depth_cfg[i].tex_target = val;
                   
                   gw->depth_cfg[i].fbc = fbc[j];
                }
           }
         XFree(fbc);
-        if (!gw->depth_cfg[DefaultDepth(disp, screen)].fbc)
+        if (!gw->depth_cfg[DefaultDepth(gw->disp, screen)].fbc)
           {
              printf("texture from pixmap not going to work\n");
           }
@@ -406,6 +406,7 @@ eng_window_new(Display *disp,
    evas_gl_common_context_use(gw->gl_context);
    evas_gl_common_context_resize(gw->gl_context, w, h, rot);
    win_count++;
+   gw->surf = 1;
    return gw;
 }
 
@@ -485,6 +486,50 @@ eng_window_use(Evas_GL_X11_Window *gw)
    evas_gl_common_context_use(gw->gl_context);
 }
 
+void
+eng_window_unsurf(Evas_GL_X11_Window *gw)
+{
+   if (!gw->surf) return;
+   if (getenv("EVAS_GL_INFO"))
+      printf("unsurf %p\n", gw);
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   if (gw->egl_surface[0] != EGL_NO_SURFACE)
+     eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
+   gw->egl_surface[0] = EGL_NO_SURFACE;
+   eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+#else
+   if (gw->glxwin) glXDestroyWindow(gw->disp, gw->glxwin);
+#endif
+   gw->surf = 0;
+}
+
+void
+eng_window_resurf(Evas_GL_X11_Window *gw)
+{
+   if (gw->surf) return;
+   if (getenv("EVAS_GL_INFO"))
+      printf("resurf %p\n", gw);
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
+                                               (EGLNativeWindowType)gw->win,
+                                               NULL);
+   if (gw->egl_surface[0] == EGL_NO_SURFACE)
+     {
+        printf("Error: eglCreateWindowSurface() fail for 0x%x.\n", (unsigned int)gw->win);
+        printf("Error: error # was: 0x%x\n", eglGetError());
+        return;
+     }
+#else
+#ifdef NEWGL
+   if (gw->alpha)
+     gw->glxwin = glXCreateWindow(gw->disp, rgba_fbconf, gw->win, NULL);
+   else
+     gw->glxwin = glXCreateWindow(gw->disp, fbconf, gw->win, NULL);
+#endif   
+#endif   
+   gw->surf = 1;
+}
+
 Visual *
 eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
 {