kwin: Return the modified damage in a separate paintScreen() parameter

icc-effect-5.14.5
Fredrik Höglund 2013-11-23 15:08:17 +01:00
parent c25b2939b1
commit a9e49e218f
4 changed files with 31 additions and 19 deletions

View File

@ -104,48 +104,56 @@ Scene::~Scene()
}
// returns mask and possibly modified region
void Scene::paintScreen(int* mask, QRegion* region)
void Scene::paintScreen(int* mask, const QRegion &damage, QRegion *validRegion)
{
const QRegion displayRegion(0, 0, displayWidth(), displayHeight());
*mask = (*region == displayRegion) ? 0 : PAINT_SCREEN_REGION;
*mask = (damage == displayRegion) ? 0 : PAINT_SCREEN_REGION;
updateTimeDiff();
// preparation step
static_cast<EffectsHandlerImpl*>(effects)->startPaint();
QRegion region = damage;
ScreenPrePaintData pdata;
pdata.mask = *mask;
pdata.paint = *region;
pdata.paint = region;
effects->prePaintScreen(pdata, time_diff);
*mask = pdata.mask;
*region = pdata.paint;
region = pdata.paint;
if (*mask & (PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS)) {
// Region painting is not possible with transformations,
// because screen damage doesn't match transformed positions.
*mask &= ~PAINT_SCREEN_REGION;
*region = infiniteRegion();
region = infiniteRegion();
} else if (*mask & PAINT_SCREEN_REGION) {
// make sure not to go outside visible screen
*region &= displayRegion;
region &= displayRegion;
} else {
// whole screen, not transformed, force region to be full
*region = displayRegion;
region = displayRegion;
}
painted_region = *region;
painted_region = region;
if (*mask & PAINT_SCREEN_BACKGROUND_FIRST) {
paintBackground(*region);
paintBackground(region);
}
ScreenPaintData data;
effects->paintScreen(*mask, *region, data);
foreach (Window * w, stacking_order) {
effects->paintScreen(*mask, region, data);
foreach (Window *w, stacking_order) {
effects->postPaintWindow(effectWindow(w));
}
effects->postPaintScreen();
*region |= painted_region;
// make sure not to go outside of the screen area
*region &= displayRegion;
*validRegion = (region | painted_region) & displayRegion;
// make sure all clipping is restored
Q_ASSERT(!PaintClipper::clip());
}

View File

@ -115,7 +115,7 @@ public Q_SLOTS:
virtual void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted) = 0;
protected:
// shared implementation, starts painting the screen
void paintScreen(int* mask, QRegion* region);
void paintScreen(int* mask, const QRegion &damage, QRegion *validRegion);
friend class EffectsHandlerImpl;
// called after all effects had their paintScreen() called
void finalPaintScreen(int mask, QRegion region, ScreenPaintData& data);

View File

@ -357,13 +357,16 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
checkGLError("Paint1");
#endif
paintScreen(&mask, &damage); // call generic implementation
QRegion validRegion;
paintScreen(&mask, damage, &validRegion); // call generic implementation
#ifndef KWIN_HAVE_OPENGLES
const QRegion displayRegion(0, 0, displayWidth(), displayHeight());
// copy dirty parts from front to backbuffer
if (options->glPreferBufferSwap() == Options::CopyFrontBuffer && damage != displayRegion) {
if (options->glPreferBufferSwap() == Options::CopyFrontBuffer && validRegion != displayRegion) {
glReadBuffer(GL_FRONT);
copyPixels(displayRegion - damage);
copyPixels(displayRegion - validRegion);
glReadBuffer(GL_BACK);
damage = displayRegion;
}
@ -372,7 +375,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
checkGLError("Paint2");
#endif
m_backend->endRenderingFrame(damage, damage);
m_backend->endRenderingFrame(validRegion, validRegion);
// do cleanup
stacking_order.clear();

View File

@ -190,7 +190,8 @@ qint64 SceneXrender::paint(QRegion damage, ToplevelList toplevels)
}
int mask = 0;
paintScreen(&mask, &damage);
QRegion validRegion;
paintScreen(&mask, damage, &validRegion);
if (m_overlayWindow->window()) // show the window only after the first pass, since
m_overlayWindow->show(); // that pass may take long