From 1d415b796bf0f506ef7888195faa8ec0ed1f0d06 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 4 Jul 2012 09:39:23 +0000 Subject: [PATCH] evas: add more infrastructure to the prepare stage of pipe rendering. NOTE: this improve some test by 10 to 15% some other are down by 5%. Their is still more tunning and improvement possible now (Particularly with Map), but it will do for now. SVN revision: 73264 --- legacy/evas/ChangeLog | 5 +- legacy/evas/NEWS | 3 +- legacy/evas/src/lib/canvas/evas_clip.c | 12 +- legacy/evas/src/lib/canvas/evas_map.c | 10 +- .../evas/src/lib/canvas/evas_object_image.c | 7 +- .../evas/src/lib/canvas/evas_object_smart.c | 61 ++- legacy/evas/src/lib/canvas/evas_render.c | 4 +- .../evas/src/lib/engines/common/evas_draw.h | 2 +- .../src/lib/engines/common/evas_draw_main.c | 30 +- .../evas/src/lib/engines/common/evas_font.h | 2 + .../src/lib/engines/common/evas_font_draw.c | 161 ++++++-- .../src/lib/engines/common/evas_font_main.c | 9 +- .../engines/common/evas_image_scalecache.c | 3 +- .../src/lib/engines/common/evas_line_main.c | 2 + .../src/lib/engines/common/evas_map_image.c | 347 +++++++++++++++++- .../src/lib/engines/common/evas_map_image.h | 13 + .../engines/common/evas_map_image_internal.c | 67 +++- .../evas/src/lib/engines/common/evas_pipe.c | 286 +++++++++++---- .../evas/src/lib/engines/common/evas_pipe.h | 9 +- .../src/lib/engines/common/evas_rectangle.h | 2 + .../lib/engines/common/evas_rectangle_main.c | 54 ++- .../src/lib/engines/common/evas_scale_main.c | 27 ++ .../src/lib/engines/common/evas_scale_main.h | 5 + .../lib/engines/common/evas_scale_sample.c | 83 ++++- .../lib/engines/common/evas_scale_smooth.c | 74 +++- .../src/lib/engines/common/evas_text_utils.c | 10 +- .../src/lib/engines/common/evas_text_utils.h | 5 +- .../lib/engines/common_16/evas_soft16_main.c | 5 +- .../engines/common_16/evas_soft16_rectangle.c | 5 +- .../lib/engines/common_8/evas_soft8_main.c | 5 +- .../engines/common_8/evas_soft8_rectangle.c | 5 +- legacy/evas/src/lib/include/evas_common.h | 11 +- legacy/evas/src/lib/include/evas_private.h | 3 +- .../modules/engines/directfb/evas_engine.c | 5 +- .../modules/engines/gl_common/evas_gl_font.c | 5 +- .../modules/engines/gl_common/evas_gl_image.c | 5 +- .../engines/gl_common/evas_gl_polygon.c | 5 +- .../engines/gl_common/evas_gl_rectangle.c | 5 +- .../src/modules/engines/gl_x11/evas_engine.c | 56 +-- .../engines/software_generic/evas_engine.c | 85 +++-- .../engines/software_x11/evas_engine.h | 2 +- .../engines/software_x11/evas_xlib_outbuf.c | 21 +- 42 files changed, 1245 insertions(+), 271 deletions(-) diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog index bddda5f49b..44e6c1f704 100644 --- a/legacy/evas/ChangeLog +++ b/legacy/evas/ChangeLog @@ -842,7 +842,7 @@ * upstream merge * Merge remote-tracking branch 'remotes/origin/upstream' -2012-07-03 Christopher Michael +2012-07-03 Christopher Michael * Merge Tizen changes to upstream EFL. * Support gif scaling in evas gif loader. @@ -852,3 +852,6 @@ * When freeing a gl_x11 window, make sure to call eglMakeCurrent with a null surface to inform EGL that this window is no longer valid. +2012-07-04 Cedric Bail + + * Make pipeline rendering use more extensively the prepare stage. diff --git a/legacy/evas/NEWS b/legacy/evas/NEWS index 3ec27d8cc6..3ecd54999d 100644 --- a/legacy/evas/NEWS +++ b/legacy/evas/NEWS @@ -13,7 +13,8 @@ Improvements: * Don't wake up prepare thread if there is nothing to prepare. * Limit the updated region to fit in CPU cache for Pipe rendering. * Cache convertion from Evas_Map to RGBA_Map. - * evas_object_smart_members_get() now returns NULL on non-smart objects + * evas_object_smart_members_get() now returns NULL on non-smart objects. + * Pipeline rendering use prepare stage more extensively. Fixes: * Add missing files in the tarball. diff --git a/legacy/evas/src/lib/canvas/evas_clip.c b/legacy/evas/src/lib/canvas/evas_clip.c index 435a0ffbaa..6baa28cdb3 100644 --- a/legacy/evas/src/lib/canvas/evas_clip.c +++ b/legacy/evas/src/lib/canvas/evas_clip.c @@ -179,11 +179,11 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip) if (obj == clip) return; if (evas_object_intercept_call_clip_set(obj, clip)) return; // illegal to set anything but a rect as a clip - if (clip->type != o_rect_type) - { - ERR("For now a clip on other object than a rectangle is disabled"); - return; - } + /* if (clip->type != o_rect_type) */ + /* { */ + /* ERR("For now a clip on other object than a rectangle is disabled"); */ + /* return; */ + /* } */ if (obj->smart.smart) { if (obj->smart.smart->smart_class->clip_set) @@ -228,7 +228,7 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip) /* If it's NOT a rectangle set the mask bits too */ /* FIXME: Optmz ths chck */ - if (strcmp(evas_object_type_get(clip),"rectangle") == 0) + if (clip->type == o_rect_type) obj->cur.mask = NULL; else { diff --git a/legacy/evas/src/lib/canvas/evas_map.c b/legacy/evas/src/lib/canvas/evas_map.c index 9c2d71a056..f402db77c9 100644 --- a/legacy/evas/src/lib/canvas/evas_map.c +++ b/legacy/evas/src/lib/canvas/evas_map.c @@ -144,7 +144,9 @@ _evas_map_copy(Evas_Map *dst, const Evas_Map *src) ERR("cannot copy map of different sizes: dst=%i, src=%i", dst->count, src->count); return EINA_FALSE; } - memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point)); + if (dst == src) return EINA_TRUE; + if (dst->points != src->points) + memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point)); dst->smooth = src->smooth; dst->alpha = src->alpha; dst->persp = src->persp; @@ -170,10 +172,10 @@ _evas_map_free(Evas_Object *obj, Evas_Map *m) { if (m->surface) obj->layer->evas->engine.func->image_map_surface_free - (obj->layer->evas->engine.data.output, m->surface); + (obj->layer->evas->engine.data.output, m->surface); if (obj->spans) { - // FIXME: destroy engine side spans + obj->layer->evas->engine.func->image_map_clean(obj->layer->evas->engine.data.output, obj->spans); free(obj->spans); obj->spans = NULL; } @@ -487,7 +489,7 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map) _evas_map_copy(obj->cur.map, map); else { - if (obj->cur.map) evas_map_free(obj->cur.map); + if (obj->cur.map) _evas_map_free(obj, obj->cur.map); obj->cur.map = _evas_map_dup(map); if (obj->cur.usemap) evas_object_mapped_clip_across_mark(obj); diff --git a/legacy/evas/src/lib/canvas/evas_object_image.c b/legacy/evas/src/lib/canvas/evas_object_image.c index b880be806b..b18ac653be 100644 --- a/legacy/evas/src/lib/canvas/evas_object_image.c +++ b/legacy/evas/src/lib/canvas/evas_object_image.c @@ -2952,14 +2952,11 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su } if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap)) { - RGBA_Map_Point *pts; - evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh); - pts = obj->spans->pts; obj->layer->evas->engine.func->image_map_draw - (output, context, surface, pixels, obj->cur.map->count, - pts, o->cur.smooth_scale | obj->cur.map->smooth, 0); + (output, context, surface, pixels, obj->spans, + o->cur.smooth_scale | obj->cur.map->smooth, 0); } else { diff --git a/legacy/evas/src/lib/canvas/evas_object_smart.c b/legacy/evas/src/lib/canvas/evas_object_smart.c index 83b4e88d67..3d9c89dd35 100644 --- a/legacy/evas/src/lib/canvas/evas_object_smart.c +++ b/legacy/evas/src/lib/canvas/evas_object_smart.c @@ -1008,19 +1008,74 @@ static void evas_object_smart_render_pre(Evas_Object *obj) { if (obj->pre_render_done) return; - if (!obj->child_has_map) + if (!obj->child_has_map && !obj->cur.cached_surface) { #if 0 Evas_Object_Smart *o; + fprintf(stderr, ""); o = (Evas_Object_Smart *)(obj->object_data); - if (o->member_count > 1 && + if (/* o->member_count > 1 && */ obj->cur.bounding_box.w == obj->prev.bounding_box.w && obj->cur.bounding_box.h == obj->prev.bounding_box.h && (obj->cur.bounding_box.x != obj->prev.bounding_box.x || obj->cur.bounding_box.y != obj->prev.bounding_box.y)) { - fprintf(stderr, "Wouhou, I can detect moving smart object (%s, %p < %p)\n", evas_object_type_get(obj), obj, obj->smart.parent); + Eina_Bool cache_map = EINA_FALSE; + + /* Check parent speed */ + /* - same speed => do not map this object */ + /* - different speed => map this object */ + /* - if parent is mapped then map this object */ + + if (!obj->smart.parent || obj->smart.parent->child_has_map) + { + cache_map = EINA_TRUE; + } + else + { + if (_evas_render_has_map(obj->smart.parent)) + { + cache_map = EINA_TRUE; + } + else + { + int speed_x, speed_y; + int speed_px, speed_py; + + speed_x = obj->cur.geometry.x - obj->prev.geometry.x; + speed_y = obj->cur.geometry.y - obj->prev.geometry.y; + + speed_px = obj->smart.parent->cur.geometry.x - obj->smart.parent->prev.geometry.x; + speed_py = obj->smart.parent->cur.geometry.y - obj->smart.parent->prev.geometry.y; + + /* speed_x = obj->cur.bounding_box.x - obj->prev.bounding_box.x; */ + /* speed_y = obj->cur.bounding_box.y - obj->prev.bounding_box.y; */ + + /* speed_px = obj->smart.parent->cur.bounding_box.x - obj->smart.parent->prev.bounding_box.x; */ + /* speed_py = obj->smart.parent->cur.bounding_box.y - obj->smart.parent->prev.bounding_box.y; */ + + fprintf(stderr, "speed: '%s',%p (%i, %i) vs '%s',%p (%i, %i)\n", + evas_object_type_get(obj), obj, speed_x, speed_y, + evas_object_type_get(obj->smart.parent), obj->smart.parent, speed_px, speed_py); + + if (speed_x != speed_px || speed_y != speed_py) + cache_map = EINA_TRUE; + } + } + + if (cache_map) + fprintf(stderr, "Wouhou, I can detect moving smart object (%s, %p [%i, %i, %i, %i] < %s, %p [%i, %i, %i, %i])\n", + evas_object_type_get(obj), obj, + obj->cur.bounding_box.x - obj->prev.bounding_box.x, + obj->cur.bounding_box.y - obj->prev.bounding_box.y, + obj->cur.bounding_box.w, obj->cur.bounding_box.h, + evas_object_type_get(obj->smart.parent), obj->smart.parent, + obj->smart.parent->cur.bounding_box.x - obj->smart.parent->prev.bounding_box.x, + obj->smart.parent->cur.bounding_box.y - obj->smart.parent->prev.bounding_box.y, + obj->smart.parent->cur.bounding_box.w, obj->smart.parent->cur.bounding_box.h); + + obj->cur.cached_surface = cache_map; } #endif } diff --git a/legacy/evas/src/lib/canvas/evas_render.c b/legacy/evas/src/lib/canvas/evas_render.c index 11edcf3bdb..374938b581 100644 --- a/legacy/evas/src/lib/canvas/evas_render.c +++ b/legacy/evas/src/lib/canvas/evas_render.c @@ -822,7 +822,6 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, _evas_render_has_map(obj)); if (_evas_render_has_map(obj)) { - RGBA_Map_Point *pts; int sw, sh; Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE; @@ -840,7 +839,6 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, } evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh); - pts = obj->spans->pts; if (obj->cur.map->surface) { @@ -1032,7 +1030,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, (e->engine.data.output, e->engine.data.context); obj->layer->evas->engine.func->image_map_draw (e->engine.data.output, e->engine.data.context, surface, - obj->cur.map->surface, obj->cur.map->count, pts, + obj->cur.map->surface, obj->spans, obj->cur.map->smooth, 0); } // FIXME: needs to cache these maps and diff --git a/legacy/evas/src/lib/engines/common/evas_draw.h b/legacy/evas/src/lib/engines/common/evas_draw.h index 34e0ed3e4a..6599d54c00 100644 --- a/legacy/evas/src/lib/engines/common/evas_draw.h +++ b/legacy/evas/src/lib/engines/common/evas_draw.h @@ -24,7 +24,7 @@ EAPI void evas_common_draw_context_cutouts_free (Cutout EAPI void evas_common_draw_context_cutouts_del (Cutout_Rects* rects, int idx); EAPI void evas_common_draw_context_add_cutout (RGBA_Draw_Context *dc, int x, int y, int w, int h); EAPI void evas_common_draw_context_clear_cutouts (RGBA_Draw_Context *dc); -EAPI Cutout_Rects *evas_common_draw_context_apply_cutouts (RGBA_Draw_Context *dc); +EAPI Cutout_Rects *evas_common_draw_context_apply_cutouts (RGBA_Draw_Context *dc, Cutout_Rects *recycle); EAPI void evas_common_draw_context_apply_clear_cutouts (Cutout_Rects* rects); EAPI void evas_common_draw_context_apply_clean_cutouts (Cutout_Rects* rects); EAPI void evas_common_draw_context_set_anti_alias (RGBA_Draw_Context *dc, unsigned char aa); diff --git a/legacy/evas/src/lib/engines/common/evas_draw_main.c b/legacy/evas/src/lib/engines/common/evas_draw_main.c index d08e7885eb..28b54cd0ae 100644 --- a/legacy/evas/src/lib/engines/common/evas_draw_main.c +++ b/legacy/evas/src/lib/engines/common/evas_draw_main.c @@ -14,6 +14,7 @@ evas_common_draw_context_cutouts_new(void) EAPI void evas_common_draw_context_cutouts_free(Cutout_Rects* rects) { + if (!rects) return ; rects->active = 0; } @@ -90,7 +91,7 @@ evas_common_draw_context_free(RGBA_Draw_Context *dc) EAPI void evas_common_draw_context_clear_cutouts(RGBA_Draw_Context *dc) { - evas_common_draw_context_apply_clean_cutouts(&dc->cutout); + evas_common_draw_context_cutouts_free(&dc->cutout); } EAPI void @@ -557,9 +558,9 @@ evas_common_draw_context_cutout_split(Cutout_Rects* res, int idx, Cutout_Rect *s } EAPI Cutout_Rects* -evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc) +evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reuse) { - Cutout_Rects* res, *res2; + Cutout_Rects* res = NULL; int i; int j; @@ -567,7 +568,15 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc) if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) return NULL; - res = evas_common_draw_context_cutouts_new(); + if (!reuse) + { + res = evas_common_draw_context_cutouts_new(); + } + else + { + evas_common_draw_context_cutouts_free(reuse); + res = reuse; + } evas_common_draw_context_cutouts_add(res, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h); for (i = 0; i < dc->cutout.active; ++i) @@ -636,15 +645,18 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc) } } } - res2 = evas_common_draw_context_cutouts_new(); + + /* Repack the cutout */ + j = 0; for (i = 0; i < res->active; i++) { if (RI.w == 0) continue; - evas_common_draw_context_cutouts_add(res2, RI.x, RI.y, RI.w, RI.h); + if (i != j) + RJ = RI; + j++; } - free(res->rects); - free(res); - return res2; + res->active = j; + return res; } return res; } diff --git a/legacy/evas/src/lib/engines/common/evas_font.h b/legacy/evas/src/lib/engines/common/evas_font.h index 313c23e9b7..5c7c1afcd3 100644 --- a/legacy/evas/src/lib/engines/common/evas_font.h +++ b/legacy/evas/src/lib/engines/common/evas_font.h @@ -25,6 +25,8 @@ EAPI Eina_Bool evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph * EAPI FT_UInt evas_common_get_char_index (RGBA_Font_Int* fi, Eina_Unicode gl); EAPI void evas_common_font_draw_init (void); EAPI void evas_common_font_draw_prepare (Evas_Text_Props *text_props); +EAPI void evas_common_font_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Gfx_Func func, RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *text_props); +EAPI Eina_Bool evas_common_font_draw_prepare_cutout(Cutout_Rects *reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func); /* load */ EAPI void evas_common_font_dpi_set (int dpi); diff --git a/legacy/evas/src/lib/engines/common/evas_font_draw.c b/legacy/evas/src/lib/engines/common/evas_font_draw.c index c1308a911c..f635756dea 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_draw.c +++ b/legacy/evas/src/lib/engines/common/evas_font_draw.c @@ -40,21 +40,22 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, in im = dst->image.data; - if (!text_props->bin) return ; + if (!text_props->glyphs) return ; - glyphs = (void*) eina_binbuf_string_get(text_props->bin); - length = eina_binbuf_length_get(text_props->bin) / sizeof (Evas_Glyph); - for (it = 0; it < length; ++it) + glyphs = text_props->glyphs; + length = text_props->glyphs_length; + for (it = 0; it < length; ++it, ++glyphs) { RGBA_Font_Glyph *fg; int chr_x, chr_y; - fg = glyphs[it].fg; + fg = glyphs->fg; - glyphs[it].coord.w = fg->glyph_out->bitmap.width; - glyphs[it].coord.h = fg->glyph_out->bitmap.rows; - glyphs[it].j = fg->glyph_out->bitmap.pitch; - glyphs[it].data = fg->glyph_out->bitmap.buffer; + /* FIXME: Why was that moved out of prepare ? This increase cache miss. */ + glyphs->coord.w = fg->glyph_out->bitmap.width; + glyphs->coord.h = fg->glyph_out->bitmap.rows; + glyphs->j = fg->glyph_out->bitmap.pitch; + glyphs->data = fg->glyph_out->bitmap.buffer; if (dc->font_ext.func.gl_new) { @@ -63,19 +64,19 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, in fg->ext_dat_free = dc->font_ext.func.gl_free; } - chr_x = x + glyphs[it].coord.x/* EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR */; - chr_y = y + glyphs[it].coord.y/* EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR */; + chr_x = x + glyphs->coord.x/* EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR */; + chr_y = y + glyphs->coord.y/* EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR */; if (chr_x < (ext_x + ext_w)) { DATA8 *data; int i, j, w, h; - data = glyphs[it].data; - j = glyphs[it].j; - w = glyphs[it].coord.w; + data = glyphs->data; + j = glyphs->j; + w = glyphs->coord.w; if (j < w) j = w; - h = glyphs[it].coord.h; + h = glyphs->coord.h; #ifdef HAVE_PIXMAN # ifdef PIXMAN_FONT @@ -230,16 +231,21 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props) { RGBA_Font_Int *fi; RGBA_Font_Glyph *fg; + Evas_Glyph *glyphs; + int glyphs_length; + int glyphs_max; EVAS_FONT_WALK_TEXT_INIT(); fi = text_props->font_instance; if (!fi) return; - if (!text_props->changed && text_props->generation == fi->generation && text_props->bin) + if (!text_props->changed && text_props->generation == fi->generation && text_props->glyphs) return ; - if (!text_props->bin) text_props->bin = eina_binbuf_new(); - else eina_binbuf_reset(text_props->bin); + glyphs = text_props->glyphs; + glyphs_length = 0; + glyphs_max = text_props->glyphs_length; + text_props->glyphs_length = 0; evas_common_font_int_reload(fi); @@ -254,7 +260,7 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props) EVAS_FONT_WALK_TEXT_START() { - Evas_Glyph glyph; + Evas_Glyph *glyph; FT_UInt idx; if (!EVAS_FONT_WALK_IS_VISIBLE) continue; @@ -264,15 +270,28 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props) if (!fg) continue; if (!fg->glyph_out) evas_common_font_int_cache_glyph_render(fg); - glyph.fg = fg; - glyph.coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR; - glyph.coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR; - glyph.idx = idx; + if (glyphs_length + 1 >= glyphs_max) + { + Evas_Glyph *tmp; - eina_binbuf_append_length(text_props->bin, (void*) &glyph, sizeof (Evas_Glyph)); + glyphs_max += 8; + tmp = realloc(glyphs, glyphs_max * sizeof (Evas_Glyph)); + if (!tmp) return ; + glyphs = tmp; + text_props->glyphs = glyphs; + } + + glyph = glyphs + glyphs_length++; + + glyph->fg = fg; + glyph->idx = idx; + glyph->coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR; + glyph->coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR; } EVAS_FONT_WALK_TEXT_END(); + text_props->glyphs_length = glyphs_length; + text_props->glyphs = glyphs; /* check if there's a request queue in fi, if so ask cserve2 to render * those glyphs */ @@ -283,10 +302,10 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props) EAPI void evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *text_props) { + static Cutout_Rects *rects = NULL; int ext_x, ext_y, ext_w, ext_h; int im_w, im_h; RGBA_Gfx_Func func; - Cutout_Rects *rects; Cutout_Rect *r; int c, cx, cy, cw, ch; int i; @@ -335,7 +354,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, cons /* our clip is 0 size.. abort */ if ((dc->clip.w > 0) && (dc->clip.h > 0)) { - rects = evas_common_draw_context_apply_cutouts(dc); + rects = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; @@ -344,8 +363,96 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, cons func, r->x, r->y, r->w, r->h, im_w, im_h); } - evas_common_draw_context_apply_clear_cutouts(rects); } dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; } } + +EAPI void +evas_common_font_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Gfx_Func func, + RGBA_Image *dst, RGBA_Draw_Context *dc, + int x, int y, const Evas_Text_Props *text_props) +{ + Eina_Rectangle area; + Cutout_Rect *r; + int i; + int im_w, im_h; + + im_w = dst->cache_entry.w; + im_h = dst->cache_entry.h; + + if (!reuse) + { + evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h); + evas_common_font_draw_internal(dst, dc, x, y, text_props, + func, clip->x, clip->y, clip->w, clip->h, + im_w, im_h); + return ; + } + + for (i = 0; i < reuse->active; ++i) + { + r = reuse->rects + i; + + EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h); + if (!eina_rectangle_intersection(&area, clip)) continue ; + evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h); + evas_common_font_draw_internal(dst, dc, x, y, text_props, + func, area.x, area.y, area.w, area.h, + im_w, im_h); + } +} + +EAPI Eina_Bool +evas_common_font_draw_prepare_cutout(Cutout_Rects *reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func) +{ + int ext_x, ext_y, ext_w, ext_h; + int im_w, im_h; + + im_w = dst->cache_entry.w; + im_h = dst->cache_entry.h; + + *func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op); + + ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h; + if (dc->clip.use) + { + ext_x = dc->clip.x; + ext_y = dc->clip.y; + ext_w = dc->clip.w; + ext_h = dc->clip.h; + if (ext_x < 0) + { + ext_w += ext_x; + ext_x = 0; + } + if (ext_y < 0) + { + ext_h += ext_y; + ext_y = 0; + } + if ((ext_x + ext_w) > im_w) + ext_w = im_w - ext_x; + if ((ext_y + ext_h) > im_h) + ext_h = im_h - ext_y; + } + if (ext_w <= 0) return EINA_FALSE; + if (ext_h <= 0) return EINA_FALSE; + + if (dc->cutout.rects) + { + evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); + /* our clip is 0 size.. abort */ + if ((dc->clip.w > 0) && (dc->clip.h > 0)) + { + reuse = evas_common_draw_context_apply_cutouts(dc, reuse); + } + else + { + return EINA_FALSE; + } + } + + return EINA_TRUE; +} + diff --git a/legacy/evas/src/lib/engines/common/evas_font_main.c b/legacy/evas/src/lib/engines/common/evas_font_main.c index bd4c6785f9..100f3b7523 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_main.c +++ b/legacy/evas/src/lib/engines/common/evas_font_main.c @@ -562,9 +562,14 @@ evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl) // } evas_common_font_int_reload(fi); - FTLOCK(); + /* + * There is no point in locking FreeType at this point as all caller + * are running in the main loop at a time where there is zero chance + * that something else try to use it. + */ + /* FTLOCK(); */ result.index = FT_Get_Char_Index(fi->src->ft.face, gl); - FTUNLOCK(); + /* FTUNLOCK(); */ result.gl = gl; // eina_hash_direct_add(fi->indexes, &result->gl, result); diff --git a/legacy/evas/src/lib/engines/common/evas_image_scalecache.c b/legacy/evas/src/lib/engines/common/evas_image_scalecache.c index 99ecd308c9..5a2d7a25a3 100644 --- a/legacy/evas/src/lib/engines/common/evas_image_scalecache.c +++ b/legacy/evas/src/lib/engines/common/evas_image_scalecache.c @@ -221,8 +221,7 @@ _sci_find(RGBA_Image *im, { if (im->cache.list != l) { - im->cache.list = eina_list_remove_list(im->cache.list, l); - im->cache.list = eina_list_prepend(im->cache.list, sci); + im->cache.list = eina_list_promote_list(im->cache.list, l); } return sci; } diff --git a/legacy/evas/src/lib/engines/common/evas_line_main.c b/legacy/evas/src/lib/engines/common/evas_line_main.c index fc1385f293..76417f5ac7 100644 --- a/legacy/evas/src/lib/engines/common/evas_line_main.c +++ b/legacy/evas/src/lib/engines/common/evas_line_main.c @@ -47,6 +47,8 @@ evas_common_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, in int clx, cly, clw, clh; int cuse, cx, cy, cw, ch; + /* No cutout ? FIXME ? */ + if ((x0 == x1) && (y0 == y1)) { _evas_draw_point(dst, dc, x0, y0); diff --git a/legacy/evas/src/lib/engines/common/evas_map_image.c b/legacy/evas/src/lib/engines/common/evas_map_image.c index 4106c206e1..776820f04b 100644 --- a/legacy/evas/src/lib/engines/common/evas_map_image.c +++ b/legacy/evas/src/lib/engines/common/evas_map_image.c @@ -1,4 +1,5 @@ #include "evas_common.h" +#include "evas_private.h" #include "evas_blend_private.h" #ifdef EVAS_CSERVE2 #include "evas_cs2_private.h" @@ -33,7 +34,7 @@ struct _Line Span span[2]; }; -static FPc +static inline FPc _interp(int x1, int x2, int p, FPc u1, FPc u2) { FPc u; @@ -46,7 +47,7 @@ _interp(int x1, int x2, int p, FPc u1, FPc u2) return u1 + u; } -static DATA32 +static inline DATA32 _interp_col(int x1, int x2, int p, DATA32 col1, DATA32 col2) { x2 -= x1; @@ -56,7 +57,7 @@ _interp_col(int x1, int x2, int p, DATA32 col1, DATA32 col2) return INTERP_256(p, col2, col1); } -static void +static inline void _limit(Span *s, int c1, int c2, int nocol) { if (s->x1 < c1) @@ -357,17 +358,293 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy } } +/* FIXME: Account for 10% during pipe rendering, should be improved + * Could be computing the interpolation once somehow. + */ +static void +_clip_spans(Line *spans, int ystart, int yend, + int cx, int cw, Eina_Bool nocol) +{ + int y, yp; + + for (y = ystart, yp = 0; y <= yend; y++, yp++) + { + if (spans[yp].span[0].x1 > -1) + { + if ((spans[yp].span[0].x1 >= (cx + cw)) || + (spans[yp].span[0].x2 < cx)) + { + spans[yp].span[0].x1 = -1; + } + else + { + _limit(&(spans[yp].span[0]), cx, cx + cw, nocol); + + if ((spans[yp].span[1].x1 >= (cx + cw)) || + (spans[yp].span[1].x2 < cx)) + { + spans[yp].span[1].x1 = -1; + } + else + { + _limit(&(spans[yp].span[1]), + spans[yp].span[0].x2, + cx + cw, nocol); + } + } + } + } +} + +typedef struct _RGBA_Map_Spans RGBA_Map_Spans; +typedef struct _RGBA_Map_Cutout RGBA_Map_Cutout; + +struct _RGBA_Map_Spans +{ + Line *spans; + int size; + int ystart; + int yend; + + int havecol; + Eina_Bool nocol; + Eina_Bool havea; + Eina_Bool direct; +}; + +struct _RGBA_Map_Cutout +{ + int count; + + Cutout_Rects *rects; + RGBA_Map_Spans spans[1]; +}; + +EAPI void +evas_common_map_rgba_clean(RGBA_Map *m) +{ + RGBA_Map_Cutout *spans = m->engine_data; + + if (spans) + { + int i; + + if (spans->rects) + evas_common_draw_context_apply_clear_cutouts(spans->rects); + for (i = 0; i < spans->count; i++) + free(spans->spans[i].spans); + free(spans); + } + + m->engine_data = NULL; +} + +static void +_rgba_map_cutout_resize(RGBA_Map *m, int count) +{ + RGBA_Map_Cutout *old = m->engine_data; + RGBA_Map_Cutout *r; + int size; + int i; + + if (count == 0) + goto empty; + + if (old && old->count == count) + { + return ; + } + + size = sizeof (RGBA_Map_Cutout) + sizeof (RGBA_Map_Spans) * (count - 1); + + if (old) + { + for (i = 0; i < old->count; i++) + { + free(old->spans[i].spans); + old->spans[i].spans = NULL; + } + } + + r = realloc(old, size); + if (!r) + goto empty; + + memset(r, 0, size); + m->engine_data = r; + r->count = count; + return ; + + empty: + evas_common_map_rgba_clean(m); + return ; +} + +static void +_evas_common_map_rgba_span(RGBA_Map_Spans *span, + RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + RGBA_Map_Point *p, + int cx, int cy, int cw, int ch) +{ + int ytop, ybottom, sw; + unsigned int i; + + span->havecol = 4; + span->havea = 0; + span->direct = 0; + + // find y yop line and y bottom line + ytop = p[0].y; + if ((p[0].col >> 24) < 0xff) span->havea = 1; + if (p[0].col == 0xffffffff) span->havecol--; + for (i = 1; i < 4; i++) + { + if (p[i].y < ytop) ytop = p[i].y; + if ((p[i].col >> 24) < 0xff) span->havea = 1; + if (p[i].col == 0xffffffff) span->havecol--; + } + + ybottom = p[0].y; + for (i = 1; i < 4; i++) + { + if (p[i].y > ybottom) ybottom = p[i].y; + } + + // convert to screen space from fixed point + ytop = ytop >> FP; + ybottom = ybottom >> FP; + + // if its outside the clip vertical bounds - don't bother + if ((ytop >= (cy + ch)) || (ybottom < cy)) return; + + // limit to the clip vertical bounds + if (ytop < cy) span->ystart = cy; + else span->ystart = ytop; + if (ybottom >= (cy + ch)) span->yend = (cy + ch) - 1; + else span->yend = ybottom; + + // get some source image information + sw = src->cache_entry.w; + + // limit u,v coords of points to be within the source image + for (i = 0; i < 4; i++) + { + if (p[i].u < 0) p[i].u = 0; + else if (p[i].u > (int)(sw << FP)) + p[i].u = src->cache_entry.w << FP; + + if (p[i].v < 0) p[i].v = 0; + else if (p[i].v > (int)(sw << FP)) + p[i].v = src->cache_entry.h << FP; + } + + // allocate some spans to hold out span list + if (span->size < (span->yend - span->ystart + 1)) + { + free(span->spans); + span->size = (span->yend - span->ystart + 1); + span->spans = calloc(1, span->size * sizeof(Line)); + } + if (!span->spans) return; + + // calculate the spans list + _calc_spans(p, span->spans, span->ystart, span->yend, cx, cy, cw, ch); + + // if operation is solid, bypass buf and draw func and draw direct to dst + if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) && + (!dc->mul.use) && (!span->havea)) + { + span->direct = 1; + } +} + +EAPI Eina_Bool +evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + RGBA_Map *m) +{ + RGBA_Map_Cutout *spans; + Cutout_Rects *rects; + Cutout_Rect *r; + int i; + + if ((!dc->cutout.rects) && (!dc->clip.use)) + { + evas_common_draw_context_clip_clip(dc, 0, 0, + dst->cache_entry.w, dst->cache_entry.h); + if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) + { + _rgba_map_cutout_resize(m, 0); + return EINA_FALSE; + } + + _rgba_map_cutout_resize(m, 1); + if (!m->engine_data) return EINA_FALSE; + + spans = m->engine_data; + + _evas_common_map_rgba_span(&spans->spans[0], src, dst, dc, m->pts, + 0, 0, + dst->cache_entry.w, dst->cache_entry.h); + return EINA_TRUE; + } + + evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); + /* our clip is 0 size.. abort */ + if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) + { + _rgba_map_cutout_resize(m, 0); + return EINA_FALSE; + } + + spans = m->engine_data; + if (spans) + { + rects = spans->rects; + spans->rects = NULL; + } + else + { + rects = evas_common_draw_context_cutouts_new(); + } + rects = evas_common_draw_context_apply_cutouts(dc, rects); + _rgba_map_cutout_resize(m, rects->active); + + spans = m->engine_data; + if (!spans) + { + evas_common_draw_context_apply_clear_cutouts(rects); + return EINA_FALSE; + } + + spans->rects = rects; + for (i = 0; i < spans->rects->active; ++i) + { + r = spans->rects->rects + i; + + _evas_common_map_rgba_span(&spans->spans[i], src, dst, dc, m->pts, + r->x, r->y, r->w, r->h); + } + + return EINA_TRUE; +} + #ifdef BUILD_SCALE_SMOOTH # ifdef BUILD_MMX # undef FUNC_NAME +# undef FUNC_NAME_DO # define FUNC_NAME evas_common_map_rgba_internal_mmx +# define FUNC_NAME_DO evas_common_map_rgba_internal_mmx_do # undef SCALE_USING_MMX # define SCALE_USING_MMX # include "evas_map_image_internal.c" # endif # ifdef BUILD_C # undef FUNC_NAME +# undef FUNC_NAME_DO # define FUNC_NAME evas_common_map_rgba_internal +# define FUNC_NAME_DO evas_common_map_rgba_internal_do # undef SCALE_USING_MMX # include "evas_map_image_internal.c" # endif @@ -382,7 +659,7 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst, #ifdef BUILD_MMX int mmx, sse, sse2; #endif - Cutout_Rects *rects; + static Cutout_Rects *rects = NULL; Cutout_Rect *r; int c, cx, cy, cw, ch; int i; @@ -422,7 +699,7 @@ evas_common_map_rgba(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 = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; @@ -436,7 +713,65 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst, evas_common_map_rgba_internal(src, dst, dc, p, smooth, level); #endif } - evas_common_draw_context_apply_clear_cutouts(rects); /* restore clip info */ dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; } + +EAPI void +evas_common_map_rgba_do(const Eina_Rectangle *clip, + RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + const RGBA_Map *m, + int smooth, int level) +{ +#ifdef BUILD_MMX + int mmx, sse, sse2; +#endif + const Cutout_Rects *rects; + const RGBA_Map_Cutout *spans; + Eina_Rectangle area; + Cutout_Rect *r; + int i; + +#ifdef BUILD_MMX + evas_common_cpu_can_do(&mmx, &sse, &sse2); +#endif + + spans = m->engine_data; + rects = spans->rects; + if (rects->active == 0 && + spans->count == 1) + { + evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h); +#ifdef BUILD_MMX + if (mmx) + evas_common_map_rgba_internal_mmx_do(src, dst, dc, + &spans->spans[0], smooth, level); + else +#endif +#ifdef BUILD_C + evas_common_map_rgba_internal_do(src, dst, dc, + &spans->spans[0], smooth, level); +#endif + return ; + } + + for (i = 0; i < rects->active; ++i) + { + r = rects->rects + i; + + EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h); + if (!eina_rectangle_intersection(&area, clip)) continue ; + evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h); +#ifdef BUILD_MMX + if (mmx) + evas_common_map_rgba_internal_mmx_do(src, dst, dc, + &spans->spans[i], smooth, level); + else +#endif +#ifdef BUILD_C + evas_common_map_rgba_internal_do(src, dst, dc, + &spans->spans[i], smooth, level); +#endif + } +} diff --git a/legacy/evas/src/lib/engines/common/evas_map_image.h b/legacy/evas/src/lib/engines/common/evas_map_image.h index a7cb8cf6b6..f9c7b971bd 100644 --- a/legacy/evas/src/lib/engines/common/evas_map_image.h +++ b/legacy/evas/src/lib/engines/common/evas_map_image.h @@ -7,4 +7,17 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst, int npoints, RGBA_Map_Point *points, int smooth, int level); +EAPI Eina_Bool +evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + RGBA_Map *m); +EAPI void +evas_common_map_rgba_do(const Eina_Rectangle *clip, + RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + const RGBA_Map *m, + int smooth, int level); +EAPI void +evas_common_map_rgba_clean(RGBA_Map *m); + #endif /* _EVAS_MAP_H */ diff --git a/legacy/evas/src/lib/engines/common/evas_map_image_internal.c b/legacy/evas/src/lib/engines/common/evas_map_image_internal.c index d60117e8ba..8f4660f1f3 100644 --- a/legacy/evas/src/lib/engines/common/evas_map_image_internal.c +++ b/legacy/evas/src/lib/engines/common/evas_map_image_internal.c @@ -74,7 +74,6 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst, // allocate some spans to hold out span list spans = alloca((yend - ystart + 1) * sizeof(Line)); - if (!spans) return; memset(spans, 0, (yend - ystart + 1) * sizeof(Line)); // calculate the spans list @@ -94,7 +93,6 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst, int pa; buf = alloca(cw * sizeof(DATA32)); - if (!buf) return; pa = src->cache_entry.flags.alpha; if (havea) src->cache_entry.flags.alpha = 1; if (dc->mul.use) @@ -115,3 +113,68 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst, #include "evas_map_image_core.c" } } + +static void +FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + const RGBA_Map_Spans *ms, + int smooth, int level __UNUSED__) // level unused for now - for future use +{ + Line *spans; + DATA32 *buf = NULL, *sp; + RGBA_Gfx_Func func = NULL; + int cx, cy, cw, ch; + int ystart, yend, y, sw, shp, swp, direct; + int havecol; + int i; + + cx = dc->clip.x; + cy = dc->clip.y; + cw = dc->clip.w; + ch = dc->clip.h; + + if (ms->ystart < cy) ystart = cy; + else ystart = ms->ystart; + if (ms->yend >= (cy + ch)) yend = (cy + ch) - 1; + else yend = ms->yend; + + // get some source image information + sp = src->image.data; + sw = src->cache_entry.w; + swp = sw << (FP + FPI); + shp = src->cache_entry.h << (FP + FPI); + havecol = ms->havecol; + direct = ms->direct; + + // allocate some s to hold out span list + spans = alloca((yend - ystart + 1) * sizeof(Line)); + memcpy(spans, &ms->spans[ystart - ms->ystart], + (yend - ystart + 1) * sizeof(Line)); + _clip_spans(spans, ystart, yend, cx, cw, ms->nocol); + + // if operation is solid, bypass buf and draw func and draw direct to dst + if (!direct) + { + int pa; + + buf = alloca(cw * sizeof(DATA32)); + pa = src->cache_entry.flags.alpha; + if (ms->havea) src->cache_entry.flags.alpha = 1; + if (dc->mul.use) + func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op); + else + func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op); + src->cache_entry.flags.alpha = pa; + } + + if (!havecol) + { +#undef COLMUL +#include "evas_map_image_core.c" + } + else + { +#define COLMUL 1 +#include "evas_map_image_core.c" + } +} diff --git a/legacy/evas/src/lib/engines/common/evas_pipe.c b/legacy/evas/src/lib/engines/common/evas_pipe.c index 0249595f93..590bcd44ca 100644 --- a/legacy/evas/src/lib/engines/common/evas_pipe.c +++ b/legacy/evas/src/lib/engines/common/evas_pipe.c @@ -1,5 +1,3 @@ -// THIS IS DEPRECATED. WILL GO EVENTUALLTY. NO NEED TO SUPPORT ANYMORE - #include "evas_common.h" #include @@ -79,14 +77,14 @@ evas_common_pipe_thread(void *data) EINA_INLIST_FOREACH(thinfo->tasks, info) { - EINA_INLIST_FOREACH(EINA_INLIST_GET(info->im->cache_entry.pipe), p) + EINA_INLIST_FOREACH(EINA_INLIST_GET(thinfo->im->cache_entry.pipe), p) { int i; for (i = 0; i < p->op_num; i++) { - if (p->op[i].op_func) - p->op[i].op_func(info->im, &(p->op[i]), info); + if (p->op[i].op_func && p->op[i].render) + p->op[i].op_func(thinfo->im, &(p->op[i]), info); } } } @@ -100,12 +98,58 @@ evas_common_pipe_thread(void *data) #endif #ifdef BUILD_PTHREAD +static Eina_List *im_task = NULL; +static Eina_List *text_task = NULL; +static Thinfo task_thinfo[TH_MAX]; +static pthread_barrier_t task_thbarrier[2]; +static LK(im_task_mutex); +static LK(text_task_mutex); + static int thread_num = 0; static Thinfo thinfo[TH_MAX]; static pthread_barrier_t thbarrier[2]; static RGBA_Pipe_Thread_Info *buf = NULL; static unsigned int buf_size = 0; + +static Cutout_Rects * +evas_pipe_cutout_rects_pop(Thinfo *info) +{ + Cutout_Rects *r; + + r = eina_array_pop(&info->cutout_trash); + if (!r) r = evas_common_draw_context_cutouts_new(); + return r; +} + +static void +evas_pipe_cutout_rects_push(Thinfo *info, Cutout_Rects *r) +{ + /* evas_common_draw_context_apply_clean_cutouts(r); */ + evas_common_draw_context_cutouts_free(r); + eina_array_push(&info->cutout_trash, r); +} + +static void +evas_pipe_cutout_rects_rotate(Cutout_Rects *r) +{ + static int current = 0; + + if (current >= thread_num) current = 0; + evas_pipe_cutout_rects_push(&task_thinfo[current], r); + current++; +} + +static void +evas_pipe_prepare_push(RGBA_Pipe_Op *op) +{ + static int current = 0; + + if (current >= thread_num) current = 0; + eina_array_push(&task_thinfo[current].rects_task, op); + current++; +} + #endif static void @@ -145,12 +189,11 @@ evas_common_pipe_begin(RGBA_Image *im) for (y = 0; y < im->cache_entry.h; y += estimatey) for (x = 0; x < im->cache_entry.w; x += estimatex) { - info->im = im; - info->x = x; - info->y = y; - info->w = (x + estimatex > im->cache_entry.w) ? im->cache_entry.w - x : estimatex; - info->h = (y + estimatey > im->cache_entry.h) ? im->cache_entry.h - y : estimatey; + EINA_RECTANGLE_SET(&info->area, x, y, + (x + estimatex > im->cache_entry.w) ? im->cache_entry.w - x : estimatex, + (y + estimatey > im->cache_entry.h) ? im->cache_entry.h - y : estimatey); + thinfo[cpu].im = im; thinfo[cpu].tasks = eina_inlist_prepend((void*) thinfo[cpu].tasks, EINA_INLIST_GET(info)); cpu++; if (cpu >= (unsigned int) thread_num) cpu = 0; @@ -180,18 +223,14 @@ evas_common_pipe_flush(RGBA_Image *im) RGBA_Pipe *p; int i; - info.im = im; - info.x = 0; - info.y = 0; - info.w = im->cache_entry.w; - info.h = im->cache_entry.h; + EINA_RECTANGLE_SET(&info.area, 0, 0, im->cache_entry.w, im->cache_entry.h); /* process pipe - 1 thead */ for (p = im->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next) { for (i = 0; i < p->op_num; i++) { - if (p->op[i].op_func) + if (p->op[i].render && p->op[i].op_func) { p->op[i].op_func(im, &(p->op[i]), &info); } @@ -223,6 +262,7 @@ evas_common_pipe_free(RGBA_Image *im) { p->op[i].free_func(&(p->op[i])); } + if (p->op[i].rects) evas_pipe_cutout_rects_rotate(p->op[i].rects); } im->cache_entry.pipe = (RGBA_Pipe *)eina_inlist_remove(EINA_INLIST_GET(im->cache_entry.pipe), EINA_INLIST_GET(p)); free(p); @@ -239,10 +279,28 @@ evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, cons RGBA_Draw_Context context; memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); - evas_common_rectangle_draw(dst, &(context), - op->op.rect.x, op->op.rect.y, - op->op.rect.w, op->op.rect.h); + evas_common_rectangle_draw_do(op->rects, &info->area, dst, &(context), + op->op.rect.x, op->op.rect.y, + op->op.rect.w, op->op.rect.h); +} + +static Eina_Bool +evas_common_pipe_rectangle_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op) +{ + RGBA_Draw_Context context; + Cutout_Rects *recycle; + Thinfo *info = data; + Eina_Bool r; + + recycle = evas_pipe_cutout_rects_pop(info); + memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); + r = evas_common_rectangle_draw_prepare(recycle, dst, &context, + op->op.rect.x, op->op.rect.y, + op->op.rect.w, op->op.rect.h); + if (recycle->active) op->rects = recycle; + else evas_pipe_cutout_rects_push(info, recycle); + + return r; } EAPI void @@ -259,6 +317,8 @@ evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, i op->op.rect.h = h; op->op_func = evas_common_pipe_rectangle_draw_do; op->free_func = evas_common_pipe_op_free; + op->prepare_func = evas_common_pipe_rectangle_prepare; + evas_pipe_prepare_push(op); evas_common_pipe_draw_context_copy(dc, op); } @@ -269,7 +329,7 @@ evas_common_pipe_line_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGB RGBA_Draw_Context context; memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); + evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h); evas_common_line_draw(dst, &(context), op->op.line.x0, op->op.line.y0, op->op.line.x1, op->op.line.y1); @@ -289,6 +349,7 @@ evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, op->op.line.y1 = y1; op->op_func = evas_common_pipe_line_draw_do; op->free_func = evas_common_pipe_op_free; + op->prepare_func = NULL; evas_common_pipe_draw_context_copy(dc, op); } @@ -298,6 +359,7 @@ evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op) { RGBA_Polygon_Point *p; +#if 0 while (op->op.poly.points) { p = op->op.poly.points; @@ -305,6 +367,7 @@ evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op) EINA_INLIST_GET(p)); free(p); } +#endif evas_common_pipe_op_free(op); } @@ -314,9 +377,9 @@ evas_common_pipe_poly_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGB RGBA_Draw_Context context; memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); + evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h); evas_common_polygon_draw(dst, &(context), - op->op.poly.points, 0, 0); + op->op.poly.points, op->op.poly.x, op->op.poly.y); } EAPI void @@ -324,12 +387,13 @@ evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y) { RGBA_Pipe_Op *op; - RGBA_Polygon_Point *pts = NULL, *p, *pp; + /* RGBA_Polygon_Point *pts = NULL, *p, *pp; */ if (!points) return; dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op); if (!dst->cache_entry.pipe) return; /* FIXME: copy points - maybe we should refcount? */ +#if 0 for (p = points; p; p = (RGBA_Polygon_Point *)(EINA_INLIST_GET(p))->next) { pp = calloc(1, sizeof(RGBA_Polygon_Point)); @@ -340,9 +404,13 @@ evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, pts = (RGBA_Polygon_Point *)eina_inlist_append(EINA_INLIST_GET(pts), EINA_INLIST_GET(pp)); } } - op->op.poly.points = pts; +#endif + op->op.poly.x = x; + op->op.poly.y = y; + op->op.poly.points = points/* pts */; op->op_func = evas_common_pipe_poly_draw_do; op->free_func = evas_common_pipe_op_poly_free; + op->prepare_func = NULL; /* FIXME: If we really want to improve it, we should prepare span for it here */ evas_common_pipe_draw_context_copy(dc, op); } @@ -360,8 +428,24 @@ evas_common_pipe_text_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGB RGBA_Draw_Context context; memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); - evas_common_font_draw(dst, &(context), op->op.text.x, op->op.text.y, op->op.text.intl_props); + evas_common_font_draw_do(op->rects, &info->area, op->op.text.func, dst, &(context), op->op.text.x, op->op.text.y, op->op.text.intl_props); +} + +static Eina_Bool +evas_common_pipe_text_draw_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op) +{ + RGBA_Draw_Context context; + Cutout_Rects *recycle; + Thinfo *info = data; + Eina_Bool r; + + recycle = evas_pipe_cutout_rects_pop(info); + memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); + r = evas_common_font_draw_prepare_cutout(recycle, dst, &context, &(op->op.text.func)); + if (recycle->active) op->rects = recycle; + else evas_pipe_cutout_rects_push(info, recycle); + + return r; } EAPI void @@ -378,6 +462,8 @@ evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, evas_common_text_props_content_ref(intl_props); op->op_func = evas_common_pipe_text_draw_do; op->free_func = evas_common_pipe_op_text_free; + op->prepare_func = evas_common_pipe_text_draw_prepare; + evas_pipe_prepare_push(op); evas_common_pipe_draw_context_copy(dc, op); evas_common_pipe_text_prepare(intl_props); } @@ -394,15 +480,35 @@ evas_common_pipe_op_image_free(RGBA_Pipe_Op *op) evas_common_pipe_op_free(op); } +static Eina_Bool +evas_common_pipe_op_image_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op) +{ + RGBA_Draw_Context context; + Cutout_Rects *recycle; + Thinfo *info = data; + Eina_Bool r; + + recycle = evas_pipe_cutout_rects_pop(info); + memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); + r = evas_common_scale_rgba_in_to_out_clip_prepare(recycle, op->op.image.src, dst, &(context), + op->op.image.dx, op->op.image.dy, + op->op.image.dw, op->op.image.dh); + if (recycle->active) op->rects = recycle; + else evas_pipe_cutout_rects_push(info, recycle); + + return r; +} + static void evas_common_pipe_image_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info) { RGBA_Draw_Context context; memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); #ifdef SCALECACHE + /* FIXME: Make the scalecache path use the prepared Cutout ? */ + evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h); evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src), dst, &(context), op->op.image.smooth, @@ -417,29 +523,31 @@ evas_common_pipe_image_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RG #else if (op->op.image.smooth) { - evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src, - dst, &(context), - op->op.image.sx, - op->op.image.sy, - op->op.image.sw, - op->op.image.sh, - op->op.image.dx, - op->op.image.dy, - op->op.image.dw, - op->op.image.dh); + evas_common_scale_rgba_in_to_out_clip_smooth_do(op->rects, &info->area, + op->op.image.src, + dst, &(context), + op->op.image.sx, + op->op.image.sy, + op->op.image.sw, + op->op.image.sh, + op->op.image.dx, + op->op.image.dy, + op->op.image.dw, + op->op.image.dh); } else { - evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src, - dst, &(context), - op->op.image.sx, - op->op.image.sy, - op->op.image.sw, - op->op.image.sh, - op->op.image.dx, - op->op.image.dy, - op->op.image.dw, - op->op.image.dh); + evas_common_scale_rgba_in_to_out_clip_sample_do(op->rects, &info->area, + op->op.image.src, + dst, &(context), + op->op.image.sx, + op->op.image.sy, + op->op.image.sw, + op->op.image.sh, + op->op.image.dx, + op->op.image.dy, + op->op.image.dw, + op->op.image.dh); } #endif } @@ -471,6 +579,8 @@ evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst, op->op.image.src = src; op->op_func = evas_common_pipe_image_draw_do; op->free_func = evas_common_pipe_op_image_free; + op->prepare_func = evas_common_pipe_op_image_prepare; + evas_pipe_prepare_push(op); evas_common_pipe_draw_context_copy(dc, op); evas_common_pipe_image_load(src); @@ -482,7 +592,7 @@ evas_common_pipe_op_map_free(RGBA_Pipe_Op *op) op->op.map.src->ref--; if (op->op.map.src->ref == 0) evas_cache_image_drop(&op->op.map.src->cache_entry); - free(op->op.map.p); + /* free(op->op.map.p); */ evas_common_pipe_op_free(op); } @@ -492,43 +602,56 @@ evas_common_pipe_map_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA RGBA_Draw_Context context; memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); + evas_common_map_rgba_do(&info->area, op->op.map.src, dst, + &context, op->op.map.m, + op->op.map.smooth, op->op.map.level); +} - evas_common_map_rgba(op->op.map.src, dst, - &context, op->op.map.npoints, op->op.map.p, - op->op.map.smooth, op->op.map.level); +static Eina_Bool +evas_common_pipe_map_draw_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op) +{ + RGBA_Draw_Context context; + Thinfo *info = data; + Eina_Bool r; + + memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); + r = evas_common_map_rgba_prepare(op->op.map.src, dst, + &context, op->op.map.m); + + return r; } EAPI void evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst, - RGBA_Draw_Context *dc, int npoints, RGBA_Map_Point *p, + RGBA_Draw_Context *dc, RGBA_Map *m, int smooth, int level) { RGBA_Pipe_Op *op; - RGBA_Map_Point *pts_copy; + /* RGBA_Map_Point *pts_copy; */ int i; if (!src) return; - pts_copy = malloc(sizeof (RGBA_Map_Point) * 4); - if (!pts_copy) return; + /* pts_copy = malloc(sizeof (RGBA_Map_Point) * 4); */ + /* if (!pts_copy) return; */ dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op); if (!dst->cache_entry.pipe) { - free(pts_copy); + /* free(pts_copy); */ return; } - for (i = 0; i < 4; ++i) - pts_copy[i] = p[i]; + /* for (i = 0; i < 4; ++i) */ + /* pts_copy[i] = p[i]; */ - op->op.map.npoints = npoints; op->op.map.smooth = smooth; op->op.map.level = level; src->ref++; op->op.map.src = src; - op->op.map.p = pts_copy; + op->op.map.m = m; op->op_func = evas_common_pipe_map_draw_do; op->free_func = evas_common_pipe_op_map_free; + op->prepare_func = evas_common_pipe_map_draw_prepare; + evas_pipe_prepare_push(op); evas_common_pipe_draw_context_copy(dc, op); evas_common_pipe_image_load(src); @@ -562,15 +685,6 @@ evas_common_pipe_map_render(RGBA_Image *root) evas_common_pipe_flush(root); } -#ifdef BUILD_PTHREAD -static Eina_List *im_task = NULL; -static Eina_List *text_task = NULL; -static Thinfo task_thinfo[TH_MAX]; -static pthread_barrier_t task_thbarrier[2]; -static LK(im_task_mutex); -static LK(text_task_mutex); -#endif - #ifdef BUILD_PTHREAD static void* evas_common_pipe_load(void *data) @@ -580,6 +694,9 @@ evas_common_pipe_load(void *data) tinfo = data; for (;;) { + RGBA_Pipe_Op *op; + Eina_Array_Iterator it; + unsigned int i; /* wait for start signal */ pthread_barrier_wait(&(tinfo->barrier[0])); @@ -625,6 +742,10 @@ evas_common_pipe_load(void *data) } } + EINA_ARRAY_ITER_NEXT(&tinfo->rects_task, i, op, it) + op->render = op->prepare_func(tinfo, tinfo->im, op); + eina_array_clean(&tinfo->rects_task); + /* send finished signal */ pthread_barrier_wait(&(tinfo->barrier[1])); } @@ -636,20 +757,23 @@ evas_common_pipe_load(void *data) static volatile int bval = 0; static void -evas_common_pipe_load_do(void) +evas_common_pipe_load_do(RGBA_Image *im) { #ifdef BUILD_PTHREAD - if (!im_task && !text_task) return ; + int i; - /* Notify worker thread. */ - pthread_barrier_wait(&(task_thbarrier[0])); + for (i = 0; i < thread_num; i++) + task_thinfo[i].im = im; - /* sync worker threads */ - pthread_barrier_wait(&(task_thbarrier[1])); + /* Notify worker thread. */ + pthread_barrier_wait(&(task_thbarrier[0])); + + /* sync worker threads */ + pthread_barrier_wait(&(task_thbarrier[1])); #endif } -static Eina_Bool +EAPI Eina_Bool evas_common_pipe_init(void) { #ifdef BUILD_PTHREAD @@ -703,6 +827,8 @@ evas_common_pipe_init(void) task_thinfo[i].thread_num = i; task_thinfo[i].tasks = NULL; task_thinfo[i].barrier = task_thbarrier; + eina_array_step_set(&task_thinfo[i].cutout_trash, sizeof (Eina_Array), 8); + eina_array_step_set(&task_thinfo[i].rects_task, sizeof (Eina_Array), 8); /* setup initial locks */ pthread_create(&(task_thinfo[i].thread_id), &attr, evas_common_pipe_load, &(task_thinfo[i])); @@ -746,7 +872,7 @@ evas_common_pipe_text_prepare(Evas_Text_Props *text_props) fi = text_props->font_instance; if (!fi) return ; - if (!text_props->changed && text_props->generation == fi->generation && text_props->bin) + if (!text_props->changed && text_props->generation == fi->generation && text_props->glyphs) return ; LKL(fi->ft_mutex); @@ -783,7 +909,7 @@ evas_common_pipe_map_begin(RGBA_Image *root) } } - evas_common_pipe_load_do(); + evas_common_pipe_load_do(root); evas_common_pipe_map_render(root); } diff --git a/legacy/evas/src/lib/engines/common/evas_pipe.h b/legacy/evas/src/lib/engines/common/evas_pipe.h index b4614241b7..c6a28ff78e 100644 --- a/legacy/evas/src/lib/engines/common/evas_pipe.h +++ b/legacy/evas/src/lib/engines/common/evas_pipe.h @@ -7,10 +7,13 @@ #ifdef BUILD_PTHREAD typedef struct _Thinfo { + RGBA_Image *im; int thread_num; pthread_t thread_id; pthread_barrier_t *barrier; const Eina_Inlist *tasks; + Eina_Array cutout_trash; + Eina_Array rects_task; } Thinfo; #endif @@ -18,6 +21,8 @@ typedef struct _Thinfo * threadable */ +EAPI Eina_Bool evas_common_pipe_init(void); + EAPI void evas_common_pipe_free(RGBA_Image *im); EAPI void evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h); EAPI void evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1); @@ -28,8 +33,8 @@ EAPI void evas_common_pipe_image_load(RGBA_Image *im); EAPI void evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int smooth, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h); EAPI void evas_common_pipe_map_begin(RGBA_Image *root); EAPI void evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst, - RGBA_Draw_Context *dc, int npoints, RGBA_Map_Point *p, - int smooth, int level); + RGBA_Draw_Context *dc, RGBA_Map *m, + int smooth, int level); EAPI void evas_common_pipe_flush(RGBA_Image *im); #endif /* _EVAS_PIPE_H */ diff --git a/legacy/evas/src/lib/engines/common/evas_rectangle.h b/legacy/evas/src/lib/engines/common/evas_rectangle.h index a653b047a2..8fdcb774cd 100644 --- a/legacy/evas/src/lib/engines/common/evas_rectangle.h +++ b/legacy/evas/src/lib/engines/common/evas_rectangle.h @@ -6,6 +6,8 @@ EAPI void evas_common_rectangle_init (void); EAPI void evas_common_rectangle_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h); +EAPI void evas_common_rectangle_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h); +EAPI Eina_Bool evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h); #endif /* _EVAS_RECTANGLE_H */ diff --git a/legacy/evas/src/lib/engines/common/evas_rectangle_main.c b/legacy/evas/src/lib/engines/common/evas_rectangle_main.c index cd3d16c1c8..40747613b9 100644 --- a/legacy/evas/src/lib/engines/common/evas_rectangle_main.c +++ b/legacy/evas/src/lib/engines/common/evas_rectangle_main.c @@ -1,4 +1,5 @@ #include "evas_common.h" +#include "evas_private.h" #include "evas_blend_private.h" static void rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h); @@ -11,7 +12,7 @@ evas_common_rectangle_init(void) EAPI void evas_common_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h) { - Cutout_Rects *rects; + static Cutout_Rects *rects = NULL; Cutout_Rect *r; int c, cx, cy, cw, ch; int i; @@ -34,20 +35,67 @@ evas_common_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, /* our clip is 0 size.. abort */ if ((dc->clip.w > 0) && (dc->clip.h > 0)) { - rects = evas_common_draw_context_apply_cutouts(dc); + rects = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); rectangle_draw_internal(dst, dc, x, y, w, h); } - evas_common_draw_context_apply_clear_cutouts(rects); } } /* restore clip info */ dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; } +EAPI Eina_Bool +evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h) +{ + if ((w <= 0) || (h <= 0)) return EINA_FALSE; + if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, dst->cache_entry.w, dst->cache_entry.h))) + return EINA_FALSE; + /* save out clip info */ + evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); + /* no cutouts - cut right to the chase */ + if (dc->cutout.rects) + { + evas_common_draw_context_clip_clip(dc, x, y, w, h); + /* our clip is 0 size.. abort */ + if ((dc->clip.w > 0) && (dc->clip.h > 0)) + reuse = evas_common_draw_context_apply_cutouts(dc, reuse); + } + + return EINA_TRUE; +} + +EAPI void +evas_common_rectangle_draw_do(const Cutout_Rects *reuse, + const Eina_Rectangle *clip, + RGBA_Image *dst, RGBA_Draw_Context *dc, + int x, int y, int w, int h) +{ + Eina_Rectangle area; + Cutout_Rect *r; + int i; + + if (!reuse) + { + evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h); + rectangle_draw_internal(dst, dc, x, y, w, h); + return ; + } + + for (i = 0; i < reuse->active; ++i) + { + r = reuse->rects + i; + + EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h); + if (!eina_rectangle_intersection(&area, clip)) continue ; + evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h); + rectangle_draw_internal(dst, dc, x, y, w, h); + } +} + static void rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h) { diff --git a/legacy/evas/src/lib/engines/common/evas_scale_main.c b/legacy/evas/src/lib/engines/common/evas_scale_main.c index 959336c0f7..bb11c6bded 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_main.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_main.c @@ -1,6 +1,33 @@ #include "evas_common.h" +#include "evas_private.h" EAPI void evas_common_scale_init(void) { } + +EAPI Eina_Bool +evas_common_scale_rgba_in_to_out_clip_prepare(Cutout_Rects *reuse, const RGBA_Image *src __UNUSED__, + const RGBA_Image *dst, + RGBA_Draw_Context *dc, + int dst_region_x, int dst_region_y, + int dst_region_w, int dst_region_h) +{ + /* handle cutouts here! */ + if ((dst_region_w <= 0) || (dst_region_h <= 0)) return EINA_FALSE; + if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, + 0, 0, dst->cache_entry.w, dst->cache_entry.h))) + return EINA_FALSE; + /* no cutouts - cut right to the chase */ + if (!dc->cutout.rects) return EINA_TRUE; + + evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); + evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h); + /* our clip is 0 size.. abort */ + if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) + return EINA_FALSE; + reuse = evas_common_draw_context_apply_cutouts(dc, reuse); + + return EINA_TRUE; +} + diff --git a/legacy/evas/src/lib/engines/common/evas_scale_main.h b/legacy/evas/src/lib/engines/common/evas_scale_main.h index eafd9d2ae2..e2ef8fa9ce 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_main.h +++ b/legacy/evas/src/lib/engines/common/evas_scale_main.h @@ -10,4 +10,9 @@ EAPI void evas_common_scale_rgba_in_to_out_clip_sample (RGBA_Image *src, RG EAPI void evas_common_rgba_image_scalecache_dump(void); +EAPI void evas_common_scale_rgba_in_to_out_clip_sample_do (const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h); +EAPI void evas_common_scale_rgba_in_to_out_clip_smooth_do (const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h); +EAPI Eina_Bool evas_common_scale_rgba_in_to_out_clip_prepare (Cutout_Rects *reuse, const RGBA_Image *src, const RGBA_Image *dst, RGBA_Draw_Context *dc, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h); + + #endif /* _EVAS_SCALE_MAIN_H */ diff --git a/legacy/evas/src/lib/engines/common/evas_scale_sample.c b/legacy/evas/src/lib/engines/common/evas_scale_sample.c index 3b232213d4..ea1061802d 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_sample.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_sample.c @@ -1,10 +1,27 @@ #include "evas_common.h" #include "evas_blend_private.h" -void scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h); +static void scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h); #ifndef BUILD_SCALE_SMOOTH #ifdef BUILD_SCALE_SAMPLE +EAPI void +evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse, + const Eina_Rectangle *clip, + RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + int src_region_x, int src_region_y, + int src_region_w, int src_region_h, + int dst_region_x, int dst_region_y, + int dst_region_w, int dst_region_h) +{ + evas_common_scale_rgba_in_to_out_clip_sample_do(reuse, clip, 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); +} + EAPI void evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, @@ -31,7 +48,7 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h) { - Cutout_Rects *rects; + static Cutout_Rects *rects = NULL; Cutout_Rect *r; int c, cx, cy, cw, ch; int i; @@ -60,7 +77,7 @@ evas_common_scale_rgba_in_to_out_clip_sample(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 = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; @@ -72,12 +89,51 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst, dst_region_w, dst_region_h); } - evas_common_draw_context_apply_clear_cutouts(rects); /* restore clip info */ dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; } -void +EAPI void +evas_common_scale_rgba_in_to_out_clip_sample_do(const Cutout_Rects *reuse, + const Eina_Rectangle *clip, + RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + int src_region_x, int src_region_y, + int src_region_w, int src_region_h, + int dst_region_x, int dst_region_y, + int dst_region_w, int dst_region_h) +{ + Eina_Rectangle area; + Cutout_Rect *r; + int i; + + if (!reuse) + { + evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h); + scale_rgba_in_to_out_clip_sample_internal(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); + return; + } + + for (i = 0; i < reuse->active; ++i) + { + r = reuse->rects + i; + + EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h); + if (!eina_rectangle_intersection(&area, clip)) continue ; + evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h); + scale_rgba_in_to_out_clip_sample_internal(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); + } +} + +static void scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, @@ -403,5 +459,22 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst, dst_region_x, dst_region_y, dst_region_w, dst_region_h); } + +EAPI void +evas_common_scale_rgba_in_to_out_clip_sample_do(const Cutout_Rects *reuse, + const Eina_Rectangle *clip, + RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + int src_region_x, int src_region_y, + int src_region_w, int src_region_h, + int dst_region_x, int dst_region_y, + int dst_region_w, int dst_region_h) +{ + evas_common_scale_rgba_in_to_out_clip_smooth_do(reuse, clip, 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); +} #endif #endif diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth.c index d3aada65b6..ca852033c8 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth.c @@ -460,7 +460,7 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst, # ifdef BUILD_MMX int mmx, sse, sse2; # endif - Cutout_Rects *rects; + static Cutout_Rects *rects = NULL; Cutout_Rect *r; int c, cx, cy, cw, ch; int i; @@ -503,7 +503,7 @@ evas_common_scale_rgba_in_to_out_clip_smooth(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 = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; @@ -525,8 +525,76 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst, dst_region_w, dst_region_h); # endif } - evas_common_draw_context_apply_clear_cutouts(rects); /* restore clip info */ dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; } + +EAPI void +evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse, + const Eina_Rectangle *clip, + RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + int src_region_x, int src_region_y, + int src_region_w, int src_region_h, + int dst_region_x, int dst_region_y, + int dst_region_w, int dst_region_h) +{ +# ifdef BUILD_MMX + int mmx, sse, sse2; +# endif + Eina_Rectangle area; + Cutout_Rect *r; + int i; + +# ifdef BUILD_MMX + evas_common_cpu_can_do(&mmx, &sse, &sse2); +# endif + if (!reuse) + { + evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h); +# ifdef BUILD_MMX + if (mmx) + evas_common_scale_rgba_in_to_out_clip_smooth_mmx(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); + else +# endif +# ifdef BUILD_C + evas_common_scale_rgba_in_to_out_clip_smooth_c(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); +# endif + return ; + } + + for (i = 0; i < reuse->active; ++i) + { + r = reuse->rects + i; + + EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h); + if (!eina_rectangle_intersection(&area, clip)) continue ; + evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h); +# ifdef BUILD_MMX + if (mmx) + evas_common_scale_rgba_in_to_out_clip_smooth_mmx(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); + else +# endif +# ifdef BUILD_C + evas_common_scale_rgba_in_to_out_clip_smooth_c(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); +# endif + } +} + #endif diff --git a/legacy/evas/src/lib/engines/common/evas_text_utils.c b/legacy/evas/src/lib/engines/common/evas_text_utils.c index c1c1a2335e..acdcc0042f 100644 --- a/legacy/evas/src/lib/engines/common/evas_text_utils.c +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.c @@ -36,6 +36,8 @@ evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst, const Evas_Text_Props *src) { memcpy(dst, src, sizeof(Evas_Text_Props)); + dst->glyphs = NULL; + dst->glyphs_length = 0; evas_common_text_props_content_ref(dst); } @@ -66,11 +68,9 @@ evas_common_text_props_content_unref(Evas_Text_Props *props) if (--(props->info->refcount) == 0) { - if (props->bin) - { - eina_binbuf_free(props->bin); - props->bin = NULL; - } + free(props->glyphs); + props->glyphs = NULL; + props->glyphs_length = 0; if (props->info->glyph) free(props->info->glyph); diff --git a/legacy/evas/src/lib/engines/common/evas_text_utils.h b/legacy/evas/src/lib/engines/common/evas_text_utils.h index a10ce7d569..675df6c200 100644 --- a/legacy/evas/src/lib/engines/common/evas_text_utils.h +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.h @@ -18,6 +18,8 @@ typedef enum /* Used for showing "malformed" or missing chars */ #define REPLACEMENT_CHAR 0xFFFD +typedef struct _Evas_Glyph Evas_Glyph; + struct _Evas_Text_Props { /* Start and len represent the start offset and the length in the @@ -31,7 +33,8 @@ struct _Evas_Text_Props Evas_Text_Props_Info *info; void *font_instance; - Eina_Binbuf *bin; + Evas_Glyph *glyphs; + int glyphs_length; int generation; Eina_Bool changed : 1; diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_main.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_main.c index 6028744a92..5258b7d5ab 100644 --- a/legacy/evas/src/lib/engines/common_16/evas_soft16_main.c +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_main.c @@ -474,8 +474,8 @@ evas_common_soft16_image_draw(Soft16_Image *src, Soft16_Image *dst, int dst_region_w, int dst_region_h, int smooth __UNUSED__) { + static Cutout_Rects *rects = NULL; Eina_Rectangle sr, dr; - Cutout_Rects *rects; Cutout_Rect *r; struct RGBA_Draw_Context_clip clip_bkp; int i; @@ -510,14 +510,13 @@ evas_common_soft16_image_draw(Soft16_Image *src, Soft16_Image *dst, dc->clip = clip_bkp; return; } - rects = evas_common_draw_context_apply_cutouts(dc); + rects = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; i++) { r = rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); _soft16_image_draw_sampled_int(src, dst, dc, sr, dr); } - evas_common_draw_context_apply_clear_cutouts(rects); dc->clip = clip_bkp; } diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_rectangle.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_rectangle.c index bd38fce9a7..ac6aa46eaa 100644 --- a/legacy/evas/src/lib/engines/common_16/evas_soft16_rectangle.c +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_rectangle.c @@ -78,8 +78,8 @@ void evas_common_soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h) { + static Cutout_Rects *rects = NULL; Eina_Rectangle dr; - Cutout_Rects *rects; Cutout_Rect *r; struct RGBA_Draw_Context_clip c_bkp; int i; @@ -108,14 +108,13 @@ evas_common_soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, dc->clip = c_bkp; return; } - rects = evas_common_draw_context_apply_cutouts(dc); + rects = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); _soft16_rectangle_draw_int(dst, dc, dr); } - evas_common_draw_context_apply_clear_cutouts(rects); dc->clip = c_bkp; } diff --git a/legacy/evas/src/lib/engines/common_8/evas_soft8_main.c b/legacy/evas/src/lib/engines/common_8/evas_soft8_main.c index cc4ce25abb..02282b8d7c 100644 --- a/legacy/evas/src/lib/engines/common_8/evas_soft8_main.c +++ b/legacy/evas/src/lib/engines/common_8/evas_soft8_main.c @@ -523,8 +523,8 @@ evas_common_soft8_image_draw(Soft8_Image * src, Soft8_Image * dst, int dst_region_w, int dst_region_h, int smooth __UNUSED__) { + static Cutout_Rects *rects = NULL; Eina_Rectangle sr, dr; - Cutout_Rects *rects; Cutout_Rect *r; struct RGBA_Draw_Context_clip clip_bkp; int i; @@ -569,14 +569,13 @@ evas_common_soft8_image_draw(Soft8_Image * src, Soft8_Image * dst, dc->clip = clip_bkp; return; } - rects = evas_common_draw_context_apply_cutouts(dc); + rects = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; i++) { r = rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); _soft8_image_draw_sampled_int(src, dst, dc, sr, dr); } - evas_common_draw_context_apply_clear_cutouts(rects); dc->clip = clip_bkp; } diff --git a/legacy/evas/src/lib/engines/common_8/evas_soft8_rectangle.c b/legacy/evas/src/lib/engines/common_8/evas_soft8_rectangle.c index 150f262e8e..98a053bb81 100644 --- a/legacy/evas/src/lib/engines/common_8/evas_soft8_rectangle.c +++ b/legacy/evas/src/lib/engines/common_8/evas_soft8_rectangle.c @@ -79,8 +79,8 @@ void evas_common_soft8_rectangle_draw(Soft8_Image * dst, RGBA_Draw_Context * dc, int x, int y, int w, int h) { + static Cutout_Rects *rects = NULL; Eina_Rectangle dr; - Cutout_Rects *rects; Cutout_Rect *r; struct RGBA_Draw_Context_clip c_bkp; int i; @@ -113,13 +113,12 @@ evas_common_soft8_rectangle_draw(Soft8_Image * dst, RGBA_Draw_Context * dc, dc->clip = c_bkp; return; } - rects = evas_common_draw_context_apply_cutouts(dc); + rects = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); _soft8_rectangle_draw_int(dst, dc, dr); } - evas_common_draw_context_apply_clear_cutouts(rects); dc->clip = c_bkp; } diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index c9a9511c6b..eba2039a08 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -728,8 +728,10 @@ struct _RGBA_Draw_Context struct _RGBA_Pipe_Op { RGBA_Draw_Context context; + Eina_Bool (*prepare_func) (void *data, RGBA_Image *dst, RGBA_Pipe_Op *op); void (*op_func) (RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info); void (*free_func) (RGBA_Pipe_Op *op); + Cutout_Rects *rects; union { struct { @@ -739,11 +741,13 @@ struct _RGBA_Pipe_Op int x0, y0, x1, y1; } line; struct { + int x, y; RGBA_Polygon_Point *points; } poly; struct { int x, y; Evas_Text_Props *intl_props; + RGBA_Gfx_Func func; } text; struct { RGBA_Image *src; @@ -753,12 +757,14 @@ struct _RGBA_Pipe_Op } image; struct { RGBA_Image *src; - RGBA_Map_Point *p; + RGBA_Map *m; int npoints; int smooth; int level; } map; } op; + + Eina_Bool render : 1; }; #define PIPE_LEN 256 @@ -773,8 +779,7 @@ struct _RGBA_Pipe struct _RGBA_Pipe_Thread_Info { EINA_INLIST; - RGBA_Image *im; - int x, y, w, h; + Eina_Rectangle area; }; #endif diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index d21ab0a7ab..86dab875d5 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -834,9 +834,10 @@ struct _Evas_Func int (*image_scale_hint_get) (void *data, void *image); int (*font_last_up_to_pos) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props, int x, int y); - void (*image_map_draw) (void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level); + void (*image_map_draw) (void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level); void *(*image_map_surface_new) (void *data, int w, int h, int alpha); void (*image_map_surface_free) (void *data, void *surface); + void (*image_map_clean) (void *data, RGBA_Map *m); void (*image_content_hint_set) (void *data, void *surface, int hint); int (*image_content_hint_get) (void *data, void *surface); diff --git a/legacy/evas/src/modules/engines/directfb/evas_engine.c b/legacy/evas/src/modules/engines/directfb/evas_engine.c index b1079827be..41386b20f2 100644 --- a/legacy/evas/src/modules/engines/directfb/evas_engine.c +++ b/legacy/evas/src/modules/engines/directfb/evas_engine.c @@ -404,10 +404,10 @@ typedef void (*_cb_for_each_cutout_t)(IDirectFBSurface *surface, RGBA_Draw_Conte static void _dfb_surface_for_each_cutout(IDirectFBSurface *surface, RGBA_Draw_Context *dc, _cb_for_each_cutout_t cb, void *data) { - Cutout_Rects *rects; + static Cutout_Rects *rects = NULL; int i; - rects = evas_common_draw_context_apply_cutouts(dc); + rects = evas_common_draw_context_apply_cutouts(dc, rects); if (!rects) { DFBRegion cr; @@ -435,7 +435,6 @@ _dfb_surface_for_each_cutout(IDirectFBSurface *surface, RGBA_Draw_Context *dc, _ surface->SetClip(surface, &cr); cb(surface, dc, &cr, data); } - evas_common_draw_context_apply_clear_cutouts(rects); } static void diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_font.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_font.c index 26760627a4..78eddc6f24 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_font.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_font.c @@ -103,7 +103,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co Evas_Engine_GL_Context *gc = context; RGBA_Draw_Context *dc = draw_context; Evas_GL_Texture *tex; - Cutout_Rects *rects; + static Cutout_Rects *rects = NULL; Cutout_Rect *rct; int r, g, b, a; double ssx, ssy, ssw, ssh; @@ -171,7 +171,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co 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; return; } - rects = evas_common_draw_context_apply_cutouts(dc); + rects = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; ++i) { int nx, ny, nw, nh; @@ -198,7 +198,6 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co nx, ny, nw, nh, r, g, b, a); } - evas_common_draw_context_apply_clear_cutouts(rects); /* restore clip info */ 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; } diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c index 39f16bbd83..79e33e71e6 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c @@ -690,12 +690,12 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, void evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth) { + static Cutout_Rects *rects = NULL; RGBA_Draw_Context *dc; Evas_GL_Image *imm; int r, g, b, a; double ssx, ssy, ssw, ssh; double mssx, mssy, mssw, mssh; - Cutout_Rects *rects; Cutout_Rect *rct; int c, cx, cy, cw, ch; int i; @@ -888,7 +888,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, 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; return; } - rects = evas_common_draw_context_apply_cutouts(dc); + rects = evas_common_draw_context_apply_cutouts(dc, rects); for (i = 0; i < rects->active; ++i) { int nx, ny, nw, nh; @@ -962,7 +962,6 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, r, g, b, a, smooth, im->tex_only); } - evas_common_draw_context_apply_clear_cutouts(rects); /* restore clip info */ 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; } diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_polygon.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_polygon.c index bc111bd3a2..81f041e4eb 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_polygon.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_polygon.c @@ -122,7 +122,7 @@ polygon_edge_sorter(const void *a, const void *b) void evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int dx, int dy) { - Cutout_Rects *rects; + static Cutout_Rects *rects = NULL; Cutout_Rect *r; int c, cx, cy, cw, ch, cr, cg, cb, ca, i; int x = 0, y = 0, w = 0, h = 0; @@ -272,7 +272,7 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int /* our clip is 0 size.. abort */ if ((gc->dc->clip.w > 0) && (gc->dc->clip.h > 0)) { - rects = evas_common_draw_context_apply_cutouts(gc->dc); + rects = evas_common_draw_context_apply_cutouts(gc->dc, rects); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; @@ -290,7 +290,6 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int } } } - evas_common_draw_context_apply_clear_cutouts(rects); } } while (spans) diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_rectangle.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_rectangle.c index 6254d87851..d95b5a28e8 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_rectangle.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_rectangle.c @@ -3,7 +3,7 @@ void evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h) { - Cutout_Rects *rects; + static Cutout_Rects *rects = NULL; Cutout_Rect *r; int c, cx, cy, cw, ch, cr, cg, cb, ca, i; @@ -37,7 +37,7 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h) /* our clip is 0 size.. abort */ if ((gc->dc->clip.w > 0) && (gc->dc->clip.h > 0)) { - rects = evas_common_draw_context_apply_cutouts(gc->dc); + rects = evas_common_draw_context_apply_cutouts(gc->dc, rects); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; @@ -46,7 +46,6 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h) evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca); } } - evas_common_draw_context_apply_clear_cutouts(rects); } } /* restore clip info */ diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c index 9fa5dcba16..f0494e28be 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c @@ -2747,7 +2747,7 @@ eng_image_scale_hint_get(void *data __UNUSED__, void *image) } static void -eng_image_map_draw(void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level) +eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level) { Evas_GL_Image *gim = image; Render_Engine *re; @@ -2757,46 +2757,51 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, int np eng_window_use(re->win); evas_gl_common_context_target_surface_set(re->win->gl_context, surface); re->win->gl_context->dc = context; - if (npoints != 4) + if (m->count != 4) { // FIXME: nash - you didn't fix this abort(); } - if ((p[0].x == p[3].x) && - (p[1].x == p[2].x) && - (p[0].y == p[1].y) && - (p[3].y == p[2].y) && - (p[0].x <= p[1].x) && - (p[0].y <= p[2].y) && - (p[0].u == 0) && - (p[0].v == 0) && - (p[1].u == (gim->w << FP)) && - (p[1].v == 0) && - (p[2].u == (gim->w << FP)) && - (p[2].v == (gim->h << FP)) && - (p[3].u == 0) && - (p[3].v == (gim->h << FP)) && - (p[0].col == 0xffffffff) && - (p[1].col == 0xffffffff) && - (p[2].col == 0xffffffff) && - (p[3].col == 0xffffffff)) + if ((m->pts[0].x == m->pts[3].x) && + (m->pts[1].x == m->pts[2].x) && + (m->pts[0].y == m->pts[1].y) && + (m->pts[3].y == m->pts[2].y) && + (m->pts[0].x <= m->pts[1].x) && + (m->pts[0].y <= m->pts[2].y) && + (m->pts[0].u == 0) && + (m->pts[0].v == 0) && + (m->pts[1].u == (gim->w << FP)) && + (m->pts[1].v == 0) && + (m->pts[2].u == (gim->w << FP)) && + (m->pts[2].v == (gim->h << FP)) && + (m->pts[3].u == 0) && + (m->pts[3].v == (gim->h << FP)) && + (m->pts[0].col == 0xffffffff) && + (m->pts[1].col == 0xffffffff) && + (m->pts[2].col == 0xffffffff) && + (m->pts[3].col == 0xffffffff)) { int dx, dy, dw, dh; - dx = p[0].x >> FP; - dy = p[0].y >> FP; - dw = (p[2].x >> FP) - dx; - dh = (p[2].y >> FP) - dy; + dx = m->pts[0].x >> FP; + dy = m->pts[0].y >> FP; + dw = (m->pts[2].x >> FP) - dx; + dh = (m->pts[2].y >> FP) - dy; eng_image_draw(data, context, surface, image, 0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth); } else { - evas_gl_common_image_map_draw(re->win->gl_context, image, npoints, p, + evas_gl_common_image_map_draw(re->win->gl_context, image, m->count, &m->pts[0], smooth, level); } } +static void +eng_image_map_clean(void *data, RGBA_Map *m) +{ +} + static void * eng_image_map_surface_new(void *data, int w, int h, int alpha) { @@ -4955,6 +4960,7 @@ module_open(Evas_Module *em) ORD(image_map_draw); ORD(image_map_surface_new); ORD(image_map_surface_free); + ORD(image_map_clean); ORD(image_content_hint_set); ORD(image_content_hint_get); diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c index 43e47279b9..bfb061c89e 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -939,41 +939,37 @@ image_loaded: } static void -eng_image_map_draw(void *data __UNUSED__, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level) +evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGBA_Image *im, RGBA_Map *m, int smooth, int level, int offset) { - RGBA_Image *im; + if (m->count - offset < 3) return; - if (!image) return; - if (npoints < 3) return; - im = image; - - if ((p[0].x == p[3].x) && - (p[1].x == p[2].x) && - (p[0].y == p[1].y) && - (p[3].y == p[2].y) && - (p[0].x <= p[1].x) && - (p[0].y <= p[2].y) && - (p[0].u == 0) && - (p[0].v == 0) && - (p[1].u == (int)(im->cache_entry.w << FP)) && - (p[1].v == 0) && - (p[2].u == (int)(im->cache_entry.w << FP)) && - (p[2].v == (int)(im->cache_entry.h << FP)) && - (p[3].u == 0) && - (p[3].v == (int)(im->cache_entry.h << FP)) && - (p[0].col == 0xffffffff) && - (p[1].col == 0xffffffff) && - (p[2].col == 0xffffffff) && - (p[3].col == 0xffffffff)) + if ((m->pts[0 + offset].x == m->pts[3 + offset].x) && + (m->pts[1 + offset].x == m->pts[2 + offset].x) && + (m->pts[0 + offset].y == m->pts[1 + offset].y) && + (m->pts[3 + offset].y == m->pts[2 + offset].y) && + (m->pts[0 + offset].x <= m->pts[1 + offset].x) && + (m->pts[0 + offset].y <= m->pts[2 + offset].y) && + (m->pts[0 + offset].u == 0) && + (m->pts[0 + offset].v == 0) && + (m->pts[1 + offset].u == (int)(im->cache_entry.w << FP)) && + (m->pts[1 + offset].v == 0) && + (m->pts[2 + offset].u == (int)(im->cache_entry.w << FP)) && + (m->pts[2 + offset].v == (int)(im->cache_entry.h << FP)) && + (m->pts[3 + offset].u == 0) && + (m->pts[3 + offset].v == (int)(im->cache_entry.h << FP)) && + (m->pts[0 + offset].col == 0xffffffff) && + (m->pts[1 + offset].col == 0xffffffff) && + (m->pts[2 + offset].col == 0xffffffff) && + (m->pts[3 + offset].col == 0xffffffff)) { int dx, dy, dw, dh; - dx = p[0].x >> FP; - dy = p[0].y >> FP; - dw = (p[2].x >> FP) - dx; - dh = (p[2].y >> FP) - dy; + dx = m->pts[0 + offset].x >> FP; + dy = m->pts[0 + offset].y >> FP; + dw = (m->pts[2 + offset].x >> FP) - dx; + dh = (m->pts[2 + offset].y >> FP) - dy; eng_image_draw - (data, context, surface, image, + (data, context, surface, im, 0, 0, im->cache_entry.w, im->cache_entry.h, dx, dy, dw, dh, smooth); } @@ -981,20 +977,39 @@ eng_image_map_draw(void *data __UNUSED__, void *context, void *surface, void *im { #ifdef BUILD_PIPE_RENDER if ((cpunum > 1)) - evas_common_pipe_map_draw(im, surface, context, npoints, p, smooth, level); + { + evas_common_pipe_map_draw(im, surface, context, m, smooth, level); + return ; + } else #endif - evas_common_map_rgba(im, surface, context, npoints, p, smooth, level); + { + evas_common_map_rgba(im, surface, context, m->count - offset, &m->pts[offset], smooth, level); + } } evas_common_cpu_end_opt(); - if (npoints > 4) + if (m->count > 4) { - eng_image_map_draw(data, context, surface, image, npoints - 2, p + 2, - smooth, level); + evas_software_image_map_draw(data, context, surface, im, m, smooth, level, offset + 2); } } +static void +eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level) +{ + if (!image) return; + if (m->count < 3) return; + + evas_software_image_map_draw(data, context, surface, image, m, smooth, level, 0); +} + +static void +eng_image_map_clean(void *data __UNUSED__, RGBA_Map *m) +{ + evas_common_map_rgba_clean(m); +} + static void * eng_image_map_surface_new(void *data __UNUSED__, int w, int h, int alpha) { @@ -1843,6 +1858,7 @@ static Evas_Func func = eng_image_map_draw, eng_image_map_surface_new, eng_image_map_surface_free, + eng_image_map_clean, NULL, // eng_image_content_hint_set - software doesn't use it NULL, // eng_image_content_hint_get - software doesn't use it eng_font_pen_coords_get, @@ -2873,6 +2889,7 @@ module_open(Evas_Module *em) } init_gl(); + evas_common_pipe_init(); em->functions = (void *)(&func); cpunum = eina_cpu_count(); diff --git a/legacy/evas/src/modules/engines/software_x11/evas_engine.h b/legacy/evas/src/modules/engines/software_x11/evas_engine.h index ce60ea7b89..73a62bccdf 100644 --- a/legacy/evas/src/modules/engines/software_x11/evas_engine.h +++ b/legacy/evas/src/modules/engines/software_x11/evas_engine.h @@ -111,7 +111,7 @@ struct _Outbuf /* 1 big buffer for updates - flush on idle_flush */ RGBA_Image *onebuf; - Eina_List *onebuf_regions; + Eina_Array onebuf_regions; /* a list of pending regions to write to the target */ Eina_List *pending_writes; diff --git a/legacy/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c b/legacy/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c index c78814715a..ab4e777a4a 100644 --- a/legacy/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c +++ b/legacy/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c @@ -181,6 +181,7 @@ evas_software_xlib_outbuf_free(Outbuf *buf) if (buf->priv.pal) evas_software_xlib_x_color_deallocate(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap, buf->priv.x11.xlib.vis, buf->priv.pal); + eina_array_flush(&buf->priv.onebuf_regions); free(buf); _clear_xob(0); } @@ -211,6 +212,8 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth, buf->priv.mask_dither = shape_dither; buf->priv.destination_alpha = destination_alpha; + eina_array_step_set(&buf->priv.onebuf_regions, sizeof (Eina_Array), 8); + { Gfx_Func_Convert conv_func; X_Output_Buffer *xob; @@ -379,8 +382,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w return NULL; } - buf->priv.onebuf_regions = eina_list_append(buf->priv.onebuf_regions, rect); - if (buf->priv.onebuf) + if (!eina_array_push(&buf->priv.onebuf_regions, rect)) { *cx = x; *cy = y; @@ -708,20 +710,20 @@ evas_software_xlib_outbuf_flush(Outbuf *buf) RGBA_Image *im; Outbuf_Region *obr; - if ((buf->priv.onebuf) && (buf->priv.onebuf_regions)) + if ((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions)) { + Eina_Rectangle *rect; + Eina_Array_Iterator it; + unsigned int i; Region tmpr; im = buf->priv.onebuf; obr = im->extended_info; tmpr = XCreateRegion(); - while (buf->priv.onebuf_regions) + EINA_ARRAY_ITER_NEXT(&buf->priv.onebuf_regions, i, rect, it) { - Eina_Rectangle *rect; XRectangle xr; - rect = buf->priv.onebuf_regions->data; - buf->priv.onebuf_regions = eina_list_remove_list(buf->priv.onebuf_regions, buf->priv.onebuf_regions); if (buf->rot == 0) { xr.x = rect->x; @@ -756,6 +758,7 @@ evas_software_xlib_outbuf_flush(Outbuf *buf) xr.x, xr.y, xr.width, xr.height); eina_rectangle_free(rect); } + eina_array_clean(&buf->priv.onebuf_regions); XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc, tmpr); if (obr->xob) evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win, @@ -1025,7 +1028,7 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i #if 1 #else /* XX async push */ - if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions))) + if (!((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions))) { if (buf->priv.debug) evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win, @@ -1076,7 +1079,7 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i #if 1 #else /* XX async push */ - if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions))) + if (!((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions))) evas_software_xlib_x_output_buffer_paste(obr->mxob, buf->priv.x11.xlib.mask, buf->priv.x11.xlib.gcm,