Commit graph

118 commits

Author SHA1 Message Date
Vlad Zahorodnii
0d2879c62d Split BufferInterface
Currently, the BufferInterface encapsulates all the kinds of client
buffers. This has become a somewhat annoying issue as we want to
reference the shm pool if a shm buffer is destroyed, or have custom
buffer readiness logic for linux dma-buf client buffers.

Implementing all of that with the current abstractions will be
challenging as there's no good separation between different client
buffer types.

This change splits the BufferInterface class in three sub-classes -
DrmClientBuffer, LinuxDmaBufV1ClientBuffer, and ShmClientBuffer.

In addition to that, this change fixes the broken buffer ref'ing api.
2021-07-22 11:41:06 +03:00
Vlad Zahorodnii
9210e25c52 Build surface-to-buffer matrix based on current state
This makes it more clear that the surface-to-buffer matrix is computed
based on the current surface state.
2021-07-21 06:18:38 +00:00
Vlad Zahorodnii
ce92ac7451 Merge SurfaceInterfacePrivate::commit() and SurfaceInterfacePrivate::surface_commit()
This removes an unnecessary layer of indirection.
2021-07-21 06:18:38 +00:00
Vlad Zahorodnii
c2f0db4a92 Split SurfaceInterfacePrivate::swapStates()
Currently, the swapStates() function does two things - (a) it merges one
state with another; (b) it applies the next state. This change splits the
swapStates() so it's simpler and the boolean trap can be removed.
2021-07-21 06:18:38 +00:00
Vlad Zahorodnii
c55de7b70b Emit the committed() signal after the state is applied
Currently, the committed signal is emitted after the client has called
wl_surface.commit. However, this breaks with synchronized subsurfaces.

Notably, Firefox splits a web page in a bunch of smaller layers, which
can be backed by wl_subsurface objects.

All the subsurfaces are in the sync mode. If a layer needs to be
repainted, Firefox will commit the corresponding subsurface with a frame
callback.

Since the committed signal is emitted when the wl_surface.commit request
is invoked, kwin will schedule a new frame immediately. Meaning, that it
is quite likely that firefox will have old contents.

The right thing to do would be to schedule a frame when all the ancestors
of the layer subsurface have been committed.

This change re-jitters the commit logic so the committed signal is
emitted when a new state is applied to the surface. It also slightly
cleans up how SubSurfaceInterface::parentCommit() is called.

It will be nice to cleanup the commit logic further by calling the
surface role's commit hook unconditionally, i.e. not check whether it's
a subsurface. But doing so may result in infinite recursions. How to
clean up that is still TBD.
2021-07-16 13:07:56 +03:00
Vlad Zahorodnii
17cccfa233 Allow placing subsurfaces below parent surface
According to the spec, if the parent surface is specified in the
wl_subsurface.place_below(), the subsurface has to be rendered below the
parent surface.

At the moment, kwaylandserver doesn't handle that case properly. It is
not possible for sub-surfaces to go below the parent surface.

Another issue is that we wrongly assume that the place_above request
will put the subsurface on top of the stack if the parent surface is
specified as sibling. It doesn't seem like that's the case, not
according to the spec.

This change splits the child sub-surface list in two lists - below and
above. The alternative solution is to store the parent surface in the
children list, but it's an error prone solution and it's conceptually
weird.
2021-07-08 05:33:14 +00:00
Vlad Zahorodnii
ac60e35818 Don't flush client connection when sending frame callbacks
This way, the compositor can batch more frame callbacks before flushing
the client connection. We attempted this before, but it broke tests.

Now, it seems like the tests pass, so we can remove the manual flush.
2021-06-19 11:12:25 +03:00
Vlad Zahorodnii
398841363b Move viewport state into a struct
It makes it more clear what state belongs to the wp_viewport extension.
2021-05-26 21:21:34 +03:00
Vlad Zahorodnii
86d39af6a0 Move surface state struct in KWaylandServer namespace
This way, it's less characters to type. In order to support delayed
surface commits, compositor extensions need to piggyback their state on
the state of the wl_surface. In other words, SurfaceState is going to
be used not only by SurfaceInterface, but the viewporter extension, the
xdg-shell extension, etc.
2021-05-26 21:21:05 +03:00
Laurent Montel
0c49d302ce Use Q_EMIT to make it compile against kf5.82 2021-05-13 11:33:08 +02:00
Vlad Zahorodnii
d740a45469 Fix invalid iterator in SurfaceInterfacePrivate::raiseChild()
The append method will invalidate the iterator, so we cannot call the
erase() method with the old iterator.
2021-05-13 10:16:25 +03:00
Vlad Zahorodnii
d9eb05c9a7 Fix delayed global removal
Unfortunately, we cannot just simply unset the wl_global's user data.
The compositor still needs to process client requests after the global
has been removed, for example bind requests or the requests that create
new resources.

CCBUG: 435258
2021-05-12 10:59:45 +03:00
Vlad Zahorodnii
8f3993c91b Drop workaround for QTBUG-52092
I've been using kwaylandserver without this workaround for a while and
haven't experienced any issues. Also, there were some sub-surface fixes
in QtWayland.
2021-04-08 10:17:01 +03:00
Vlad Zahorodnii
f30bd9e341 Rework OutputInterface following new design principles 2021-04-07 11:04:26 +00:00
Vlad Zahorodnii
18815f88fb Drop SurfaceInterface::trackedDamage()
There is no need for both kwin and kwaylandserver track damage.
2021-03-31 13:33:29 +00:00
Vlad Zahorodnii
75a6fd29fd Introduce SurfaceInterface::childSubSurfacesChanged
Currently, the SurfaceInterface class has a signal that is emitted
whenever any sub-surfaces in its sub-tree changes in a way that requires
a repaint. It is emitted when a sub-surface is resized, moved, or
damaged, etc. There is no way for the compositor to track changes in the
stacking order of sub-surfaces efficiently.

This change replaces the subTreeChanged signal with a less noisy signal
that's emitted whenever the list of direct child sub-surfaces changes.
2021-03-31 13:24:58 +00:00
Vlad Zahorodnii
16db81b5cc Make RegionInterface private
If a Wayland protocol deals with regions, they will be exposed as
QRegion objects in public API. Therefore, it makes sense to make
RegionInterface private as it's an implementation detail and it's
not intended to be used in public api.

The corresponding test was dropped because the CompositorInterface
no longer emits a signal to indicate that a wl_region has been created.
It should be also noted that wl_region stuff is already tested via
other means, e.g. surface damage, etc.
2021-03-15 16:28:30 +00:00
Aleix Pol
a0419faecb Include implementation of declared method 2021-03-11 13:49:38 +01:00
Vlad Zahorodnii
eb123a40b7 Introduce SurfaceInterface::mapToChild()
The new method provides a convenient way to map a point from the
parent's coordinate system to a child's coordinate system.
2021-03-10 14:05:20 +00:00
Vlad Zahorodnii
b0a20b2815 Prevent setting invalid buffer transform and scale
At the moment, it is possible to crash the compositor if some client
sets a buffer scale less than 1.
2021-02-11 10:10:12 +02:00
Vlad Zahorodnii
ae5a31acd1 Introduce SurfaceInterface::hasFrameCallbacks()
The new method can be used to check if the surface has a pending frame
callback.

CCBUG: 428499
2021-02-02 14:00:34 +00:00
David Edmundson
fbe8aff439 Send SurfaceInterface::enter events after clients bind to outputs
The following order of events are legal:

Typically order is:
 - server announces a new output
 - client binds to a new output
 - server updates the surface to be on new output

But we can have events occur in the following order:

 - server announces a new output
 - server updates the surface to be on new output
 - client binds to a new output

At which point when we update the surface there is no ID to tell the
client which output the surface is on.

This patch watches for clients binding to output and updates
appropriately.
2021-01-12 11:10:50 +00:00
Aleix Pol
0dffc569ea Notify subsurfaces about output changes
Otherwise they wouldn't notice and wouldn't update to the settings of
the new output, like the new output's scaling.
2020-11-17 14:55:07 +00:00
Vlad Zahorodnii
0ed0066d74 Port pointer-constraints-v1 to the new design 2020-11-04 06:19:13 +00:00
Vlad Zahorodnii
9f83741621 Introduce resource_cast<> helper function
Getting the object associated with the particular wl_resource is not
difficult, but it involves a pretty reasonable amount of boilerplate
code.

This change, introduces a helper function with an intend to reduce the
amount of boilerplate code.

It can be used as resource_cast<const ObjectPrivate *>(resource) or
just simply resource_cast<ObjectPrivate *>(resource).
2020-11-04 08:15:31 +02:00
Vlad Zahorodnii
6c113e1cef Rewrite subsurface wrappers following the new design principles
This change rewrites implementation of subsurfaces with qtwaylandscanner
and fixes various smaller issues, such as proper handling of position
updates for subsurfaces in the desync mode and getting rid of QPointer in
the public API.
2020-11-02 08:26:57 +02:00
David Edmundson
a8883c35a5 Don't use Qt::UniqueConnection on a lambda
It won't detect properly, instead the same code is moved into a member
function.
2020-10-29 12:49:36 +00:00
David Edmundson
d5ca50deb3 Only connect to BufferInterface::aboutToBeDestroyed once
It is allowed to call surface_attach multiple times with the same
buffer. We want to only connect once.

Found whilst debugging a freeze, going through the list of
BufferInterface connections I had multiple to the same SurfaceInterface.

CCBUG: 428361
2020-10-28 18:16:46 +00:00
Vlad Zahorodnii
0561c17552 Simplify how infinite input regions are handled
Some input related code in kwin is mislead by the fact that when the
input region is infinite, SurfaceInterface::input() is going to return
an empty QRegion object.

We cannot really do that because the client could have just set a valid
empty wl_region object to ignore all input events.

This change makes SurfaceInterface assign an actually infinite region
when a NULL input region has been passed to set_input_region().
2020-10-19 08:48:52 +03:00
Vlad Zahorodnii
430aa08714 Improve readability of code that destroys frame callback resources
If a frame callback resource is destroyed, it will unregister itself
from corresponding lists in current, pending, and cached state.

However, this means that we need to be super duper careful when the
compositor wants to destroy all frame callbacks. We need to make a copy
of a frameCallbacks list; otherwise a call to removeOne() will
invalidate iterators and the compositor may crash.

Currently, that copy is made implicitly. Some people may see that code
and add qAsConst() without realizing the consequences it will lead to.

This change improves the readability of that code by making explicit
copies of frameCallbacks in code that shuts down SurfaceInterface.
2020-10-02 09:07:15 +03:00
Aleix Pol
d7ff3703bc Do not create a temporary QRegion unnecessarily
Just modify the one we are updating in one go
2020-09-23 04:20:17 +02:00
Vlad Zahorodnii
e727dc2fa9 Untangle SurfaceInterface and BufferInterface
A wl_buffer object can be bound to multiple surfaces or none at all. So
the BufferInterface::surface() property makes very little sense.
2020-09-21 13:58:37 +00:00
Vlad Zahorodnii
a930e59fcf Revert "Don't flush in SurfaceInterface::frameRendered()"
This reverts commit 3cf004b68e.

Unfortunately, 3cf004b broke a couple of tests in kwin due to Qt not
emitting QAbstractEventDispatcher::aboutToBlock() signal when macros
such as QTRY_VERIFY() or QTRY_COMPARE() spin the event loop.
2020-08-18 13:18:58 +03:00
Vlad Zahorodnii
3cf004b68e Don't flush in SurfaceInterface::frameRendered()
Frame callbacks only indicate when the client can start rendering a new
frame, it's not meant to be precise. If the client wants to do some
black magic with frame scheduling and so on, it needs to use a protocol
such as presentation_time. This change removes the pointless flush to
prevent over-flushing client connections.
2020-08-18 07:28:03 +00:00
Adrien Faveraux
87abc0e483 move idle Inhibitor to the news approach 2020-07-28 10:46:30 +00:00
Vlad Zahorodnii
3994faff50 Rename the aboutToBeUnbound() signal in SurfaceInterface
Rename the aboutToBeUnbound() signal to aboutToBeDestroyed() in order to
make the usage of the word "destroyed" consistent.
2020-07-16 14:31:41 +00:00
Aleix Pol Gonzalez
c57270fa4a Update surface_interface.cpp 2020-07-15 22:22:40 +00:00
David Edmundson
df9413638d Cache clientConnection in SurfaceInterface
Order of a client teardown is:
 - ClientConnection is removed from the static map
 - All our client owned resources are torn down
 - ClientConnection is deleted (via a previous deleteLater)

The recent refactor led to a behavioural change where ::client could
return a null pointer.

We want the client getter to be valid throughout the lifespan of
SurfaceInterface, by doing the lookup once we achieve that.

BUG: 424255
2020-07-15 22:55:37 +01:00
Vlad Zahorodnii
9a23695bab Use shorter name for variable that holds cached subsurface state 2020-07-15 11:05:59 +03:00
Vlad Zahorodnii
46e4f0948b Port the wl_surface wrapper to the new approach 2020-07-15 11:05:57 +03:00
Vlad Zahorodnii
ec0c109f4d Provide an easy way to monitor buffer size changes
The main purpose behind the kwaylandserver library is to provide a set
of re-usable wayland compositor extension implementations. However, it's
worth noting that the design of kwaylandserver is far from perfect at
the moment.

KWaylandServer tries to hide all low level wayland details from the
compositor. But it's not the case with buffers, which diminishes the
whole point behind the library.

Creating OpenGL textures from Wayland buffers is the responsibility of
the compositor. So, when it comes to client buffers, we are one foot in
KWaylandServer, and the other foot in the compositor.

Since the surface size is a logical size, the compositor can't use it
for allocating memory for OpenGL textures. This change adds the buffer
size property in SurfaceInterface that can be used for allocating memory
for textures as well as monitoring buffer size changes.

I must say that the introduction of the buffer size property is a crude
hack because BufferInterface just needs to provide an OpenGL texture for
each plane. The main blocker for that is that it would involve moving
the backend, the compositor, and the wayland bits in the same place, for
example kwayland-server or ultimately kwin.
2020-06-30 09:25:24 +03:00
Vlad Zahorodnii
ecca34dea3 Rename buffer-specific surface properties
The buffer scale and the buffer transform property specify transforms
that had been applied to the buffer's contents. Neither one of those
properties apply to the surface, in other words the buffer transform
property doesn't indicate that the surface was rotated or flipped or both.

This change doesn't gain anything in terms of new features, etc. It just
attempts to make things more clear.
2020-06-24 06:58:46 +00:00
Vlad Zahorodnii
ac66d25364 Drop SurfaceInterface::inputIsInfitine
Since we don't guarantee SC and BC in KWaylandServer, we can drop
SurfaceInterface::inputIsInfitine().
2020-06-19 16:12:00 +00:00
Vlad Zahorodnii
45812785cf Introduce surface-to-buffer and buffer-to-surface matrices
The compositor needs to monitor changes in the mapping between the
surface local coordinates and the buffer coordinates because texture
coordinates correspond to the latter. One way to do it is to monitor
things such as the surface size, the buffer size, the buffer scale,
etc. The main problem with doing so is that there are so many factors
that contribute to how mapping between the surface local coordinate
space and the buffer coordinate space is performed.

In order to provide a generic way for monitoring changes in the mapping
between the surface local coordinate space and the buffer coordinate
space, this patch introduces two new matrices. The first one specifies
how the surface-local coordinates are mapped to buffer coordinates, and
the other one specifies how to map the buffer coordinates to surface
local coordinates.

With the new two matrices, the compositor has a generic way to get
notified when it has to re-compute texture coordinates.
2020-06-19 06:43:31 +00:00
Vlad Zahorodnii
0c8b77edc0 Drop unnecessary emptiness check
If a buffer is attached to the surface, its width or height cannot be 0.
2020-06-17 06:48:20 +00:00
Vlad Zahorodnii
963551d775 Add support for the wp_viewporter protocol
The wp_viewporter compositor extension allows clients to crop and scale
their surface. It can be useful for applications such as video players
because it may potentially reduce their power usage.
2020-06-02 15:33:00 +03:00
Vlad Zahorodnii
99ef521e6d Add methods for converting buffer and surface coordinates
Unfortunately, in order to map a point from the surface-local coordinate
space to the buffer pixel coordinate space, one cannot divide the point
by the scale factor since the buffer might be rotated or flipped.

This change introduces a couple of helper methods for converting points,
regions, and rectangles from the surface-local coordinates to the buffer
pixel coordinates and vice versa.
2020-06-01 17:04:50 +03:00
Vlad Zahorodnii
8651045c4b Mark the buffer transform as committed
We need to mark the buffer transform as committed or else it won't be
ever applied.
2020-06-01 17:04:50 +03:00
Vlad Zahorodnii
238f59365f Simplify code that emits mapped() and unmapped() 2020-06-01 17:04:50 +03:00
Vlad Zahorodnii
7c7d9a117b [server] Introduce mapped() signal
Summary:
In KWin, we need to know when a sub-surface becomes mapped or unmapped
so we can generate or filter out window quads for the sub-surface.

Reviewers: #kwin, davidedmundson, apol

Reviewed By: #kwin, davidedmundson, apol

Differential Revision: https://phabricator.kde.org/D29256
2020-05-04 14:55:15 +03:00