Delegate repaint scheduling to the Scene
In order to unlock per screen rendering, we need to track repaints for every screen individually. While we could do this in the Compositor class, tracking repaints in the Scene seems a better alternative in long run because we will have to instantiate a Scene for each composited screen one day.
This commit is contained in:
parent
992e88de50
commit
a3ec0c9a57
4 changed files with 75 additions and 29 deletions
|
@ -448,7 +448,6 @@ void Compositor::stop()
|
|||
delete m_scene;
|
||||
m_scene = nullptr;
|
||||
compositeTimer.stop();
|
||||
repaints_region = QRegion();
|
||||
|
||||
m_state = State::Off;
|
||||
emit compositingToggled(false);
|
||||
|
@ -529,41 +528,26 @@ void Compositor::reinitialize()
|
|||
}
|
||||
}
|
||||
|
||||
void Compositor::addRepaint(int x, int y, int w, int h)
|
||||
void Compositor::addRepaint(int x, int y, int width, int height)
|
||||
{
|
||||
if (m_state != State::On) {
|
||||
return;
|
||||
}
|
||||
repaints_region += QRegion(x, y, w, h);
|
||||
scheduleRepaint();
|
||||
addRepaint(QRegion(x, y, width, height));
|
||||
}
|
||||
|
||||
void Compositor::addRepaint(const QRect& r)
|
||||
void Compositor::addRepaint(const QRect &rect)
|
||||
{
|
||||
if (m_state != State::On) {
|
||||
return;
|
||||
}
|
||||
repaints_region += r;
|
||||
scheduleRepaint();
|
||||
addRepaint(QRegion(rect));
|
||||
}
|
||||
|
||||
void Compositor::addRepaint(const QRegion& r)
|
||||
void Compositor::addRepaint(const QRegion ®ion)
|
||||
{
|
||||
if (m_state != State::On) {
|
||||
return;
|
||||
if (m_scene) {
|
||||
m_scene->addRepaint(region);
|
||||
}
|
||||
repaints_region += r;
|
||||
scheduleRepaint();
|
||||
}
|
||||
|
||||
void Compositor::addRepaintFull()
|
||||
{
|
||||
if (m_state != State::On) {
|
||||
return;
|
||||
}
|
||||
const QSize &s = screens()->size();
|
||||
repaints_region = QRegion(0, 0, s.width(), s.height());
|
||||
scheduleRepaint();
|
||||
addRepaint(screens()->geometry());
|
||||
}
|
||||
|
||||
void Compositor::timerEvent(QTimerEvent *te)
|
||||
|
@ -666,10 +650,6 @@ void Compositor::performCompositing()
|
|||
}
|
||||
}
|
||||
|
||||
QRegion repaints = repaints_region;
|
||||
// clear all repaints, so that post-pass can add repaints for the next repaint
|
||||
repaints_region = QRegion();
|
||||
|
||||
const std::chrono::nanoseconds now = std::chrono::steady_clock::now().time_since_epoch();
|
||||
const std::chrono::milliseconds presentTime =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(now);
|
||||
|
@ -680,9 +660,15 @@ void Compositor::performCompositing()
|
|||
m_renderTimer.start();
|
||||
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
|
||||
for (int screenId = 0; screenId < screens()->count(); ++screenId) {
|
||||
const QRegion repaints = m_scene->repaints(screenId);
|
||||
m_scene->resetRepaints(screenId);
|
||||
|
||||
m_scene->paint(screenId, repaints, windows, presentTime);
|
||||
}
|
||||
} else {
|
||||
const QRegion repaints = m_scene->repaints(-1);
|
||||
m_scene->resetRepaints(-1);
|
||||
|
||||
m_scene->paint(-1, repaints, windows, presentTime);
|
||||
}
|
||||
m_timeSinceLastVBlank = m_renderTimer.elapsed();
|
||||
|
|
|
@ -146,7 +146,6 @@ private:
|
|||
QList<xcb_atom_t> m_unusedSupportProperties;
|
||||
QTimer m_unusedSupportPropertyTimer;
|
||||
qint64 vBlankInterval, fpsInterval;
|
||||
QRegion repaints_region;
|
||||
|
||||
qint64 m_timeSinceLastVBlank;
|
||||
|
||||
|
|
48
scene.cpp
48
scene.cpp
|
@ -56,6 +56,7 @@
|
|||
*/
|
||||
|
||||
#include "scene.h"
|
||||
#include "abstract_output.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include <QQuickWindow>
|
||||
|
@ -86,6 +87,10 @@ namespace KWin
|
|||
Scene::Scene(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
|
||||
connect(screens(), &Screens::countChanged, this, &Scene::reallocRepaints);
|
||||
}
|
||||
reallocRepaints();
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
|
@ -93,6 +98,49 @@ Scene::~Scene()
|
|||
Q_ASSERT(m_windows.isEmpty());
|
||||
}
|
||||
|
||||
void Scene::addRepaint(const QRegion ®ion)
|
||||
{
|
||||
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
|
||||
if (m_repaints.count() != screens()->count()) {
|
||||
return; // Repaints haven't been reallocated yet, do nothing.
|
||||
}
|
||||
for (int screenId = 0; screenId < m_repaints.count(); ++screenId) {
|
||||
AbstractOutput *output = kwinApp()->platform()->findOutput(screenId);
|
||||
const QRegion dirtyRegion = region & output->geometry();
|
||||
if (!dirtyRegion.isEmpty()) {
|
||||
m_repaints[screenId] += dirtyRegion;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_repaints[0] += region;
|
||||
}
|
||||
|
||||
Compositor::self()->scheduleRepaint();
|
||||
}
|
||||
|
||||
QRegion Scene::repaints(int screenId) const
|
||||
{
|
||||
const int index = screenId == -1 ? 0 : screenId;
|
||||
return m_repaints[index];
|
||||
}
|
||||
|
||||
void Scene::resetRepaints(int screenId)
|
||||
{
|
||||
const int index = screenId == -1 ? 0 : screenId;
|
||||
m_repaints[index] = QRegion();
|
||||
}
|
||||
|
||||
void Scene::reallocRepaints()
|
||||
{
|
||||
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
|
||||
m_repaints.resize(screens()->count());
|
||||
} else {
|
||||
m_repaints.resize(1);
|
||||
}
|
||||
|
||||
m_repaints.fill(infiniteRegion());
|
||||
}
|
||||
|
||||
// returns mask and possibly modified region
|
||||
void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint,
|
||||
QRegion *updateRegion, QRegion *validRegion,
|
||||
|
|
13
scene.h
13
scene.h
|
@ -55,6 +55,17 @@ public:
|
|||
class EffectFrame;
|
||||
class Window;
|
||||
|
||||
/**
|
||||
* Schedules a repaint for the specified @a region.
|
||||
*/
|
||||
void addRepaint(const QRegion ®ion);
|
||||
|
||||
/**
|
||||
* Returns the repaints region for output with the specified @a screenId.
|
||||
*/
|
||||
QRegion repaints(int screenId) const;
|
||||
void resetRepaints(int screenId);
|
||||
|
||||
// Returns true if the ctor failed to properly initialize.
|
||||
virtual bool initFailed() const = 0;
|
||||
virtual CompositingType compositingType() const = 0;
|
||||
|
@ -265,9 +276,11 @@ private:
|
|||
void paintWindowThumbnails(Scene::Window *w, const QRegion ®ion, qreal opacity, qreal brightness, qreal saturation);
|
||||
void paintDesktopThumbnails(Scene::Window *w);
|
||||
std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero();
|
||||
void reallocRepaints();
|
||||
QHash< Toplevel*, Window* > m_windows;
|
||||
// windows in their stacking order
|
||||
QVector< Window* > stacking_order;
|
||||
QVector<QRegion> m_repaints;
|
||||
// how many times finalPaintScreen() has been called
|
||||
int m_paintScreenCount = 0;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue