diff --git a/src/plugins/platforms/drm/drm_output.cpp b/src/plugins/platforms/drm/drm_output.cpp index 6bff9b5105..47d0ffa18e 100644 --- a/src/plugins/platforms/drm/drm_output.cpp +++ b/src/plugins/platforms/drm/drm_output.cpp @@ -955,14 +955,23 @@ bool DrmOutput::atomicReqModesetPopulate(drmModeAtomicReq *req, bool enable) { if (enable) { const QSize mSize = modeSize(); - const QSize sourceSize = hardwareTransforms() ? pixelSize() : mSize; + const QSize bufferSize = m_primaryPlane->next() ? m_primaryPlane->next()->size() : pixelSize(); + const QSize sourceSize = hardwareTransforms() ? bufferSize : mSize; + QRect targetRect = QRect(QPoint(0, 0), mSize); + if (mSize != sourceSize) { + targetRect.setSize(sourceSize.scaled(mSize, Qt::AspectRatioMode::KeepAspectRatio)); + targetRect.setX((mSize.width() - targetRect.width()) / 2); + targetRect.setY((mSize.height() - targetRect.height()) / 2); + } m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::SrcX), 0); m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::SrcY), 0); m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::SrcW), sourceSize.width() << 16); m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::SrcH), sourceSize.height() << 16); - m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcW), mSize.width()); - m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcH), mSize.height()); + m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcX), targetRect.x()); + m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcY), targetRect.y()); + m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcW), targetRect.width()); + m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcH), targetRect.height()); m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcId), m_crtc->id()); } else { if (m_gpu->deleteBufferAfterPageFlip()) { @@ -976,6 +985,8 @@ bool DrmOutput::atomicReqModesetPopulate(drmModeAtomicReq *req, bool enable) m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::SrcY), 0); m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::SrcW), 0); m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::SrcH), 0); + m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcX), 0); + m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcY), 0); m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcW), 0); m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcH), 0); m_primaryPlane->setValue(int(DrmPlane::PropertyIndex::CrtcId), 0); diff --git a/src/plugins/platforms/drm/egl_gbm_backend.cpp b/src/plugins/platforms/drm/egl_gbm_backend.cpp index 26a379c474..238dbdbd8f 100644 --- a/src/plugins/platforms/drm/egl_gbm_backend.cpp +++ b/src/plugins/platforms/drm/egl_gbm_backend.cpp @@ -698,7 +698,8 @@ bool EglGbmBackend::scanout(int screenId, KWaylandServer::SurfaceInterface *surf } auto buffer = surface->buffer(); Output output = m_outputs[screenId]; - if (buffer->linuxDmabufBuffer()->size() != output.output->modeSize()) { + if (buffer->linuxDmabufBuffer()->size() != output.output->modeSize() + && output.output->isBeingRecorded()) { return false; } EglDmabufBuffer *dmabuf = static_cast(buffer->linuxDmabufBuffer()); @@ -739,7 +740,7 @@ bool EglGbmBackend::scanout(int screenId, KWaylandServer::SurfaceInterface *surf } // damage tracking for screen casting QRegion damage; - if (output.surfaceInterface == surface) { + if (output.surfaceInterface == surface && buffer->size() == output.output->modeSize()) { QRegion trackedDamage = surface->trackedDamage(); surface->resetTrackedDamage(); for (const auto &rect : trackedDamage) { diff --git a/src/plugins/scenes/opengl/scene_opengl.cpp b/src/plugins/scenes/opengl/scene_opengl.cpp index d2f7342201..e458258d4f 100644 --- a/src/plugins/scenes/opengl/scene_opengl.cpp +++ b/src/plugins/scenes/opengl/scene_opengl.cpp @@ -638,24 +638,23 @@ void SceneOpenGL::paint(int screenId, const QRegion &damage, const QListblocksDirectScanout()) { for (int i = stacking_order.count() - 1; i >= 0; i--) { Window *window = stacking_order[i]; - AbstractClient *c = dynamic_cast(window->window()); - if (!c) { - break; - } - if (c->isOnScreen(screenId)) { - if (window->isOpaque() && c->isFullScreen()) { - auto pixmap = window->windowPixmap(); - if (!pixmap) { - break; - } - pixmap->update(); - pixmap = pixmap->topMostSurface(); - // the subsurface has to be able to cover the whole window - if (pixmap->position() != QPoint(0, 0)) { - break; - } - directScanout = m_backend->scanout(screenId, pixmap->surface()); + Toplevel *toplevel = window->window(); + if (toplevel->isOnScreen(screenId)) { + AbstractClient *c = dynamic_cast(toplevel); + if (!c || !c->isFullScreen() || !window->isOpaque()) { + break; } + auto pixmap = window->windowPixmap(); + if (!pixmap) { + break; + } + pixmap->update(); + pixmap = pixmap->topMostSurface(); + // the subsurface has to be able to cover the whole window + if (pixmap->position() != QPoint(0, 0)) { + break; + } + directScanout = m_backend->scanout(screenId, pixmap->surface()); break; } }