From a909ca1f68e178f54c5cc047ddff79d25b2c34c6 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Tue, 31 Jan 2017 14:50:52 +0900 Subject: [PATCH] evas draw context - reduce size and allocations and frees so a little perf fun shows malloc/free/realloc/etc. are, combined a reasonable overhead. this reduced malloc overhead for draw contexts so whne we duplicate them or create new ones, we re-use a small cache of 8 of them to avoid re-allocation. just take the first one from the list as it really is that simple. mempool would not have helped more here and cost more overhead. @optimize --- src/bin/evas/evas_cserve2_scale.c | 1 - src/lib/evas/common/evas_draw.h | 1 - src/lib/evas/common/evas_draw_main.c | 117 ++++++++++++++------- src/lib/evas/filters/evas_filter_utils.c | 1 - src/lib/evas/include/evas_common_private.h | 61 +++++------ 5 files changed, 110 insertions(+), 71 deletions(-) diff --git a/src/bin/evas/evas_cserve2_scale.c b/src/bin/evas/evas_cserve2_scale.c index bf6e9400dc..4a877d88d9 100644 --- a/src/bin/evas/evas_cserve2_scale.c +++ b/src/bin/evas/evas_cserve2_scale.c @@ -47,7 +47,6 @@ cserve2_rgba_image_scale_do(void *src_data, int src_full_w, int src_full_h, dst.flags = RGBA_IMAGE_NOTHING; memset(&ct, 0, sizeof(ct)); - ct.sli.h = 1; ct.render_op = _EVAS_RENDER_COPY; if (smooth) diff --git a/src/lib/evas/common/evas_draw.h b/src/lib/evas/common/evas_draw.h index 374b2c799a..6323e8d674 100644 --- a/src/lib/evas/common/evas_draw.h +++ b/src/lib/evas/common/evas_draw.h @@ -33,7 +33,6 @@ EAPI void evas_common_draw_context_apply_clean_cutouts (Cutout EAPI void evas_common_draw_context_set_anti_alias (RGBA_Draw_Context *dc, unsigned char aa); EAPI void evas_common_draw_context_set_color_interpolation (RGBA_Draw_Context *dc, int color_space); EAPI void evas_common_draw_context_set_render_op (RGBA_Draw_Context *dc, int op); -EAPI void evas_common_draw_context_set_sli (RGBA_Draw_Context *dc, int y, int h); EAPI void evas_common_draw_context_target_set (RGBA_Draw_Context *dc, int x, int y, int w, int h); #endif /* _EVAS_DRAW_H */ diff --git a/src/lib/evas/common/evas_draw_main.c b/src/lib/evas/common/evas_draw_main.c index 60ab694e90..6a7c0f75da 100644 --- a/src/lib/evas/common/evas_draw_main.c +++ b/src/lib/evas/common/evas_draw_main.c @@ -18,13 +18,14 @@ evas_common_draw_context_cutouts_dup(Cutout_Rects *rects2, const Cutout_Rects *r rects2->active = rects->active; rects2->max = rects->active; rects2->last_add = rects->last_add; - rects2->rects = NULL; if (rects2->max > 0) { const size_t sz = sizeof(Cutout_Rect) * rects2->max; rects2->rects = malloc(sz); memcpy(rects2->rects, rects->rects, sz); + return; } + else rects2->rects = NULL; } EAPI void @@ -59,12 +60,73 @@ evas_common_draw_context_cutouts_del(Cutout_Rects* rects, int idx) } static int _init_count = 0; +static int _ctxt_spares_count = 0; +static Eina_List *_ctxt_spares = NULL; +static SLK(_ctx_spares_lock); + +static void +_evas_common_draw_context_real_free(RGBA_Draw_Context *dc) +{ +#ifdef HAVE_PIXMAN +# if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY) + if (dc->col.pixman_color_image) + pixman_image_unref(dc->col.pixman_color_image); +# endif +#endif + evas_common_draw_context_apply_clean_cutouts(&dc->cutout); + evas_common_draw_context_cutouts_real_free(dc->cache.rects); + free(dc); +} + +static void +_evas_common_draw_context_stash(RGBA_Draw_Context *dc) +{ + if (_ctxt_spares_count < 8) + { +#ifdef HAVE_PIXMAN +# if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY) + if (dc->col.pixman_color_image) + { + pixman_image_unref(dc->col.pixman_color_image); + dc->col.pixman_color_image = NULL; + } +# endif +#endif + evas_common_draw_context_apply_clean_cutouts(&dc->cutout); + evas_common_draw_context_cutouts_real_free(dc->cache.rects); + SLKL(_ctx_spares_lock); + _ctxt_spares = eina_list_prepend(_ctxt_spares, dc); + _ctxt_spares_count++; + SLKU(_ctx_spares_lock); + return; + } + _evas_common_draw_context_real_free(dc); +} + +static RGBA_Draw_Context * +_evas_common_draw_context_find(void) +{ + RGBA_Draw_Context *dc; + + if (_ctxt_spares) + { + SLKL(_ctx_spares_lock); + dc = _ctxt_spares->data; + _ctxt_spares = eina_list_remove_list(_ctxt_spares, _ctxt_spares); + _ctxt_spares_count--; + SLKU(_ctx_spares_lock); + return dc; + } + dc = malloc(sizeof(RGBA_Draw_Context)); + return dc; +} EAPI void evas_common_init(void) { - if (_init_count++) return ; + if (_init_count++) return; + SLKI(_ctx_spares_lock); evas_common_cpu_init(); evas_common_blend_init(); @@ -83,13 +145,20 @@ evas_common_init(void) EAPI void evas_common_shutdown(void) { - if (--_init_count) return ; + if (--_init_count) return; evas_font_dir_cache_free(); evas_common_font_shutdown(); evas_common_image_shutdown(); evas_common_image_cache_free(); evas_common_scale_sample_shutdown(); +// just in case any thread is still doing things... don't del this here +// RGBA_Draw_Context *dc; +// SLKL(_ctx_spares_lock); +// EINA_LIST_FREE(_ctxt_spares, dc) _evas_common_draw_context_real_free(dc); +// _ctxt_spares_count = 0; +// SLKU(_ctx_spares_lock); +// SLKD(_ctx_spares_lock); } EAPI void @@ -101,31 +170,27 @@ EAPI RGBA_Draw_Context * evas_common_draw_context_new(void) { RGBA_Draw_Context *dc; - - dc = calloc(1, sizeof(RGBA_Draw_Context)); - dc->sli.h = 1; + dc = _evas_common_draw_context_find(); + if (!dc) return NULL; + memset(dc, 0, sizeof(RGBA_Draw_Context)); return dc; } EAPI RGBA_Draw_Context * evas_common_draw_context_dup(RGBA_Draw_Context *dc) { - RGBA_Draw_Context *dc2; + RGBA_Draw_Context *dc2 = _evas_common_draw_context_find(); - if (!dc) return evas_common_draw_context_new(); - dc2 = malloc(sizeof(RGBA_Draw_Context)); + if (!dc) return dc2; 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); +# if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY) + dc2->col.pixman_color_image = NULL; +# endif #endif -#endif - dc2->cache.rects = NULL; dc2->cache.used = 0; - return dc2; } @@ -133,20 +198,7 @@ EAPI void evas_common_draw_context_free(RGBA_Draw_Context *dc) { if (!dc) return; - -#ifdef HAVE_PIXMAN -#if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY) - if (dc->col.pixman_color_image) - { - pixman_image_unref(dc->col.pixman_color_image); - dc->col.pixman_color_image = NULL; - } -#endif -#endif - - evas_common_draw_context_apply_clean_cutouts(&dc->cutout); - evas_common_draw_context_cutouts_real_free(dc->cache.rects); - free(dc); + _evas_common_draw_context_stash(dc); } EAPI void @@ -814,10 +866,3 @@ evas_common_draw_context_set_render_op(RGBA_Draw_Context *dc , int op) { dc->render_op = op; } - -EAPI void -evas_common_draw_context_set_sli(RGBA_Draw_Context *dc, int y, int h) -{ - dc->sli.y = y; - dc->sli.h = h; -} diff --git a/src/lib/evas/filters/evas_filter_utils.c b/src/lib/evas/filters/evas_filter_utils.c index 486532ea9f..1f0869820f 100644 --- a/src/lib/evas/filters/evas_filter_utils.c +++ b/src/lib/evas/filters/evas_filter_utils.c @@ -48,7 +48,6 @@ evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, // Basic draw context memset(&dc, 0, sizeof(dc)); - dc.sli.h = 1; dc.render_op = EVAS_RENDER_COPY; // Do the scale diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index d52dec5fb3..b256318dbd 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -743,32 +743,6 @@ struct _Evas_Common_Transform struct _RGBA_Draw_Context { - struct { - Eina_Bool use : 1; - DATA32 col; - } mul; - struct { -#ifdef HAVE_PIXMAN - pixman_image_t *pixman_color_image; -#endif - DATA32 col; - } col; - struct RGBA_Draw_Context_clip { - int x, y, w, h; - Evas_Public_Data *evas; // for async unref - void *mask; // RGBA_Image (SW) or Evas_GL_Image (GL) - int mask_x, mask_y; - Eina_Bool use : 1; - Eina_Bool async : 1; - } clip; - Cutout_Rects cutout; - struct { - int x, y, w, h; - } cutout_target; - struct { - Cutout_Rects *rects; - int used; - } cache; struct { struct { void *(*gl_new) (void *data, RGBA_Font_Glyph *fg); @@ -781,13 +755,36 @@ struct _RGBA_Draw_Context void *data; } font_ext; struct { - int color_space; - } interpolation; + int x, y, w, h; + } cutout_target; + struct RGBA_Draw_Context_clip { + Evas_Public_Data *evas; // for async unref + void *mask; // RGBA_Image (SW) or Evas_GL_Image (GL) + int x, y, w, h; + int mask_x, mask_y; + Eina_Bool use : 1; + Eina_Bool async : 1; + } clip; struct { - int y, h; - } sli; - int render_op; - Eina_Bool anti_alias : 1; +#ifdef HAVE_PIXMAN + pixman_image_t *pixman_color_image; +#endif + DATA32 col; + } col; + Cutout_Rects cutout; + struct { + DATA32 col; + Eina_Bool use : 1; + } mul; + struct { + Cutout_Rects *rects; + unsigned int used; + } cache; + struct { + unsigned char color_space; + } interpolation; + unsigned char render_op; + unsigned char anti_alias : 1; }; #ifdef BUILD_PIPE_RENDER