jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=f83ce20e1c72c3a645553feeea640e0c4b69e6c1

commit f83ce20e1c72c3a645553feeea640e0c4b69e6c1
Author: Youngbok Shin <[email protected]>
Date:   Wed Mar 8 19:33:15 2017 +0900

    evas: clean up GL images for emojis when GL context is free'd
    
    If GL context is free'd before processing font shutdown,
    textures for emoji glyph's GL images will be free'd without clean
    up its GL images. It causes eina mempool infinite loop issue when
    emoji's GL images are free'd in shutdown process.
    
    So, the patch will make a list for emoji's GL images in context and
    clean up them when the context is free'd. Just like font textures in
    context.
    
    @fix
    
    Differential Revision: https://phab.enlightenment.org/D4695
    
    Signed-off-by: Jean-Philippe Andre <[email protected]>
---
 src/lib/evas/common/evas_draw.h                    |  4 +--
 src/lib/evas/common/evas_draw_main.c               |  6 ++--
 src/lib/evas/common/evas_font_draw.c               | 10 +++---
 src/lib/evas/include/evas_common_private.h         |  4 +--
 .../evas/engines/gl_common/evas_gl_common.h        |  8 +++--
 .../evas/engines/gl_common/evas_gl_context.c       |  3 ++
 src/modules/evas/engines/gl_common/evas_gl_font.c  | 41 ++++++++++++++++++++++
 src/modules/evas/engines/gl_common/evas_gl_image.c | 34 +++++-------------
 src/modules/evas/engines/gl_generic/evas_engine.c  |  6 ++--
 9 files changed, 71 insertions(+), 45 deletions(-)

diff --git a/src/lib/evas/common/evas_draw.h b/src/lib/evas/common/evas_draw.h
index 6323e8d..28b7c94 100644
--- a/src/lib/evas/common/evas_draw.h
+++ b/src/lib/evas/common/evas_draw.h
@@ -12,9 +12,9 @@ EAPI void               evas_common_draw_context_font_ext_set 
           (RGBA_D
                                                                           void 
*(*gl_new)  (void *data, RGBA_Font_Glyph *fg),
                                                                           void 
 (*gl_free) (void *ext_dat),
                                                                           void 
 (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, 
int y),
-                                                                          void 
*(*gl_image_new_from_data) (void *gc, unsigned int w, unsigned int h, DATA32 
*image_data, int alpha, Evas_Colorspace cspace),
+                                                                          void 
*(*gl_image_new) (void *gc, RGBA_Font_Glyph *fg, int alpha, Evas_Colorspace 
cspace),
                                                                           void 
 (*gl_image_free) (void *image),
-                                                                          void 
 (*gl_image_draw) (void *gc, void *im, int sx, int sy, int sw, int sh, int dx, 
int dy, int dw, int dh, int smooth));
+                                                                          void 
 (*gl_image_draw) (void *gc, void *im, int dx, int dy, int dw, int dh, int 
smooth));
 EAPI void               evas_common_draw_context_clip_clip               
(RGBA_Draw_Context *dc, int x, int y, int w, int h);
 EAPI void               evas_common_draw_context_set_clip                
(RGBA_Draw_Context *dc, int x, int y, int w, int h);
 EAPI void               evas_common_draw_context_unset_clip              
(RGBA_Draw_Context *dc);
diff --git a/src/lib/evas/common/evas_draw_main.c 
b/src/lib/evas/common/evas_draw_main.c
index d7c26c7..d6b0a89 100644
--- a/src/lib/evas/common/evas_draw_main.c
+++ b/src/lib/evas/common/evas_draw_main.c
@@ -216,15 +216,15 @@ evas_common_draw_context_font_ext_set(RGBA_Draw_Context 
*dc,
                                       void *(*gl_new)  (void *data, 
RGBA_Font_Glyph *fg),
                                       void  (*gl_free) (void *ext_dat),
                                       void  (*gl_draw) (void *data, void 
*dest, void *context, RGBA_Font_Glyph *fg, int x, int y),
-                                      void *(*gl_image_new_from_data) (void 
*gc, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, 
Evas_Colorspace cspace),
+                                      void *(*gl_image_new) (void *gc, 
RGBA_Font_Glyph *fg, int alpha, Evas_Colorspace cspace),
                                       void  (*gl_image_free) (void *image),
-                                      void  (*gl_image_draw) (void *gc, void 
*im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int 
smooth))
+                                      void  (*gl_image_draw) (void *gc, void 
*im, int dx, int dy, int dw, int dh, int smooth))
 {
    dc->font_ext.data = data;
    dc->font_ext.func.gl_new = gl_new;
    dc->font_ext.func.gl_free = gl_free;
    dc->font_ext.func.gl_draw = gl_draw;
-   dc->font_ext.func.gl_image_new_from_data = gl_image_new_from_data;
+   dc->font_ext.func.gl_image_new = gl_image_new;
    dc->font_ext.func.gl_image_free = gl_image_free;
    dc->font_ext.func.gl_image_draw = gl_image_draw;
 }
diff --git a/src/lib/evas/common/evas_font_draw.c 
b/src/lib/evas/common/evas_font_draw.c
index b4b0a99..f7fcb13 100644
--- a/src/lib/evas/common/evas_font_draw.c
+++ b/src/lib/evas/common/evas_font_draw.c
@@ -123,13 +123,11 @@ evas_common_font_rgba_draw(RGBA_Image *dst, 
RGBA_Draw_Context *dc, int x, int y,
 
         if ((!fg->ext_dat) && FT_HAS_COLOR(fg->fi->src->ft.face))
           {
-             if (dc->font_ext.func.gl_image_new_from_data)
+             if (dc->font_ext.func.gl_image_new)
                {
                   /* extension calls */
-                  fg->ext_dat = dc->font_ext.func.gl_image_new_from_data
-                    (dc->font_ext.data, (unsigned int)w, (unsigned int)h,
-                     (DATA32 *)fg->glyph_out->bitmap.buffer, EINA_TRUE,
-                     EVAS_COLORSPACE_ARGB8888);
+                  fg->ext_dat = dc->font_ext.func.gl_image_new
+                    (dc->font_ext.data, fg, EINA_TRUE, 
EVAS_COLORSPACE_ARGB8888);
                   fg->ext_dat_free = dc->font_ext.func.gl_image_free;
                }
              else
@@ -163,7 +161,7 @@ evas_common_font_rgba_draw(RGBA_Image *dst, 
RGBA_Draw_Context *dc, int x, int y,
                     {
                        if (dc->font_ext.func.gl_image_draw)
                          dc->font_ext.func.gl_image_draw
-                           (dc->font_ext.data, fg->ext_dat, 0, 0, w, h,
+                           (dc->font_ext.data, fg->ext_dat,
                             chr_x, y - (chr_y - y), w, h, EINA_TRUE);
                        else
                          _evas_font_image_draw
diff --git a/src/lib/evas/include/evas_common_private.h 
b/src/lib/evas/include/evas_common_private.h
index f576fc3..0da1e32 100644
--- a/src/lib/evas/include/evas_common_private.h
+++ b/src/lib/evas/include/evas_common_private.h
@@ -748,9 +748,9 @@ struct _RGBA_Draw_Context
          void *(*gl_new)  (void *data, RGBA_Font_Glyph *fg);
          void  (*gl_free) (void *ext_dat);
          void  (*gl_draw) (void *data, void *dest, void *context, 
RGBA_Font_Glyph *fg, int x, int y);
-         void *(*gl_image_new_from_data) (void *gc, unsigned int w, unsigned 
int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace);
+         void *(*gl_image_new) (void *gc, RGBA_Font_Glyph *fg, int alpha, 
Evas_Colorspace cspace);
          void  (*gl_image_free) (void *image);
-         void  (*gl_image_draw) (void *gc, void *im, int sx, int sy, int sw, 
int sh, int dx, int dy, int dw, int dh, int smooth);
+         void  (*gl_image_draw) (void *gc, void *im, int dx, int dy, int dw, 
int dh, int smooth);
       } func;
       void *data;
    } font_ext;
diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h 
b/src/modules/evas/engines/gl_common/evas_gl_common.h
index d78c21a..ef91f7b 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -331,6 +331,7 @@ struct _Evas_Engine_GL_Context
    } pipe[MAX_PIPES];
 
    Eina_List     *font_glyph_textures;
+   Eina_List     *font_glyph_images;
    Evas_GL_Image *def_surface;
    RGBA_Image    *font_surface;
 
@@ -414,6 +415,7 @@ struct _Evas_GL_Image
    RGBA_Image             *im;
    Evas_GL_Texture        *tex;
    Evas_Image_Load_Opts    load_opts;
+   RGBA_Font_Glyph        *fglyph;
    int                     references;
    // if im->im == NULL, it's a render-surface so these here are used
    int                     w, h;
@@ -690,9 +692,9 @@ void              
evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_
 void             *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg);
 void              evas_gl_font_texture_free(void *);
 void              evas_gl_font_texture_draw(void *gc, void *surface, void *dc, 
RGBA_Font_Glyph *fg, int x, int y);
-void             *evas_gl_image_new_from_data(void *gc, unsigned int w, 
unsigned int h, DATA32 *data, int alpha, Evas_Colorspace cspace);
-void              evas_gl_image_free(void *im);
-void              evas_gl_image_draw(void *gc, void *im, int sx, int sy, int 
sw, int sh, int dx, int dy, int dw, int dh, int smooth);
+void             *evas_gl_font_image_new(void *gc, RGBA_Font_Glyph *fg, int 
alpha, Evas_Colorspace cspace);
+void              evas_gl_font_image_free(void *im);
+void              evas_gl_font_image_draw(void *gc, void *im, int dx, int dy, 
int dw, int dh, int smooth);
 
 Evas_GL_Polygon  *evas_gl_common_poly_point_add(Evas_GL_Polygon *poly, int x, 
int y);
 Evas_GL_Polygon  *evas_gl_common_poly_points_clear(Evas_GL_Polygon *poly);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c 
b/src/modules/evas/engines/gl_common/evas_gl_context.c
index 45ea677..cc70c2b 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -1386,6 +1386,9 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
    while (gc->font_glyph_textures)
      evas_gl_common_texture_free(gc->font_glyph_textures->data, EINA_TRUE);
 
+   while (gc->font_glyph_images)
+     evas_gl_common_image_free(gc->font_glyph_images->data);
+
    if ((gc->shared) && (gc->shared->references == 0))
      {
         Evas_GL_Texture_Pool *pt;
diff --git a/src/modules/evas/engines/gl_common/evas_gl_font.c 
b/src/modules/evas/engines/gl_common/evas_gl_font.c
index 968168d..5a5fdeb 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_font.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_font.c
@@ -185,3 +185,44 @@ evas_gl_font_texture_draw(void *context, void *surface 
EINA_UNUSED, void *draw_c
    /* restore clip info */
    gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; 
gc->dc->clip.w = cw; gc->dc->clip.h = ch;
 }
+
+void *
+evas_gl_font_image_new(void *gc, RGBA_Font_Glyph *fg, int alpha, 
Evas_Colorspace cspace)
+{
+   Evas_Engine_GL_Context *context = (Evas_Engine_GL_Context *)gc;
+   Evas_GL_Image *im = evas_gl_common_image_new_from_data(context,
+                                                          (unsigned 
int)fg->glyph_out->bitmap.width,
+                                                          (unsigned 
int)fg->glyph_out->bitmap.rows,
+                                                          (DATA32 
*)fg->glyph_out->bitmap.buffer,
+                                                          alpha,
+                                                          cspace);
+
+   if (im)
+     {
+        im->fglyph = fg;
+        context->font_glyph_images = 
eina_list_append(context->font_glyph_images, im);
+     }
+
+   return (void *)im;
+}
+
+void
+evas_gl_font_image_free(void *im)
+{
+   evas_gl_common_image_free((Evas_GL_Image *)im);
+}
+
+void
+evas_gl_font_image_draw(void *gc, void *gl_image, int dx, int dy, int dw, int 
dh, int smooth)
+{
+   Evas_GL_Image *im = (Evas_GL_Image *)gl_image;
+
+   if (!im || !im->fglyph) return;
+
+   evas_gl_common_image_draw((Evas_Engine_GL_Context *)gc,
+                             im, 0, 0,
+                             (unsigned int)im->fglyph->glyph_out->bitmap.width,
+                             (unsigned int)im->fglyph->glyph_out->bitmap.rows,
+                             dx, dy, dw, dh,
+                             smooth);
+}
diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c 
b/src/modules/evas/engines/gl_common/evas_gl_image.c
index bfbef7b..3b02db1 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_image.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_image.c
@@ -766,6 +766,14 @@ evas_gl_common_image_free(Evas_GL_Image *im)
 {
    im->references--;
    if (im->references > 0) return;
+
+   if (im->fglyph)
+     {
+        im->gc->font_glyph_images = 
eina_list_remove(im->gc->font_glyph_images, im);
+        im->fglyph->ext_dat = NULL;
+        im->fglyph->ext_dat_free = NULL;
+     }
+
    evas_gl_common_context_flush(im->gc);
 
    evas_gl_common_image_preload_unwatch(im);
@@ -1355,29 +1363,3 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, 
Evas_GL_Image *im, int sx,
    /* restore clip info */
    gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; 
gc->dc->clip.w = cw; gc->dc->clip.h = ch;
 }
-
-void *
-evas_gl_image_new_from_data(void *gc, unsigned int w, unsigned int h, DATA32 
*data, int alpha, Evas_Colorspace cspace)
-{
-   return (void *)evas_gl_common_image_new_from_data((Evas_Engine_GL_Context 
*)gc,
-                                                     w, h,
-                                                     data,
-                                                     alpha,
-                                                     cspace);
-}
-
-void
-evas_gl_image_free(void *im)
-{
-   evas_gl_common_image_free((Evas_GL_Image *)im);
-}
-
-void
-evas_gl_image_draw(void *gc, void *im, int sx, int sy, int sw, int sh, int dx, 
int dy, int dw, int dh, int smooth)
-{
-   evas_gl_common_image_draw((Evas_Engine_GL_Context *)gc,
-                             (Evas_GL_Image *)im,
-                             sx, sy, sw, sh,
-                             dx, dy, dw, dh,
-                             smooth);
-}
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c 
b/src/modules/evas/engines/gl_generic/evas_engine.c
index 4fdcced..5f97c36 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -1532,9 +1532,9 @@ eng_font_draw(void *data, void *context, void *surface, 
Evas_Font_Set *font EINA
                                               evas_gl_font_texture_new,
                                               evas_gl_font_texture_free,
                                               evas_gl_font_texture_draw,
-                                              evas_gl_image_new_from_data,
-                                              evas_gl_image_free,
-                                              evas_gl_image_draw);
+                                              evas_gl_font_image_new,
+                                              evas_gl_font_image_free,
+                                              evas_gl_font_image_draw);
         evas_common_font_draw_prepare(intl_props);
         evas_common_font_draw(gl_context->font_surface, context, x, y, 
intl_props->glyphs);
         evas_common_draw_context_font_ext_set(context,

-- 


Reply via email to