so our yuv import funcs for gstreamer 1.x engine were ignoring the
plane offsets and strides provided by gstreamer. though this nicely
shows that these numbers provided are actually wrong - at least in the
testing with vaapi back-ends with gst.
so this fixes emotions' badness but there is still badness in gst
apparently. the numbers provided if used are just simply wrong for teh
image data. commented code in the src to show how to "Fix it up" by
forcing some alignment of content to get it to work.
@fix
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.
An odd-sized image scaled down by 2 was losing 1 pixel during the
downscale, and it was not restored after scaling up. The same
happened with downscaling by 4 except the effect was even more
visible.
This meant that a moving snapshot with a large blur would trigger
some really ugly sampling issues if the content below was precise
(such a text).
If the obscured area in a snapshot object changes a lot, do
not try to keep track of it forever. Instead, redraw the filter
over the entire object region, without obscure.
This fixes a performance issue when an opaque window is moved
above a fixed transparent window (the latter has a snapshot with
blur filter).
This dramatically improves the performance and now seems
to give acceptable results. Eventually we need a quality flag
in order to enable this or not. Alternatively, "gaussian" blur
mode would skip this optimization, while "default" would trigger
it.
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 can help with performance when a large region of the
filtered image (eg. snapshot) is fully hidden by an opaque
object. For instance the window border is hidden by the
opaque window content.
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
If we delete the image that was the target surface for gl
rendering, a crash would occur on the next render cycle.
Unlikely but not impossible to trigger from app side.
@fix
This was a poor attempt at improving the performance but
obviously the root cause isn't fixed (too many texel fetches).
Uniform should (theoretically) work better than an attribute
the for loop. Just a guess here.
This also makes GL blur use a float value as radius, allowing
future extension to non-integer blur radii, as well as using
linear scaling as a fast blur approximation.
This factorizes some of the common code for image render
and resolving is_inside (verifying alpha value of a pixel).
This should also be used by save(), as well as buffer_map().
This patch introduces lots of whitespace changes by using return
instead of long if() {} or else {} blocks.
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 optimizes the GL blur algorithm by reducing the number of
texel fetches (roughly half the number of before this patch). This
works by exploiting GL's interpolation capabilities.
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).
By simply splitting X and Y blurs in two passes we can improve
the performance of the blur filter a lot.
There is still much to be done to make it really fast and nice
looking:
- implement true gaussian blur (not sine-based approximation,
right now the actual blurs look different in SW and GL)
- exploit linear interpolation for R tap instead of R*2+1 taps
(a tap being a texel fetch)
- downscale & upscale large images with large blur radii
Wait a second though, this implementation is not only incomplete
(no support for box vs. gaussian blur), it's also insanely bad in
terms of performance. Small radii may work fine, but at least blurs
render properly in GL with this patch (no more glReadPixels!).
The shader needs a lot of love, including in particular:
- support for 1D box blur single pass
- support for 1D gaussian (or sine) blur
- use linear interpolation and N-tap filters
- separation of 2D blur in two passes (high-level logic)
- potentially separation of large 1D blurs in 2 or more passes
knowing that 2sigma == sigma + sigma when it comes to the gaussian
bell curve.
This one was a bit more... "fun". I had to add a new vertex
attribute and obviously using a VertexAttribPointer led to
incomprehensible crashes. But a simple glVertexAttrib2fv makes
it work like a charm!
A rare option is not handled yet.
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 ;)