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 5917b49f59
This commit is contained in:
Jean-Philippe Andre 2016-11-08 16:22:22 +09:00
parent f909a6d6ea
commit bff8dcfe21
2 changed files with 28 additions and 18 deletions

View File

@ -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);

View File

@ -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;