https://bugs.kde.org/show_bug.cgi?id=526325
Bug ID: 526325
Summary: PipeWire framebuffer does not enable damage reporting,
causing repeated full-screen VNC updates
Classification: Applications
Product: krfb
Version First unspecified
Reported In:
Platform: Other
OS: Other
Status: REPORTED
Severity: normal
Priority: NOR
Component: general
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
Created attachment 196617
--> https://bugs.kde.org/attachment.cgi?id=196617&action=edit
Enable PipeWire damage reporting in KRFB
Title: PipeWire framebuffer does not enable damage reporting, causing repeated
full-screen VNC updates
Product: krfb
Version: 25.04.3
Platform: Linux / KDE Plasma / Wayland / PipeWire
Description
KRFB's PipeWire framebuffer already contains support for processing
PipeWireFrame::damage in PWFrameBuffer::Private::handleFrame().
However, damage reporting is not enabled on the PipeWireSourceStream.
The stream is currently initialized without calling:
stream->setDamageEnabled(true);
As a consequence, frame.damage is not available during normal operation and
handleFrame() falls back to marking the complete framebuffer as modified:
if (auto damage = frame.damage) {
for (const auto &rect : *damage) {
q->tiles.append(rect);
}
} else {
q->tiles.append(QRect(0, 0, videoSize.width(), videoSize.height()));
}
This causes KRFB to generate repeated full-screen framebuffer updates even when
only small parts of the screen have changed.
Observed behavior
Using a VNC client with framebuffer update instrumentation, KRFB 25.04.3
repeatedly produced updates covering essentially the complete 1920x1080
framebuffer.
Typical sequence:
1920x1080
1919x1079
1919x1079
1919x1079
...
This results in unnecessarily large VNC updates and significant encoding,
network and client decoding overhead.
Fix
Enabling damage reporting when the PipeWireSourceStream is created fixes the
problem:
PWFrameBuffer::Private::Private(PWFrameBuffer *q)
: q(q)
, stream(new PipeWireSourceStream(q))
{
stream->setDamageEnabled(true);
QObject::connect(stream.get(), &PipeWireSourceStream::frameReceived, q,
[this] (const PipeWireFrame &frame) {
handleFrame(frame);
});
}
Result after the change
After adding stream->setDamageEnabled(true), the VNC stream behaves as
expected.
There is one initial full-frame update when the client connects:
0,0 1920x1080
Subsequent updates contain the actual PipeWire damage rectangles, for example:
466,14 31x31
1246,342 32x16
1220,359 58x11
...
Instrumentation on both sides confirmed that the damage rectangles generated by
KRFB correspond to the rectangles received by the VNC client.
During a complete test run, no repeated full-screen framebuffer updates were
observed after the initial framebuffer transfer.
Patch
--- a/framebuffers/pipewire/pw_framebuffer.cpp
+++ b/framebuffers/pipewire/pw_framebuffer.cpp
@@ -111,6 +111,7 @@ PWFrameBuffer::Private::Private(PWFrameBuffer *q)
: q(q)
, stream(new PipeWireSourceStream(q))
{
+ stream->setDamageEnabled(true);
QObject::connect(stream.get(), &PipeWireSourceStream::frameReceived, q,
[this] (const PipeWireFrame &frame) {
handleFrame(frame);
});
I have also attached this change as krfb-pipewire-enable-damage.patch.
--
You are receiving this mail because:
You are watching all bug changes.