diff options
author | Youngbok Shin <youngb.shin@samsung.com> | 2017-03-08 19:33:15 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2017-03-08 19:35:03 +0900 |
commit | f83ce20e1c72c3a645553feeea640e0c4b69e6c1 (patch) | |
tree | 50e5634b68cfd67d5f7ecee92616750f50ef65c0 | |
parent | 437ae4a3d3b0d00a279fb93f4341c9205d785c36 (diff) |
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>
-rw-r--r-- | src/lib/evas/common/evas_draw.h | 4 | ||||
-rw-r--r-- | src/lib/evas/common/evas_draw_main.c | 6 | ||||
-rw-r--r-- | src/lib/evas/common/evas_font_draw.c | 10 | ||||
-rw-r--r-- | src/lib/evas/include/evas_common_private.h | 4 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_common.h | 8 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_context.c | 3 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_font.c | 41 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_image.c | 34 | ||||
-rw-r--r-- | 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 6323e8d674..28b7c9429f 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 | |||
12 | void *(*gl_new) (void *data, RGBA_Font_Glyph *fg), | 12 | void *(*gl_new) (void *data, RGBA_Font_Glyph *fg), |
13 | void (*gl_free) (void *ext_dat), | 13 | void (*gl_free) (void *ext_dat), |
14 | void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y), | 14 | void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y), |
15 | void *(*gl_image_new_from_data) (void *gc, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace), | 15 | void *(*gl_image_new) (void *gc, RGBA_Font_Glyph *fg, int alpha, Evas_Colorspace cspace), |
16 | void (*gl_image_free) (void *image), | 16 | void (*gl_image_free) (void *image), |
17 | 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)); | 17 | void (*gl_image_draw) (void *gc, void *im, int dx, int dy, int dw, int dh, int smooth)); |
18 | EAPI void evas_common_draw_context_clip_clip (RGBA_Draw_Context *dc, int x, int y, int w, int h); | 18 | EAPI void evas_common_draw_context_clip_clip (RGBA_Draw_Context *dc, int x, int y, int w, int h); |
19 | EAPI void evas_common_draw_context_set_clip (RGBA_Draw_Context *dc, int x, int y, int w, int h); | 19 | EAPI void evas_common_draw_context_set_clip (RGBA_Draw_Context *dc, int x, int y, int w, int h); |
20 | EAPI void evas_common_draw_context_unset_clip (RGBA_Draw_Context *dc); | 20 | 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 d7c26c73f5..d6b0a8942b 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, | |||
216 | void *(*gl_new) (void *data, RGBA_Font_Glyph *fg), | 216 | void *(*gl_new) (void *data, RGBA_Font_Glyph *fg), |
217 | void (*gl_free) (void *ext_dat), | 217 | void (*gl_free) (void *ext_dat), |
218 | void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y), | 218 | void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y), |
219 | void *(*gl_image_new_from_data) (void *gc, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace), | 219 | void *(*gl_image_new) (void *gc, RGBA_Font_Glyph *fg, int alpha, Evas_Colorspace cspace), |
220 | void (*gl_image_free) (void *image), | 220 | void (*gl_image_free) (void *image), |
221 | 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)) | 221 | void (*gl_image_draw) (void *gc, void *im, int dx, int dy, int dw, int dh, int smooth)) |
222 | { | 222 | { |
223 | dc->font_ext.data = data; | 223 | dc->font_ext.data = data; |
224 | dc->font_ext.func.gl_new = gl_new; | 224 | dc->font_ext.func.gl_new = gl_new; |
225 | dc->font_ext.func.gl_free = gl_free; | 225 | dc->font_ext.func.gl_free = gl_free; |
226 | dc->font_ext.func.gl_draw = gl_draw; | 226 | dc->font_ext.func.gl_draw = gl_draw; |
227 | dc->font_ext.func.gl_image_new_from_data = gl_image_new_from_data; | 227 | dc->font_ext.func.gl_image_new = gl_image_new; |
228 | dc->font_ext.func.gl_image_free = gl_image_free; | 228 | dc->font_ext.func.gl_image_free = gl_image_free; |
229 | dc->font_ext.func.gl_image_draw = gl_image_draw; | 229 | dc->font_ext.func.gl_image_draw = gl_image_draw; |
230 | } | 230 | } |
diff --git a/src/lib/evas/common/evas_font_draw.c b/src/lib/evas/common/evas_font_draw.c index b4b0a994d9..f7fcb13bd8 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, | |||
123 | 123 | ||
124 | if ((!fg->ext_dat) && FT_HAS_COLOR(fg->fi->src->ft.face)) | 124 | if ((!fg->ext_dat) && FT_HAS_COLOR(fg->fi->src->ft.face)) |
125 | { | 125 | { |
126 | if (dc->font_ext.func.gl_image_new_from_data) | 126 | if (dc->font_ext.func.gl_image_new) |
127 | { | 127 | { |
128 | /* extension calls */ | 128 | /* extension calls */ |
129 | fg->ext_dat = dc->font_ext.func.gl_image_new_from_data | 129 | fg->ext_dat = dc->font_ext.func.gl_image_new |
130 | (dc->font_ext.data, (unsigned int)w, (unsigned int)h, | 130 | (dc->font_ext.data, fg, EINA_TRUE, EVAS_COLORSPACE_ARGB8888); |
131 | (DATA32 *)fg->glyph_out->bitmap.buffer, EINA_TRUE, | ||
132 | EVAS_COLORSPACE_ARGB8888); | ||
133 | fg->ext_dat_free = dc->font_ext.func.gl_image_free; | 131 | fg->ext_dat_free = dc->font_ext.func.gl_image_free; |
134 | } | 132 | } |
135 | else | 133 | else |
@@ -163,7 +161,7 @@ evas_common_font_rgba_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, | |||
163 | { | 161 | { |
164 | if (dc->font_ext.func.gl_image_draw) | 162 | if (dc->font_ext.func.gl_image_draw) |
165 | dc->font_ext.func.gl_image_draw | 163 | dc->font_ext.func.gl_image_draw |
166 | (dc->font_ext.data, fg->ext_dat, 0, 0, w, h, | 164 | (dc->font_ext.data, fg->ext_dat, |
167 | chr_x, y - (chr_y - y), w, h, EINA_TRUE); | 165 | chr_x, y - (chr_y - y), w, h, EINA_TRUE); |
168 | else | 166 | else |
169 | _evas_font_image_draw | 167 | _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 f576fc3c49..0da1e3200c 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 | |||
748 | void *(*gl_new) (void *data, RGBA_Font_Glyph *fg); | 748 | void *(*gl_new) (void *data, RGBA_Font_Glyph *fg); |
749 | void (*gl_free) (void *ext_dat); | 749 | void (*gl_free) (void *ext_dat); |
750 | void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y); | 750 | void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y); |
751 | void *(*gl_image_new_from_data) (void *gc, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace); | 751 | void *(*gl_image_new) (void *gc, RGBA_Font_Glyph *fg, int alpha, Evas_Colorspace cspace); |
752 | void (*gl_image_free) (void *image); | 752 | void (*gl_image_free) (void *image); |
753 | 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); | 753 | void (*gl_image_draw) (void *gc, void *im, int dx, int dy, int dw, int dh, int smooth); |
754 | } func; | 754 | } func; |
755 | void *data; | 755 | void *data; |
756 | } font_ext; | 756 | } 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 d78c21a5b1..ef91f7b9d6 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 | |||
331 | } pipe[MAX_PIPES]; | 331 | } pipe[MAX_PIPES]; |
332 | 332 | ||
333 | Eina_List *font_glyph_textures; | 333 | Eina_List *font_glyph_textures; |
334 | Eina_List *font_glyph_images; | ||
334 | Evas_GL_Image *def_surface; | 335 | Evas_GL_Image *def_surface; |
335 | RGBA_Image *font_surface; | 336 | RGBA_Image *font_surface; |
336 | 337 | ||
@@ -414,6 +415,7 @@ struct _Evas_GL_Image | |||
414 | RGBA_Image *im; | 415 | RGBA_Image *im; |
415 | Evas_GL_Texture *tex; | 416 | Evas_GL_Texture *tex; |
416 | Evas_Image_Load_Opts load_opts; | 417 | Evas_Image_Load_Opts load_opts; |
418 | RGBA_Font_Glyph *fglyph; | ||
417 | int references; | 419 | int references; |
418 | // if im->im == NULL, it's a render-surface so these here are used | 420 | // if im->im == NULL, it's a render-surface so these here are used |
419 | int w, h; | 421 | int w, h; |
@@ -690,9 +692,9 @@ void evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_ | |||
690 | void *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg); | 692 | void *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg); |
691 | void evas_gl_font_texture_free(void *); | 693 | void evas_gl_font_texture_free(void *); |
692 | void evas_gl_font_texture_draw(void *gc, void *surface, void *dc, RGBA_Font_Glyph *fg, int x, int y); | 694 | void evas_gl_font_texture_draw(void *gc, void *surface, void *dc, RGBA_Font_Glyph *fg, int x, int y); |
693 | void *evas_gl_image_new_from_data(void *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, Evas_Colorspace cspace); | 695 | void *evas_gl_font_image_new(void *gc, RGBA_Font_Glyph *fg, int alpha, Evas_Colorspace cspace); |
694 | void evas_gl_image_free(void *im); | 696 | void evas_gl_font_image_free(void *im); |
695 | 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); | 697 | void evas_gl_font_image_draw(void *gc, void *im, int dx, int dy, int dw, int dh, int smooth); |
696 | 698 | ||
697 | Evas_GL_Polygon *evas_gl_common_poly_point_add(Evas_GL_Polygon *poly, int x, int y); | 699 | Evas_GL_Polygon *evas_gl_common_poly_point_add(Evas_GL_Polygon *poly, int x, int y); |
698 | Evas_GL_Polygon *evas_gl_common_poly_points_clear(Evas_GL_Polygon *poly); | 700 | 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 45ea67776b..cc70c2bfdc 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) | |||
1386 | while (gc->font_glyph_textures) | 1386 | while (gc->font_glyph_textures) |
1387 | evas_gl_common_texture_free(gc->font_glyph_textures->data, EINA_TRUE); | 1387 | evas_gl_common_texture_free(gc->font_glyph_textures->data, EINA_TRUE); |
1388 | 1388 | ||
1389 | while (gc->font_glyph_images) | ||
1390 | evas_gl_common_image_free(gc->font_glyph_images->data); | ||
1391 | |||
1389 | if ((gc->shared) && (gc->shared->references == 0)) | 1392 | if ((gc->shared) && (gc->shared->references == 0)) |
1390 | { | 1393 | { |
1391 | Evas_GL_Texture_Pool *pt; | 1394 | 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 968168d9b5..5a5fdeb730 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 | |||
185 | /* restore clip info */ | 185 | /* restore clip info */ |
186 | 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; | 186 | 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; |
187 | } | 187 | } |
188 | |||
189 | void * | ||
190 | evas_gl_font_image_new(void *gc, RGBA_Font_Glyph *fg, int alpha, Evas_Colorspace cspace) | ||
191 | { | ||
192 | Evas_Engine_GL_Context *context = (Evas_Engine_GL_Context *)gc; | ||
193 | Evas_GL_Image *im = evas_gl_common_image_new_from_data(context, | ||
194 | (unsigned int)fg->glyph_out->bitmap.width, | ||
195 | (unsigned int)fg->glyph_out->bitmap.rows, | ||
196 | (DATA32 *)fg->glyph_out->bitmap.buffer, | ||
197 | alpha, | ||
198 | cspace); | ||
199 | |||
200 | if (im) | ||
201 | { | ||
202 | im->fglyph = fg; | ||
203 | context->font_glyph_images = eina_list_append(context->font_glyph_images, im); | ||
204 | } | ||
205 | |||
206 | return (void *)im; | ||
207 | } | ||
208 | |||
209 | void | ||
210 | evas_gl_font_image_free(void *im) | ||
211 | { | ||
212 | evas_gl_common_image_free((Evas_GL_Image *)im); | ||
213 | } | ||
214 | |||
215 | void | ||
216 | evas_gl_font_image_draw(void *gc, void *gl_image, int dx, int dy, int dw, int dh, int smooth) | ||
217 | { | ||
218 | Evas_GL_Image *im = (Evas_GL_Image *)gl_image; | ||
219 | |||
220 | if (!im || !im->fglyph) return; | ||
221 | |||
222 | evas_gl_common_image_draw((Evas_Engine_GL_Context *)gc, | ||
223 | im, 0, 0, | ||
224 | (unsigned int)im->fglyph->glyph_out->bitmap.width, | ||
225 | (unsigned int)im->fglyph->glyph_out->bitmap.rows, | ||
226 | dx, dy, dw, dh, | ||
227 | smooth); | ||
228 | } | ||
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 bfbef7bc84..3b02db1406 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) | |||
766 | { | 766 | { |
767 | im->references--; | 767 | im->references--; |
768 | if (im->references > 0) return; | 768 | if (im->references > 0) return; |
769 | |||
770 | if (im->fglyph) | ||
771 | { | ||
772 | im->gc->font_glyph_images = eina_list_remove(im->gc->font_glyph_images, im); | ||
773 | im->fglyph->ext_dat = NULL; | ||
774 | im->fglyph->ext_dat_free = NULL; | ||
775 | } | ||
776 | |||
769 | evas_gl_common_context_flush(im->gc); | 777 | evas_gl_common_context_flush(im->gc); |
770 | 778 | ||
771 | evas_gl_common_image_preload_unwatch(im); | 779 | 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, | |||
1355 | /* restore clip info */ | 1363 | /* restore clip info */ |
1356 | 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; | 1364 | 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; |
1357 | } | 1365 | } |
1358 | |||
1359 | void * | ||
1360 | evas_gl_image_new_from_data(void *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, Evas_Colorspace cspace) | ||
1361 | { | ||
1362 | return (void *)evas_gl_common_image_new_from_data((Evas_Engine_GL_Context *)gc, | ||
1363 | w, h, | ||
1364 | data, | ||
1365 | alpha, | ||
1366 | cspace); | ||
1367 | } | ||
1368 | |||
1369 | void | ||
1370 | evas_gl_image_free(void *im) | ||
1371 | { | ||
1372 | evas_gl_common_image_free((Evas_GL_Image *)im); | ||
1373 | } | ||
1374 | |||
1375 | void | ||
1376 | 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) | ||
1377 | { | ||
1378 | evas_gl_common_image_draw((Evas_Engine_GL_Context *)gc, | ||
1379 | (Evas_GL_Image *)im, | ||
1380 | sx, sy, sw, sh, | ||
1381 | dx, dy, dw, dh, | ||
1382 | smooth); | ||
1383 | } | ||
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 4fdccedd18..5f97c36071 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 | |||
1532 | evas_gl_font_texture_new, | 1532 | evas_gl_font_texture_new, |
1533 | evas_gl_font_texture_free, | 1533 | evas_gl_font_texture_free, |
1534 | evas_gl_font_texture_draw, | 1534 | evas_gl_font_texture_draw, |
1535 | evas_gl_image_new_from_data, | 1535 | evas_gl_font_image_new, |
1536 | evas_gl_image_free, | 1536 | evas_gl_font_image_free, |
1537 | evas_gl_image_draw); | 1537 | evas_gl_font_image_draw); |
1538 | evas_common_font_draw_prepare(intl_props); | 1538 | evas_common_font_draw_prepare(intl_props); |
1539 | evas_common_font_draw(gl_context->font_surface, context, x, y, intl_props->glyphs); | 1539 | evas_common_font_draw(gl_context->font_surface, context, x, y, intl_props->glyphs); |
1540 | evas_common_draw_context_font_ext_set(context, | 1540 | evas_common_draw_context_font_ext_set(context, |