From 3ad7bf01c81ecdb5fda5b0d656f79ff705229bbf Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 24 Nov 2021 19:18:31 +0200 Subject: [PATCH] Allow specifying scene geometry The main motivation behind this change is to decouple the scene a bit further from Screens, which is also obsolete. --- src/scene.cpp | 32 +++++++++++++++++++++-------- src/scene.h | 4 ++++ src/scenes/opengl/lanczosfilter.cpp | 3 +-- src/scenes/opengl/scene_opengl.cpp | 16 +++++++-------- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/scene.cpp b/src/scene.cpp index 3b465079ce..b65fb7cd14 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -71,7 +71,6 @@ #include "deleted.h" #include "effects.h" #include "renderloop.h" -#include "screens.h" #include "shadow.h" #include "wayland_server.h" #include "composite.h" @@ -100,15 +99,19 @@ void Scene::initialize() connect(workspace(), &Workspace::deletedRemoved, this, &Scene::removeToplevel); - connect(workspace(), &Workspace::geometryChanged, this, &Scene::addRepaintFull); connect(workspace(), &Workspace::currentActivityChanged, this, &Scene::addRepaintFull); connect(workspace(), &Workspace::currentDesktopChanged, this, &Scene::addRepaintFull); connect(workspace(), &Workspace::stackingOrderChanged, this, &Scene::addRepaintFull); + + setGeometry(workspace()->geometry()); + connect(workspace(), &Workspace::geometryChanged, this, [this]() { + setGeometry(workspace()->geometry()); + }); } void Scene::addRepaintFull() { - addRepaint(workspace()->geometry()); + addRepaint(geometry()); } void Scene::addRepaint(int x, int y, int width, int height) @@ -138,6 +141,19 @@ void Scene::addRepaint(const QRegion ®ion) } } +QRect Scene::geometry() const +{ + return m_geometry; +} + +void Scene::setGeometry(const QRect &rect) +{ + if (m_geometry != rect) { + m_geometry = rect; + addRepaintFull(); + } +} + QRegion Scene::repaints(AbstractOutput *output) const { return m_repaints.value(output, infiniteRegion()); @@ -196,8 +212,7 @@ void Scene::paintScreen(const QRegion &damage, const QRegion &repaint, QRegion *updateRegion, QRegion *validRegion, RenderLoop *renderLoop, const QMatrix4x4 &projection) { - const QSize &screenSize = screens()->size(); - const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height()); + const QRegion displayRegion(geometry()); const std::chrono::milliseconds presentTime = std::chrono::duration_cast(renderLoop->nextPresentationTimestamp()); @@ -309,7 +324,7 @@ void Scene::paintGenericScreen(int orig_mask, const ScreenPaintData &) phase2.append({w, infiniteRegion(), data.clip, data.mask,}); } - damaged_region = QRegion(QRect {{}, screens()->size()}); + damaged_region = geometry(); if (m_paintScreenCount == 1) { aboutToStartPainting(painted_screen, damaged_region); @@ -407,8 +422,7 @@ void Scene::paintSimpleScreen(int orig_mask, const QRegion ®ion) const QRegion repaintClip = repaint_region - dirtyArea; dirtyArea |= repaint_region; - const QSize &screenSize = screens()->size(); - const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height()); + const QRegion displayRegion(geometry()); bool fullRepaint(dirtyArea == displayRegion); // spare some expensive region operations if (!fullRepaint) { extendPaintRegion(dirtyArea, opaqueFullscreen); @@ -535,7 +549,7 @@ void Scene::clearStackingOrder() void Scene::paintWindow(Window* w, int mask, const QRegion &_region) { // no painting outside visible screen (and no transformations) - const QRegion region = _region & QRect({0, 0}, screens()->size()); + const QRegion region = _region & geometry(); if (region.isEmpty()) // completely clipped return; diff --git a/src/scene.h b/src/scene.h index 7fbc548e1c..015001d4b8 100644 --- a/src/scene.h +++ b/src/scene.h @@ -62,6 +62,9 @@ public: void addRepaint(int x, int y, int width, int height); void addRepaintFull(); + QRect geometry() const; + void setGeometry(const QRect &rect); + /** * Returns the repaints region for output with the specified @a output. */ @@ -261,6 +264,7 @@ private: std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero(); QHash< Toplevel*, Window* > m_windows; QMap m_repaints; + QRect m_geometry; // how many times finalPaintScreen() has been called int m_paintScreenCount = 0; }; diff --git a/src/scenes/opengl/lanczosfilter.cpp b/src/scenes/opengl/lanczosfilter.cpp index 43dfc5e6cf..919b950a95 100644 --- a/src/scenes/opengl/lanczosfilter.cpp +++ b/src/scenes/opengl/lanczosfilter.cpp @@ -12,7 +12,6 @@ #include "x11client.h" #include "deleted.h" #include "effects.h" -#include "screens.h" #include "unmanaged.h" #include "options.h" #include "utils.h" @@ -98,7 +97,7 @@ void LanczosFilter::init() void LanczosFilter::updateOffscreenSurfaces() { - const QSize &s = screens()->size(); + const QSize &s = m_scene->geometry().size(); int w = s.width(); int h = s.height(); diff --git a/src/scenes/opengl/scene_opengl.cpp b/src/scenes/opengl/scene_opengl.cpp index 4bb3806314..98c1776606 100644 --- a/src/scenes/opengl/scene_opengl.cpp +++ b/src/scenes/opengl/scene_opengl.cpp @@ -28,7 +28,6 @@ #include "main.h" #include "overlaywindow.h" #include "renderloop.h" -#include "screens.h" #include "cursor.h" #include "decorations/decoratedclient.h" #include "shadowitem.h" @@ -255,7 +254,7 @@ void SceneOpenGL::paint(AbstractOutput *output, const QRegion &damage, const QLi geo = output->geometry(); scaling = output->scale(); } else { - geo = screens()->geometry(); + geo = geometry(); scaling = 1; } @@ -320,8 +319,7 @@ void SceneOpenGL::paint(AbstractOutput *output, const QRegion &damage, const QLi paintCursor(valid); if (!GLPlatform::instance()->isGLES() && !output) { - const QSize &screenSize = screens()->size(); - const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height()); + const QRegion displayRegion(geometry()); // copy dirty parts from front to backbuffer if (!m_backend->supportsBufferAge() && @@ -395,11 +393,11 @@ void SceneOpenGL::extendPaintRegion(QRegion ®ion, bool opaqueFullscreen) if (m_backend->supportsBufferAge()) return; - const QSize &screenSize = screens()->size(); if (options->glPreferBufferSwap() == Options::ExtendDamage) { // only Extend "large" repaints - const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height()); + const QRegion displayRegion(geometry()); uint damagedPixels = 0; - const uint fullRepaintLimit = (opaqueFullscreen?0.49f:0.748f)*screenSize.width()*screenSize.height(); + const QSize &sceneSize = geometry().size(); + const uint fullRepaintLimit = (opaqueFullscreen?0.49f:0.748f)*sceneSize.width()*sceneSize.height(); // 16:9 is 75% of 4:3 and 2.55:1 is 49.01% of 5:4 // (5:4 is the most square format and 2.55:1 is Cinemascope55 - the widest ever shot // movie aspect - two times ;-) It's a Fox format, though, so maybe we want to restrict @@ -414,7 +412,7 @@ void SceneOpenGL::extendPaintRegion(QRegion ®ion, bool opaqueFullscreen) } } } else if (options->glPreferBufferSwap() == Options::PaintFullScreen) { // forced full rePaint - region = QRegion(0, 0, screenSize.width(), screenSize.height()); + region = QRegion(geometry()); } } @@ -422,7 +420,7 @@ void SceneOpenGL::paintDesktop(int desktop, int mask, const QRegion ®ion, Scr { const QRect r = region.boundingRect(); glEnable(GL_SCISSOR_TEST); - glScissor(r.x(), screens()->size().height() - r.y() - r.height(), r.width(), r.height()); + glScissor(r.x(), geometry().size().height() - r.y() - r.height(), r.width(), r.height()); KWin::Scene::paintDesktop(desktop, mask, region, data); glDisable(GL_SCISSOR_TEST); }