We want to call the outputs updated signal when an output scale or transform
changes. Otherwise helpers like the scene surface helpers will not be
notified of scale changes and not pass them to clients.
There were a couple of problems with this:
1. The behavior is unexpected. Typically objects in wlroots won't
also destroy objects that they depend on. For instance, wlr_scene_output
will not destroy the wlr_output when it's destroyed. It shouldn't be any
different for scene layouts.
2. This fixes a crash where because wlr_output_layout and wlr_scene_output
are both addons to wlr_output, we might get into a situation where
wl_list_for_each_safe might malfunction. See [1]
This means that the compositor needs to manually destroy the output
when they destroy the layout, hence ~breaking. Compositors can just
call `wlr_scene_output_destroy()` if they want to destroy both at the
same time.
[1] https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4358#note_2106260
This reverts commit 1a731596c5.
Co-authored-by: Kirill Primak <vyivel@eclair.cafe>
Opaque region is a optimization hint, (bugs outstanding) it will not
change the output contents, therefore damage does not need to be submitted.
However, we still need to update the visibility state of the other
nodes in the tree. To do this call scene_update_region() by ourselves
but not `scene_node_update()` which will damage the outputs.
We need to intersect the opaque region with the node size or else we'll
get damage tracking effects with compositors attempting to use
wlr_scene_buffer_set_opaque_region() along with resizing the buffer
at the same time in a certain order.
Consider this: I have a new buffer that I want to commit to my scene buffer
that is smaller than the old one. However, I still have the old opaque
region that is the size of the old larger buffer, so that means that
for the small moment between when we reconfigure the opaque region for the
new buffer the opaque region will be oversized. Scene logic will then
try to apply occluding optimizations outside of the node boundaries
causing damage artifacts.
Without a round in this case the damage region is translated to truncated coordinates, potentially
misplacing it relative to the actual position of that region in the output buffer.
The backend is not able to tell whether a surface is being
presented via direct scan-out or not. The backend will set
ZERO_COPY if the buffer submitted via the output commit was
presented in a zero-copy fashion, but will no know whether the
buffer comes from the compositor or the client.
Using "present" is confusing here: the event is emitted when the
buffer is being sampled to be displayed on an output, not when it's
being presented on-screen.
Rename to match the presentation-time terminology.
By adding a sent_feedback bool into the list entry that we can mutate
we no longer need to maintain this `sent_direct_scanout_feedback` variable.
sent_feedback will also be useful for output layers.
This changes the semantics of wlr_output_state. Instead of having
fields with uninitialized memory when missing from the committed
bitflag, all fields are always initialized (and maybe NULL/empty),
just like we do in wlr_surface_state. This reduces the chances of
footguns when reading a field, and removes the need to check for
the committed bitfield everywhere.
A new wlr_output_state_init() function takes care of initializing
the Pixman region.
Based on five calls:
wlr_render_timer_create - creates a timer which can be reused across
frames on the same renderer
wlr_renderer_begin_buffer_pass - now takes a timer so that backends can
record when the rendering starts and finishes
wlr_render_timer_get_time - should be called as late as possible so that
queries can make their way back from the GPU
wlr_render_timer_destroy - self-explanatory
The timer is exposed as an opaque `struct wlr_render_timer` so that
backends can store whatever they want in there.