plugins/screencast: Clean up cursor scale tracking
Poll the screen cast scale from the source rather have code on top of ScreenCastStream and ScreenCastSource that figures out by itself how the cursor should be scaled. It ensures that the cursor size will be consistent and it makes the ScreenCastStream initialization code simpler.
This commit is contained in:
parent
e4a272e166
commit
50717a2f9a
10 changed files with 32 additions and 18 deletions
|
@ -47,6 +47,11 @@ QSize OutputScreenCastSource::textureSize() const
|
||||||
return m_output->pixelSize();
|
return m_output->pixelSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qreal OutputScreenCastSource::devicePixelRatio() const
|
||||||
|
{
|
||||||
|
return m_output->scale();
|
||||||
|
}
|
||||||
|
|
||||||
void OutputScreenCastSource::render(QImage *target)
|
void OutputScreenCastSource::render(QImage *target)
|
||||||
{
|
{
|
||||||
const auto [outputTexture, colorDescription] = Compositor::self()->scene()->textureForOutput(m_output);
|
const auto [outputTexture, colorDescription] = Compositor::self()->scene()->textureForOutput(m_output);
|
||||||
|
|
|
@ -25,6 +25,7 @@ public:
|
||||||
|
|
||||||
uint refreshRate() const override;
|
uint refreshRate() const override;
|
||||||
QSize textureSize() const override;
|
QSize textureSize() const override;
|
||||||
|
qreal devicePixelRatio() const override;
|
||||||
quint32 drmFormat() const override;
|
quint32 drmFormat() const override;
|
||||||
|
|
||||||
void render(GLFramebuffer *target) override;
|
void render(GLFramebuffer *target) override;
|
||||||
|
|
|
@ -61,6 +61,11 @@ QSize RegionScreenCastSource::textureSize() const
|
||||||
return m_region.size() * m_scale;
|
return m_region.size() * m_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qreal RegionScreenCastSource::devicePixelRatio() const
|
||||||
|
{
|
||||||
|
return m_scale;
|
||||||
|
}
|
||||||
|
|
||||||
quint32 RegionScreenCastSource::drmFormat() const
|
quint32 RegionScreenCastSource::drmFormat() const
|
||||||
{
|
{
|
||||||
return DRM_FORMAT_ARGB8888;
|
return DRM_FORMAT_ARGB8888;
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
|
|
||||||
quint32 drmFormat() const override;
|
quint32 drmFormat() const override;
|
||||||
QSize textureSize() const override;
|
QSize textureSize() const override;
|
||||||
|
qreal devicePixelRatio() const override;
|
||||||
uint refreshRate() const override;
|
uint refreshRate() const override;
|
||||||
|
|
||||||
void render(GLFramebuffer *target) override;
|
void render(GLFramebuffer *target) override;
|
||||||
|
|
|
@ -48,7 +48,7 @@ void ScreencastManager::streamWindow(ScreencastStreamV1Interface *waylandStream,
|
||||||
|
|
||||||
auto stream = new ScreenCastStream(new WindowScreenCastSource(window), getPipewireConnection(), this);
|
auto stream = new ScreenCastStream(new WindowScreenCastSource(window), getPipewireConnection(), this);
|
||||||
stream->setObjectName(window->desktopFileName());
|
stream->setObjectName(window->desktopFileName());
|
||||||
stream->setCursorMode(mode, 1);
|
stream->setCursorMode(mode);
|
||||||
|
|
||||||
integrateStreams(waylandStream, stream);
|
integrateStreams(waylandStream, stream);
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,7 @@ void ScreencastManager::streamOutput(ScreencastStreamV1Interface *waylandStream,
|
||||||
|
|
||||||
auto stream = new ScreenCastStream(new OutputScreenCastSource(streamOutput), getPipewireConnection(), this);
|
auto stream = new ScreenCastStream(new OutputScreenCastSource(streamOutput), getPipewireConnection(), this);
|
||||||
stream->setObjectName(streamOutput->name());
|
stream->setObjectName(streamOutput->name());
|
||||||
stream->setCursorMode(mode, streamOutput->scale());
|
stream->setCursorMode(mode);
|
||||||
|
|
||||||
connect(streamOutput, &Output::changed, stream, [streamOutput, stream, mode]() {
|
|
||||||
stream->setCursorMode(mode, streamOutput->scale());
|
|
||||||
});
|
|
||||||
|
|
||||||
integrateStreams(waylandStream, stream);
|
integrateStreams(waylandStream, stream);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +104,7 @@ void ScreencastManager::streamRegion(ScreencastStreamV1Interface *waylandStream,
|
||||||
auto source = new RegionScreenCastSource(geometry, scale);
|
auto source = new RegionScreenCastSource(geometry, scale);
|
||||||
auto stream = new ScreenCastStream(source, getPipewireConnection(), this);
|
auto stream = new ScreenCastStream(source, getPipewireConnection(), this);
|
||||||
stream->setObjectName(rectToString(geometry));
|
stream->setObjectName(rectToString(geometry));
|
||||||
stream->setCursorMode(mode, scale);
|
stream->setCursorMode(mode);
|
||||||
|
|
||||||
integrateStreams(waylandStream, stream);
|
integrateStreams(waylandStream, stream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ public:
|
||||||
virtual uint refreshRate() const = 0;
|
virtual uint refreshRate() const = 0;
|
||||||
virtual quint32 drmFormat() const = 0;
|
virtual quint32 drmFormat() const = 0;
|
||||||
virtual QSize textureSize() const = 0;
|
virtual QSize textureSize() const = 0;
|
||||||
|
virtual qreal devicePixelRatio() const = 0;
|
||||||
|
|
||||||
virtual void render(GLFramebuffer *target) = 0;
|
virtual void render(GLFramebuffer *target) = 0;
|
||||||
virtual void render(QImage *target) = 0;
|
virtual void render(QImage *target) = 0;
|
||||||
|
|
|
@ -720,13 +720,15 @@ void ScreenCastStream::addCursorMetadata(spa_buffer *spaBuffer, Cursor *cursor)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_cursor.visible = true;
|
m_cursor.visible = true;
|
||||||
const auto position = m_source->mapFromGlobal(cursor->pos()) * m_cursor.scale;
|
|
||||||
|
const qreal scale = m_source->devicePixelRatio();
|
||||||
|
const auto position = m_source->mapFromGlobal(cursor->pos()) * scale;
|
||||||
|
|
||||||
spaMetaCursor->id = 1;
|
spaMetaCursor->id = 1;
|
||||||
spaMetaCursor->position.x = position.x();
|
spaMetaCursor->position.x = position.x();
|
||||||
spaMetaCursor->position.y = position.y();
|
spaMetaCursor->position.y = position.y();
|
||||||
spaMetaCursor->hotspot.x = cursor->hotspot().x() * m_cursor.scale;
|
spaMetaCursor->hotspot.x = cursor->hotspot().x() * scale;
|
||||||
spaMetaCursor->hotspot.y = cursor->hotspot().y() * m_cursor.scale;
|
spaMetaCursor->hotspot.y = cursor->hotspot().y() * scale;
|
||||||
spaMetaCursor->bitmap_offset = 0;
|
spaMetaCursor->bitmap_offset = 0;
|
||||||
|
|
||||||
if (!m_cursor.invalid) {
|
if (!m_cursor.invalid) {
|
||||||
|
@ -736,7 +738,7 @@ void ScreenCastStream::addCursorMetadata(spa_buffer *spaBuffer, Cursor *cursor)
|
||||||
m_cursor.invalid = false;
|
m_cursor.invalid = false;
|
||||||
spaMetaCursor->bitmap_offset = sizeof(struct spa_meta_cursor);
|
spaMetaCursor->bitmap_offset = sizeof(struct spa_meta_cursor);
|
||||||
|
|
||||||
const QSize targetSize = (cursor->rect().size() * m_cursor.scale).toSize();
|
const QSize targetSize = (cursor->rect().size() * scale).toSize();
|
||||||
|
|
||||||
struct spa_meta_bitmap *spaMetaBitmap = SPA_MEMBER(spaMetaCursor,
|
struct spa_meta_bitmap *spaMetaBitmap = SPA_MEMBER(spaMetaCursor,
|
||||||
spaMetaCursor->bitmap_offset,
|
spaMetaCursor->bitmap_offset,
|
||||||
|
@ -771,12 +773,11 @@ QRegion ScreenCastStream::addCursorEmbedded(ScreenCastBuffer *buffer, Cursor *cu
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QRectF cursorRect = scaledRect(m_source->mapFromGlobal(cursor->geometry()), m_cursor.scale);
|
const QRectF cursorRect = scaledRect(m_source->mapFromGlobal(cursor->geometry()), m_source->devicePixelRatio());
|
||||||
if (auto memfd = dynamic_cast<MemFdScreenCastBuffer *>(buffer)) {
|
if (auto memfd = dynamic_cast<MemFdScreenCastBuffer *>(buffer)) {
|
||||||
QPainter painter(memfd->view.image());
|
QPainter painter(memfd->view.image());
|
||||||
const auto position = m_source->mapFromGlobal(cursor->pos() - cursor->hotspot()) * m_cursor.scale;
|
|
||||||
const PlatformCursorImage cursorImage = kwinApp()->cursorImage();
|
const PlatformCursorImage cursorImage = kwinApp()->cursorImage();
|
||||||
painter.drawImage(QRect{position.toPoint(), cursorImage.image().size()}, cursorImage.image());
|
painter.drawImage(cursorRect, cursorImage.image());
|
||||||
} else if (auto dmabuf = dynamic_cast<DmaBufScreenCastBuffer *>(buffer)) {
|
} else if (auto dmabuf = dynamic_cast<DmaBufScreenCastBuffer *>(buffer)) {
|
||||||
if (m_cursor.invalid) {
|
if (m_cursor.invalid) {
|
||||||
m_cursor.invalid = false;
|
m_cursor.invalid = false;
|
||||||
|
@ -816,10 +817,9 @@ QRegion ScreenCastStream::addCursorEmbedded(ScreenCastBuffer *buffer, Cursor *cu
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenCastStream::setCursorMode(ScreencastV1Interface::CursorMode mode, qreal scale)
|
void ScreenCastStream::setCursorMode(ScreencastV1Interface::CursorMode mode)
|
||||||
{
|
{
|
||||||
m_cursor.mode = mode;
|
m_cursor.mode = mode;
|
||||||
m_cursor.scale = scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ScreenCastDmaBufTextureParams> ScreenCastStream::testCreateDmaBuf(const QSize &size, quint32 format, const QList<uint64_t> &modifiers)
|
std::optional<ScreenCastDmaBufTextureParams> ScreenCastStream::testCreateDmaBuf(const QSize &size, quint32 format, const QList<uint64_t> &modifiers)
|
||||||
|
|
|
@ -68,7 +68,7 @@ public:
|
||||||
|
|
||||||
void scheduleRecord(const QRegion &damage, Contents contents = Content::Video);
|
void scheduleRecord(const QRegion &damage, Contents contents = Content::Video);
|
||||||
|
|
||||||
void setCursorMode(ScreencastV1Interface::CursorMode mode, qreal scale);
|
void setCursorMode(ScreencastV1Interface::CursorMode mode);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void invalidateCursor();
|
void invalidateCursor();
|
||||||
|
@ -121,7 +121,6 @@ private:
|
||||||
{
|
{
|
||||||
ScreencastV1Interface::CursorMode mode = ScreencastV1Interface::Hidden;
|
ScreencastV1Interface::CursorMode mode = ScreencastV1Interface::Hidden;
|
||||||
const QSize bitmapSize = QSize(256, 256);
|
const QSize bitmapSize = QSize(256, 256);
|
||||||
qreal scale = 1;
|
|
||||||
QRectF lastRect;
|
QRectF lastRect;
|
||||||
std::unique_ptr<GLTexture> texture;
|
std::unique_ptr<GLTexture> texture;
|
||||||
bool visible = false;
|
bool visible = false;
|
||||||
|
|
|
@ -52,6 +52,11 @@ QSize WindowScreenCastSource::textureSize() const
|
||||||
return m_window->clientGeometry().size().toSize();
|
return m_window->clientGeometry().size().toSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qreal WindowScreenCastSource::devicePixelRatio() const
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
void WindowScreenCastSource::render(QImage *target)
|
void WindowScreenCastSource::render(QImage *target)
|
||||||
{
|
{
|
||||||
const auto offscreenTexture = GLTexture::allocate(GL_RGBA8, textureSize());
|
const auto offscreenTexture = GLTexture::allocate(GL_RGBA8, textureSize());
|
||||||
|
|
|
@ -25,6 +25,7 @@ public:
|
||||||
|
|
||||||
quint32 drmFormat() const override;
|
quint32 drmFormat() const override;
|
||||||
QSize textureSize() const override;
|
QSize textureSize() const override;
|
||||||
|
qreal devicePixelRatio() const override;
|
||||||
uint refreshRate() const override;
|
uint refreshRate() const override;
|
||||||
|
|
||||||
void render(GLFramebuffer *target) override;
|
void render(GLFramebuffer *target) override;
|
||||||
|
|
Loading…
Reference in a new issue