This adds Perfetto debug annotations for printing optimizations, color
vision deficiencies, alpha.
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Rename 'timeline' to 'activity' and 'elapsed' to
'active'.
Feels like this it would more familiar to people when analysing
traces and uses the Perfetto naming for consistency. Otherwise I'd
rename 'activity' to 'timeline' for Perfetto track names.
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
This avoids truncation to zero, by using an explicit cast to float and
print out properly the last 2 digits.
43 / 1000 = 0.00
43 / 1000.0 = 0.04
Fixes: 2d70cbf037
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Continuing my quest to remove weston_view from backends and renderers,
drop gl-renderer's last use of weston_view.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Rather than fail the tests that require fb-fetch GL ES feature and it's
missing, mark them as skipped instead. This helps people who run the
test suite manually.
In CI, a skip is marked as failure anyway.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This ensures that both blending implementations will be tested. The AUTO
mode, which was the only mode before this patch, would not test the
fixed-function blending a.k.a GL-renderer shadow framebuffer.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This creates the fragment shader state needed for in-shader blending.
In-shader blending is always enabled if supported:
- GL supports the necessary features, and
- the blend-to-output color curve is exactly invertible.
The exact inverse is required, because the compositor will do repeated
decode-encode cycles per destination pixel, one for each non-opaque
source. Roundtrip errors through decode-encode might accumulate
otherwise. For now, identity, enumerated, and parametric curves are
deemed invertible while LUT is rejected without inspection.
Therefore to make use of this feature, outputs need to be configured with
a non-LUT type EOTF/TRC.
In-shader blending is always enabled, because it should be universally
more efficient than the use of a shadow buffer.
This feature was originally drafted for Weston by Sebastian Wick.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This will be needed for framebuffer decoder and encoder for in-shader
blending.
Pure refactoring in gl_renderer_color_transform_create_steps().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Discriminate between renderbuffer discard and shadow allocation
failures. While at it, let's pring the shadow pixel format rather than
hardcoding it in a string.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Make the shader description strings easier to read. Before they looked
like this:
Compiling shader program for: SHADER_TEXCOORD_INPUT_ATTRIB
SHADER_VARIANT_SOLID SHADER_COLOR_EFFECT_NONE SHADER_COLOR_CURVE_LINPOW
SHADER_COLOR_MAPPING_IDENTITY SHADER_COLOR_CURVE_IDENTITY
+input_is_premult -tint -shader_blending (SHADER_COLOR_CURVE_IDENTITY,
SHADER_COLOR_CURVE_IDENTITY)
Now they look like this:
Compiling shader program for: attr tc, solid tex, no effect, CP{
linpow, I, I }, +premult_in -tint -shader_blending (I, I)
Turn the switches into arrays for easier handling.
This is different from weston_enum_map, because we need two different
strings for each value: a symbol for the shader code, and a description
for the debug logs.
Unknown enum values will abort(), but they should be asserted anyway.
Unfortunately getting a weston_compositor here would be inconvenient for
using weston-assert macros.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This prepares the fragment shader for blending in-shader instead of
using the fixed-function blending.
This is not yet used, but it will allow avoiding the 16F shadow
framebuffer in the future.
TEX_UNIT_LAST is actually a count rather than the index of the last
unit. Fix the off-by-one in the check.
The FB fetch/store curves push our potential texture count beyond 8, so
implement a runtime check.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This adds support for dma-buf screenshots in our GL-renderer.
For now it only supports GLES >= 3.0, as it depends on
glBlitFramebuffer(). In the future we'll add support for older GLES
versions as well, using a shader to do the blit.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
For now this doesn't bring any benefits besides making
gl_renderer_do_read_pixels_async() easier to read. But in the next
commits this will be important.
This allows callers to decide if they want to use a timer when they fail
to get a sync fence for a capture task. For SHM tasks we always fallback
to a timer, but for dma-buf we will not allow the fallback path.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
For now we support creating gl_capture_task only for SHM buffers. This
is used when the GL renderer pulls an output capture task from the
queue and its buffer type is SHM.
In the next commits we'll add support to allow output capture tasks to
be created with dma-buf buffers, so we need to extend gl_capture_task to
support that as well.
Differently from the SHM case, for dma-buf we don't have to do any copy.
The gl_capture_task is created just to wait for the blit to finish, and
then retire the output capture task.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
transform_damage() returns an allocated set of quads; if a surface had
both opaque and blended regions, we were overwriting the
previously-allocated set of quads for the blended region.
Luckily, transform_damage() doesn't need to be called twice anyway, so
we can fix this by only calling it once in the first case.
Signed-off-by: Daniel Stone <daniels@collabora.com>
On drivers without explicit modifier support we can't use
eglQueryDmaBufModifiersEXT() to check the correct texture target. We
already hardcode GL_TEXTURE_EXTERNAL_OES for various YUV/YCbCr formats -
let's assume it applies to all of them.
Signed-off-by: Robert Mader <robert.mader@collabora.com>
This should cut the cost of debug_scene_view_print_buffer() in half on
ARM A55 CPU. Debug printing is quite expensive on such platform.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This adds a new output color effect: grayscale. It takes RGB color as
input and computes a gray pixel color using the luminance formula for
linear sRGB:
Y = 0.2126 * R + 0.7152 * G + 0.0722 * B
Just like the other color effects we have, this only works for sRGB and
are not enabled when color-management is on.
Note: although the technique is designed to be applied in linear, it's
costly to convert to linear and then back to electrical. As doing the
conversion in electrical still gives a reasonable result, we do it this
way. When we add support for color effects with color-management on,
we'll apply the effect in linear.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This was logging the CVD correction effects, but not the inversion one.
This commit adds this.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Use the new label field instead. The code becomes much simpler.
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Add a new gl-renderer scope (gl-renderer-paint-nodes) to print out
repaint (damage) regions, opaque and blended regions as well as other
optimizations we might be taking (clear region, color effects), and
skipping repaints.
It includes as well the elapsed time being used by GPU timeline
(GL_EXT_disjoint_timer_query) as well.
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Further clarify that is printing the GL/EGL-extension by renaming
the internal scope name to extensions_scope and the advertised name
is gl-renderer-ext.
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
yuv_coefficients and yuv_offsets should get optimized away by shader
compilers as the related code paths can never be reached. This seems to
work well on Mesa but not necessarily with other drivers.
While on it, assert that the uniforms *are* present, unless the
yuv-to-rgb conversion is handled by the driver.
Signed-off-by: Robert Mader <robert.mader@collabora.com>
Texture storage formats and parameters validity checks are done using
glGet*() functions which can be pretty slow depending on the OpenGL
implementation. Wrap these checks around a define disabled by default
in order to get the best OpenGL renderer performance in release
builds.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
We seem to initialize the uniform with -1 so check against as the test
branch will actually try to use the supplied matrix (although it is
zero in this case).
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
CVD correction is composed by a linear transformation, so we should be
able to collapse it into a single matrix multiplication:
Y = M * X
Where Y is the result, X is the original color, and M is the CVD
correction matrix.
As we need to perform CVD correction for every pixel, this can be
beneficial for limited hardware.
In this patch we do that, updating the libweston core code and also the
GL-renderer and its fragment shader.
Suggested-by: Christopher Healy <healych@amazon.com>
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
CVD correction have the following format. These are linear
transformations in which M is a 3x3 matrix and X is a RGB vector.
F(X) = M * X
It is well known that CVD simulation/correction is done using straight
alpha values. So when we have alpha premultiplied values, we compute
straight alpha values first, apply the correction and premultiply by
alpha again. But this is not necessary, as we can see mathematically:
a * F(X) = a * (M * X) = M * (a * X) = F(a * X)
So do not convert premultiplied alpha values to straight alpha values
before applying CVD correction. This saves a few operations per pixel.
Note that the same does not apply to color inversion:
F(X) = 1 - X
a * F(X) = a - a * X
F(a * X) = 1 - a * X
=>
a * F(X) != F(a * X)
Suggested-by: Christopher Healy <healych@amazon.com>
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
When repainting a paint node, if the buffer is a solid color buffer we
may skip the rendering pipeline and directly call glClear() with the
solid color, for optimization purposes.
Currently there's a bug where if the output has an output color effect
set, it is skipped when we have a solid color buffer (as we don't go
through the rendering pipeline, where the effects are implemented).
When we have color-management and the paint node contains a color xform,
we've opted for skipping this optimization and going through the
rendering pipeline for now. However, output color effects are simple,
so let's add the logic to apply them on CPU when we have a solid color
buffer.
Reported-by: Christopher Healy <healych@amazon.com>
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
`EGL_YUV_COLOR_SPACE_HINT_EXT` and `EGL_SAMPLE_RANGE_HINT_EXT` have
to be set at image import, which again happens on wl_buffer creation.
This is problematic because in Wayland (and Vulkan) those values are
surface attributes and thus only known once the buffer gets attached
to a particular surface.
We solve that by first importing the dmabuf with default values and,
when attaching a buffer to a surface, creating additional EGLImages
as needed.
Note that we ignore `EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT` and
`EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT` for now, which are neither
required by the Wayland color-representation protocol nor supported by
Mesa shaders (as of 25.3).
Signed-off-by: Robert Mader <robert.mader@collabora.com>
Unlike EGL image import, texture creation and binding is quite fast and
cheap. Thus, instead of doing it as early as possible in various places,
do it right before we actually need it in prepare_textured_draw().
This will follow-up changes easier and includes some preparations for
them.
Signed-off-by: Robert Mader <robert.mader@collabora.com>
Add matrix-coefficients and range tracking to more gl-renderer structures
and get the relevant values from the color-representation implementation
instead of hard-coding them in the shader.
Signed-off-by: Robert Mader <robert.mader@collabora.com>
We've been clobbering non-solid buffers with solid buffer attachment in
situations where we override the real buffer with a placeholder.
If the reason (punch hole, censor) that led to the placeholder is no
longer in effect, and new buffer is attached, we won't render what we should.
Instead, let's not attach anything for the paint node draw_solid case, and
allow gl_buffer_state be NULL when the real buffer is solid. gl_buffer_state
can then always be the correct state for the real buffer, even if we don't
use it.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Currently it uses some values from the existing sconf, instead let's make
it calculate everything on its own
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Refactor textured draw setup into a separate function, preparing for a
future where we set up solid draws from init_for_paint_node as well.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Turns out gl_shader_config_set_input_textures is what adds the filter
parameters to the sconf, so we must set the filters before calling it.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This removes the API impedance mismatch between
weston_color_curve_sample() and weston_color_curve_to_3x1D_LUT() that
was temporarily introduced in the previous commit. That mismatch is now
limited to gl_color_curve_lut_3x1d().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
We can handle the mirroring for negative input without conditional this
way. Maybe it's faster, maybe it's not, but I like this style better.
In color-operations we need only one call to the elementary function
rather than two. This helps a lot with code clarity, when we get a vec3
at a time to handle in the future, doing three trivial calls instead of
six with an if-else hassle.
fragment.glsl sheds one layer of function wrapping, which is nice.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
In order to be more in line with weston_view_is_opaque() - which we
use in most cases to set the value - and ensure the expectations of
existing places in the code are honored, see usages in both
draw_paint_node() implementations.
An exception here are holes - these always need to get painted as fully
opaque in the renderer path.
Signed-off-by: Robert Mader <robert.mader@collabora.com>