Commit fd995084 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

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.
parent 39a27ec2
......@@ -388,6 +388,7 @@ void SurfaceInterface::Private::swapStates(State *source, State *target, bool em
const bool childrenChanged = source->childrenChanged;
const bool visibilityChanged = bufferChanged && (bool(source->buffer) != bool(target->buffer));
const QSize oldSize = target->size;
const QSize oldBufferSize = bufferSize;
const QMatrix4x4 oldSurfaceToBufferMatrix = surfaceToBufferMatrix;
if (bufferChanged) {
// TODO: is the reffing correct for subsurfaces?
......@@ -472,6 +473,7 @@ void SurfaceInterface::Private::swapStates(State *source, State *target, bool em
}
// TODO: Refactor the state management code because it gets more clumsy.
if (target->buffer) {
bufferSize = target->buffer->size();
if (target->destinationSize.isValid()) {
target->size = target->destinationSize;
} else if (target->sourceGeometry.isValid()) {
......@@ -494,6 +496,7 @@ void SurfaceInterface::Private::swapStates(State *source, State *target, bool em
}
} else {
target->size = QSize();
bufferSize = QSize();
}
surfaceToBufferMatrix = buildSurfaceToBufferMatrix(target);
bufferToSurfaceMatrix = surfaceToBufferMatrix.inverted();
......@@ -538,6 +541,9 @@ void SurfaceInterface::Private::swapStates(State *source, State *target, bool em
if (surfaceToBufferMatrix != oldSurfaceToBufferMatrix) {
emit q->surfaceToBufferMatrixChanged();
}
if (bufferSize != oldBufferSize) {
emit q->bufferSizeChanged();
}
if (target->size != oldSize) {
emit q->sizeChanged();
}
......
......@@ -174,6 +174,12 @@ public:
* @since 5.69
*/
QRect boundingRect() const;
/**
* Returns the size of the attached buffer, in device pixels.
*
* If no buffer is attached to this surface, an invalid QSize will be returned.
*/
QSize bufferSize() const;
/**
* @returns The SubSurface for this Surface in case there is one.
......@@ -369,6 +375,10 @@ Q_SIGNALS:
* This signal is emitted when the buffer transform has changed.
*/
void bufferTransformChanged(KWaylandServer::OutputInterface::Transform);
/**
* This signal is emitted when the size of the attached buffer has changed.
*/
void bufferSizeChanged();
/**
* Emitted when the Surface becomes visible, i.e. a non-null buffer has been attached.
**/
......
......@@ -87,6 +87,7 @@ public:
QRegion trackedDamage;
QMatrix4x4 surfaceToBufferMatrix;
QMatrix4x4 bufferToSurfaceMatrix;
QSize bufferSize;
// workaround for https://bugreports.qt.io/browse/QTBUG-52192
// A subsurface needs to be considered mapped even if it doesn't have a buffer attached
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment