Instead of using cairo for scaling and rotating cursors before putting
them on a plane, use Cogl. For now still download them back to the CPU
so we can place them on a dumb buffer, but can explore rendering to a
DMA buffer directly as a future improvement.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
A ClutterPipelineNode took a reference to the passed pipeline and used
it during the lifetime of the paint node. In theory this meant that a
paint node pipeline could be changed, and reused, affecting the previous
paint node drawing.
Referencing instead of copying also meant the ClutterPipelineNode isn't
able to itself manipulate the pipeline any further.
Fix both of these issues by copying, instead of adding a reference to,
the passed pipeline. While resulting in some additional allocation
over head, it means we can now eventually handle color transformations
automatically for ClutterPipelineNode's.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
When running with COGL_DEBUG=show-source, log what pipeline and shader
program is used when painting, and what shader source code corresponds
to each shader program.
This helps identify what shader is used when painting to what
framebuffer.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
So far 'color-state' is added, intended to tag pipelines with color
state transformation capabilities. Color state transformation snippets
are tagged with it. Eventually handlers of pipelines will use this
information to on-demand decorate pipelines with color transformation
snippets.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
A snippet is assigned a capability, which is then transferred to the
pipeline it gets added to. Managers of pipelines can then check whether
a pipeline it got handed whether it has a certain capability, and if
not, handle the situation where it is not.
The intention is to allow Clutter to tag color state transformation
snippets with a capability, allowing generic paint nodes to handle color
transformations when needed.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
This looks at the color state it got from the actor on construction, and
the target color state from the paint context and generates (and caches)
color aware pipelines used for painting. One of the purposes here is for
mixing SDR and HDR content and painting to a HDR monitor. If HDR (or
optical blending) isn't activated, the produced shaders will be
equivalent to what we had before.
Also add some names to the piplines, as this helps identifying what
pipeline source is associated with what pipeline.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
In some of the places we need more context than just the CoglContext, so
prepare for that by passing around the paint context, which carries
this, everywhere instead. It won't be needed everywhere, but lets stay
consistent.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
Color aware rendering needs shaders / pipelines that adapt to what
output they render to. For example if we want to render to a linear
BT.2020 intermediate framebuffer on one monitor, and a non-linear sRGB
direct target buffer on another, the shader for the same paint node or
content will depend on where they are going to be presented.
In order to help keeping track of what shader should target what
monitor, without having to regenerate them each time, introduce a
pipeline cache that knows how to handle differentiating between
transforming between different color state.
The cache is meant to handle caches for multiple pipeline users, where
each user might potentially want to keep track of multiple pipelines
itself. Lookup should be O(1), and in order to achieve this, separate
the cache into 3 levels.
The first level is the "pipeline group", where e.g. a ClutterContent
type allocates a group where it can store its pipelines. Each group has
a fixed number of "slots" where it can store a pipeline. Each slot has a
hash table where the key is derived from a color state transform, and
where the value is a CoglPipeline where the thame color state
transformation is expected to be handled.
A content will when painting know about its own color state, and the
target state it should render into, retrieve a cached pipeline for the
correct transform, or if the cache didn't have it, generate it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
Allow compositing in a linear color space and do so either when forcing
it via the debug controls D-Bus API, or when the experimental HDR mode
is enabled.
This relies on paint nodes etc to actually transform everything into the
linear target color space, which isn't done yet, so enabling it right
now will cause a broken result. Yet, introduce this now, so that
painting can be fixed piece by piece.
Linear blending is automatically enabled on monitors where HDR is
enabled, as this makes it possible to use an linear color space when
blending content from different color spaces with different transfer
functions.
Linear blending requires extra precision, i.e. 16 bit per channel
in the intermediate buffer due how the values are distributed,
so only enable the experimental HDR mode if the Cogl context supports
half float formats.
By default, no intermadiate linear offscreen framebuffer is used.
To test, do e.g.
./tools/debug-control.py --toggle ForceLinearBlending
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
The initial target color state is the color state of the stage view
being painted to. If we're painting to an arbitrary framebuffer, it's
currently hard coded to sRGB/electrical.
The content color state is not set on construction, but when starting to
paint, it's set to the color state of the stage itself. Whenever an
actor is painted, it'll set the color state to the color state of
itself. The intention is that offscreen rendering pushes a target color
state that causes painting to it to not necessarily be in the stage view
color state.
Pass color state with offscreen framebuffer, as this avoids hard coding
sRGB in the lower level bits of paint contexts. It's still practically
hard coded, only that it's derived from somewhere else (e.g. the stage
or window actor).
Nothing is actually using this yet, but will eventually.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
This aims to provide the color state used for compositing for a specific
view. It's currently hard coded to default, but will eventually be
configured depending on the monitor and configuration. It's intended to
be used as a target color state for rendering with color awareness.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
The cogl shader cache uses snippet pointers as cache keys, meaning even
if we generate two identical snippets; if they have different pointer
addresses, they'll generate separate cache entries. Handle this by
caching our snippets on the context.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
This helper generates shader snippets that converts pixels from one
color state to another. For example if there is content with sRGB color
state that should be converted to linear BT.2020 before being written to
the framebuffer, a shader that makes the pixel go through the following
steps will be generated:
1. sRGB EOTF
2. Luminance gain (hard coded for now)
3. Color space mapping
The intention is that it should be possible to composite in a linear
color space, into an intermediate framebuffer, which is then passed
through an inverse EOTF to produce linear content in the output color
state.
When transforming from BT.2020/PQ to sRGB/sRGB, clamping to the sRGB
max luminance is done.
Cases where direct transform is also handled, i.e. where one doesn't go
via an linear intermediate buffer, in which case there might be both an
EOTF and an inverted EOTF in the same shader snippet to still do color
space mapping using optical color encoding. This will be used for e.g.
transforming cursor sprites.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
An unknown color space isn't very useful to have, as there is not very
actionable what to do with it. Rename it to 'default'. Later it'll be
used to an implicit color space, which in practice will be treated as
sRGB.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
The context can be set via a property (currently unused) or via the
current global singleton as a fallback. It means API that acts on an
actor can avoid going via any globals.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>