forked from enlightenment/efl
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 <jp.andre@samsung.com>
This commit is contained in:
parent
437ae4a3d3
commit
f83ce20e1c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue