Make begin_frame() set a rendering colorstate and depth, and provide it
to the renderers via gdk_draw_context_get_depth() and
gdk_draw_context_get_color_state().
This allows the draw contexts to define their own values, so that ie the
Cairo and GL renderer can choose different settings for rendering (in
particular, GL can choose GL_SRGB and do the srgb conversion; while
Cairo relies on the renderer).
That's basically the "undefined" value. We need that when drawing
nothing, which so far only happens with empty container nodes.
But empty container nodes can be children of other nodes, and that makes
things propagate. So instead of catching them, force the whole rest of
the code to deal with an undefined depth.
We also can't just set a random depth, because that will cause merging
to fail.
Make our visual selection code prefer fbconfigs that are
'srgb framebuffer capable', and mark the surface as 'is srgb'
in this case.
This arranges things so that GSK knows not to use an offscreen
for converting contents back to srgb in the end.
For GDK_MEMORY_U8_SRGB depth, try to create an SRGB surface.
This requires the EXT_KHR_gl_colorspace extension, which
isn't super-common in the wild (37%), so we fall back to regular U8 if
that fails.
But if we have the extension, create our egl surface with the
srgb colorspace, and report that fact in gdk_surface_gl_is_srgb().
We still only differentiate between high bit depth or not, but we now
choose at the end instead of the start, which makes it easier to adapt
to a different method of choosing.
This is an experiment for now, but it seems that encoding srgb inside
the depth makes sense, as we not just use depth to decide on the
GL fbconfigs/Vulkan formats to pick, depth also encodes how the [0...1]
color values are quantized when stored.
Let's see where this goes.
This commit just adds the flag, but I wanted to make it an individual
commit to explain the purpose:
The SRGB flag is meant to be used for images that have an SRGB format.
In Vulkan terms, that means VK_FORMAT_*_SRGB.
In GL, it means GL_SRGB or GL_SRGB_ALPHA.
As these formats have been madatory since GL 3.0, we can (ab)use them
uncoditionally. Images in these formats are renderable, too, so it's
not just usable for uploading.
What these images allow is treating the data as sRGB while shaders
access them as linear, thereby getting sRGB<=>linear conversions for
free.
It is also possible to switch off the linearization of these images and
treat them as sRGB, which allows all sorts of shenanigans, though one
has to be careful if that turning off applies to the relevant GL/Vulkan
code in question.
Returns the linear color state that renderers should render in when
this is the target color state.
We disable this function unless linear compositing is enabled and just
return @self by default.
This function checks if the colorstate uses an sRGB transfer function
as final operation. In that case, it is suitable for use with GL_SRGB
(and the Vulkan equivalents).
We disable this function (by always returning NULL) unless linear
compositing is enabled, because this function is used to transition
textures and framebuffers to their linear counterparts.
This is mostly an empty shell for now. We only have static instances
for srgb and srgb-linear, which we will use as markers during our
node processing.
In the future, this object may grow more instances, as well as the
ability to create them from and save them to icc profiles or cicp
data. And a color conversion API.
This is a temporary solution to allow testing how well linear rendering
already works while refactoring code.
This will be removed once linear rendering is the default.
If the GL texture is exportable to a dmabuf, we can just use our dmabuf
importing code to get that texture into Vulkan.
There is no need to go via host memory in that case.
And if it doesn't work, we just fall back, like before.
We have code with proper error handling for dmabuf export, we can just
try to use it.
And if it doesn't work, we don't offload the texture like before.
But it does work - at least for me.
Instead of hardcoding which textures we presumably support, just try
creating a buffer and use the failure of that for the error message.
This makes the error message a bit less obvious, but it makes it
possible to refactor the get_buffer() code without having to deal with
the error path.
If we want to improve the debug message, we can start putting debug
messages into the get_buffer() function.
But I think this is good enough.
Unimplemented nodes are a failure now.
We make this a soft failure with a g_warning() so that during
development when adding new nodes, the renderer doesn't instantly crash,
but instead prnts a warning.
But we do consider unimplemented nodes a bug now.
Because of that, add_fallback_node() is now renamed to add_cairo_node().
Everyone should draw the error pink here, because that's what the
renderers not supporting it do, and it's also what the default shader
does.
So no matter if a renderer supports GL shaders or not, it should draw
the same pink.
When determining which way is up for the offloaded texture, we
must take all transforms into account - the ones outside the
subsurface node, and the ones inside.