forked from enlightenment/efl
evas render - async sw - fix context duplication by using proper dup call
valgrind pointed this one out. we access freed memory when we dup a context because the context CONTAINS ptrs to things like rects for cutouts. we didnt dup these. use the proper context dup call (and properly ref pixman color image too). this was a random bug/crash waiting to happen and valgrind caught it. suprising it hasnt turned up before :/ @fix
This commit is contained in:
parent
82095adae4
commit
8a4ddea224
|
@ -107,6 +107,12 @@ evas_common_draw_context_dup(RGBA_Draw_Context *dc)
|
|||
dc2 = malloc(sizeof(RGBA_Draw_Context));
|
||||
memcpy(dc2, dc, sizeof(RGBA_Draw_Context));
|
||||
evas_common_draw_context_cutouts_dup(&dc2->cutout, &dc->cutout);
|
||||
#ifdef HAVE_PIXMAN
|
||||
#if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY)
|
||||
if (dc2->col.pixman_color_image)
|
||||
pixman_image_ref(dc2->col.pixman_color_image);
|
||||
#endif
|
||||
#endif
|
||||
return dc2;
|
||||
}
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ struct _Evas_Thread_Command_Font
|
|||
struct _Evas_Thread_Command_Map
|
||||
{
|
||||
void *image;
|
||||
RGBA_Draw_Context image_ctx;
|
||||
RGBA_Draw_Context *image_ctx;
|
||||
void *surface;
|
||||
Eina_Rectangle clip;
|
||||
DATA32 mul_col;
|
||||
|
@ -385,7 +385,7 @@ struct _Evas_Thread_Command_Map
|
|||
|
||||
struct _Evas_Thread_Command_Multi_Font
|
||||
{
|
||||
RGBA_Draw_Context context;
|
||||
RGBA_Draw_Context *context;
|
||||
void *surface;
|
||||
int x, y;
|
||||
Evas_Font_Array *texts;
|
||||
|
@ -2068,25 +2068,25 @@ _draw_thread_map_draw(void *data)
|
|||
dw = (m->pts[2 + offset].x >> FP) - dx;
|
||||
dh = (m->pts[2 + offset].y >> FP) - dy;
|
||||
|
||||
col = map->image_ctx.mul.col;
|
||||
use = map->image_ctx.mul.use;
|
||||
if (use) map->image_ctx.mul.col = MUL4_SYM(col, m->pts[0].col);
|
||||
else map->image_ctx.mul.col = m->pts[0].col;
|
||||
map->image_ctx.mul.use = 1;
|
||||
col = map->image_ctx->mul.col;
|
||||
use = map->image_ctx->mul.use;
|
||||
if (use) map->image_ctx->mul.col = MUL4_SYM(col, m->pts[0].col);
|
||||
else map->image_ctx->mul.col = m->pts[0].col;
|
||||
map->image_ctx->mul.use = 1;
|
||||
|
||||
if (map->smooth)
|
||||
evas_common_scale_rgba_in_to_out_clip_cb
|
||||
(im, map->surface, &map->image_ctx,
|
||||
(im, map->surface, map->image_ctx,
|
||||
0, 0, im->cache_entry.w, im->cache_entry.h,
|
||||
dx, dy, dw, dh, _map_image_smooth_draw);
|
||||
else
|
||||
evas_common_scale_rgba_in_to_out_clip_cb
|
||||
(im, map->surface, &map->image_ctx,
|
||||
(im, map->surface, map->image_ctx,
|
||||
0, 0, im->cache_entry.w, im->cache_entry.h,
|
||||
dx, dy, dw, dh, _map_image_sample_draw);
|
||||
|
||||
map->image_ctx.mul.col = col;
|
||||
map->image_ctx.mul.use = use;
|
||||
map->image_ctx->mul.col = col;
|
||||
map->image_ctx->mul.use = use;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2106,6 +2106,7 @@ _draw_thread_map_draw(void *data)
|
|||
|
||||
free_out:
|
||||
free(m);
|
||||
evas_common_draw_context_free(map->image_ctx);
|
||||
eina_mempool_free(_mp_command_map, map);
|
||||
}
|
||||
|
||||
|
@ -2119,7 +2120,7 @@ _map_draw_thread_cmd(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, RG
|
|||
if (!cm) return EINA_FALSE;
|
||||
|
||||
cm->image = src;
|
||||
memcpy(&cm->image_ctx, dc, sizeof(*dc));
|
||||
cm->image_ctx = evas_common_draw_context_dup(dc);
|
||||
cm->surface = dst;
|
||||
|
||||
if (dc->clip.use)
|
||||
|
@ -2402,11 +2403,12 @@ _draw_thread_multi_font_draw(void *data)
|
|||
b = itr->color.b;
|
||||
a = itr->color.a;
|
||||
|
||||
eng_context_color_set(NULL, &mf->context, r, g, b, a);
|
||||
evas_common_font_draw(mf->surface, &mf->context, x, y, itr->glyphs);
|
||||
eng_context_color_set(NULL, mf->context, r, g, b, a);
|
||||
evas_common_font_draw(mf->surface, mf->context, x, y, itr->glyphs);
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
|
||||
evas_common_draw_context_free(mf->context);
|
||||
eina_mempool_free(_mp_command_multi_font, mf);
|
||||
}
|
||||
|
||||
|
@ -2424,7 +2426,7 @@ _multi_font_draw_thread_cmd(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
memcpy(&mf->context, dc, sizeof(*dc));
|
||||
mf->context = evas_common_draw_context_dup(dc);
|
||||
mf->surface = dst;
|
||||
mf->x = x;
|
||||
mf->y = y;
|
||||
|
|
Loading…
Reference in New Issue