From 53dd596f437ae53b96d746f0a5cf0963642f76ad Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 16 Nov 2016 16:05:56 -0800 Subject: [PATCH] evas: reduce usage of __thread directive. Moved rects caching into draw context to avoid the use of __thread slot. Draw context are defined per thread anyway and should be just fine. This doesn't really change the picture regarding glibc problem when to many __thread are needed, but slightly improve the global picture. Also this patch doesn't affect our performance in expedite benchmark as far as I can tell. --- src/lib/evas/common/evas_draw_main.c | 5 +++ src/lib/evas/common/evas_font_draw.c | 24 ++--------- src/lib/evas/common/evas_map_image.c | 48 ++++------------------ src/lib/evas/common/evas_rectangle_main.c | 24 ++--------- src/lib/evas/common/evas_scale_main.c | 24 ++--------- src/lib/evas/include/evas_common_private.h | 4 ++ src/lib/evas/include/evas_inline.x | 12 ++++++ 7 files changed, 41 insertions(+), 100 deletions(-) diff --git a/src/lib/evas/common/evas_draw_main.c b/src/lib/evas/common/evas_draw_main.c index 289d6dfdb4..b87c473bd6 100644 --- a/src/lib/evas/common/evas_draw_main.c +++ b/src/lib/evas/common/evas_draw_main.c @@ -122,6 +122,10 @@ evas_common_draw_context_dup(RGBA_Draw_Context *dc) pixman_image_ref(dc2->col.pixman_color_image); #endif #endif + + dc2->cache.rects = NULL; + dc2->cache.used = 0; + return dc2; } @@ -141,6 +145,7 @@ evas_common_draw_context_free(RGBA_Draw_Context *dc) #endif evas_common_draw_context_apply_clean_cutouts(&dc->cutout); + evas_common_draw_context_cutouts_real_free(dc->cache.rects); free(dc); } diff --git a/src/lib/evas/common/evas_font_draw.c b/src/lib/evas/common/evas_font_draw.c index 79c8900c34..b4b0a994d9 100644 --- a/src/lib/evas/common/evas_font_draw.c +++ b/src/lib/evas/common/evas_font_draw.c @@ -348,12 +348,6 @@ error: EAPI Eina_Bool evas_common_font_draw_cb(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, Evas_Glyph_Array *glyphs, Evas_Common_Font_Draw_Cb cb) { -#ifdef HAVE_THREAD_SPECIFIER - static __thread int rects_used = 0; - static __thread Cutout_Rects *rects = NULL; -#else - Cutout_Rects *rects = NULL; -#endif int ext_x, ext_y, ext_w, ext_h; int im_w, im_h; RGBA_Gfx_Func func; @@ -408,26 +402,16 @@ evas_common_font_draw_cb(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, E /* our clip is 0 size.. abort */ if ((dc->clip.w > 0) && (dc->clip.h > 0)) { - rects = evas_common_draw_context_apply_cutouts(dc, rects); - for (i = 0; i < rects->active; ++i) + dc->cache.rects = evas_common_draw_context_apply_cutouts(dc, dc->cache.rects); + for (i = 0; i < dc->cache.rects->active; ++i) { - r = rects->rects + i; + r = dc->cache.rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); ret |= cb(dst, dc, x, y, glyphs, func, r->x, r->y, r->w, r->h, im_w, im_h); } -#ifdef HAVE_THREAD_SPECIFIER - rects_used++; - if (rects_used >= 4096) - { - evas_common_draw_context_cutouts_real_free(rects); - rects = NULL; - rects_used = 0; - } -#else - evas_common_draw_context_cutouts_real_free(rects); -#endif + evas_common_draw_context_cache_update(dc); } dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; diff --git a/src/lib/evas/common/evas_map_image.c b/src/lib/evas/common/evas_map_image.c index 2a48b20d35..339db5aff4 100644 --- a/src/lib/evas/common/evas_map_image.c +++ b/src/lib/evas/common/evas_map_image.c @@ -752,12 +752,6 @@ evas_common_map_rgba_cb(RGBA_Image *src, RGBA_Image *dst, int smooth, int level, Evas_Common_Map_RGBA_Cb cb) { -#ifdef HAVE_THREAD_SPECIFIER - static __thread int rects_used = 0; - static __thread Cutout_Rects *rects = NULL; -#else - Cutout_Rects *rects = NULL; -#endif Cutout_Rect *r; int c, cx, cy, cw, ch; int i; @@ -789,24 +783,14 @@ evas_common_map_rgba_cb(RGBA_Image *src, RGBA_Image *dst, dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; return; } - rects = evas_common_draw_context_apply_cutouts(dc, rects); - for (i = 0; i < rects->active; ++i) + dc->cache.rects = evas_common_draw_context_apply_cutouts(dc, dc->cache.rects); + for (i = 0; i < dc->cache.rects->active; ++i) { - r = rects->rects + i; + r = dc->cache.rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); cb(src, dst, dc, p, smooth, level); } -#ifdef HAVE_THREAD_SPECIFIER - rects_used++; - if (rects_used >= 4096) - { - evas_common_draw_context_cutouts_real_free(rects); - rects = NULL; - rects_used = 0; - } -#else - evas_common_draw_context_cutouts_real_free(rects); -#endif + evas_common_draw_context_cache_update(dc); /* restore clip info */ dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; } @@ -814,12 +798,6 @@ evas_common_map_rgba_cb(RGBA_Image *src, RGBA_Image *dst, EAPI Eina_Bool evas_common_map_thread_rgba_cb(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Map *map, int smooth, int level, int offset, Evas_Common_Map_Thread_RGBA_Cb cb) { -#ifdef HAVE_THREAD_SPECIFIER - static __thread int rects_used = 0; - static __thread Cutout_Rects *rects = NULL; -#else - Cutout_Rects *rects = NULL; -#endif Cutout_Rect *r; int c, cx, cy, cw, ch; int i; @@ -854,24 +832,14 @@ evas_common_map_thread_rgba_cb(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Conte return EINA_FALSE; } - rects = evas_common_draw_context_apply_cutouts(dc, rects); - for (i = 0; i < rects->active; ++i) + dc->cache.rects = evas_common_draw_context_apply_cutouts(dc, dc->cache.rects); + for (i = 0; i < dc->cache.rects->active; ++i) { - r = rects->rects + i; + r = dc->cache.rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); ret |= cb(src, dst, dc, map, smooth, level, offset); } -#ifdef HAVE_THREAD_SPECIFIER - rects_used++; - if (rects_used >= 4096) - { - evas_common_draw_context_cutouts_real_free(rects); - rects = NULL; - rects_used = 0; - } -#else - evas_common_draw_context_cutouts_real_free(rects); -#endif + evas_common_draw_context_cache_update(dc); /* restore clip info */ dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; diff --git a/src/lib/evas/common/evas_rectangle_main.c b/src/lib/evas/common/evas_rectangle_main.c index ed78cca58e..29b93e464d 100644 --- a/src/lib/evas/common/evas_rectangle_main.c +++ b/src/lib/evas/common/evas_rectangle_main.c @@ -12,12 +12,6 @@ evas_common_rectangle_init(void) EAPI void evas_common_rectangle_draw_cb(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h, Evas_Common_Rectangle_Draw_Cb cb) { -#ifdef HAVE_THREAD_SPECIFIER - static __thread int rects_used = 0; - static __thread Cutout_Rects *rects = NULL; -#else - Cutout_Rects *rects = NULL; -#endif Cutout_Rect *r; int c, cx, cy, cw, ch; int i; @@ -40,24 +34,14 @@ evas_common_rectangle_draw_cb(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int /* our clip is 0 size.. abort */ if ((dc->clip.w > 0) && (dc->clip.h > 0)) { - rects = evas_common_draw_context_apply_cutouts(dc, rects); - for (i = 0; i < rects->active; ++i) + dc->cache.rects = evas_common_draw_context_apply_cutouts(dc, dc->cache.rects); + for (i = 0; i < dc->cache.rects->active; ++i) { - r = rects->rects + i; + r = dc->cache.rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); cb(dst, dc, x, y, w, h); } -#ifdef HAVE_THREAD_SPECIFIER - rects_used++; - if (rects_used >= 4096) - { - evas_common_draw_context_cutouts_real_free(rects); - rects = NULL; - rects_used = 0; - } -#else - evas_common_draw_context_cutouts_real_free(rects); -#endif + evas_common_draw_context_cache_update(dc); } } /* restore clip info */ diff --git a/src/lib/evas/common/evas_scale_main.c b/src/lib/evas/common/evas_scale_main.c index a09f0c6805..06b20f30e6 100644 --- a/src/lib/evas/common/evas_scale_main.c +++ b/src/lib/evas/common/evas_scale_main.c @@ -40,12 +40,6 @@ evas_common_scale_rgba_in_to_out_clip_cb(RGBA_Image *src, RGBA_Image *dst, int dst_region_w, int dst_region_h, Evas_Common_Scale_In_To_Out_Clip_Cb cb) { -#ifdef HAVE_THREAD_SPECIFIER - static __thread int rects_used = 0; - static __thread Cutout_Rects *rects = NULL; -#else - Cutout_Rects *rects = NULL; -#endif Cutout_Rect *r; int c, cx, cy, cw, ch; int i; @@ -76,26 +70,16 @@ evas_common_scale_rgba_in_to_out_clip_cb(RGBA_Image *src, RGBA_Image *dst, return EINA_FALSE; } - rects = evas_common_draw_context_apply_cutouts(dc, rects); - for (i = 0; i < rects->active; ++i) + dc->cache.rects = evas_common_draw_context_apply_cutouts(dc, dc->cache.rects); + for (i = 0; i < dc->cache.rects->active; ++i) { - r = rects->rects + i; + r = dc->cache.rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); ret |= cb(src, dst, dc, src_region_x, src_region_y, src_region_w, src_region_h, dst_region_x, dst_region_y, dst_region_w, dst_region_h); } -#ifdef HAVE_THREAD_SPECIFIER - rects_used++; - if (rects_used >= 4096) - { - evas_common_draw_context_cutouts_real_free(rects); - rects = NULL; - rects_used = 0; - } -#else - evas_common_draw_context_cutouts_real_free(rects); -#endif + evas_common_draw_context_cache_update(dc); /* restore clip info */ dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index 07ff291761..c0df4ce12d 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -756,6 +756,10 @@ struct _RGBA_Draw_Context Eina_Bool async : 1; } clip; Cutout_Rects cutout; + struct { + Cutout_Rects *rects; + int used; + } cache; struct { struct { void *(*gl_new) (void *data, RGBA_Font_Glyph *fg); diff --git a/src/lib/evas/include/evas_inline.x b/src/lib/evas/include/evas_inline.x index e60431a10f..8adbd73ae4 100644 --- a/src/lib/evas/include/evas_inline.x +++ b/src/lib/evas/include/evas_inline.x @@ -427,6 +427,18 @@ evas_canvas_async_block(Evas_Public_Data *e) } } +static inline void +evas_common_draw_context_cache_update(RGBA_Draw_Context *dc) +{ + dc->cache.used++; + if (dc->cache.used >= 4096) + { + evas_common_draw_context_cutouts_real_free(dc->cache.rects); + dc->cache.rects = NULL; + dc->cache.used = 0; + } +} + #define _EVAS_COLOR_CLAMP(x, y) do { \ if (x > y) { x = y; bad = 1; } \ if (x < 0) { x = 0; bad = 1; } } while (0)