From bff8dcfe213d6a78b3ba0a5eab47c83d6701e30f Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 8 Nov 2016 16:22:22 +0900 Subject: [PATCH] evas: Fix clipping of masks and masks of masks When an object inside a genlist is masked, scrolling would cause render issues as the mask is not redrawn on move (only the clip geometry is marked as dirty and recalculated, the mask pixels are assumed to be well prepared already). As a result, masked objects in a genlist would not show up properly once you start scrolling. This fixes that by hacking into evas a safety test to avoid unnecessary clipping, and by using parent masks even if they are not the direct clipper. Note that no_render is still quite broken (eg. a no_render mask may cause major issues, even crashes). This reverts 5917b49f594089a3ebc4586d41c29e --- src/lib/evas/canvas/evas_render.c | 44 +++++++++++++++++++----------- src/lib/evas/include/evas_inline.x | 2 -- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index e4c553337d..285a2b95f9 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -1624,6 +1624,8 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj, if (obj->map->surface) { + Evas_Object_Protected_Data *mask = obj->clip.mask; + if (obj->cur->clipper) { evas_object_clip_recalc(obj); @@ -1641,10 +1643,9 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj, off_y); /* Clipper masks */ - if (_evas_render_object_is_mask(obj->cur->clipper)) + if (mask) { // This path can be hit when we're multiplying masks on top of each other... - Evas_Object_Protected_Data *mask = obj->cur->clipper; RD(level, " has mask: [%p%s%s] redraw:%d sfc:%p\n", mask, mask->name?":":"", mask->name?mask->name:"", mask->mask->redraw, mask->mask->surface); @@ -1769,29 +1770,40 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj, if (obj->cur->clipper && (mapped > 1)) { - if (proxy_src_clip) + Evas_Object_Protected_Data *mask = obj->clip.mask; + + if (obj->mask->surface != surface) { - if ((_evas_render_has_map(obj) && !_evas_render_can_map(obj)) || - _evas_render_object_is_mask(obj->cur->clipper)) - evas_object_clip_recalc(obj); - _evas_render_mapped_context_clip_set(evas, eo_obj, obj, ctx, - proxy_render_data, - off_x, off_y); + if (proxy_src_clip) + { + if ((_evas_render_has_map(obj) && !_evas_render_can_map(obj)) || + _evas_render_object_is_mask(obj->cur->clipper)) + evas_object_clip_recalc(obj); + _evas_render_mapped_context_clip_set(evas, eo_obj, obj, ctx, + proxy_render_data, + off_x, off_y); + } + else + { + if (!_proxy_context_clip(evas, ctx, proxy_render_data, obj, off_x, off_y)) + { + eina_evlog("-render_object", eo_obj, 0.0, NULL); + return clean_them; + } + } } else { - if (!_proxy_context_clip(evas, ctx, proxy_render_data, obj, off_x, off_y)) - { - eina_evlog("-render_object", eo_obj, 0.0, NULL); - return clean_them; - } + // rendering a mask in its own surface: + // we want to render it fully and clip only at + // clippee (maskee) render time + RD(level, " draw mask\n"); } /* Clipper masks */ - if (_evas_render_object_is_mask(obj->cur->clipper)) + if (mask) { // This path can be hit when we're multiplying masks on top of each other... - Evas_Object_Protected_Data *mask = obj->cur->clipper; RD(level, " has mask: [%p%s%s] redraw:%d sfc:%p\n", mask, mask->name?":":"", mask->name?mask->name:"", mask->mask->redraw, mask->mask->surface); diff --git a/src/lib/evas/include/evas_inline.x b/src/lib/evas/include/evas_inline.x index 0fcf8a4d1a..e60431a10f 100644 --- a/src/lib/evas/include/evas_inline.x +++ b/src/lib/evas/include/evas_inline.x @@ -140,8 +140,6 @@ evas_object_is_source_invisible(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Pro { if (obj->parent_cache.src_invisible_valid) return obj->parent_cache.src_invisible; - if (obj->no_render) - return EINA_TRUE; if ((obj->proxy->proxies || obj->proxy->proxy_textures) && obj->proxy->src_invisible) return 1; if (!obj->smart.parent) return 0; if (obj->mask->is_mask) return 0;