Replace window repaints with layer repaints
Windows have two kinds of repaints - window repaints and layer repaints. The main difference between the two is that the former is specified in the window-local coordinates while the latter is specified in the global screen coordinates. Window repaints are useful in case the position of the window doesn't matter, for example for repainting damaged regions, etc. But its biggest issue is that with per screen rendering, it's not possible to determine what screens exactly have to be repainted. The final area affected by the window repaint will be known only at compositing time. If a window gets damaged, we have to schedule a repaint on ALL outputs. Understandably, this costs a little bit in terms of performance. This change replaces the window repaints with the layer repaints. By doing so, we can avoid scheduling repaints on outputs that don't intersect with the dirty region and improve performance.
This commit is contained in:
parent
41718a1d8f
commit
8f9fcd7eb3
3 changed files with 7 additions and 21 deletions
24
scene.cpp
24
scene.cpp
|
@ -1164,14 +1164,6 @@ void Scene::Window::preprocess()
|
|||
}
|
||||
}
|
||||
|
||||
void Scene::Window::addRepaint(const QRegion ®ion)
|
||||
{
|
||||
for (int screen = 0; screen < m_repaints.count(); ++screen) {
|
||||
m_repaints[screen] += region;
|
||||
}
|
||||
Compositor::self()->scheduleRepaint();
|
||||
}
|
||||
|
||||
void Scene::Window::addLayerRepaint(const QRegion ®ion)
|
||||
{
|
||||
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
|
||||
|
@ -1182,46 +1174,42 @@ void Scene::Window::addLayerRepaint(const QRegion ®ion)
|
|||
AbstractOutput *output = kwinApp()->platform()->findOutput(screenId);
|
||||
const QRegion dirtyRegion = region & output->geometry();
|
||||
if (!dirtyRegion.isEmpty()) {
|
||||
m_layerRepaints[screenId] += dirtyRegion;
|
||||
m_repaints[screenId] += dirtyRegion;
|
||||
output->renderLoop()->scheduleRepaint();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_layerRepaints[0] += region;
|
||||
m_repaints[0] += region;
|
||||
kwinApp()->platform()->renderLoop()->scheduleRepaint();
|
||||
}
|
||||
}
|
||||
|
||||
QRegion Scene::Window::repaints(int screen) const
|
||||
{
|
||||
Q_ASSERT(!m_repaints.isEmpty() && !m_layerRepaints.isEmpty());
|
||||
Q_ASSERT(!m_repaints.isEmpty());
|
||||
const int index = screen != -1 ? screen : 0;
|
||||
if (m_repaints[index] == infiniteRegion() || m_layerRepaints[index] == infiniteRegion()) {
|
||||
if (m_repaints[index] == infiniteRegion()) {
|
||||
return QRect(QPoint(0, 0), screens()->size());
|
||||
}
|
||||
return m_repaints[index].translated(pos()) + m_layerRepaints[index];
|
||||
return m_repaints[index];
|
||||
}
|
||||
|
||||
void Scene::Window::resetRepaints(int screen)
|
||||
{
|
||||
Q_ASSERT(!m_repaints.isEmpty() && !m_layerRepaints.isEmpty());
|
||||
Q_ASSERT(!m_repaints.isEmpty());
|
||||
const int index = screen != -1 ? screen : 0;
|
||||
m_repaints[index] = QRegion();
|
||||
m_layerRepaints[index] = QRegion();
|
||||
}
|
||||
|
||||
void Scene::Window::reallocRepaints()
|
||||
{
|
||||
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
|
||||
m_repaints.resize(screens()->count());
|
||||
m_layerRepaints.resize(screens()->count());
|
||||
} else {
|
||||
m_repaints.resize(1);
|
||||
m_layerRepaints.resize(1);
|
||||
}
|
||||
|
||||
m_repaints.fill(infiniteRegion());
|
||||
m_layerRepaints.fill(infiniteRegion());
|
||||
}
|
||||
|
||||
//****************************************
|
||||
|
|
2
scene.h
2
scene.h
|
@ -364,7 +364,6 @@ public:
|
|||
void unreferencePreviousPixmap();
|
||||
void discardQuads();
|
||||
void preprocess();
|
||||
void addRepaint(const QRegion ®ion);
|
||||
void addLayerRepaint(const QRegion ®ion);
|
||||
QRegion repaints(int screen) const;
|
||||
void resetRepaints(int screen);
|
||||
|
@ -410,7 +409,6 @@ private:
|
|||
QScopedPointer<WindowPixmap> m_currentPixmap;
|
||||
QScopedPointer<WindowPixmap> m_previousPixmap;
|
||||
QVector<QRegion> m_repaints;
|
||||
QVector<QRegion> m_layerRepaints;
|
||||
SubSurfaceMonitor *m_subsurfaceMonitor = nullptr;
|
||||
int m_referencePixmapCounter;
|
||||
int disable_painting;
|
||||
|
|
|
@ -444,7 +444,7 @@ void Toplevel::addRepaint(const QRegion ®ion)
|
|||
if (!effectWindow() || !effectWindow()->sceneWindow()) {
|
||||
return;
|
||||
}
|
||||
effectWindow()->sceneWindow()->addRepaint(region);
|
||||
effectWindow()->sceneWindow()->addLayerRepaint(region.translated(pos()));
|
||||
}
|
||||
|
||||
void Toplevel::addLayerRepaint(const QRect &rect)
|
||||
|
|
Loading…
Reference in a new issue