This is the first step toward handling multi output. This patch
remove engine.data.output from Evas structure and use an Eina_List
for it instead. It also start moving code around to fetch an output
or an engine context (which are the same at the moment, but will be
split in a later patch).
This might not be used as over two consecutive runs all the
same buffers should be used. But it could happen if some
parameters in the filter change (eg. blur radius).
Fixes major (GPU) memory leaks. Reuse mode is still leaking.
When the filtered object is an image, without borders, map,
fill info or anything of this sort, then the filter input
buffer is really just a copy of the original image. We can
skip that to save on memory usage and pixel fetches.
This improves over the previous code for handling
snapshot objects and cutouts. Basically any opaque object
above a snapshot should be obscuring it. That is true
unless a crazy filter is applied, or the snapshot object
is itself the source of a map or proxy.
This also uses eina_tiler instead of a custom (and really
bad) algorithm to compute the obscure regions.
This make save() work on snapshot objects, provided the call
is done from inside render_post.
Also, this saves the filtered output of an image, rather than
its source pixels. Any call to save() on a filtered image must
be done from post-render as well.
Fixes T2102
@feature
The situation is clearly visible in the Snapshot test case:
increase the radius and a red glow would appear. This is because
the snapshot object was not marked as needing redraw and so had
no pixels under the opaque rectangle.
This will reuse existing buffers by resetting only the minimum
required in the filter context (also reused). Work in progress,
as the actual reuse is disabled for now.
This avoids creating one more FBO and doing one more draw,
by rendering the image input data directly into the input
buffer. This also makes the code common between SW and GL.
This skips extra tests with image objects that have the
is_opaque() function. That way, if an object is marked as COPY,
rendering of all objects below it will be skipped.
This can dramatically help with performance when flagging a
snapshot object as COPY. This should not be done if a filter is
applied and is meant to blend with the underlying UI.
When using a snapshot object we have access to exactly all
the pixels below it inside the snapshot surface. So, in order
to produce a nice blur, it is necessary to expand this snapshot
and then clip it otherwise the edges will look a bit ugly.
Unfortunately, there are still places where blurs didn't look
so good, as objects below an opaque region would never get
rendered into the snapshot object. So the edges, inside a
snapshot object, around an opaque region would have blur
artifacts.
This fixes that by shrinking the cutout regions by the radius
of the filter. Eg for blur this is the blur radius.
The test case in elm_test can exhibit this fix very clearly:
a red glow would be visible around the opaque rectangle, but with
these changes we instead see the blurry edges of the objects
below the rectangle.
This will be most useful in a special case, where a filter is
used in a window decoration, applied to a snapshot object.
Another optimization that might be wanted is passing a list
of update regions (from the proxy or snapshot).
The filters don't support the obscuring region yet, only some
of the high-level logic is implemented.
If anything in the canvas needs redraw and a snapshot object
happens to intersect with the update region then it was redrawn,
even if all objects below it hadn't changed. This has an insane
performance impact when you apply a blur filter on the snapshot
object. Walking the object list will always be cheaper than
rendering the snapshot!
Note: Added a FIXME comment and forced clean_them to be true
because some odd behaviour happens when breaking with GDB and
the array snapshot_objects keeps growing at each frame (I guess
only if we miss a frame or something like that).
This reuses the existing mask infrastructure, but adds a color
flag to use the whole RGBA range, rather than just the Alpha
channel.
Filters are still very slow (glReadPixels and non-optimized use of
GL buffers...), but this is progress :)
This corrects two things:
- the blur filter high-level logic, that lead to reusing some
temporary buffers which contained garbage;
- the versatile gl buffer implementation so that it now properly
switches between the RGBA_Image and the FBO content (yes, this
is insanely slow and inefficient... but it works and that was
the only point).
Alright, so this is a massive patch that is the result of
trying to get rid of unused or poorly implemented classes in
ector. Originally ector was meant to support VG but extend to
things like filters as well. At the moment, ector's design
makes it quite hard to plug in the filters.
For now I think it's easier to implement the GL support for
the filters directly in the engine, where I hope to interfere
as little as possible.
This massive patch keeps only the required minimum to support
a versatile gl buffer that can be mapped, drawn or rendered to (FBO).
It's extremely inefficient as it relies on glReadPixels and lots
of texture uploads, as well as conversions between ARGB and Alpha.
Another type of GL buffer is a wrap around an existing GL image,
but that one is read-only (map or draw: no write map, no FBO).
No, all the filters run fine, and the high-level implementation
(evas_filters.c) does not need to know whether the underlying engine
is SW or GL. One problem though appears with the blending or blurring
of some Alpha buffers, the colors are wrong.
This patch removes more lines than it adds so it must be good ;)
This is an attempt at refactoring the filters code so I can
later implement GL support. This patch adds a few extra changes
to remove avoid calling functions of libevas from the software
engine: use the draw functions from static_libs/draw rather
than evas_common APIs.
Summary:
If the last item before ellipsis item has bigger width than its advance,
evas_common_font_query_last_up_to_pos() function can find wrong ellipsis position.
When Evas finds a position for non last item, Evas must care about additionally
available space for glyph's width of the given x position.
ex) the last item's glyph before ellipsis item has a tail to draw above the ellipsis item.
@fix
Test Plan:
Test case will added as comment.
(Becasue of font license problem.)
Reviewers: herdsman, raster, jpeg, woohyun
Subscribers: cedric, Blackmole
Differential Revision: https://phab.enlightenment.org/D4727
If GL context is free'd before processing font shutdown,
textures for emoji glyph's GL images will be free'd without clean
up its GL images. It causes eina mempool infinite loop issue when
emoji's GL images are free'd in shutdown process.
So, the patch will make a list for emoji's GL images in context and
clean up them when the context is free'd. Just like font textures in
context.
@fix
Differential Revision: https://phab.enlightenment.org/D4695
Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
clip_dirty is called A LOT. Unfortunately this patch does not
result in very measurable improvements.
**********************
Note about this merge:
After this series of patches, the CPU usage for a certain test
case has significantly gone down:
Based on c0e6a8d698c17fc16f9b67fc9 (upstream before git push):
NS since frame 2 = 28910806786 , 2937 frames = 9843652 / frame
After this patch:
NS since frame 2 = 19218592951 , 2928 frames = 6563727 / frame
1.18:
NS since 2 = 13105584220 , 2961 frames = 4426066 / frame
As we can see, 1.18 remains *much* better than 1.19. I'm still
struggling trying to figure out why (clip_recalc is called more,
but the call tree is hard to decypher).
The test case is:
EINA_FREEQ_BYPASS=1 ELM_TEST_AUTOBOUNCE=100 \
elementary_test -to "Scroller 2"
EFL was compiled with GCC 6.3.1 with -O3 -g
@optimization
This function was moved out of inline (see d7c6fca6c0) but
unfortunately the early checks at its beginning are likely
to result in an early return. Inline this part so we get back a
better performance. Inlining the whole function does not improve
the performance, as GCC simply gives up with inlining.
Note: Between 1.18 and master the number of calls to clip_recalc
has simply blown out. It is thus crucial to find out where those
calls come from but also micro-optimize the function itself. This
patch does the latter only.
@optimize
In relative smart move, we only need to check once that the object
is indeed a valid smart object. This drops the call count from ~1.02M
to ~785k.
@optimization
The previous patch (b184874fa5) was preventing
post-event callbacks from triggering any form of input event,
including side-effects due to mouse,in. In fact by tracking
which exact events we want to post-process we can support
proper recursion. This fixes crashes in Bryce.
I'm not changing the documentation as this is still a dubious
code design.
Fixes T3144
Fixes T5157
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
After a long search I found that fileselector was not calling
super.group_del on deletion, leading to the use of dangling pointers.
So let's verify that group_del is properly called.
See T4598
A use of the post event callback in Bryce triggered a double free
as an event was being processed but not yet removed from its list,
leading to an invalid state of the Eina_List.
Also remove obj from struct as it is unused.
Fixes T5157
several calls, specifically evas_object_change_reset,
evas_object_cur_prev, and evas_object_clip_changes_clean that are
called directly or indirectly as part of evas render on at least every
active object if not more, were doing full eo obj lookups when their
calling functions already all had the eo protected data looked up.
tha's silly and just adds overhead we don't need. my test dropped
_eo_obj_pointer_get overhead in perf profiles from 4.48% to 2.65%. see:
4.48% libeo.so.1.18.99 [.] _eo_obj_pointer_get
4.23% libevas.so.1.18.99 [.] evas_render_updates_internal
2.61% libevas.so.1.18.99 [.] evas_render_updates_internal_loop
1.68% libeo.so.1.18.99 [.] efl_data_scope_get
1.57% libc-2.24.so [.] _int_malloc
1.42% libevas.so.1.18.99 [.] evas_object_smart_changed_get
1.09% libevas.so.1.18.99 [.] evas_object_clip_recalc.part.37
1.08% libpthread-2.24.so [.] pthread_getspecific
1.05% libevas.so.1.18.99 [.] efl_canvas_object_class_get
1.01% libevas.so.1.18.99 [.] evas_object_cur_prev
0.99% libeo.so.1.18.99 [.] _efl_object_event_callback_legacy_call
0.87% libevas.so.1.18.99 [.] _evas_render_phase1_object_ctx_render_cache_append
0.82% libpthread-2.24.so [.] pthread_mutex_lock
0.81% libevas.so.1.18.99 [.] _evas_render_phase1_object_process
0.79% libc-2.24.so [.] _int_free
vs now the improved:
4.82% libevas.so.1.18.99 [.] evas_render_updates_internal
3.44% libevas.so.1.18.99 [.] evas_render_updates_internal_loop
2.65% libeo.so.1.18.99 [.] _eo_obj_pointer_get
2.22% libc-2.24.so [.] _int_malloc
1.46% libevas.so.1.18.99 [.] evas_object_smart_changed_get
1.04% libeo.so.1.18.99 [.] _efl_object_event_callback_legacy_call
1.03% libevas.so.1.18.99 [.] _evas_render_phase1_object_ctx_render_cache_append
0.97% libeina.so.1.18.99 [.] eina_chained_mempool_malloc
0.93% libevas.so.1.18.99 [.] evas_object_clip_recalc.part.37
0.92% libpthread-2.24.so [.] pthread_mutex_lock
0.91% libevas.so.1.18.99 [.] _evas_render_phase1_object_process
0.84% libc-2.24.so [.] _int_free
0.84% libevas.so.1.18.99 [.] evas_object_cur_prev
0.83% libeina.so.1.18.99 [.] eina_chained_mempool_free
0.80% libeo.so.1.18.99 [.] efl_data_scope_get
of course other things "increase their percentage" as oe overhead now
dropped, and things seem to move around a bit, but it does make sense
to do this with no downsides i can see as we already are accessing the
protected data ptr in the parent func.
so a little perf fun shows malloc/free/realloc/etc. are, combined a
reasonable overhead. this reduced malloc overhead for draw contexts so
whne we duplicate them or create new ones, we re-use a small cache of
8 of them to avoid re-allocation. just take the first one from the
list as it really is that simple. mempool would not have helped more
here and cost more overhead.
@optimize
During a stress test of EFL a seemingly impossible crash happened, where
one of object's cow fields was NULL inside evas_object_was_visible.
Nothing in the code flow can possibly lead to this situation but
it still happened. For information, the object's delete_me flag was 2 in
evas_object_is_active() called from _evas_render_phase1_object_process().
So let's add a small safety check for crash prevention.
Differential Revision: https://phab.enlightenment.org/D4608
This is the most basic optimization that needs to be done for
filters to be useful: cache the output rgba buffers for each
filtered element. Hopefully this doesn't leak. I'm not making
any promises about that though :)
If a gfx filter was applied to a block of text spanning over
multiple text items, then it would improperly render as the
filter context was stored in the format, rather than the text
item. This is fixed by using a list of contexts in the format
node rather than a single context.
This should save a bit of memory for all image & text
objects. This exploits the previous patch for the post-render
job queue added to evas, and simplifies this bit of code.
This is a preparation step for (experimental) textblock support.
Textblock objects won't have a single filter, and the buffer's
geometry wouldn't be that of of the object itself. Thus a few
internal APIs need to be reworked first.
to date if you use async preload we still load the header
synchronously and this can be horrible especially with generic
loaders. there is no way to farm this off to the preload thread. now
there is. youhave to set it as a skip head load option before doing a
file_set AND you need to issue a preload ... but now it's possible.
@feature
i found evas_common_draw_context_apply_cutouts() was procsessing 300+
cutouts and as it's O(n^2)/2 to try and merge adjacent rects for
cutouts this really performs like complete junk. we apply cutout rects
a LOT. this is not the best solution, but it's quick and much faster
than doing the clipouts which drop framerate to like 1-2fps or so in the
nasty case i say (tyls -m of photos in a dir with a 2160 high
terminal).
this figures out the target area to limit the count of rects
significantly so O(n^2) is far far better when n is now < 10 most of
the time. and for the few operations where it's a high value this now
uses qsort to speed up merges etc. etc.
@optimize
This fixes evas_object_image_save after changing the orientation
of an image in the GL engine. In SW engine the pixel data is rotated
in memory, so things worked fine from the beginning. In GL we may
have to go through loops and hoops in order to rotate and fetch the
data from the GL texture.
This should fix ce45d44.
This reverts commit 4e110a34bf.
Urgh. I'm stupid. Conceptually I still like the idea of the
region proxy, that only renders part of the source object
in a proxy surface. The problem right now is that the proxy
subrender mechanism renders to a surface that belongs to
the **source** and not the proxy object. As a consequence,
the region would become a property of the source, rather than
the proxy, which is not at all the intention of the original
patch. In other words, everything would fall apart if an object
has more than one proxy, for whatever reason.
I realized that when trying to actually test the region proxy.
It didn't work at all. Revert for now.
Only the size of events_whitelist isn't enough, because in some
cases the user may be disabling the usage of a specific seat.
Considering the following scenario, the issue will easy to understand:
- an application with two entries (one to be used by seat 1 and other
by seat 2)
- the first seat is announced - it is enabled for entry 1 and
disabled for entry 2
- the second seat is announced
Before second seat is announced, the first seat would be able
to input the entry 1, because the events_whitelist of such
object will continue empty.
So a flag will be used to identify an object with active
filter.
Reviewed By: iscaro
Differential Revision: https://phab.enlightenment.org/D4498
Always assume use_mapped_ctx as true, the caller of evas_render_mapped
must ensure that the context is suitable (so either clean or contains
the appropriate clip info).
Also pass do_async to mask_subrender. For now it will always be reset
to false as the SW engine requires sync render to convert from RGBA
to Alpha (not great). The upcoming GL async engine should be able to
render masks asynchronously without any problem.
It was never used, except in dubious situations (most likely a typo).
A clean context is now used in the top-most call to
evas_render_updates_internal_loop.
This will allow partially rendering a proxy in a smaller image,
limited to the specified region. At the moment, this will allow
apps to create proxies of very large objects and let them deal
with the geometry & clipping.
This is not directly solving the issues with adding a filter
to textblock or the infinite page scrollers.
@feature
The hash implementation demonstrated that too much memory was being used
to store the Evas_Object_Pointer_Data. In order to reduce the memory usage
this patches now changes the Evas_Object_Pointer_Data storage to an Eina_Inlist and
now Massif profiles shows that the memory usage was drastically reduced.
With this new API one can block or unblock keyboard, mouse and
focus events that was originated from a seat. This is useful to
create applications that wants to establish some kind of seat segregation.
After @cedric's commit 6427c77707 we end up with E
not working in Xephyr, because evas_common_shutdown() is called
too many times (init_count == -1). So I'm being paranoid and
tracking whether Evas has initialized or not evas_common. That
way we end up with exactly the right number of inits. We even
reach 0 after E shuts down :)
This patch introduces possibility to enable key locks and modifers by seat.
It's very useful when the user has two keyboards attached to different seats.
This patch introduces the possibility to set the pointer mode and
query other properties like current position per pointer device.
The old API will still works, however it will only act on the default seat.
evas_object_clip_recalc is big. it's fat. it shouldnt be inline. so
make it a real function. being inline just hurts performance by making
our code bigger, hurting l1 instruction prefetch and cache
performance. this function isn't small. it's huge and should not be
inline basically because of that reason.
also throw in some likely/unlikely hints etc.
@optimize
part of rendering is figuring if obj is inside current geometry.
before we had to actuall poke around inside the object. this moves the
geometry into the active object array so the data is fecthed fast and
already there for filtering as this is the most likely thing to filter
out an object.
unfortunately this seems to have some bugsd and i'm baffled why, so
leave it there and ifdefed out for now for suture hunting.
evas render in phase1 in order to generate update rects, active,
render etc. object arrays has to walk every object in our tree. this
is a waste of time if we already have walked objects in a previous
frame if they havent changed, so cache this data in render cache in
smart objects to avoid re-walking and now just dumbly "memcpy" these
cached arrays into the master array. i have seen cpu usage by e drop
like about 15% in the sencarios i'm looking at "enlightenment
compositor with some window updating animation all the time, but most
other stuff being static).
@optimize
This fixes invalid mouse cursor used when windows are
created.
Due to the changes in the border theme and the fact that
a border is now always created, the event region
"elm.resize.bl" contains the point (0,0) when the window
size itself is 1x1. As a consequence every EFL application
would permanently have a cursor like the resize bottom/left
handle.
This fixes that by properly checking whether the pointer is
inside an object based on the ins list, and not just the
object geometry.
@feature
See also: b735386a45
this refactors _evas_render_phase1_object_process() into a bunch of
sub functions with leaner code, some LIKELY/UNLIKELY hints etc. etc.
in the hope that we have better l1 instruction cache use when
executing. this actually measureably helps and drops the overhead of
this func ANd all its sub functions from (in my tests in enlightenment
compositing while a video plays) from about 13.2% of all cpu usage by
e to 10%. that's about a 25% drop in cost for passing through phase 1
of evas render... and thats a good thing.
and it also makes the code nicer and more broken up.
@optimize
Summary:
In case of thread creation failure, shutdown logic will be stuck.
To prevent stuck, set exit variables to make thread_shutdown working
even if init fails.
Also modify init logics to return init result to a caller.
Reviewers: jypark, woohyun, cedric, jpeg
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D4411
Note (@jpeg):
I have modified the patch just a little bit.
Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
this is how you would possibly use prepare stages for objects like
image objects by pre-rendering them to a buffer. this is not complete
and it's actually disabled right now, but it's to show how it might be
done. some more exploring is needed, but this is to share how it
might/should work.
for gl noscale buffers are texture atlases that are fbo's. the point
is never to scale or transofmr them but to render them pixel for pixel
and just store pre-rendered data where its cheaper to do this than
rebuild every time. this is the enigne infra for sw and gl with the gl
code... it SHOULD work... in theory...
preparing an object is a good idea. especially with gl. you want to do
texture uploads BEFORE using textures all in one batch. otherwise this
may mean the gl implementation has to make a copy of your data in a
tmp location then copy it in later when texture becomes "unused" as it
may be in use at the moment, or it may have to stall and wait.
i have seen somewhere around 7-10% speedups on nvidia and intel
drivers with this on given a very special test case i brewed up (1000
32x32 images where i change 1 pixel every frame). this should have
impact really when we are modifying textures a lot. this is all i've
implemented for now, but this should/would/could do much more like
re-order map, proxy renders to render FIRST in a pre-render list
instead of inline and to pre-render fbo/buffer content for complex
objects like text or textblock etc.
Moved rects caching into draw context to avoid the use of __thread
slot. Draw context are defined per thread anyway and should be just
fine. This doesn't really change the picture regarding glibc problem
when to many __thread are needed, but slightly improve the global
picture. Also this patch doesn't affect our performance in expedite
benchmark as far as I can tell.
After a few patches trying to fix clipping of frame or
non-frame objects the icon finally ended up invisible. Even
if the elm_icon was marked as is_frame, its internal evas
object image would not have the flag set, thus it would be
clipped out.
Solution: Propagate the is_frame flag to all smart children,
not only when setting it but also when adding new members.
A hack with the API indicates that the frame edje is a very
special object that does not propagate the flag.
See also:
7ce79be1a10f6c33eff19c9c8809a7ac5ca9281c
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
Using the multi-seat support, Evas is able to handle multiple focused objects.
This implementation allows one focused object per seat.
This patch introduces new APIs and events to handle this new scenario,
while keeping compatible with the old focus APIs.
so i have been doing some profiling on my rpi3 ... and it seems
memcmp() is like the number one top used function - especially running
e in wayland compositor mode. it uses accoring to perf top about 9-15%
of samples (samples are not adding up to 100%). no - i cant seem to
get a call graph because all that happens is the whole kernel locks up
solid if i try, so i can only get the leaf node call stats. what
function was currently active at the sample time. memcmp is the
biggest by far. 2-3 times anything else.
13.47% libarmmem.so [.] memcmp
6.43% libevas.so.1.18.99 [.] _evas_render_phase1_object_pro
4.74% libevas.so.1.18.99 [.] evas_render_updates_internal.c
2.84% libeo.so.1.18.99 [.] _eo_obj_pointer_get
2.49% libevas.so.1.18.99 [.] evas_render_updates_internal_l
2.03% libpthread-2.24.so [.] pthread_getspecific
1.61% libeo.so.1.18.99 [.] efl_data_scope_get
1.60% libevas.so.1.18.99 [.] _evas_event_object_list_raw_in
1.54% libevas.so.1.18.99 [.] evas_object_smart_changed_get
1.32% libgcc_s.so.1 [.] __udivsi3
1.21% libevas.so.1.18.99 [.] evas_object_is_active
1.14% libc-2.24.so [.] malloc
0.96% libevas.so.1.18.99 [.] evas_render_mapped
0.85% libeo.so.1.18.99 [.] efl_isa
yeah. it's perf. it's sampling so not 100% accurate, but close to
"good enough" for the bigger stuff. so interestingly memcmp() is
actually in a special library/module (libarmmem.so) and is a REAL
function call. so doing memcmp's for small bits of memory ESPECIALLY
when we know their size in advance is not great. i am not sure our own
use of memcmp() is the actual culprit because even with this patch
memcmp still is right up there. we use it for stringshare which is
harder to remove as stringshare has variable sized memory blobs to
compare.
but the point remains - memcmp() is an ACTUAL function call. even on
x86 (i checked the assembly). and replacing it with a static inline
custom comparer is better. in fact i did that and benchmarked it as a
sample case for eina_tiler which has 4 ints (16 bytes) to compare
every time. i also compiled to assembly on x86 to inspect and make sure
things made sense.
the text color compare was just comparing 4 bytes as a color (an int
worth) which was silly to use memcmp on as it could just cast to an
int and do a == b. the map was a little more evil as it was 2 ptrs
plus 2 bitfields, but the way bitfields work means i can assume the
last byte is both bitfields combined. i can be a little more evil for
the rect tests as 4 ints compared is the same as comparing 2 long
longs (64bit types). yes. don't get pedantic. all platforms efl works
on work this way and this is a base assumption in efl and it's true
everywhere worth talking about.
yes - i tried __int128 too. it was not faster on x86 anyway and can't
compile on armv7. in my speed tests on x86-64, comparing 2 rects by
casting to a struct of 2 long long's and comparing just those is 70%
faster than comapring 4 ints. and the 2 long longs is 360% faster than
a memcmp. on arm (my rpi3) the long long is 12% faster than the 4 ints,
and it is 226% faster than a memcmp().
it'd be best if we didnt even have to compare at all, but with these
algorithms we do, so doing it faster is better.
we probably should nuke all the memcmp's we have that are not of large
bits of memory or variable sized bits of memory.
i set breakpoints for memcmp and found at least a chunk in efl. but
also it seems the vc4 driver was also doing it too. i have no idea how
much memory it was doing this to and it may ultimately be the biggest
culprit here, BUT we may as well reduce our overhead since i've found
this anyway. less "false positives" when hunting problems.
why am i doing this? i'm setting framerate hiccups. eg like we drop 3,
5 or 10 frames, then drop another bunch, then go back to smooth, then
this hiccup again. finding out WHAT is causing that hiccup is hard. i
can only SEE the hiccups on my rpi3 - not on x86. i am not so sure
it's cpufreq bouncing about as i've locked cpu to 600mhz and it still
happens. it's something else. maybe something we are polling? maybe
it's something in our drm/kms backend? maybe its in the vc4 drivers or
kernel parts? i have no idea. trying to hunt this is hard, but this is
important as this is something that possibly is affecting everyone but
other hw is fast enough to hide it...
in the meantime find and optimize what i find along the way.
@optimize
I'm trying to fix a crash that seems to happens in some very odd
circumstances under stress testing. I have absolutely no idea
what is going wrong... So let's just add some extra safety.
so since this uses new pos - cur pos to move BY x pixels... there is
an issue that if the move of the obj ends up re-moving the current obj
TO the same pos. it moved BY the same delta again thus racing ahead.
not great. because x/y is not stored until the call stack returns to
after the smart move func and the pos set storce the new position in
the object struct. the easiest way atm until we have relative
positioning etc. is to store this in the smart obj and use the delta
at that time of the call then store it immediately so a recursion ends
up with a delta of 0 if its the same pos, so go back to where we were.
this fixes a nasty issue i spotted in fileselector that made filesel
icons race along when scrolling 2x as fast as everything else. oddly i
couldnt see this in any other widget that scrolled when i looked...
which is odd, but... either way a nasty issue... subtle... and now
fixed. never saw this before so this seems new.
In case of a mapped object (eg. when applying a map to a window
in wayland compositor), the canvas and output coordinates are
not meant to be the same.
In EO land, applications should instead use the common interface
Efl.Input.Interface.pointer_xy.get (on the canvas).
@fix
This is an override of efl_gfx_size_set. Same as before, the
order of operations matter so it is possible that a corner
case will break. In particular, legacy code was:
- intercept
- smart resize (do stuff), super, super, super
- evas object resize
The new code is more like:
- intercept
- super, super, super, evas object resize
- do stuff
But unfortunately this broke elm_widget (read: all widgets) as
the internal resize was done before the object resize. So,
inside the resize event cb, the resize_obj size would not match
the smart object size. >_<
Similarly to group_color_set, group_clip_[un]set should not
exist and should be a result of efl_super and inheritance.
This patch also removes clip_unset from the EO API and keeps
only clip_set(NULL). The reason is that it will avoid bad overrides
of clip_unset() vs. clip_unset(NULL). This also simplifies the code
a bit. Ideally we should be able to reintroduce clip_unset in EO
if we can have a "@final" tag (like java's final keyword), to
prevent overrides.
This is a poor man's solution to get rid of group functions such
as clip_set, clip_unset, color_set, etc... See the following
commits.
This API needs to be EAPI for elementary but shouldn't be used
outside EFL. This is required purely for legacy compatibility.
Here's the call flow, inside show(obj):
1. if (intercept_show(obj)) return;
2. show(super(obj));
3. do other stuff
This brings support for the eo api for external buffers (like
the old data_set / data_get). The new API now works with slices
and planes.
The internal code still relies on the old cs.data array for
YUV color conversion. This makes the code a little bit too
complex to my taste.
Tested with expedite for RGBA and YUV 422 601 planar, both
SW and GL engines (x11).
This combines evas canvas functions to list and query
touch points into a single iterator:
- evas_touch_point_list_count
- evas_touch_point_list_nth_xy_get
- evas_touch_point_list_nth_id_get
- evas_touch_point_list_nth_state_get
This also fixes a number of issues related to feeding fake
input events.
Note: I wanted to add delta x,y information as well but it's
in fact not really possible outside the event callback itself,
as the previous x,y position will not be updated unless there's
an event.
@feature
This removes:
Efl.Event interface
And renames:
Efl.Event.Input -> Efl.Input.Event
Efl.Event -> Efl.Input.Event (merged)
Efl.Event.Pointer -> Efl.Input.Pointer
Efl.Event.Key -> Efl.Input.Key
Efl.Event.Hold -> Efl.Input.Hold
This also moves some interfaces from efl/ to evas/ where they
belong better.
This allows renaming Eo_Event to Efl_Event.
This sets a bit whenever a callback listener is added.
I couldn't get any profiling data easily (too small for
valgrind).
Note: This removes the proper refcounting on the "move"
event listeners. I believe this is not a problem as most times
the move_ref goes to 0, it is because the object is deleted.
Worst case, we just trigger a callback_call with no listeners.
This adds 32 bits to each evas object private data.
Since the new event type is the same for multi and single
touch (finger id is the only difference), multi touch listeners
would get triggered even for single mouse events.
Fixes https://phab.enlightenment.org/T4345
Fixes https://phab.enlightenment.org/T4378
This raises a question though: How do we want to differentiate
between single & multi touch events in the eo interfaces?
The previous patch 1185c40e50 shows how having
two event types for the same thing (key or mouse input events)
was a bad idea. The only guaranteed order of callbacks is the
priority but even that was not enforced (since legacy or eo
style event had to come first).
Fixes T4310
is_visible returns 0 if no_render is true, so should
was_visible as well. Yeah, there will be problems if
no_render changes on the fly. Don't do that.
Fixes T4193
i don't know for sure if this fixes T4103 but in theory i think it
might given a reading of the backtrace and a guess at what might
happen, so try this fix. it doesn't hurt and can only help.
@fix
This should fix T3309
Snapshot objects are image objects, so the function is_opaque
exists. No need to bypass it. Also, alpha rectangles are not
opaque. Assume that anything with a filter is not opaque.
All of this fixes T3309 but the main point was on snapshot
objects (probably because the only point of a snapshot is
to apply a filter on it).
this is a continuation fix from
25d77bc1d2 and
9f0fd66ab8
this fixes yet more corner cases after the above 2 fixes. our clip
cache tracking code seems to be broken somewhere and not updating - at
least when events are processed so i did ti the slightly slower way
and recursed through clippers to figure it out in this path. it all
works now it seems but it's got a small speed hit. better be right
than a little faster.
@fix
Summary:
Some fonts can have weird style and weight value.
If a font has a style name as "medium" and a weight value as "semi-bold",
Evas can't load the font using "font=Somefont:style=Medium".
It only can be load with "font=Somefont:style=SemiBold" or
"font=Somefont:weight=SemiBold".
On the other hand, it could be loaded when I tested the following commands.
fc-match -s ":family=Somefont:style=Medium" or
fc-match -s ":family=Somefont:weight=SemiBold"
Evas also should load font based on font's style name.
@fix
Test Plan: N/A
Reviewers: tasn, herdsman, cedric, woohyun, raster
Reviewed By: raster
Subscribers: Blackmole, z-wony, jpeg
Differential Revision: https://phab.enlightenment.org/D4108
smart_get and attach referred to an opaque struct, from EO
point of view.
Also, attach was an EO-only function, used nowhere besides
evas object smart itself, and evas grid (which is not EO
public API).
This is a horrible API used for internal optimizations. Which
may or may not be partly broken anyway.
We can do better, in the future. Let's not expose this kind
of API.
Now called "hint_min", not sure if it's the proper name for it.
At first I wanted to reuse the request size hint instead of
adding a new hint, but doing that would break Terminology
or any app that already used size_hint_request.
One problem with hint_request is that the legacy function
already exists but its support is practically not implemented.
@feature
Summary:
Implemented interface Efl.Gfx.Buffer functions bufer_map/unmap for Efl.Canvas3D.Scene.
Added function e3d_drawable_texture_rendered_pixels_get to module evas_gl_3d
to getting pixels from FBO. Added wrappers for functions
e3d_drawable_texture_rendered_pixels_get and e3d_drawable_texture_id_get
to have possibility call it through engine functions.
Reviewers: cedric, Hermet, raster, jpeg
Reviewed By: jpeg
Subscribers: jpeg
Differential Revision: https://phab.enlightenment.org/D3978
This lets me narrow down the remaining cases of pointers across the EFL.
The void pointers will later need to be reevaluated on per-case basis and
replaced appropriately where possible/feasible.
So, I was stupid. I was relying on legacy callbacks to
trigger eo events, which means that only when a legacy
callback was registered would my new eo events be triggered.
Instead, I can pass the eo event desc & info whenever
calling evas_object_event_callback_call().
Summary:
- added is_active property in Evas_Key_Grab.
- Evas key down and key up events transferred to active grabs only.
- If evas grabs has a exclusive grab, other grabs will be deactivated.
- If a exclusive grab is ungrabbed, remained grabs will be activated.
Reviewers: jypark
Reviewed By: jypark
Subscribers: cedric, jpeg
Differential Revision: https://phab.enlightenment.org/D3996
So, this is not a very clean solution, but this mostly
makes Evas_Device an Eo object of class Efl.Input.Device.
Since evas_device relies on some Evas knowledge (evas
callbacks, canvas private data), it can't be fully moved
to lib/efl/.
Making the input device an interface rather than a class
was also not a great solution, as the goal is to share
the data structure around EFL internals (Ecore and Evas).
Complex types (i.e. list, array, hash, accessor etc.) now do not require
pointers with them anymore (the pointer is implied) and the same goes for
class handles. Eolian now explicitly disallows creating pointers to these
as well. This is the first part of the work to remove pointers from Eolian
completely, with the goal of simplifying the DSL (higher level) and therefore
making it easier for bindings (as well as easier API usage).
@feature
in the event that the global gl context changes, all engine image data
must be destroyed and then re-created in order to continue rendering
successfully
Summary:
enum Evas.Canvas3D.Shade_Mode are using for choose relevant shader source code.
So renaming have a sence.
Rename evas_canvas3d_shade_mode_set/get property to evas_canvas3d_shader_mode_set/get
Rename internal fields and functions
Reviewers: cedric, Hermet, raster
Subscribers: jpeg
Differential Revision: https://phab.enlightenment.org/D3882
Summary:
Add post processing render function as rendering full screen quard after
rendering to texture.
Add possibility use size of current frame in shader.
Add FXAA shader source files
Reviewers: raster, cedric, Hermet
Subscribers: jpeg
Differential Revision: https://phab.enlightenment.org/D3847
Summary:
Evas Image should be independent of render engine.
So remove native.func.data member of RGBA_Image, Evas_GL_Image struct.
And remove data argument,too.
Test Plan: Local test, Tizen3.0 mobile, Desktop englitenment
Reviewers: jpeg, spacegrapher, wonsik
Subscribers: cedric, dkdk
Differential Revision: https://phab.enlightenment.org/D3850
Despite the previous patches, no-render objects could be
partially visible. Eg a fileselector marked as no-render
would have its file list visible. All other children were not
shown.
I think this is not the last fix for this feature, but
eventually source_visible will have to die internally
and be replaced by no-render.
Thanks @yakov-g for the report.
Setting the no-render flag on an elm widget had no effect,
as it was not properly propagated to its children. This should
fix that, but I'm not a fan of the solution.
Fixes T3371
1. unsigned char* as a return type was not even compatible
with the default colorspace (ARGB: 32 bits).
2. Change all unsigned to int for... uh... simplicity
unsigned is more correct than int for things like width,
size or stride, but in fact having both ints (x,y) and unsigned
ints makes the code more complex.
This is a matter of personal taste.
So I forgot to clean my hard drive from previously generated files,
and obviously everything still worked. This lead to having to roll back
evas_smart_clipped.eo as a public eo object until we merge elementary.
Still I would like someone to take a look at elm_pan.eo and figure out
how to not rely on smart clipped there.
Summary:
Main flow: add several meshes(with different number of polygons) in one node,
enable LOD for node, set boundary distances to choose need mesh depend on distance
to the camera node, render only need mesh. Add API's enable lod in
evas_canvas3d_node module and set boundary distance to module
evas_canvas3d_mesh module Refactored function evas_canvas3d_node_mesh_collect
to calculate distance. Refactored _scene_render to have possibility pass to the
render only need LOD mesh.
Reviewers: cedric, Hermet, raster
Subscribers: jpeg
Differential Revision: https://phab.enlightenment.org/D3731
Signed-off-by: Cedric Bail <cedric@osg.samsung.com>
Summary:
Add spin lock to access to new flag can check to
status of the preload
Reviewers: jpeg, cedric, jypark
Subscribers: raster
Differential Revision: https://phab.enlightenment.org/D3775
Signed-off-by: Cedric Bail <cedric@osg.samsung.com>
- image_native_init
- image_native_shutdown
init() will be used to test whether the engine supports a
certain type of native image.
Note: Native image support is very much dependent on the engine,
and some stuff like opengl should work everywhere (even in sw
with osmesa) but that's not the case.
This checks whether the object was created with a legacy
API, ie without not using eo_add directly. This will be used
to help with the transition from EAPI to EO APIs, as some EAPIs
should not be used with the new EO types (eg. file_set on a
Proxy object).
By default it doesn't do anything besides ERR().
In DEBUG mode, it will return immediately.
The macro will return if eo_obj is NULL.
Summary: Bounding box and sphere will calculate if user need callback of collision or data of box or data of sphere.
Reviewers: sri.hebbar, cedric
Subscribers: cedric, jpeg
Differential Revision: https://phab.enlightenment.org/D3643
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Summary:
Evas Text, Textblock, Textgrid keeps own language information.
This language information could be vary from the result of setlocale().
Especially, Evas Textblock supports <lang> tag. The language could be
changed in the middle of text. All of these language has to be used
for harfbuzz shaping.
@fix
Test Plan: N/A
Reviewers: herdsman, raster, woohyun, tasn
Reviewed By: tasn
Subscribers: cedric, jpeg
Differential Revision: https://phab.enlightenment.org/D3628
This give a constant improvement of 2% over a total benchmark run while scrolling
genlist. This benchmark included setup and destruction of the scene, so under
estimate the cost of the callback emit.
Summary:
The configuration files for Fontconfig can describe
how font list is made according to language information.
EFL also set the language for each Evas textblock styles
and used for loading font list.
But, this is inconvenient to use if we want to apply language
for loading font list according to system-wide locale information.
This patch will apply locale information for font list if there is
no specific language in description.
And it also add [lang=auto] for Evas Textblock.
auto - It loads locale for language.
none - It disables language.
@feature
Test Plan: N/A
Reviewers: woohyun, herdsman, tasn
Subscribers: jpeg, cedric
Differential Revision: https://phab.enlightenment.org/D3344
Use delete callback instead of direct call to clip_unset,
which lets us know that clip_unset() is called during the
clipper's deletion, as opposed to a simple call.
We can then make sure that the previous object state does
not point to invalid data anymore.
Here is a scenario that could have crashed:
- load and show an edje object, hide it
- change its theme or style
- show it again
@fix
Summary: remove extra if from evas_3d_utils.h according to Coverity (CID1339788)
Reviewers: raster, Hermet, cedric
Subscribers: jpeg, artem.popov
Differential Revision: https://phab.enlightenment.org/D3558
This fixes crashes, adds safety, and notes a couple of things that
are not yet implemented:
- Make an Evas_GL_Image from an RGBA_Image so we can draw it on the
canvas. This means Evas.Ector.GL.RGBA_Image.Buffer
- Readable Evas_GL_Image objects with gl_read_pixels
--> Implement proper map() & unmap() for GL buffers
This is a major refactoring of the evas filters submodule.
Use Ector.Buffer and the map/unmap methods instead of directly
accessing image buffers with RGBA_Image. RGBA_Image is still
used under the hood, for two reasons:
- Required for the final output (blend onto Evas itself)
- Required for the scaling routines
FIXME:
- Breaks proxy support (ie. all kind of texturing).
- This breaks filters support for the GL engine.
Since Evas still relies entirely on Image_Entry and Evas_GL_Image,
we will need an engine-specific wrapper object creating a Buffer
around an existing cached image.
Currently only SW support is implemented. GL will be more fun to
do (with glReadPixels and whatnot).