Screencast: update PW buffer with only mouse cursor metadata on cursor change

As of now, we update cursor metadata only when the screen content changes, but
this results into not having smooth cursor movement. We can update only mouse
cursor location when it changes and send an empty buffer with mouse cursor
metadata so clients can have update mouse location.
This commit is contained in:
Jan Grulich 2022-01-05 11:41:56 +01:00
parent 861eac9205
commit 9f44013fb5
2 changed files with 37 additions and 0 deletions

View file

@ -305,6 +305,8 @@ bool ScreenCastStream::createStream()
connect(Cursors::self(), &Cursors::positionChanged, this, [this] {
recordFrame(QRegion{m_cursor.lastRect} | cursorGeometry(Cursors::self()->currentCursor()));
});
} else if (m_cursor.mode == KWaylandServer::ScreencastV1Interface::Metadata) {
connect(Cursors::self(), &Cursors::positionChanged, this, &ScreenCastStream::recordCursor);
}
return true;
@ -458,6 +460,38 @@ void ScreenCastStream::recordFrame(const QRegion &damagedRegion)
tryEnqueue(buffer);
}
void ScreenCastStream::recordCursor()
{
Q_ASSERT(!m_stopped);
if (m_pendingBuffer) {
qCWarning(KWIN_SCREENCAST) << "Dropping a screencast cursor update because the compositor is slow";
return;
}
const char *error = "";
auto state = pw_stream_get_state(pwStream, &error);
if (state != PW_STREAM_STATE_STREAMING) {
if (error) {
qCWarning(KWIN_SCREENCAST) << "Failed to record cursor position: stream is not active" << error;
}
return;
}
struct pw_buffer *buffer = pw_stream_dequeue_buffer(pwStream);
if (!buffer) {
return;
}
struct spa_buffer *spa_buffer = buffer->buffer;
spa_buffer->datas[0].chunk->size = 0;
sendCursorData(Cursors::self()->currentCursor(),
(spa_meta_cursor *) spa_buffer_find_meta_data (spa_buffer, SPA_META_Cursor, sizeof (spa_meta_cursor)));
tryEnqueue(buffer);
}
void ScreenCastStream::tryEnqueue(pw_buffer *buffer)
{
m_pendingBuffer = buffer;

View file

@ -55,6 +55,9 @@ public:
void setCursorMode(KWaylandServer::ScreencastV1Interface::CursorMode mode, qreal scale, const QRect &viewport);
public Q_SLOTS:
void recordCursor();
Q_SIGNALS:
void streamReady(quint32 nodeId);
void startStreaming();