Provide a fixed allocation to each texture unit in order to prevent
conflicts. This fixes a conflict between colour transforms and the
wireframe debug mode.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
The GL renderer is able to use a gbm_device to allocate gbm_bos, which can be
used as DMABUFs.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Support importing dmabuf buffers as renderbuffers and binding them to
FBOs. These can then be rendered to directly, or they can be blitted
into from the shadow render buffer.
How to best create those dmabuf buffers in the backend is an open
question and may vary depending on what external API the backend is
interfacing with.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
The batches debug mode tints each batch of a repaint pass in a
different color in order to highlight batches.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
The wireframe debug mode needs to clear the current renderbuffer in
order to clean up old wireframes lying around. This commit makes this
system generic for upcoming debug modes with similar needs.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
In order to avoid the complexity of handling multiple debug modes at
the same time, this commit makes wireframe a proper debug mode. It
also uses the new tinting system to make the white wireframe pop over
a darkened damaged region.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Don't color sub-mesh differently in wireframe mode. There's not much
interest in being able to distinguish the sub-meshes in a paint node
and this allows to simplify the logic by removing the color vertex
stream.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Current green tint support is a hard-coded Porter-Duff premultiplied
blending of a green source (slightly skewed on the green channel) over
the updated damaged destination. This commit makes green tinting
generic by letting the shader user provide a custom tint color.
The goal is to reuse that system for the upcoming debug modes.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Set up debug mode initial infrastructure using a dedicated key binding
and make shaders debug a debug mode.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Render wireframe within paint nodes instead of drawing lines in a
second pass. The wireframe is blended over the node in a single draw
call. This slightly simplifies the logic by removing the computation
of a second set of indices and enables wireframe anti-aliasing using
Celes and Abraham's "Fast and versatile texture-based wireframe
rendering" paper from 2011.
Celes and Abraham use a one-dimensional set of texture coords for each
triangle edge, 1.0 for the 2 vertices defining the edge and 0.0 for
the other vertex, which basically define barycentric coords. Texture
mapping and the mip chain is then exploited to give a constant-width
edge. The main drawback of the technique is that contour edges of
node's damage mesh are drawn half as thick as interior lines since
each triangle draws half of each line's thickness.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This makes the code slightly easier to read and prevents using
incorrect locations now that shader permutations can provide different
vertex streams.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Index vertices from the damage mesh as lines and emit a single draw
call in fan debug mode. A new shader path and an additional vertex
stream are added in order to filter the color of the solid shader
variant per sub-mesh.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
A paint node with 'n' rects damaged by 'm' quads emits 'n*m' OpenGL
draw calls. This commit batches the 'n*m' clipped polygons into an
indexed triangle strip damage mesh using degenerate triangles. A
single draw call per paint node is emitted to reduce API overhead.
Fan debug mode is disabled for now and will be added back using
batching in the next commits.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Until now, all the curves would be represented with 3x1D LUT's. Now we
support LINPOW and POWLIN curves (arbitrary names that we've picked).
We can use these curves to represent LittleCMS curves type 1, 4 and
their inverses -1, -4. The reason why we want that is because we gain
precision using the parametric curves (compared to the LUT's);
Surprisingly we had to increase the tolerance of the sRGB->adobeRGB MAT
test. Our analysis is that the inverse EOTF power-law curve with
exponent 1.0 / 2.2 amplifies errors more than the LUT, specially for
input (optical) values closer to zero.
That makes sense, because this curve is more sensible to input values
closer to zero (i.e. little input variation results in lots of output
variation). And this model makes sense, as humans are more capable of
perceiving changes of light intensity in the dark.
But the downside of all that is that for input values closer to zero, a
little bit of noise increases significantly the error.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In the next commit we'll add support for more color curves. So move
lut_3x1d to an union.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Plug async read back support to OpenGL ES 2 implementations using
GL_NV_pixel_buffer_object, GL_OES_mapbuffer extensions and
GL_EXT_map_buffer_range.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
ReadPixels() implies a synchronous read back of the render buffer to
return pixel data. OpenGL ES 3 adds asynchronous read back support by
writing the pixel data into a dedicated buffer object. This commit
adds asynchronous read back support to the output capture code. It
spawns a read back request and schedules a timeout a few frames later
in order to store the pixels into the client SHM buffer.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Let the graphics hardware handle the transformation from surface
position to texture coordinates. Paint nodes now have a single vertex
position attribute from which texture coordinates are derived. A new
vertex shader variant handles the transformation.
Signed-off-by: Loïc Molinari <loic.molinari@gmail.com>
Add support for creating surfaceless outputs and rendering to FBOs.
The backend has to create FBOs with the create_fbo API and pass the
resulting weston_renderbuffer handles to repaint_output.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Output repaint uses a pair of fence syncs to profile GPU execution by
retrieving their timestamps once signalled. While the end timestamp
can be rather inaccurate in some cases (drivers reusing sync objects
from previous command buffers), the begin timestamp is never correct
because fence syncs are signalled on command buffer completion.
Get rid of the begin fence sync and use the EXT_disjoint_timer_query
extension to measure the actual repaint duration and extrapolate the
begin timestamp from the end one.
Fixes#342
Signed-off-by: Loïc Molinari <loic.molinari@gmail.com>
Use struct pixel_format_info pointers instead of uint32_t drm fourcc
values at the API surface for output and image creation.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This services output capture tasks for the 'framebuffer' and 'full
framebuffer' pixel sources.
Both pixel sources come from the same source: the EGLSurface. The only
difference is the area. The EGLSurface contains the borders used for
output decorations, hence 'full framebuffer' is possible to capture.
We use GL_ANGLE_pack_reverse_row_order extension to make glReadPixels
return the image data in the layout we need for wl_shm buffers directly.
Without the extension we have to flip manually.
Another extension to the same effect is MESA_pack_invert, but this is
not specified for GL ES. It also uses a different token value, so it
cannot be directly substituted even if supported.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Add matrix in color.h
Matrix is used as an optimized method for
color mapping vs 3DLUT.
Nothing sets color mapping to matrix yet.
Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Add post-curve support in color.h.
Pre-curve and post-curve describe color pipeline components
in a single GL shader invocation.The GL shader is supposed
to match struct weston_color_transform exactly.
We have the following color pipeline:
shader A -> blending -> shader B -> KMS. Both A and B shaders
using the same source file :fragment.glsl.
Each shader has pre and post curve.
The typical color pipeline with 3DLUT:
Shader A: pre-curve identity->3DLUT->blending->post-curve identity
Shader B: pre-curve->3DLUT identity->post-curve identity->KMS
The typical color pipeline with matrix (in next commits):
Shader A: pre-curve->matrix->blending->post-curve identity
Shader B: pre-curve->matrix identity->post-curve identity->KMS
The pre-curve plays role of EOTF (shader A) or INV_EOTF
(shader B) becouse we are stiching the shaders.
We assume that someone in the future may use both pre-curve
and post-curve, for example, when it is not possible to combine
these curves into 3DLUT and we will do mapping elements based on
their location in ICC profile.
Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Print all EGL and OpenGL extension lists into a new log scope
"gl-renderer" instead of the usual log.
These lists cluttered the log while they were very rarely actually
useful. Sometimes they might be interesting, so make them still
available through the new log scope.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Plumb struct gl_renderer all the way through to
gl_renderer_log_extensions(). In the future, the extension lists will be
printed into a debug scope specifically, and it will get the debug scope
from gr.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Introduce shader color mapping identity and 3D LUT.
Shader requirements struct uses union for color mapping
to prepare the place for 3x3 matrix.
Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
These formats are useful because they are often easier to produce
on CPU than half-float formats, and abgr16161616 has both >= 10bpc
color channels and adequate alpha, unlike abgr2101010.
The 16-bpc textures created from buffers with these formats require
the GL_EXT_texture_norm16 extension.
As WL_SHM_FORMAT_ABGR16161616 was introduced in libwayland 1.20,
update Weston's build requirements and CI.
The formats also needed to be registered in the pixel format table,
and defined in a fallback path if recent libdrm is not available.
Signed-off-by: Manuel Stoeckl <code@mstoeckl.com>
Add function to query the DRM device given an EGLDisplay. It is the
device being used by the compositor to perform composition.
This will be useful in the next commits of this series, where we add
support for dma-buf feedback.
Signed-off-by: Scott Anderson <scott.anderson@collabora.com>
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Adding these formats makes it possible for clients using wl_shm to
submit buffers with 10 bits per pixel, and thus (if Weston is
configured with an xrgb2101010 frame buffer) display more precise
colors on some computer monitors.
Signed-off-by: Manuel Stoeckl <code@mstoeckl.com>
This makes weston_color_transform object be able to express
three-channel one-dimensional look-up table transformations. They are
useful for applying EOTF and EOTF^-1 mapping, or, gamma curves. They
will also be useful in optimizing a following 3D LUT tap distribution
once support for 3D LUT is added.
The code added here translates from the lut_3x1d fill_in() interface to
a GL texture to be used with SHADER_COLOR_CURVE_LUT_3x1D for
weston_surfaces.
It demonstrates how renderer data is attached to weston_color_transform
and cached.
GL_OES_texture_float_linear is required to be able to use bilinear
texture filtering with 32-bit floating-point textures, used for the LUT.
As the size of the LUT depends on what implements it, lut_3x1d fill_in()
interface is a callback to the color management component to ask for an
arbitrary size. For GL-renderer this is not important as it can easily
realize any LUT size, but when DRM-backend wants to offload the EOTF^-1
mapping to KMS (GAMMA_LUT), the LUT size comes from KMS.
Nothing actually implements lut_3x1d fill_in() yet, that will come in a
later patch.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This adds shader support for using a three-channel one-dimensional
look-up table for de/encoding input colors. This operation will be useful
for applying EOTF or its inverse, in other words, gamma curves. It will
also be useful in optimizing a following 3D LUT tap distribution once
support for 3D LUT is added.
Even though called three-channel and one-dimensional, it is actually
implemented as a one-channel two-dimensional texture with four rows.
Each row corresponds to a source color channel except the fourth one is
unused. The reason for having the fourth row is to get texture
coordinates in 1/8 steps instead of 1/6 steps. 1/6 may would not be
exact in floating- or fixed-point arithmetic and might perhaps risk
unintended results from bilinear texture filtering when we want linear
filtering only in x but not in y texture coordinates. I may be paranoid.
The LUT is applied on source colors after they have been converted to
straight RGB. It cannot be applied with pre-multiplied alpha. A LUT can
be used for both applying EOTF to go from source color space to blending
color space, and EOTF^-1 to go from blending space to output
(electrical) space. However, this type of LUT cannot do color space
conversions.
For now, this feature is hardcoded to off everywhere, to be enabled in
following patches.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Add a new shader requirements bit input_is_premult which says whether
the texture sampling results in premultiplied alpha or not. Currently
this can be deduced fully from the shader texture variant, but in the
future there might a protocol extension to explicitly control it. Hence
the need for a new bit.
yuva2rgba() is changed to produce straight alpha always. This makes
sample_input_texture() sometimes produce straight or premultiplied
alpha. The input_is_premult bit needs to match sample_input_texture()
behavior. Doing this should save three multiplications in the shader for
straight alpha formats.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Trying to support GL ES 2.0 + extensions along with GL ES 3.0 for better
control is becoming too complicated fast. In this patch you see the
GL_RGBA vs. GL_RBA16F and GL_HALF_FLOAT vs. GL_HALF_FLOAT_OES paths.
More such cases will come, e.g. GL_RED_EXT vs. GL_R32F.
Make things simpler and require GL ES 3.0 +
GL_EXT_color_buffer_half_float for all color management related
functionality. If one doesn't have GL ES 3.0, all you lose is color
management.
Also, all extensions needed by color transformation operations are
gathered under one boolean flag instead of having a flag per extension,
again for simplicity.
This makes the GL ES extension handling much easier.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This reverts commit 36d699a164.
A different way to fix this same issue is the previous commit
"gl-renderer: do not unbind the context on output destroy"
which is needed for other reasons.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
In commit "libweston: add struct weston_drm_format" struct
weston_drm_format and its helper functions were added to libweston.
The functions query_dmabuf_formats and query_dmabuf_modifiers are very
specific to GL-renderer and its internals. So instead of exposing them
in libweston, query and store DRM formats and modifiers internally in
GL-renderer. Also, add a vfunction to struct weston_renderer in order
to retrieve the formats.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This patch gathers all values to be loaded to shader uniforms into a new
struct gl_shader_config along with texture target and filter
information. Struct gl_shader becomes opaque outside of gl-shaders.c.
Everything that used or open-coded these are converted.
The aim is to make gl-renderer.c easier to read. Previously, uniform
values were loaded up in various places, texture units were set up in
one place, textures were bound into units in different places. Stuff was
all over the place.
Now, shader requirements and associated uniform data is stored in a
single struct. The data is loaded into a shader program in one function
only.
That makes it easy for things like maybe_censor_override() to replace
the whole config rather than poke only the shader requirements. This may
not look like much right now, but when color management adds more
uniforms and even hardcoded color need to go through the proper color
pipeline, doing things the old way would become intractable.
Similar simplification can be seen in draw_view(), where the RGBA->RGBX
override becomes more contained. There is no longer a need to "pre-load"
the shader used by triangle fan debug. Triangle fan debug no longer
needs to play tricks with saving and restoring the current shader.
The real benefit of this change will probably come when almost all
shader operations need to take color spaces into account. That means
filling in gl_shader_config parts based on a color transformation.
This is based on an idea Sebastian already used in his Weston color
management work.
Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net>
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
These functions are related to shaders, so they are more at home in
gl-shaders.c. gl-renderer.c is too long already.
This allows making a couple functions static while the moved functions
become non-static. Future changes turn some of these functions into
static again, with the ultimate goal of making struct gl_shader opaque.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This adds a heuristic for freeing shader programs that have not been
needed for a while. The intention is to stop Weston accumulating shader
programs indefinitely, especially in the future when color management
will explode the number of possible different shader programs.
Shader programs that have not been used in the past minute are freed,
except always keep the ten most recently used shader programs anyway.
The former rule is to ensure we keep shader programs that are actively
used regardless of how many. The latter rule is to prevent freeing too
many shader programs after Weston has been idle for a long time and then
repaints just a small area. Many of the shader programs could still be
relevant even though not needed in the first repaint after idle.
The numbers ten and one minute in the above are arbitrary and not based
on anything.
These heuristics are simpler to implement than e.g. views taking
references on shader programs. Expiry by time allows shader programs to
survive a while even after their last user is gone, with the hope of
being re-used soon. Tracking actual use instead of references also
adapts to what is actually visible rather than what merely exists.
Keeping the shader list in most recently used order might also make
gl_renderer_get_program() more efficient on average.
last_repaint_start time is used for shader timestamp to avoid calling
clock_gettime() more often. Adding that variable is an ABI break, but
libweston major has already been bumped to 10 since last release.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This is useful for seeing that the shader program garbage collection
works in a future patch.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
One more thing is coming to need this, so add the compositor pointer and
migrate existing places to use it where it simplifies things.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Proper color management will need blending done with linear light pixel
values, that is, EOTF applied before blending, and then inverse-EOTF
applied for scanout after blending. The simplest way to set that up is
to use an intemediate framebuffer a.k.a shadow buffer containing the
composited image in linear light values, then blit from that to the
actual framebuffer.
This patch implements the shadow buffer, but the linear light
blending is left for another patch. This allows GL-renderer to turn
WESTON_CAP_COLOR_OPS on.
Half-float is chosen as the buffer format because linear light values
require more bits to encode with sufficient precision than the usual
non-linear pixel values.
v2: Use /* */ instead of // (Pekka)
Rename fbo and tex to shadow_{fbo,tex} (Pekka)
Check for OpenGLES capabilities before creating
shadow_{tex,fbo} (Pekka)
Signed-off-by: Harish Krupo <harishkrupo@gmail.com>
v3: Rebased.
Simplified GL version checks (Sebastian)
Apply changes from "libweston: add color ops cap and bool renderer
shadow buffer"
Renamed supports_half_float_texture to has_gl_half_float to
follow the existing naming pattern.
Introduce gl_renderer_create_shadow_16f().
Undo moving of glViewport() call.
Replace half_float_texture_enabled with shadow_exists().
Introduce struct gl_output_state_shadow.
Assert no resizing with shadow.
Fix triangle fan debug.
Rename repaint_from_texture() to blit_shadow_to_output().
Rewrite commit message because linear light blending is not
implemented in this patch.
Fix blit_shadow_to_output() for scaled/transformed outputs and
remove redundant code.
Fix has_gl_half_float determination.
v4: Disable blending in blit_shadow. (Daniel)
Port to gl_renderer_get_program().
Make a generic fbo-texture struct with parameterized format. (Daniel)
Change has_gl_half_float into gl_half_float_type.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This helps accounting how many shaders live in the cache, what the
shader source code is, and when shaders are compiled.
Signed-off-by: Harish Krupo <harishkrupo@gmail.com>
v2: Resolved rebase conflicts.
Put shader_scope in struct gl_renderer, remove struct
gl_shader_generator.
Wrote commit message.
Rebased for "gl-renderer: rewrite fragment shaders" which completely
changed how shader sources are generated.
Added cache statistics to debug output on subscribe.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
If shader compiling on demand fails, then rather than using whatever
random shader happens to be current, use an explicit fallback shader
painting stuff brown.
The color is chosen dim enough to hopefully not cause problems even in
a HDR setting as it will be written verbatim into the fb/shadow.
This also prevents NULL dereference on shader->key.variant in
draw_view().
One way to test this shader is to hack fragment.glsl:
#if DEF_VARIANT == SHADER_VARIANT_EXTERNAL
#extension GL_OES_EGL_image_external : require
+#error haa haa
#endif
and then run e.g. weston-simple-dmabuf-v4l -f YUYV
with vivid kernel module loaded. This worked on Intel.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>