From efb72afbc15a557db61adaa6deb7156263fea248 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Thu, 26 Aug 2010 09:40:48 +0000 Subject: [PATCH] be able to free and alloc gl surface when asked to dump SVN revision: 51654 --- .../modules/engines/gl_common/evas_gl_image.c | 10 +- .../src/modules/engines/gl_x11/evas_engine.c | 137 +++++++++++------- .../src/modules/engines/gl_x11/evas_engine.h | 5 +- .../src/modules/engines/gl_x11/evas_x_main.c | 101 +++++++++---- 4 files changed, 169 insertions(+), 84 deletions(-) diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c index 4fca68558f..c9ebc758b2 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c @@ -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; + } + } } } diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c index bb4e1ce097..aab524c097 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c @@ -25,6 +25,8 @@ struct _Render_Engine struct { // xres - dpi int dpi; // xres - dpi } xr; // xres - dpi + + int w, h; }; static int initted = 0; @@ -203,6 +205,25 @@ eng_info_free(Evas *e __UNUSED__, void *info) free(in); } +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) { @@ -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; diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.h b/legacy/evas/src/modules/engines/gl_x11/evas_engine.h index b83dc871f4..715676fdef 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.h +++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.h @@ -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); diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_x_main.c b/legacy/evas/src/modules/engines/gl_x11/evas_x_main.c index cbe1a984ec..03fe72527b 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_x_main.c +++ b/legacy/evas/src/modules/engines/gl_x11/evas_x_main.c @@ -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) {