If a view is in the view list when it's being destroyed, we need to
rebuild the view list. However, doing so is currently very hairy as
views are created and destroyed at will ... including when rebuilding
the view list.
In preparation for creating and destroying subsurface views at the time
of the action rather than later at repaint time, pull out the immediate
view-list rebuild and simply mark the view list as needing a full
rebuild.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Most of the time when we're changing things about views, we don't need
to throw away the view list and rebuild it from scratch. The only times
when we need to do this are when views have been added to or removed
from the scene graph, or have been restacked within it.
Signed-off-by: Daniel Stone <daniels@collabora.com>
weston_view_geometry_dirty_internal() can be used by internal callers to
mark a view's internal geometry as dirty, without signaling the need for
a full rebuild of the view list.
This is a transitional step towards eliminating
weston_view_geometry_dirty() from public API. Up until recently, the
view-manipulation API has been that users should manually manipulate
lists of transforms, layers, and other internal members, then call
weston_view_geometry_dirty() as well as manually provoking damage.
Now that we have helper functions to handle view manipulation, they
still need to mark the view geometry as being dirty. However, most of
them do not need to invoke a full rebuild of the view_list, which is
only required when views are added or removed from the scene graph, or
restacked.
weston_view_geometry_dirty() will assume that everything has changed
before eventually being ushered out of existence.
Signed-off-by: Daniel Stone <daniels@collabora.com>
There's no need to go through and rebuild the subsurface list every
time. In addition to being unnecessary work, it complicates things like
damage tracking.
Track a new surface dirty status indicating that the subsurface tree has
changed in some way, and only rebuild subsurface stacking when this has
occurred.
Signed-off-by: Daniel Stone <daniels@collabora.com>
When we're committing anything, return the collected status of what
we've just made live, including any changes resulting from subsurfaces
having changed.
Signed-off-by: Daniel Stone <daniels@collabora.com>
weston_view_geometry_dirty() marks the passed-in view as dirty, as well
as all of its children.
weston_view_update_transform() updates the geometry of its ancestors,
then itself.
Users are required (for now) to call weston_view_update_transform() in
order to not experience a disappointing amount of death-by-assert.
Users do not have a pointer to child views which are magically
materialised by the subsurface code.
The end result is disappointing. But it is less disappointing if
updating the transform for a view the user is actually aware exists,
also updates the transform for all its children.
Signed-off-by: Daniel Stone <daniels@collabora.com>
When the destroy signal is fired, child views will disassociate
themselves from the parent. This means that we can no longer see what
the child views are - and that recursive unmapping does not work.
Make sure that views are fully unmapped before anything else happens in
destroy, so we can recursively unmap child views.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Per the wl_subsurface spec:
A sub-surface becomes mapped, when a non-NULL wl_buffer is applied
and the parent surface is mapped. The order of which one happens
first is irrelevant. A sub-surface is hidden if the parent becomes
hidden, or if a NULL wl_buffer is applied. These rules apply
recursively through the tree of surfaces.
[...]
If the parent wl_surface object is destroyed, the sub-surface is
unmapped.
The terminology is kind of loose. My reading of this is that we should
'unmap' (hide from display, remove from input/focus consideration, etc)
a subsurface immediately when a parent is destroyed.
However, if the child surface is then paired with another parent which
is itself mapped, then the child surface should immediately be mapped,
because it has a non-NULL buffer already applied, and the parent surface
is mapped.
By marking the surface as 'unmapped' on parent destroy, we were removing
it from the scene graph, but also I think breaking the rules on mapping
by requiring another commit when it was reassociated with another,
already mapped, surface.
Removing the explicit surface unmap leaves the surface in the 'mapped'
state, but without any views, which I believe has the intended effect.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Quoth the spec:
A sub-surface becomes mapped, when a non-NULL wl_buffer is applied
and the parent surface is mapped. The order of which one happens
first is irrelevant. A sub-surface is hidden if the parent becomes
hidden, or if a NULL wl_buffer is applied. These rules apply
recursively through the tree of surfaces.
We currently apply this rule through reconstructing the view_list at
repaint time, materialising new views and garbage-collecting unwanted
views as appropriate. Since this can be a costly operation, it's best if
we move this closer to the source.
This makes the core recursively unmap any child views when the parent is
unmapped. Future commits will do the same for mapping new views.
Signed-off-by: Daniel Stone <daniels@collabora.com>
View transform parents can be set by anyone. parent_view, on the other
hand, is only set for subsurfaces.
Signed-off-by: Daniel Stone <daniels@collabora.com>
This is heading towards being able to materialise subsurface views
closer to the source. weston_view_create() - being used only by
window-management code - will ultimately create all required subsurface
views as well. The internal variant will be used by this and also by the
subsurface code as required.
Signed-off-by: Daniel Stone <daniels@collabora.com>
This indicates that more than just the content changing, the form of the
buffer has changed in a way which may not be like-for-like to the
previous buffer but require significant reinterpretation. Examples
include the format, opacity, colour state, etc.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Both wl_surface.damage and wl_surface.damage_buffer explicitly refer to
the 'pending buffer'. wl_surface.attach states that there is no pending
buffer after the commit is processed, so it follows that a commit which
includes damage but no attach will not process any damage.
Change surface-commit processing to ignore all damage unless a buffer
was attached in the same commit cycle.
(Thanks to @pH5 for his spec analysis which I've just paraphrased here.)
Signed-off-by: Daniel Stone <daniels@collabora.com>
Instead of having a bool for whether or not a buffer has been attached
in this commit cycle, use a status bitmask.
Signed-off-by: Daniel Stone <daniels@collabora.com>
The only time we need to go through recalculating the surface size is
when either the buffer dimensions or the surface transforms have
changed. Now that we have dirty flags, use them to avoid a calculation
where required.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Instead of passing an output to weston_compositor_build_view_list(),
have it set up all the output z_order_lists at once.
This is a preamble for MR !1285 which wants to maintain a compositor
wide dirty bit for the view list.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Moves the output specific stuff into one place, after the view_list is
already properly set up.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
If backend initialization fails, weston_compositor_shutdown() is called
twice, once right away in weston_compositor_load_backend(), and once in
weston_compositor_destroy().
Remove the first and fix a segfault when trying to weston_plane_remove()
the primary plane a second time.
Fixes: 90c11cf40e ("libweston: move weston_compositor_shutdown call out of backends")
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
If we want to support multiple backends, the compositor must take care
to call this once, at the appropriate moment, so stop letting the
backends handle compositor shutdown themselves.
Move the weston_compositor_shutdown() calls from the backend::destroy
callbacks into weston_compositor_destroy() and the calls in the backend
creation error paths into weston_compositor_load_backend().
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Add a weston_backend::shutdown callback to split out the part of
weston_backend::destroy that needs to be done before compositor
shutdown.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Preserve the same order as desktop-shell for handling view (un)mapping,
so we can move these into a shared helper. These should have no
functional effect but provide a helpful bisect point.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Prefer outputs that are not powered off when assigning a surface to an
output. If a surface covers the same area on two outputs, prefer the
one with the higher refresh rate.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
attach needs to consider the viewport as well, so it makes more sense
for attach to consistently access the weston_surface_state, rather than
part from the surface and part from a function argument.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Pull the buffer-size calculation in when we attach a new buffer. This
will be able to save us from doing the calculation at all in some cases.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Rebuilding regions can be an expensive operation, and we're adding more
of them. This means we need to be clever about when we actually do them.
Only dirty the paint nodes when the transform or buffer size has
actually changed, not on every commit.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Akin to the paint_node_status we already have, start also tracking a
surface dirty status. This will allow us to minimise the updates we need
to make.
Currently this is only collected, with no functional change made.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Until now we've only had the unadorned arithmetic functions, but they're
easy to abuse and tedious to use.
For now, we just add weston_coord_global_add/sub functions and use them
where appropriate.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This is stored as an unadorned weston_coord internally, but with getter
functions we can put together the appropriate global or surface
coordinate.
Use them where appropriate.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
When an output is moved, all views that are not moving with it should
cause damage where they appear in it before and after the move, and all
prior damage should move with the output.
To avoid this complexity, just damage the full output after the move.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Consolidates the 'Using GL/Pixman renderer' message emitted by the
PipeWire, RDP, VNC, and X11 backends by moving the weston_log() into
weston_compositor_init_renderer(). Only print the message after
initializing the renderer has succeeded.
This effectively adds the message to the DRM, headless, and Wayland
backends.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Add a separate PipeWire backend based on the PipeWire plugin. The backend
requires PipeWire 0.3.x.
The PipeWire backend can be used as a standalone-backend backend for streaming
and composing Wayland clients to PipeWire.
The backend supports the on-demand creation of heads via the
weston_pipewire_output_api_v1. It also supports per-output pixel format
configuration via a gbm-format option.
Multiple PipeWire outputs can be created by setting the num-outputs option in
the [pipewire] section.
Co-authored-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Rather than setting the initial power state when adding
it (using weston_compositor_add_output), do that at the initilization
stage.
Reason being that the compositor can set up the output from the start as
FORCED_OFF, before enabling the output, rather than enabling the output
and then turning off the power of the output.
Signed-off-by: marius vlad <marius.vlad@collabora.com>
Rather than damaging the output before the output has been added with
weston_compositor_add_output, do that afterwards as to avoid scheduling
a repaint for that output *before* actually adding the output.
This would avoid the awkward case where we attempt to set initial power
state to normal, but we can't apply it at that stage.
Signed-off-by: marius vlad <marius.vlad@collabora.com>