summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-01-31 14:50:52 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-01-31 23:01:50 +0900
commita909ca1f68e178f54c5cc047ddff79d25b2c34c6 (patch)
treeb4f604ded3a6d03f115b42aa62640a261f045401
parentb38c610c7e60cbdcb45fd6d27450e39e3a9c9dd1 (diff)
downloadefl-a909ca1f68e178f54c5cc047ddff79d25b2c34c6.tar.gz
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
-rw-r--r--src/bin/evas/evas_cserve2_scale.c1
-rw-r--r--src/lib/evas/common/evas_draw.h1
-rw-r--r--src/lib/evas/common/evas_draw_main.c117
-rw-r--r--src/lib/evas/filters/evas_filter_utils.c1
-rw-r--r--src/lib/evas/include/evas_common_private.h55
5 files changed, 107 insertions, 68 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);
-#endif
+# if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY)
+ dc2->col.pixman_color_image = NULL;
+# 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
@@ -744,50 +744,47 @@ struct _Evas_Common_Transform
struct _RGBA_Draw_Context
{
struct {
- Eina_Bool use : 1;
- DATA32 col;
- } mul;
+ struct {
+ 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_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);
+ } func;
+ void *data;
+ } font_ext;
struct {
-#ifdef HAVE_PIXMAN
- pixman_image_t *pixman_color_image;
-#endif
- DATA32 col;
- } col;
+ int x, y, w, h;
+ } cutout_target;
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 x, y, w, h;
int mask_x, mask_y;
Eina_Bool use : 1;
Eina_Bool async : 1;
} clip;
+ struct {
+#ifdef HAVE_PIXMAN
+ pixman_image_t *pixman_color_image;
+#endif
+ DATA32 col;
+ } col;
Cutout_Rects cutout;
struct {
- int x, y, w, h;
- } cutout_target;
+ DATA32 col;
+ Eina_Bool use : 1;
+ } mul;
struct {
Cutout_Rects *rects;
- int used;
+ unsigned int used;
} cache;
struct {
- struct {
- 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_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);
- } func;
- void *data;
- } font_ext;
- struct {
- int color_space;
+ unsigned char color_space;
} interpolation;
- struct {
- int y, h;
- } sli;
- int render_op;
- Eina_Bool anti_alias : 1;
+ unsigned char render_op;
+ unsigned char anti_alias : 1;
};
#ifdef BUILD_PIPE_RENDER