From cdaebfa0406b02974f5c68f1e87b467f2fb14bc8 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 10 May 2019 14:14:49 -0400 Subject: [PATCH] evas/render: size and draw proxy render surface based on proxy clipper if a proxy is not being proxied, it's optimal to create a surface for only the necessary dimensions and then only draw within those dimensions. when a proxy is clipped to a size smaller than the proxy object, the required size for the proxy render becomes smaller as the proxy has less visible area. this enables us to draw only the clipped region and thus gives a performance boost this can only be enabled if the clipper is marked as static Reviewed-by: Hermet Park Differential Revision: https://phab.enlightenment.org/D8881 --- src/lib/evas/canvas/evas_render.c | 32 +++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index b0179ba7cf..4895517c1a 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -2312,10 +2312,10 @@ evas_render_proxy_subrender(Evas *eo_e, void *output, Evas_Object *eo_source, Ev Eina_Bool source_clip, Eina_Bool do_async) { Evas_Public_Data *evas = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); - Evas_Object_Protected_Data *source; + Evas_Object_Protected_Data *source, *proxy; int level = 1; void *ctx; - int w, h; + int w, h, off_x = 0, off_y = 0; #ifdef REND_DBG level = __RD_level; @@ -2324,9 +2324,29 @@ evas_render_proxy_subrender(Evas *eo_e, void *output, Evas_Object *eo_source, Ev if (!eo_source) return; eina_evlog("+proxy_subrender", eo_proxy, 0.0, NULL); source = efl_data_scope_get(eo_source, EFL_CANVAS_OBJECT_CLASS); + proxy = efl_data_scope_get(eo_proxy, EFL_CANVAS_OBJECT_CLASS); - w = source->cur->geometry.w; - h = source->cur->geometry.h; + if (proxy->proxy->proxies || (!proxy->cur->clipper) || (!proxy->cur->has_fixed_size)) + { + /* make full surface available if this proxy is being sampled from */ + w = source->cur->geometry.w; + h = source->cur->geometry.h; + } + else + { + Eina_Rectangle clip = _evas_render_smallest_static_clipped_geometry_get(proxy->cur); + /* nothing is using this proxy, so the proxy render surface can be sized + * to fit exactly the proxy object's render size, and the proxy render will + * naturally be clipped to this geometry + */ + w = clip.w; + h = clip.h; + /* set the render offset for the proxy offset based on the geometry which will + * be visible on the proxy surface after clipping + */ + off_x = proxy->cur->geometry.x - clip.x; + off_y = proxy->cur->geometry.y - clip.y; + } RD(level, " proxy_subrender(source: %s, proxy: %s, %dx%d)\n", RDNAME(source), RDNAME(proxy_obj), w, h); @@ -2379,8 +2399,8 @@ evas_render_proxy_subrender(Evas *eo_e, void *output, Evas_Object *eo_source, Ev ctx = ENFN->context_new(ENC); evas_render_mapped(evas, eo_source, source, ctx, output, proxy_write->surface, - -source->cur->geometry.x, - -source->cur->geometry.y, + -source->cur->geometry.x + off_x, + -source->cur->geometry.y + off_y, level + 1, 0, 0, evas->output.w, evas->output.h, &proxy_render_data, level + 1, do_async); ENFN->context_free(ENC, ctx);