diff options
Diffstat (limited to 'src/compositor/compositor_api')
-rw-r--r-- | src/compositor/compositor_api/qwaylandcompositor.cpp | 2 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurface.cpp | 37 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurface_p.h | 2 |
3 files changed, 39 insertions, 2 deletions
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 8878ce121..fb99f9413 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -190,7 +190,7 @@ void QWaylandCompositorPrivate::init() if (socketArg != -1 && socketArg + 1 < arguments.size()) socket_name = arguments.at(socketArg + 1).toLocal8Bit(); } - wl_compositor::init(display, 3); + wl_compositor::init(display, 4); wl_subcompositor::init(display, 1); #if QT_CONFIG(wayland_datadevice) diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 2ebb04a35..efd186fc5 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -195,9 +195,26 @@ void QWaylandSurfacePrivate::surface_attach(Resource *, struct wl_resource *buff pending.newlyAttached = true; } +/* + Note: The Wayland protocol specifies that buffer scale and damage can be interleaved, so + we cannot scale the damage region until commit. We assume that clients will either use + surface_damage or surface_damage_buffer within one frame for one surface. +*/ + void QWaylandSurfacePrivate::surface_damage(Resource *, int32_t x, int32_t y, int32_t width, int32_t height) { + if (Q_UNLIKELY(pending.damageInBufferCoordinates && !pending.damage.isNull())) + qCWarning(qLcWaylandCompositor) << "Unsupported: Client is using both wl_surface.damage_buffer and wl_surface.damage."; + pending.damage = pending.damage.united(QRect(x, y, width, height)); + pending.damageInBufferCoordinates = false; +} + +void QWaylandSurfacePrivate::surface_damage_buffer(Resource *, int32_t x, int32_t y, int32_t width, int32_t height) +{ + if (Q_UNLIKELY(!pending.damageInBufferCoordinates && !pending.damage.isNull())) + qCWarning(qLcWaylandCompositor) << "Unsupported: Client is using both wl_surface.damage_buffer and wl_surface.damage."; pending.damage = pending.damage.united(QRect(x, y, width, height)); + pending.damageInBufferCoordinates = true; } void QWaylandSurfacePrivate::surface_frame(Resource *resource, uint32_t callback) @@ -240,7 +257,24 @@ void QWaylandSurfacePrivate::surface_commit(Resource *) QSize surfaceSize = bufferSize / bufferScale; sourceGeometry = !pending.sourceGeometry.isValid() ? QRect(QPoint(), surfaceSize) : pending.sourceGeometry; destinationSize = pending.destinationSize.isEmpty() ? sourceGeometry.size().toSize() : pending.destinationSize; - damage = pending.damage.intersected(QRect(QPoint(), destinationSize)); + if (!pending.damageInBufferCoordinates || pending.bufferScale == 1) { + // pending.damage is already in surface coordinates + damage = pending.damage.intersected(QRect(QPoint(), destinationSize)); + } else { + // We must transform pending.damage from buffer coordinate system to surface coordinates + // TODO(QTBUG-85461): Also support wp_viewport setting more complex transformations + auto xform = [](const QRect &r, int scale) -> QRect { + QRect res{ + QPoint{ r.x() / scale, r.y() / scale }, + QPoint{ (r.right() + scale - 1) / scale, (r.bottom() + scale - 1) / scale } + }; + return res; + }; + damage = {}; + for (const QRect &r : pending.damage) { + damage |= xform(r, bufferScale).intersected(QRect{{}, destinationSize}); + } + } hasContent = bufferRef.hasContent(); frameCallbacks << pendingFrameCallbacks; inputRegion = pending.inputRegion.intersected(QRect(QPoint(), destinationSize)); @@ -255,6 +289,7 @@ void QWaylandSurfacePrivate::surface_commit(Resource *) pending.offset = QPoint(); pending.newlyAttached = false; pending.damage = QRegion(); + pending.damageInBufferCoordinates = false; pendingFrameCallbacks.clear(); // Notify buffers and views diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h index 3f657c9d0..1150ccf91 100644 --- a/src/compositor/compositor_api/qwaylandsurface_p.h +++ b/src/compositor/compositor_api/qwaylandsurface_p.h @@ -116,6 +116,7 @@ protected: struct wl_resource *buffer, int x, int y) override; void surface_damage(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) override; + void surface_damage_buffer(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) override; void surface_frame(Resource *resource, uint32_t callback) override; void surface_set_opaque_region(Resource *resource, @@ -141,6 +142,7 @@ public: //member variables struct { QWaylandBufferRef buffer; QRegion damage; + bool damageInBufferCoordinates = false; QPoint offset; bool newlyAttached = false; QRegion inputRegion; |