Allow specifying scene geometry

The main motivation behind this change is to decouple the scene a bit
further from Screens, which is also obsolete.
This commit is contained in:
Vlad Zahorodnii 2021-11-24 19:18:31 +02:00
parent e20c9e7099
commit 3ad7bf01c8
4 changed files with 35 additions and 20 deletions

View file

@ -71,7 +71,6 @@
#include "deleted.h" #include "deleted.h"
#include "effects.h" #include "effects.h"
#include "renderloop.h" #include "renderloop.h"
#include "screens.h"
#include "shadow.h" #include "shadow.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "composite.h" #include "composite.h"
@ -100,15 +99,19 @@ void Scene::initialize()
connect(workspace(), &Workspace::deletedRemoved, this, &Scene::removeToplevel); connect(workspace(), &Workspace::deletedRemoved, this, &Scene::removeToplevel);
connect(workspace(), &Workspace::geometryChanged, this, &Scene::addRepaintFull);
connect(workspace(), &Workspace::currentActivityChanged, this, &Scene::addRepaintFull); connect(workspace(), &Workspace::currentActivityChanged, this, &Scene::addRepaintFull);
connect(workspace(), &Workspace::currentDesktopChanged, this, &Scene::addRepaintFull); connect(workspace(), &Workspace::currentDesktopChanged, this, &Scene::addRepaintFull);
connect(workspace(), &Workspace::stackingOrderChanged, 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() void Scene::addRepaintFull()
{ {
addRepaint(workspace()->geometry()); addRepaint(geometry());
} }
void Scene::addRepaint(int x, int y, int width, int height) void Scene::addRepaint(int x, int y, int width, int height)
@ -138,6 +141,19 @@ void Scene::addRepaint(const QRegion &region)
} }
} }
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 QRegion Scene::repaints(AbstractOutput *output) const
{ {
return m_repaints.value(output, infiniteRegion()); 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, QRegion *updateRegion, QRegion *validRegion, RenderLoop *renderLoop,
const QMatrix4x4 &projection) const QMatrix4x4 &projection)
{ {
const QSize &screenSize = screens()->size(); const QRegion displayRegion(geometry());
const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height());
const std::chrono::milliseconds presentTime = const std::chrono::milliseconds presentTime =
std::chrono::duration_cast<std::chrono::milliseconds>(renderLoop->nextPresentationTimestamp()); std::chrono::duration_cast<std::chrono::milliseconds>(renderLoop->nextPresentationTimestamp());
@ -309,7 +324,7 @@ void Scene::paintGenericScreen(int orig_mask, const ScreenPaintData &)
phase2.append({w, infiniteRegion(), data.clip, data.mask,}); phase2.append({w, infiniteRegion(), data.clip, data.mask,});
} }
damaged_region = QRegion(QRect {{}, screens()->size()}); damaged_region = geometry();
if (m_paintScreenCount == 1) { if (m_paintScreenCount == 1) {
aboutToStartPainting(painted_screen, damaged_region); aboutToStartPainting(painted_screen, damaged_region);
@ -407,8 +422,7 @@ void Scene::paintSimpleScreen(int orig_mask, const QRegion &region)
const QRegion repaintClip = repaint_region - dirtyArea; const QRegion repaintClip = repaint_region - dirtyArea;
dirtyArea |= repaint_region; dirtyArea |= repaint_region;
const QSize &screenSize = screens()->size(); const QRegion displayRegion(geometry());
const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height());
bool fullRepaint(dirtyArea == displayRegion); // spare some expensive region operations bool fullRepaint(dirtyArea == displayRegion); // spare some expensive region operations
if (!fullRepaint) { if (!fullRepaint) {
extendPaintRegion(dirtyArea, opaqueFullscreen); extendPaintRegion(dirtyArea, opaqueFullscreen);
@ -535,7 +549,7 @@ void Scene::clearStackingOrder()
void Scene::paintWindow(Window* w, int mask, const QRegion &_region) void Scene::paintWindow(Window* w, int mask, const QRegion &_region)
{ {
// no painting outside visible screen (and no transformations) // 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 if (region.isEmpty()) // completely clipped
return; return;

View file

@ -62,6 +62,9 @@ public:
void addRepaint(int x, int y, int width, int height); void addRepaint(int x, int y, int width, int height);
void addRepaintFull(); void addRepaintFull();
QRect geometry() const;
void setGeometry(const QRect &rect);
/** /**
* Returns the repaints region for output with the specified @a output. * 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(); std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero();
QHash< Toplevel*, Window* > m_windows; QHash< Toplevel*, Window* > m_windows;
QMap<AbstractOutput *, QRegion> m_repaints; QMap<AbstractOutput *, QRegion> m_repaints;
QRect m_geometry;
// how many times finalPaintScreen() has been called // how many times finalPaintScreen() has been called
int m_paintScreenCount = 0; int m_paintScreenCount = 0;
}; };

View file

@ -12,7 +12,6 @@
#include "x11client.h" #include "x11client.h"
#include "deleted.h" #include "deleted.h"
#include "effects.h" #include "effects.h"
#include "screens.h"
#include "unmanaged.h" #include "unmanaged.h"
#include "options.h" #include "options.h"
#include "utils.h" #include "utils.h"
@ -98,7 +97,7 @@ void LanczosFilter::init()
void LanczosFilter::updateOffscreenSurfaces() void LanczosFilter::updateOffscreenSurfaces()
{ {
const QSize &s = screens()->size(); const QSize &s = m_scene->geometry().size();
int w = s.width(); int w = s.width();
int h = s.height(); int h = s.height();

View file

@ -28,7 +28,6 @@
#include "main.h" #include "main.h"
#include "overlaywindow.h" #include "overlaywindow.h"
#include "renderloop.h" #include "renderloop.h"
#include "screens.h"
#include "cursor.h" #include "cursor.h"
#include "decorations/decoratedclient.h" #include "decorations/decoratedclient.h"
#include "shadowitem.h" #include "shadowitem.h"
@ -255,7 +254,7 @@ void SceneOpenGL::paint(AbstractOutput *output, const QRegion &damage, const QLi
geo = output->geometry(); geo = output->geometry();
scaling = output->scale(); scaling = output->scale();
} else { } else {
geo = screens()->geometry(); geo = geometry();
scaling = 1; scaling = 1;
} }
@ -320,8 +319,7 @@ void SceneOpenGL::paint(AbstractOutput *output, const QRegion &damage, const QLi
paintCursor(valid); paintCursor(valid);
if (!GLPlatform::instance()->isGLES() && !output) { if (!GLPlatform::instance()->isGLES() && !output) {
const QSize &screenSize = screens()->size(); const QRegion displayRegion(geometry());
const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height());
// copy dirty parts from front to backbuffer // copy dirty parts from front to backbuffer
if (!m_backend->supportsBufferAge() && if (!m_backend->supportsBufferAge() &&
@ -395,11 +393,11 @@ void SceneOpenGL::extendPaintRegion(QRegion &region, bool opaqueFullscreen)
if (m_backend->supportsBufferAge()) if (m_backend->supportsBufferAge())
return; return;
const QSize &screenSize = screens()->size();
if (options->glPreferBufferSwap() == Options::ExtendDamage) { // only Extend "large" repaints 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; 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 // 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 // (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 // movie aspect - two times ;-) It's a Fox format, though, so maybe we want to restrict
@ -414,7 +412,7 @@ void SceneOpenGL::extendPaintRegion(QRegion &region, bool opaqueFullscreen)
} }
} }
} else if (options->glPreferBufferSwap() == Options::PaintFullScreen) { // forced full rePaint } 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 &region, Scr
{ {
const QRect r = region.boundingRect(); const QRect r = region.boundingRect();
glEnable(GL_SCISSOR_TEST); 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); KWin::Scene::paintDesktop(desktop, mask, region, data);
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
} }