From cb10c7d01974b6afbc75839da4988f259335c1e0 Mon Sep 17 00:00:00 2001 From: Leandro Pereira Date: Tue, 18 Dec 2012 16:28:55 +0000 Subject: [PATCH] evas: Modify software_generic and gl_x11 to with with threaded renderer SVN revision: 81284 --- src/lib/evas/canvas/evas_object_image.c | 59 +- src/lib/evas/canvas/evas_object_line.c | 7 +- src/lib/evas/canvas/evas_object_polygon.c | 7 +- src/lib/evas/canvas/evas_object_rectangle.c | 7 +- src/lib/evas/canvas/evas_object_smart.c | 4 +- src/lib/evas/canvas/evas_object_text.c | 7 +- src/lib/evas/canvas/evas_object_textblock.c | 9 +- src/lib/evas/canvas/evas_object_textgrid.c | 13 +- src/lib/evas/canvas/evas_render.c | 31 +- src/lib/evas/include/evas_common.h | 3 + src/lib/evas/include/evas_private.h | 14 +- src/modules/evas/engines/gl_x11/evas_engine.c | 14 +- .../engines/software_generic/evas_engine.c | 715 +++++++++++++++++- 13 files changed, 790 insertions(+), 100 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 5f2f02ce97..5913f367cd 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -111,7 +111,7 @@ static Evas_Coord evas_object_image_figure_y_fill(Evas_Object *eo_obj, Evas_Obje static void evas_object_image_init(Evas_Object *eo_obj); static void evas_object_image_new(Evas_Object *eo_obj); -static void evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y); +static void evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async); static void evas_object_image_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_image_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_image_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); @@ -132,7 +132,7 @@ static void evas_object_image_filled_resize_listener(void *data, Evas *eo_e, Eva static void _proxy_unset(Evas_Object *proxy); static void _proxy_set(Evas_Object *proxy, Evas_Object *src); -static void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y); +static void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y, Eina_Bool do_async); static void _cleanup_tmpf(Evas_Object *eo_obj); @@ -1272,6 +1272,9 @@ _image_data_get(Eo *eo_obj, void *_pd, va_list *list) } Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS); + + if (for_writing) evas_render_rendering_wait(obj->layer->evas); + data = NULL; if (obj->layer->evas->engine.func->image_scale_hint_set) obj->layer->evas->engine.func->image_scale_hint_set @@ -2744,7 +2747,7 @@ _proxy_set(Evas_Object *eo_proxy, Evas_Object *eo_src) */ static void _proxy_error(Evas_Object *eo_proxy, void *context, void *output, void *surface, - int x, int y) + int x, int y, Eina_Bool do_async) { Evas_Func *func; int r = rand() % 255; @@ -2763,7 +2766,8 @@ _proxy_error(Evas_Object *eo_proxy, void *context, void *output, void *surface, func->rectangle_draw(output, context, surface, proxy->cur.geometry.x + x, proxy->cur.geometry.y + y, proxy->cur.geometry.w, - proxy->cur.geometry.h); + proxy->cur.geometry.h, + do_async); return; } @@ -2808,7 +2812,7 @@ _proxy_subrender_recurse(Evas_Object *eo_obj, Evas_Object *clip, void *output, v * Used to force a draw if necessary, else just makes sures it's available. */ static void -_proxy_subrender(Evas *eo_e, Evas_Object *eo_source) +_proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Eina_Bool do_async) { Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS); void *ctx; @@ -2848,7 +2852,8 @@ _proxy_subrender(Evas *eo_e, Evas_Object *eo_source) e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0, 0, 0); e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY); e->engine.func->rectangle_draw(e->engine.data.output, ctx, - source->proxy.surface, 0, 0, w, h); + source->proxy.surface, 0, 0, w, h, + do_async); e->engine.func->context_free(e->engine.data.output, ctx); ctx = e->engine.func->context_new(e->engine.data.output); @@ -2859,7 +2864,7 @@ _proxy_subrender(Evas *eo_e, Evas_Object *eo_source) #ifdef REND_DBG , 1 #endif - ); + , do_async); e->engine.func->context_free(e->engine.data.output, ctx); source->proxy.surface = e->engine.func->image_dirty_region @@ -3130,7 +3135,7 @@ evas_object_image_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) } static void -evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y) +evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async) { Evas_Object_Image *o = eo_data_get(eo_obj, MY_CLASS); int imagew, imageh, uvw, uvh; @@ -3142,7 +3147,7 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v /* Proxy sanity */ if (o->proxyrendering) { - _proxy_error(eo_obj, context, output, surface, x, y); + _proxy_error(eo_obj, context, output, surface, x, y, EINA_FALSE); return; } @@ -3163,9 +3168,10 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v obj->cur.geometry.x + x, obj->cur.geometry.y + y, obj->cur.geometry.w, - obj->cur.geometry.h); + obj->cur.geometry.h, + do_async); - return ; + return; } obj->layer->evas->engine.func->context_color_set(output, @@ -3225,7 +3231,7 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v else { o->proxyrendering = EINA_TRUE; - _proxy_subrender(obj->layer->evas->evas, o->cur.source); + _proxy_subrender(obj->layer->evas->evas, o->cur.source, EINA_FALSE); pixels = source->proxy.surface; imagew = source->proxy.w; imageh = source->proxy.h; @@ -3278,7 +3284,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v obj->layer->evas->engine.func->image_map_draw (output, context, surface, pixels, obj->spans, - o->cur.smooth_scale | obj->cur.map->smooth, 0); + o->cur.smooth_scale | obj->cur.map->smooth, 0, + do_async); } else { @@ -3357,7 +3364,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v obj->cur.geometry.x + ix + x, obj->cur.geometry.y + iy + y, iw, ih, - o->cur.smooth_scale); + o->cur.smooth_scale, + do_async); } else #endif @@ -3369,7 +3377,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v obj->cur.geometry.x + ix + x, obj->cur.geometry.y + iy + y, iw, ih, - o->cur.smooth_scale); + o->cur.smooth_scale, + do_async); } } else @@ -3423,28 +3432,28 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v inw = bl; inh = bt; outx = ox; outy = oy; outw = bsl; outh = bst; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // .## // | inx = bl; iny = 0; inw = imw - bl - br; inh = bt; outx = ox + bsl; outy = oy; outw = iw - bsl - bsr; outh = bst; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // --# // | inx = imw - br; iny = 0; inw = br; inh = bt; outx = ox + iw - bsr; outy = oy; outw = bsr; outh = bst; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // .-- // # inx = 0; iny = bt; inw = bl; inh = imh - bt - bb; outx = ox; outy = oy + bst; outw = bsl; outh = ih - bst - bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // .--. // |##| if (o->cur.border.fill > EVAS_BORDER_FILL_NONE) @@ -3459,12 +3468,12 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v { obj->layer->evas->engine.func->context_render_op_set(output, context, EVAS_RENDER_COPY); - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); obj->layer->evas->engine.func->context_render_op_set(output, context, obj->cur.render_op); } else - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); } // --. // # @@ -3472,28 +3481,28 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v inw = br; inh = imh - bt - bb; outx = ox + iw - bsr; outy = oy + bst; outw = bsr; outh = ih - bst - bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // | // #-- inx = 0; iny = imh - bb; inw = bl; inh = bb; outx = ox; outy = oy + ih - bsb; outw = bsl; outh = bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // | // .## inx = bl; iny = imh - bb; inw = imw - bl - br; inh = bb; outx = ox + bsl; outy = oy + ih - bsb; outw = iw - bsl - bsr; outh = bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); // | // --# inx = imw - br; iny = imh - bb; inw = br; inh = bb; outx = ox + iw - bsr; outy = oy + ih - bsb; outw = bsr; outh = bsb; - obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale); + obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale, do_async); } idy += idh; if (dobreak_h) break; diff --git a/src/lib/evas/canvas/evas_object_line.c b/src/lib/evas/canvas/evas_object_line.c index 76a6263d85..ac39fce525 100644 --- a/src/lib/evas/canvas/evas_object_line.c +++ b/src/lib/evas/canvas/evas_object_line.c @@ -31,7 +31,7 @@ struct _Evas_Object_Line /* private methods for line objects */ static void evas_object_line_init(Evas_Object *eo_obj); -static void evas_object_line_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y); +static void evas_object_line_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async); static void evas_object_line_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_line_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); @@ -253,7 +253,7 @@ _destructor(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) } static void -evas_object_line_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y) +evas_object_line_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async) { Evas_Object_Line *o = eo_data_get(eo_obj, MY_CLASS); @@ -277,7 +277,8 @@ evas_object_line_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, vo o->cur.cache.x1 + x, o->cur.cache.y1 + y, o->cur.cache.x2 + x, - o->cur.cache.y2 + y); + o->cur.cache.y2 + y, + do_async); } static void diff --git a/src/lib/evas/canvas/evas_object_polygon.c b/src/lib/evas/canvas/evas_object_polygon.c index 475c555197..9e57b45b7e 100644 --- a/src/lib/evas/canvas/evas_object_polygon.c +++ b/src/lib/evas/canvas/evas_object_polygon.c @@ -32,7 +32,7 @@ struct _Evas_Polygon_Point /* private methods for polygon objects */ static void evas_object_polygon_init(Evas_Object *eo_obj); -static void evas_object_polygon_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y); +static void evas_object_polygon_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async); static void evas_object_polygon_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_polygon_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_polygon_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); @@ -297,7 +297,7 @@ evas_object_polygon_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) } static void -evas_object_polygon_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y) +evas_object_polygon_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async) { Evas_Object_Polygon *o = eo_data_get(eo_obj, MY_CLASS); Eina_List *l; @@ -335,7 +335,8 @@ evas_object_polygon_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, context, surface, o->engine_data, - o->offset.x + x, o->offset.y + y); + o->offset.x + x, o->offset.y + y, + do_async); } static void diff --git a/src/lib/evas/canvas/evas_object_rectangle.c b/src/lib/evas/canvas/evas_object_rectangle.c index a90aeb77b4..1b132e5a31 100644 --- a/src/lib/evas/canvas/evas_object_rectangle.c +++ b/src/lib/evas/canvas/evas_object_rectangle.c @@ -22,7 +22,7 @@ struct _Evas_Object_Rectangle /* private methods for rectangle objects */ static void evas_object_rectangle_init(Evas_Object *eo_obj); -static void evas_object_rectangle_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y); +static void evas_object_rectangle_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async); static void evas_object_rectangle_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_rectangle_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); @@ -122,7 +122,7 @@ _destructor(Eo *eo_obj, void *_obj EINA_UNUSED, va_list *list EINA_UNUSED) } static void -evas_object_rectangle_render(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y) +evas_object_rectangle_render(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async) { /* render object to surface with context, and offxet by x,y */ obj->layer->evas->engine.func->context_color_set(output, @@ -141,7 +141,8 @@ evas_object_rectangle_render(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protec obj->cur.geometry.x + x, obj->cur.geometry.y + y, obj->cur.geometry.w, - obj->cur.geometry.h); + obj->cur.geometry.h, + do_async); //// obj->cur.cache.geometry.x + x, //// obj->cur.cache.geometry.y + y, //// obj->cur.cache.geometry.w, diff --git a/src/lib/evas/canvas/evas_object_smart.c b/src/lib/evas/canvas/evas_object_smart.c index 9502aef7a4..86a0f78310 100644 --- a/src/lib/evas/canvas/evas_object_smart.c +++ b/src/lib/evas/canvas/evas_object_smart.c @@ -41,7 +41,7 @@ struct _Evas_Smart_Callback /* private methods for smart objects */ static void evas_object_smart_callbacks_clear(Evas_Object *eo_obj); static void evas_object_smart_init(Evas_Object *eo_obj); -static void evas_object_smart_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y); +static void evas_object_smart_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async); static void evas_object_smart_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_smart_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); @@ -1322,7 +1322,7 @@ evas_object_smart_init(Evas_Object *eo_obj) } static void -evas_object_smart_render(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj EINA_UNUSED, void *output EINA_UNUSED, void *context EINA_UNUSED, void *surface EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED) +evas_object_smart_render(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj EINA_UNUSED, void *output EINA_UNUSED, void *context EINA_UNUSED, void *surface EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, Eina_Bool do_async EINA_UNUSED) { return; } diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c index 0c410d1588..2f0f229389 100644 --- a/src/lib/evas/canvas/evas_object_text.c +++ b/src/lib/evas/canvas/evas_object_text.c @@ -66,7 +66,7 @@ struct _Evas_Object_Text_Item /* private methods for text objects */ static void evas_object_text_init(Evas_Object *eo_obj); -static void evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y); +static void evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async); static void evas_object_text_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_text_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_text_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); @@ -1886,7 +1886,7 @@ evas_object_text_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) } static void -evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y) +evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async) { int i, j; Evas_Object_Text *o = eo_data_get(eo_obj, MY_CLASS); @@ -1977,7 +1977,8 @@ evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, vo obj->cur.geometry.h, \ obj->cur.geometry.w, \ obj->cur.geometry.h, \ - &it->text_props); + &it->text_props, \ + do_async); /* shadows */ shad_dst = shad_sz = dx = dy = haveshad = 0; diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index fa7cad7c6d..8ce1a6dfb8 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -506,7 +506,7 @@ struct _Evas_Object_Textblock /* private methods for textblock objects */ static void evas_object_textblock_init(Evas_Object *eo_obj); -static void evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y); +static void evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async); static void evas_object_textblock_free(Evas_Object *eo_obj); static void evas_object_textblock_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_textblock_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); @@ -9608,7 +9608,7 @@ evas_object_textblock_free(Evas_Object *eo_obj) static void -evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y) +evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async) { Evas_Object_Textblock_Paragraph *par, *start = NULL; Evas_Object_Textblock_Line *ln; @@ -9703,7 +9703,7 @@ evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob obj->cur.geometry.x + ln->x + ti->parent.x + x + (ox), \ obj->cur.geometry.y + ln->par->y + ln->y + yoff + y + (oy), \ ti->parent.w, ti->parent.h, ti->parent.w, ti->parent.h, \ - &ti->text_props); + &ti->text_props, do_async); /* backing */ #define DRAW_RECT(ox, oy, ow, oh, or, og, ob, oa) \ @@ -9721,7 +9721,8 @@ evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob obj->cur.geometry.x + ln->x + x + (ox), \ obj->cur.geometry.y + ln->par->y + ln->y + y + (oy), \ (ow), \ - (oh)); \ + (oh), \ + do_async); \ } \ while (0) diff --git a/src/lib/evas/canvas/evas_object_textgrid.c b/src/lib/evas/canvas/evas_object_textgrid.c index fcb6892c65..c82122e3bb 100644 --- a/src/lib/evas/canvas/evas_object_textgrid.c +++ b/src/lib/evas/canvas/evas_object_textgrid.c @@ -114,7 +114,7 @@ struct _Evas_Object_Textgrid_Line /* private methods for textgrid objects */ static void evas_object_textgrid_init(Evas_Object *eo_obj); -static void evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y); +static void evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async); static void evas_object_textgrid_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); static void evas_object_textgrid_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); @@ -551,7 +551,7 @@ evas_object_textgrid_row_line_append(Evas_Object_Textgrid_Row *row, int x, int w } static void -evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y) +evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async) { Evas_Textgrid_Cell *cells; Evas_Object_Textgrid_Color *c; @@ -670,7 +670,8 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj row->rects[xx].b, row->rects[xx].a); ENFN->rectangle_draw(output, context, surface, xp + row->rects[xx].x, yp, - row->rects[xx].w, h); + row->rects[xx].w, h, + do_async); } for (xx = 0; xx < row->texts_num; xx++) { @@ -680,7 +681,8 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj ENFN->font_draw(output, context, surface, o->font, xp + row->texts[xx].x, yp + o->max_ascent, ww, hh, ww, hh, - evas_object_textgrid_textprop_int_to(o, row->texts[xx].text_props)); + evas_object_textgrid_textprop_int_to(o, row->texts[xx].text_props), + do_async); } for (xx = 0; xx < row->lines_num; xx++) { @@ -689,7 +691,8 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj row->lines[xx].b, row->lines[xx].a); ENFN->rectangle_draw(output, context, surface, xp + row->lines[xx].x, yp + row->lines[xx].y, - row->lines[xx].w, 1); + row->lines[xx].w, 1, + do_async); } yp += h; } diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index eb4f823a3b..7e1f80b87d 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -49,8 +49,15 @@ rend_dbg(const char *txt) #define RDI(x) #endif -static Eina_List * -evas_render_updates_internal(Evas *eo_e, unsigned char make_updates, unsigned char do_draw); +typedef struct _Render_Updates Render_Updates; +struct _Render_Updates +{ + void *surface; + Eina_Rectangle *area; +}; + +static Eina_Bool +evas_render_updates_internal(Evas *eo_e, unsigned char make_updates, unsigned char do_draw, Evas_Render_Done_Cb done_func, void *done_data, Eina_Bool do_async); EAPI void evas_damage_rectangle_add(Evas *eo_e, int x, int y, int w, int h) @@ -870,7 +877,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, #ifdef REND_DBG , int level #endif - ) + , Eina_Bool do_async) { void *ctx; Evas_Object_Protected_Data *obj2; @@ -1007,7 +1014,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, obj->map.surface, 0, 0, obj->map.surface_w, - obj->map.surface_h); + obj->map.surface_h, + EINA_FALSE); e->engine.func->context_free(e->engine.data.output, ctx); } ctx = e->engine.func->context_new(e->engine.data.output); @@ -1027,7 +1035,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, #ifdef REND_DBG , level + 1 #endif - ); + , do_async); } } else @@ -1045,7 +1053,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, e->engine.func->context_clip_set(e->engine.data.output, ctx, x, y, w, h); obj->func->render(eo_obj, obj, e->engine.data.output, ctx, - obj->map.surface, off_x2, off_y2); + obj->map.surface, off_x2, off_y2, + EINA_FALSE); } e->engine.func->context_free(e->engine.data.output, ctx); rendered = EINA_TRUE; @@ -1107,7 +1116,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, obj->layer->evas->engine.func->image_map_draw (e->engine.data.output, context, surface, obj->map.surface, obj->spans, - obj->cur.map->smooth, 0); + obj->cur.map->smooth, 0, do_async); } // FIXME: needs to cache these maps and // keep them only rendering updates @@ -1140,7 +1149,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, #ifdef REND_DBG , level + 1 #endif - ); + , do_async); } } else @@ -1185,7 +1194,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, ctx, x, y, w, h); } obj->func->render(eo_obj, obj, e->engine.data.output, ctx, - surface, off_x, off_y); + surface, off_x, off_y, EINA_FALSE); } e->engine.func->context_free(e->engine.data.output, ctx); } @@ -1217,7 +1226,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, RDI(level); RD(" draw normal obj\n"); obj->func->render(eo_obj, obj, e->engine.data.output, context, surface, - off_x, off_y); + off_x, off_y, do_async); } if (obj->changed_map) clean_them = EINA_TRUE; } @@ -1607,7 +1616,7 @@ evas_render_updates_internal(Evas *eo_e, e->engine.func->rectangle_draw(e->engine.data.output, e->engine.data.context, surface, - cx, cy, cw, ch); + cx, cy, cw, ch, do_async); e->engine.func->context_cutout_clear(e->engine.data.output, e->engine.data.context); e->engine.func->context_clip_unset(e->engine.data.output, diff --git a/src/lib/evas/include/evas_common.h b/src/lib/evas/include/evas_common.h index 5b231ace7a..15c1d3a5f9 100644 --- a/src/lib/evas/include/evas_common.h +++ b/src/lib/evas/include/evas_common.h @@ -428,6 +428,9 @@ typedef void (*Gfx_Func_Copy) (DATA32 *src, DATA32 *dst, int len); typedef void (*Gfx_Func_Convert) (DATA32 *src, DATA8 *dst, int src_jump, int dst_jump, int w, int h, int dith_x, int dith_y, DATA8 *pal); + +typedef void (*Evas_Render_Done_Cb)(void *); + #include "../cache/evas_cache.h" #ifdef EVAS_CSERVE2 #include "../cache2/evas_cache2.h" diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 8f68171c2e..56ddc4c9d7 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -795,13 +795,13 @@ struct _Evas_Func void (*context_render_op_set) (void *data, void *context, int render_op); int (*context_render_op_get) (void *data, void *context); - void (*rectangle_draw) (void *data, void *context, void *surface, int x, int y, int w, int h); + void (*rectangle_draw) (void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async); - void (*line_draw) (void *data, void *context, void *surface, int x1, int y1, int x2, int y2); + void (*line_draw) (void *data, void *context, void *surface, int x1, int y1, int x2, int y2, Eina_Bool do_async); void *(*polygon_point_add) (void *data, void *context, void *polygon, int x, int y); void *(*polygon_points_clear) (void *data, void *context, void *polygon); - void (*polygon_draw) (void *data, void *context, void *surface, void *polygon, int x, int y); + void (*polygon_draw) (void *data, void *context, void *surface, void *polygon, int x, int y, Eina_Bool do_async); void *(*image_load) (void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo); void *(*image_new_from_data) (void *data, int w, int h, DATA32 *image_data, int alpha, int cspace); @@ -819,7 +819,7 @@ struct _Evas_Func int (*image_alpha_get) (void *data, void *image); void *(*image_border_set) (void *data, void *image, int l, int r, int t, int b); void (*image_border_get) (void *data, void *image, int *l, int *r, int *t, int *b); - void (*image_draw) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth); + void (*image_draw) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async); char *(*image_comment_get) (void *data, void *image, char *key); char *(*image_format_get) (void *data, void *image); void (*image_colorspace_set) (void *data, void *image, int cspace); @@ -847,7 +847,7 @@ struct _Evas_Func int (*font_v_advance_get) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props); int (*font_char_coords_get) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch); int (*font_char_at_coords_get) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch); - void (*font_draw) (void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w, int h, int ow, int oh, Evas_Text_Props *intl_props); + void (*font_draw) (void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w, int h, int ow, int oh, Evas_Text_Props *intl_props, Eina_Bool do_async); void (*font_cache_flush) (void *data); void (*font_cache_set) (void *data, int bytes); @@ -864,7 +864,7 @@ 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, RGBA_Map *m, int smooth, int level); + void (*image_map_draw) (void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async); 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); @@ -1207,7 +1207,7 @@ Eina_Bool evas_render_mapped(Evas_Public_Data *e, Evas_Object *obj, #ifdef REND_DBG , int level #endif - ); + , Eina_Bool do_async); void evas_render_invalidate(Evas *e); void evas_render_object_recalc(Evas_Object *obj); diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 35bbd9542c..63dd9196ca 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -1293,7 +1293,7 @@ eng_context_cutout_clear(void *data EINA_UNUSED, void *context) } static void -eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h) +eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED) { Render_Engine *re; @@ -1305,7 +1305,7 @@ eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w } static void -eng_line_draw(void *data, void *context, void *surface, int p1x, int p1y, int p2x, int p2y) +eng_line_draw(void *data, void *context, void *surface, int p1x, int p1y, int p2x, int p2y, Eina_Bool do_async EINA_UNUSED) { Render_Engine *re; @@ -1337,7 +1337,7 @@ eng_polygon_points_clear(void *data, void *context EINA_UNUSED, void *polygon) } static void -eng_polygon_draw(void *data, void *context, void *surface EINA_UNUSED, void *polygon, int x, int y) +eng_polygon_draw(void *data, void *context, void *surface EINA_UNUSED, void *polygon, int x, int y, Eina_Bool do_async EINA_UNUSED) { Render_Engine *re; @@ -2430,7 +2430,7 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const void *t } static void -eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) +eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async EINA_UNUSED) { Render_Engine *re; re = (Render_Engine *)data; @@ -2474,7 +2474,7 @@ eng_image_scale_hint_get(void *data EINA_UNUSED, void *image) } static void -eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level) +eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async) { Evas_GL_Image *gim = image; Render_Engine *re; @@ -2515,7 +2515,7 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_M 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); + 0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth, do_async); } else { @@ -2602,7 +2602,7 @@ eng_image_stride_get(void *data EINA_UNUSED, void *image, int *stride) } static void -eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font EINA_UNUSED, int x, int y, int w EINA_UNUSED, int h EINA_UNUSED, int ow EINA_UNUSED, int oh EINA_UNUSED, Evas_Text_Props *intl_props) +eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font EINA_UNUSED, int x, int y, int w EINA_UNUSED, int h EINA_UNUSED, int ow EINA_UNUSED, int oh EINA_UNUSED, Evas_Text_Props *intl_props, Eina_Bool do_async EINA_UNUSED) { Render_Engine *re; diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index e16795d06c..6b8fa8b7a6 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -1,5 +1,6 @@ #include "evas_common.h" /* Also includes international specific stuff */ #include "evas_private.h" +#include "evas_blend_private.h" #ifdef EVAS_CSERVE2 #include "evas_cs2_private.h" #endif @@ -273,6 +274,83 @@ static void (*_sym_glViewport) (GLint x, GLint /* static void (*_sym_glProgramParameteri) (GLuint a, GLuint b, GLint d) = NULL; */ #endif +// Threaded Render + +typedef struct _Evas_Thread_Command_Rect Evas_Thread_Command_Rect; +typedef struct _Evas_Thread_Command_Line Evas_Thread_Command_Line; +typedef struct _Evas_Thread_Command_Polygon Evas_Thread_Command_Polygon; +typedef struct _Evas_Thread_Command_Image Evas_Thread_Command_Image; +typedef struct _Evas_Thread_Command_Font Evas_Thread_Command_Font; +typedef struct _Evas_Thread_Command_Map Evas_Thread_Command_Map; + +struct _Evas_Thread_Command_Rect +{ + void *surface; + DATA32 color; + int render_op; + int x, y, w, h; +}; + +struct _Evas_Thread_Command_Line +{ + void *surface; + Eina_Rectangle clip; + DATA32 color; + int render_op; + Eina_Bool anti_alias; + int x1, y1; + int x2, y2; +}; + +struct _Evas_Thread_Command_Polygon +{ + Eina_Rectangle ext; + DATA32 col; + int render_op; + void *surface; + RGBA_Polygon_Point *points; + int x, y; +}; + +struct _Evas_Thread_Command_Image +{ + void *surface; + void *image; + Eina_Rectangle src, dst, clip; + DATA32 mul_col; + int render_op; + int smooth; +}; + +struct _Evas_Thread_Command_Font +{ + RGBA_Image *dst; + int x; + int y; + Evas_Glyph_Array *glyphs; + RGBA_Gfx_Func func; + void *gl_new; + void *gl_free; + void *gl_draw; + void *font_ext_data; + DATA32 col; + Eina_Bool clip_use : 1; + Eina_Rectangle clip_rect, ext; + int im_w, im_h; +}; + +struct _Evas_Thread_Command_Map +{ + void *image; + RGBA_Draw_Context image_ctx; + void *surface; + Eina_Rectangle clip; + DATA32 mul_col; + int render_op; + RGBA_Map *map; + int smooth, level, offset; +}; + /* ***** ** @@ -416,33 +494,154 @@ eng_context_render_op_get(void *data EINA_UNUSED, void *context) return ((RGBA_Draw_Context *)context)->render_op; } +static void +_draw_thread_rectangle_draw(void *data) +{ + Evas_Thread_Command_Rect *rect = data; + evas_common_rectangle_rgba_draw(rect->surface, + rect->color, rect->render_op, + rect->x, rect->y, rect->w, rect->h); +} static void -eng_rectangle_draw(void *data EINA_UNUSED, void *context, void *surface, int x, int y, int w, int h) +_draw_rectangle_thread_cmd(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h) { + Evas_Thread_Command_Rect cr; + + RECTS_CLIP_TO_RECT(x, y, w, h, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h); + if ((w <= 0) || (h <= 0)) return; + + cr.surface = dst; + cr.color = dc->col.col; + cr.render_op = dc->render_op; + cr.x = x; + cr.y = y; + cr.w = w; + cr.h = h; + + evas_thread_cmd_enqueue(_draw_thread_rectangle_draw, &cr, sizeof(cr)); +} + +static void +eng_rectangle_draw(void *data EINA_UNUSED, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async) +{ + if (do_async) + evas_common_rectangle_draw_cb(surface, context, x, y, w, h, + _draw_rectangle_thread_cmd); #ifdef BUILD_PIPE_RENDER - if ((cpunum > 1)) + else if ((cpunum > 1)) evas_common_pipe_rectangle_draw(surface, context, x, y, w, h); - else #endif + else { - evas_common_rectangle_draw(surface, context, x, y, w, h); - evas_common_cpu_end_opt(); + evas_common_rectangle_draw(surface, context, x, y, w, h); + evas_common_cpu_end_opt(); } } static void -eng_line_draw(void *data EINA_UNUSED, void *context, void *surface, int x1, int y1, int x2, int y2) +_draw_thread_line_draw(void *data) { -#ifdef BUILD_PIPE_RENDER - if ((cpunum > 1)) - evas_common_pipe_line_draw(surface, context, x1, y1, x2, y2); - else -#endif + Evas_Thread_Command_Line *line = data; + int clip_x, clip_y, clip_w, clip_h; + + clip_x = line->clip.x; + clip_y = line->clip.y; + clip_w = line->clip.w; + clip_h = line->clip.h; + + if ((line->x1 == line->x2) && (line->y1 == line->y2)) { - evas_common_line_draw(surface, context, x1, y1, x2, y2); - evas_common_cpu_end_opt(); + evas_common_line_point_draw(line->surface, + clip_x, clip_y, clip_w, clip_h, + line->color, line->render_op, + line->x1, line->y1); + return; + } + + if (line->anti_alias) + evas_common_line_draw_line_aa + (line->surface, + clip_x, clip_y, clip_w, clip_h, + line->color, line->render_op, + line->x1, line->y1, + line->x2, line->y2); + else + evas_common_line_draw_line + (line->surface, + clip_x, clip_y, clip_w, clip_h, + line->color, line->render_op, + line->x1, line->y1, + line->x2, line->y2); +} + +static void +_line_draw_thread_cmd(RGBA_Image *dst, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2) +{ + Evas_Thread_Command_Line cl; + int clx, cly, clw, clh; + int cx, cy, cw, ch; + int x, y, w, h; + + cl.surface = dst; + + if ((x1 == x2) && (y1 == y2)) + { + EINA_RECTANGLE_SET(&cl.clip, + dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h); + goto done; + } + + clx = cly = 0; + clw = dst->cache_entry.w; + clh = dst->cache_entry.h; + + cx = dc->clip.x; + cy = dc->clip.y; + cw = dc->clip.w; + ch = dc->clip.h; + + if (dc->clip.use) + { + RECTS_CLIP_TO_RECT(clx, cly, clw, clh, cx, cy, cw, ch); + if ((clw < 1) || (clh < 1)) return; + } + + x = MIN(x1, x2); + y = MIN(y1, y2); + w = MAX(x1, x2) - x + 1; + h = MAX(y1, y2) - y + 1; + + RECTS_CLIP_TO_RECT(clx, cly, clw, clh, x, y, w, h); + if ((clw < 1) || (clh < 1)) return; + + EINA_RECTANGLE_SET(&cl.clip, clx, cly, clw, clh); + + done: + cl.color = dc->col.col; + cl.render_op = dc->render_op; + cl.anti_alias = dc->anti_alias; + cl.x1 = x1; + cl.y1 = y1; + cl.x2 = x2; + cl.y2 = y2; + + evas_thread_cmd_enqueue(_draw_thread_line_draw, &cl, sizeof(cl)); +} + +static void +eng_line_draw(void *data EINA_UNUSED, void *context, void *surface, int x1, int y1, int x2, int y2, Eina_Bool do_async) +{ + if (do_async) _line_draw_thread_cmd(surface, context, x1, y1, x2, y2); +#ifdef BUILD_PIPE_RENDER + else if ((cpunum > 1)) + evas_common_pipe_line_draw(surface, context, x1, y1, x2, y2); +#endif + else + { + evas_common_line_draw(surface, context, x1, y1, x2, y2); + evas_common_cpu_end_opt(); } } @@ -459,13 +658,115 @@ eng_polygon_points_clear(void *data EINA_UNUSED, void *context EINA_UNUSED, void } static void -eng_polygon_draw(void *data EINA_UNUSED, void *context, void *surface, void *polygon, int x, int y) +_draw_thread_polygon_cleanup(Evas_Thread_Command_Polygon *poly) { + RGBA_Polygon_Point *points = poly->points; + + while (points) + { + RGBA_Polygon_Point *p; + + p = points; + points = + (RGBA_Polygon_Point *)eina_inlist_remove(EINA_INLIST_GET(points), + EINA_INLIST_GET(points)); + free(p); + } + + poly->points = NULL; +} + +static void +_draw_thread_polygon_draw(void *data) +{ + Evas_Thread_Command_Polygon *poly = data; + + evas_common_polygon_rgba_draw + (poly->surface, + poly->ext.x, poly->ext.y, poly->ext.w, poly->ext.h, + poly->col, poly->render_op, + poly->points, poly->x, poly->y); + + _draw_thread_polygon_cleanup(poly); +} + +static void +_polygon_draw_thread_points_populate(Evas_Thread_Command_Polygon *cp, RGBA_Polygon_Point *points) +{ + RGBA_Polygon_Point *cur, *npoints = NULL; + + if (!points) return; + + EINA_INLIST_FOREACH(EINA_INLIST_GET(points), cur) + { + RGBA_Polygon_Point *point; + + point = malloc(sizeof *point); + point->x = cur->x; + point->y = cur->y; + + npoints = + (RGBA_Polygon_Point *)eina_inlist_append(EINA_INLIST_GET(npoints), + EINA_INLIST_GET(point)); + } + + cp->points = npoints; +} + +static void +_polygon_draw_thread_cmd(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y) +{ + int ext_x, ext_y, ext_w, ext_h; + Evas_Thread_Command_Polygon cp; + + ext_x = 0; + ext_y = 0; + ext_w = dst->cache_entry.w; + ext_h = dst->cache_entry.h; + + if (dc->clip.use) + { + if (dc->clip.x > ext_x) + { + ext_w += ext_x - dc->clip.x; + ext_x = dc->clip.x; + } + + if ((ext_x + ext_w) > (dc->clip.x + dc->clip.w)) + ext_w = (dc->clip.x + dc->clip.w) - ext_x; + + if (dc->clip.y > ext_y) + { + ext_h += ext_y - dc->clip.y; + ext_y = dc->clip.y; + } + + if ((ext_y + ext_h) > (dc->clip.y + dc->clip.h)) + ext_h = (dc->clip.y + dc->clip.h) - ext_y; + } + + EINA_RECTANGLE_SET(&cp.ext, ext_x, ext_y, ext_w, ext_h); + cp.col = dc->col.col; + cp.render_op = dc->render_op; + cp.surface = dst; + + _polygon_draw_thread_points_populate(&cp, points); + + cp.x = x; + cp.y = y; + + evas_thread_cmd_enqueue(_draw_thread_polygon_draw, &cp, sizeof(cp)); +} + +static void +eng_polygon_draw(void *data EINA_UNUSED, void *context, void *surface, void *polygon, int x, int y, Eina_Bool do_async) +{ + if (do_async) _polygon_draw_thread_cmd(surface, context, polygon, x, y); #ifdef BUILD_PIPE_RENDER - if ((cpunum > 1)) + else if ((cpunum > 1)) evas_common_pipe_poly_draw(surface, context, polygon, x, y); - else #endif + else { evas_common_polygon_draw(surface, context, polygon, x, y); evas_common_cpu_end_opt(); @@ -825,14 +1126,132 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const void *t } static void -eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) +_drop_cache_ref(void *target, Evas_Callback_Type type EINA_UNUSED, void *event_info EINA_UNUSED) +{ + evas_cache_image_drop((Image_Entry *)target); +} + +static void +draw_thread_image_draw(void *data) +{ + Evas_Thread_Command_Image *image = data; + + if (image->smooth) + evas_common_scale_rgba_smooth_draw + (image->image, image->surface, + image->clip.x, image->clip.y, image->clip.w, image->clip.h, + image->mul_col, image->render_op, + image->src.x, image->src.y, image->src.w, image->src.h, + image->dst.x, image->dst.y, image->dst.w, image->dst.h); + else + evas_common_scale_rgba_sample_draw + (image->image, image->surface, + image->clip.x, image->clip.y, image->clip.w, image->clip.h, + image->mul_col, image->render_op, + image->src.x, image->src.y, image->src.w, image->src.h, + image->dst.x, image->dst.y, image->dst.w, image->dst.h); + + evas_async_events_put(image->image, 0, NULL, _drop_cache_ref); +} + +static void +_image_draw_thread_cmd(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, int smooth) +{ + Evas_Thread_Command_Image cr; + int clip_x, clip_y, clip_w, clip_h; + + if ((dst_region_w <= 0) || (dst_region_h <= 0)) return; + 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; + + evas_cache_image_ref((Image_Entry *)src); + + cr.image = src; + cr.surface = dst; + EINA_RECTANGLE_SET(&cr.src, src_region_x, src_region_y, src_region_w, src_region_h); + EINA_RECTANGLE_SET(&cr.dst, dst_region_x, dst_region_y, dst_region_w, dst_region_h); + + if (dc->clip.use) + { + clip_x = dc->clip.x; + clip_y = dc->clip.y; + clip_w = dc->clip.w; + clip_h = dc->clip.h; + } + else + { + clip_x = 0; + clip_y = 0; + clip_w = dst->cache_entry.w; + clip_h = dst->cache_entry.h; + } + + EINA_RECTANGLE_SET(&cr.clip, clip_x, clip_y, clip_w, clip_h); + + cr.mul_col = dc->mul.use ? dc->mul.col : 0xffffffff; + cr.render_op = dc->render_op; + cr.smooth = smooth; + + evas_thread_cmd_enqueue(draw_thread_image_draw, &cr, sizeof(cr)); +} + +static void +_image_draw_thread_cmd_smooth(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) +{ + _image_draw_thread_cmd + (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, + 1); +} + +static void +_image_draw_thread_cmd_sample(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) +{ + _image_draw_thread_cmd + (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, + 0); +} + +static void +eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async) { RGBA_Image *im; if (!image) return; im = image; + + if (do_async) + { + if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888) + { +#if EVAS_CSERVE2 + if (evas_cserve2_use_get()) + evas_cache2_image_load_data(&im->cache_entry); + else +#endif + evas_cache_image_load_data(&im->cache_entry); + } + + evas_common_image_colorspace_normalize(im); + + if (smooth) + evas_common_scale_rgba_in_to_out_clip_cb + (image, surface, context, + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h, + _image_draw_thread_cmd_smooth); + else + evas_common_scale_rgba_in_to_out_clip_cb + (image, surface, context, + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h, + _image_draw_thread_cmd_sample); + } #ifdef BUILD_PIPE_RENDER - if ((cpunum > 1)) + else if ((cpunum > 1)) { #ifdef EVAS_CSERVE2 if (evas_cserve2_use_get()) @@ -847,8 +1266,8 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h); } - else #endif + else { #if 0 #ifdef EVAS_CSERVE2 @@ -901,7 +1320,185 @@ image_loaded: } static void -evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGBA_Image *im, RGBA_Map *m, int smooth, int level, int offset) +_map_image_draw(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, int smooth) +{ + int clip_x, clip_y, clip_w, clip_h; + DATA32 mul_col; + + if ((dst_region_w <= 0) || (dst_region_h <= 0)) return; + 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; + + if (dc->clip.use) + { + clip_x = dc->clip.x; + clip_y = dc->clip.y; + clip_w = dc->clip.w; + clip_h = dc->clip.h; + } + else + { + clip_x = clip_y = 0; + clip_w = dst->cache_entry.w; + clip_h = dst->cache_entry.h; + } + + mul_col = dc->mul.use ? dc->mul.col : 0xffffffff; + + if (smooth) + evas_common_scale_rgba_smooth_draw + (src, dst, + clip_x, clip_y, clip_w, clip_h, + mul_col, dc->render_op, + 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 + evas_common_scale_rgba_sample_draw + (src, dst, + clip_x, clip_y, clip_w, clip_h, + mul_col, dc->render_op, + 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 +_map_image_sample_draw(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) +{ + _map_image_draw(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, + 0); +} + +static void +_map_image_smooth_draw(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) +{ + _map_image_draw(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, + 1); +} + +static void +_draw_thread_map_draw(void *data) +{ + Evas_Thread_Command_Map *map = data; + int offset = map->offset; + RGBA_Map *m = map->map; + RGBA_Image *im = map->image; + int dx, dy, dw, dh; + + if (m->count - offset < 3) goto free_out; + + do + { + 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)) + { + 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; + + if (map->smooth) + evas_common_scale_rgba_in_to_out_clip_cb + (im, map->surface, &map->image_ctx, + 0, 0, im->cache_entry.w, im->cache_entry.h, + dx, dy, dw, dh, _map_image_smooth_draw); + else + evas_common_scale_rgba_in_to_out_clip_cb + (im, map->surface, &map->image_ctx, + 0, 0, im->cache_entry.w, im->cache_entry.h, + dx, dy, dw, dh, _map_image_sample_draw); + } + else + { + evas_common_map_rgba_draw + (im, map->surface, + map->clip.x, map->clip.y, map->clip.w, map->clip.h, + map->mul_col, map->render_op, m->count - offset, &m->pts[offset], + map->smooth, map->level); + } + + evas_common_cpu_end_opt(); + + offset += 2; + } + while ((m->count > 4) && (m->count - offset >= 3)); + + free_out: + free(m); + evas_async_events_put(map->image, 0, NULL, _drop_cache_ref); +} + +static void +_map_draw_thread_cmd(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Map *map, int smooth, int level, int offset) +{ + Evas_Thread_Command_Map cm; + int clip_x, clip_y, clip_w, clip_h; + + evas_cache_image_ref((Image_Entry *)src); + + cm.image = src; + memcpy(&cm.image_ctx, dc, sizeof(*dc)); + cm.surface = dst; + + if (dc->clip.use) + { + clip_x = dc->clip.x; + clip_y = dc->clip.y; + clip_w = dc->clip.w; + clip_h = dc->clip.h; + } + else + { + clip_x = clip_y = 0; + clip_w = dst->cache_entry.w; + clip_h = dst->cache_entry.h; + } + + EINA_RECTANGLE_SET(&cm.clip, clip_x, clip_y, clip_w, clip_h); + + cm.mul_col = dc->mul.use ? dc->mul.col : 0xffffffff; + cm.render_op = dc->render_op; + + cm.map = calloc(1, sizeof(RGBA_Map) + + sizeof(RGBA_Map_Point) * map->count); + cm.map->engine_data = map->engine_data; + cm.map->image.w = map->image.w; + cm.map->image.h = map->image.h; + cm.map->uv.w = map->uv.w; + cm.map->uv.h = map->uv.h; + cm.map->x = map->x; + cm.map->y = map->y; + cm.map->count = map->count; + memcpy(&cm.map->pts[0], &map->pts[0], sizeof(RGBA_Map_Point) * map->count); + + cm.smooth = smooth; + cm.level = level; + cm.offset = offset; + + evas_thread_cmd_enqueue(_draw_thread_map_draw, &cm, sizeof(cm)); +} + +static void +evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGBA_Image *im, RGBA_Map *m, int smooth, int level, int offset, Eina_Bool do_async) { if (m->count - offset < 3) return; @@ -933,7 +1530,8 @@ evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGB eng_image_draw (data, context, surface, im, 0, 0, im->cache_entry.w, im->cache_entry.h, - dx, dy, dw, dh, smooth); + dx, dy, dw, dh, smooth, + do_async); } else { @@ -953,17 +1551,22 @@ evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGB if (m->count > 4) { - evas_software_image_map_draw(data, context, surface, im, m, smooth, level, offset + 2); + evas_software_image_map_draw(data, context, surface, im, m, smooth, level, offset + 2, do_async); } } static void -eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level) +eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async) { if (!image) return; if (m->count < 3) return; - evas_software_image_map_draw(data, context, surface, image, m, smooth, level, 0); + if (do_async) + evas_common_map_thread_rgba_cb(image, surface, context, + m, smooth, level, 0, _map_draw_thread_cmd); + else + evas_software_image_map_draw(data, context, surface, image, m, + smooth, level, 0, do_async); } static void @@ -1251,13 +1854,71 @@ eng_font_run_font_end_get(void *data EINA_UNUSED, Evas_Font_Set *font, Evas_Font } static void -eng_font_draw(void *data EINA_UNUSED, void *context, void *surface, Evas_Font_Set *font EINA_UNUSED, int x, int y, int w EINA_UNUSED, int h EINA_UNUSED, int ow EINA_UNUSED, int oh EINA_UNUSED, Evas_Text_Props *text_props) +_draw_thread_font_draw(void *data) { + Evas_Thread_Command_Font *font = data; + RGBA_Draw_Context dc; + + dc.font_ext.data = font->font_ext_data; + dc.font_ext.func.gl_new = font->gl_new; + dc.font_ext.func.gl_free = font->gl_free; + dc.font_ext.func.gl_draw = font->gl_draw; + dc.col.col = font->col; + dc.clip.use = font->clip_use; + dc.clip.x = font->clip_rect.x; + dc.clip.y = font->clip_rect.y; + dc.clip.w = font->clip_rect.w; + dc.clip.h = font->clip_rect.h; + + evas_common_font_rgba_draw + (font->dst, &dc, + font->x, font->y, font->glyphs, font->func, + font->ext.x, font->ext.y, font->ext.w, font->ext.h, + font->im_w, font->im_h); + + evas_common_font_glyphs_unref(font->glyphs); +} + +static void +_font_draw_thread_cmd(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, Evas_Glyph_Array *glyphs, RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w, int ext_h, int im_w, int im_h) +{ + Evas_Thread_Command_Font cf; + + cf.dst = dst; + cf.x = x; + cf.y = y; + cf.gl_new = dc->font_ext.func.gl_new; + cf.gl_free = dc->font_ext.func.gl_free; + cf.gl_draw = dc->font_ext.func.gl_draw; + cf.font_ext_data = dc->font_ext.data; + cf.col = dc->col.col; + cf.clip_use = dc->clip.use; + EINA_RECTANGLE_SET(&cf.clip_rect, + dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h); + cf.glyphs = glyphs; + cf.func = func; + EINA_RECTANGLE_SET(&cf.ext, ext_x, ext_y, ext_w, ext_h); + cf.im_w = im_w; + cf.im_h = im_h; + + evas_common_font_glyphs_ref(glyphs); + evas_thread_cmd_enqueue(_draw_thread_font_draw, &cf, sizeof(cf)); +} + +static void +eng_font_draw(void *data EINA_UNUSED, void *context, void *surface, Evas_Font_Set *font EINA_UNUSED, int x, int y, int w EINA_UNUSED, int h EINA_UNUSED, int ow EINA_UNUSED, int oh EINA_UNUSED, Evas_Text_Props *text_props, Eina_Bool do_async) +{ + if (do_async) + { + evas_common_font_draw_prepare(text_props); + evas_common_font_draw_cb(surface, context, x, y, text_props->glyphs, + _font_draw_thread_cmd); + } #ifdef BUILD_PIPE_RENDER - if ((cpunum > 1)) + else if ((cpunum > 1)) evas_common_pipe_text_draw(surface, context, x, y, text_props); - else #endif + else { evas_common_font_draw_prepare(text_props); evas_common_font_draw(surface, context, x, y, text_props->glyphs);