This should theorically work, need some test. Design is easy to understand. Render
every part of a snapshot object by rendering the content below it, before rendering
the stack above it using that object content.
i think this has been disabled for a while. image unloading is broken
- esp with gl enigne as due to async move it was effectively disabled.
this re-enables it. unloading is deferred with a managed list of things
needing unloading and then when any async sw renders are not busy any
more - do the unload then in the mainloop of all pending/flagged
images to unload
@fix
Those two functions were doing exactly the same thing[1], which
is free an image, so this commit only attempts to simplify the code
a little bit.
[1] Actually image_map_surface_free() might even not have worked
properly with cserve2 sw (calling unload instead of close).
Those objects should never be rendered on the canvas, even if they
are visible. On the other hand, they need to be rendered in mask or
proxy surfaces.
note: this patch includes some extra whitespaces changes :(
@feature
On minimizing, free all mask surfaces. This could save a lot
of memory.
Also, write "proxy" COW only when there is a surface (the "proxy"
pointer itself is always valid and non-NULL).
Right now the engines don't support mask tiles so we can't
just scale up an image on-the-fly when doing a masking operation.
Skip fast path and force render of border images into their own surface.
Situation:
- Evas Object A has a clip C and a map M.
Problem:
- Clip C will be applied once inside the map surface S and
again when the surface S is drawn to the canvas.
Solution:
- Track whether the current object is the mapped object
or a child of the mapped object. In the first case,
discard the clipper when rendering to the map surface.
In the second case, the child's clipper is PROBABLY[*]
inside the map, so it should be applied when rendering the
map surface itself.
Note: This also applies to masks.
[*] This is clearly not the ultimate clipping fix.
In some rare cases, a mask would be rendered (from mask_subrender)
into a surface that is NOT an FBO. This would happen because the
previous surface was a "scaled GL image" and its size would
match the required geometry.
That took a while to figure out...
http://thecodinglove.com/post/111546429281/when-i-finally-solve-a-nasty-bug
The function image_scaled_update() frees() the old scaled image
passed as input if it doesn't match the old dimensions. This commit
will avoid double frees.
Edje may not set the filled flag on an image even if its fill
properties make it fill the whole object. For masking, it can
then be considered as a filled image.
If the image is not "filled", then we can't assume its image
source geometry is the same as its texture geometry.
Note: Implementing a fast path for non-filled images would
require a hell of a lot more work (need to cut the render
into a lot more triangles) for little real-life use.
Call object's function to get the private engine_data (here, the
image object). Thanks Dongyeon for your patch which inspired me to
do that instead of forcing pre_render.
This will currently optimize most of the masks when using the
GL engine[1].
This is a very special case that adds a highly optimized path
for masking in GL. It works by creating a virtual image, containing
a pointer to the original image and a new geometry[2].
Instead of creating a new FBO-based surface (image_map_surface),
we refer to the original image and adjust the mask geometry on
the fly.
KNOWN BUGS:
- masking a map with such a scaled image is now broken.
[1] Right now all masks are simple Evas Object Image, so that means
all cases of masking, except masks of masks, or masks of maps,
will be optimized with this new method.
[2] This virtual image mechanism is still quite hackish and may
be improved (for memory usage, refcounting, etc...)
this adds a lock for when walking all the objects to generate render
commands for an async render. this allows even the object tree walk
plus update area caluclation to be moved off into async if every oject
that can change canvas state actually does so correctly. this change
adds all those lock block calls to synchronise with an async object
tree walk.
Fixes rendering in the following case:
- Object with a map has a mask
- Object is child of smart object which also has a map (eg. transit)
--> Masking did not apply to the children before this patch.
NOTE: This works fine in SW but still didn't work in GL, see the
following commit...
I know. This title does not explain anything. Whatever.
This fixes the following issue:
- Mask a genlist (big mask)
- Each item has an icon masked (small mask)
- Apply a map to the genlist
- Scrolling the genlist
--> The big mask still works but totally screws up the
small icons with masks.
Note: Once again this patch only affects code paths where an
object is a mask.
Yeah, mixing maps and masks of masks in a genlist leads
to tons of amazing bugs :)
This commit removes x,y from the "mask" field in an object,
as they are duplicates of cur->geometry.{x,y} but were not
properly kept in sync.
This patch fixes a situation of:
- A genlist in a map
- Each item has an icon masked
- Scrolling the genlist
--> The masked items would not render properly before this
patch.
Remaining known problem:
- Mask a genlist (big mask)
- Each item has an icon masked (small mask)
- Apply a map to the genlist
- Scrolling the genlist
--> The big mask still works but totally screws up the
small icons with masks.
Note: These changes look scary just before the release
but I would have to backport them to 1.13.x as they
definitely are bug fixes. Also, they only concern
code paths used exclusively by masking.
All those masking bug fixes become harder to explain. But here goes:
- Take a genlist, apply a mask to it (for example put everything
in an elm_layout). Also play with various objects in the genlist.
- Also apply a map to it (for instance, elm_transit zoom).
--> Now some elements will be masked, some others will not,
and some may even not render at all.
This patch restores a mask in the current drawing context, instead
of just unsetting it.
In a situation where an object with mask of mask is in a map
(Yes! It can happen!) the masks would not get properly "multiplied".
Now the problem is that some objects still seem to bypass some
masks... Hmm...
This is a left-over from a previous fix a few weeks ago.
The point of this "if" is just to avoid writing the COW value
if not needed.
For reference:
commit f876cf31f8
Author: Jean-Philippe Andre <jp.andre@samsung.com>
Date: Tue Dec 23 18:57:45 2014 +0900
Evas masking: Fix invalid geometry after mask redraw
Summary:
This is an attempt at fixing:
- T1767: The ultimate evil map & clip bug
Force recalculation and re-propagation of clipper geometry
after or just before a map is applied (only when transiting
between map enabled and map disabled).
I realized that doing clip_unset+clip_set in the E widget
code would fix the issue, but this is not a solution that
makes a lot of sense.
Unfortunately I have no idea about the side effects of this
patch, especially in terms of performance.
Fixes T1767 and maybe T1630.
Test Plan:
Open PackageKit popup in E, check the animations
and that clipping works fine both during, before and after
the animations.
Reviewers: raster, cedric
Reviewed By: cedric
Subscribers: cedric, Hermet
Maniphest Tasks: T1767
Differential Revision: https://phab.enlightenment.org/D1897
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
While invesigating some clip & map issues, I found some very
strange piece of code:
{
tmp = a;
a = c;
a = tmp;
}
This actually comes from a very old code refactoring where a
line in-between was removed:
tobj = obj->cur.map_parent;
obj->cur.map_parent = obj->cur.clipper->cur.map_parent;
- evas_object_clip_recalc(obj);
obj->cur.map_parent = tobj;
Adding this line back there doesn't seem to do anything anyways.
So, let's just remove useless code.
For the record (legacy evas):
commit e1f6f3c5f239dfd95a307949acd5f98831c0c3c0
Date: Fri Aug 17 06:16:04 2012 +0000
evas/render - code refactoring.
SVN revision: 75351
Some complex examples of masking with mapped smart objects
would fail miserably, rendering the object without any mask,
and/or showing the mask itself somewhere in white color...
The memory usage graph was going up and to the right!
I was told this is always a good thing!
... maybe not this time :)
Hopefully I didn't forget a case. An intense session of
genlist scrolling with masks all over the place and masks
of masks didn't show any glitch, crash or memory leak.
This implements supports for masking inside evas_render, which
means:
- Render the mask itself into a surface (ALPHA if possible)
- Pass this mask surface to the draw context
- Apply mask recursively in case a masked object is contained
by another masked object.
@feature
Here's a macro that's used for debugging in some of the ugliest
ways possible: avoid passing an extra argument to a function when the
cost of always passing it is negligible (it's an int).
Fixes T1749.