Commit 9f2cb0ae authored by Vlad Zahorodnii's avatar Vlad Zahorodnii

Provide expected presentation time to effects

Effects are given the interval between two consecutive frames. The main
flaw of this approach is that if the Compositor transitions from the idle
state to "active" state, i.e. when there is something to repaint,
effects may see a very large interval between the last painted frame and
the current. In order to address this issue, the Scene invalidates the
timer that is used to measure time between consecutive frames before the
Compositor is about to become idle.

While this works perfectly fine with Xinerama-style rendering, with per
screen rendering, determining whether the compositor is about to idle is
rather a tedious task mostly because a single output can't be used for
the test.

Furthermore, since the Compositor schedules pointless repaints just to
ensure that it's idle, it might take several attempts to figure out
whether the scene timer must be invalidated if you use (true) per screen
rendering.

Ideally, all effects should use a timeline helper that is aware of the
underlying render loop and its timings. However, this option is off the
table because it will involve a lot of work to implement it.

Alternative and much simpler option is to pass the expected presentation
time to effects rather than time between consecutive frames. This means
that effects are responsible for determining how much animation timelines
have to be advanced. Typically, an effect would have to store the
presentation timestamp provided in either prePaint{Screen,Window} and
use it in the subsequent prePaint{Screen,Window} call to estimate the
amount of time passed between the next and the last frames.

Unfortunately, this is an API incompatible change. However, it shouldn't
take a lot of work to port third-party binary effects, which don't use the
AnimationEffect class, to the new API. On the bright side, we no longer
need to be concerned about the Compositor getting idle.

We do still try to determine whether the Compositor is about to idle,
primarily, because the OpenGL render backend swaps buffers on present,
but that will change with the ongoing compositing timing rework.
parent 66464220
......@@ -167,8 +167,8 @@ public:
void paintWindow(KWin::EffectWindow *, int, const QRegion &, KWin::WindowPaintData &) override {}
void postPaintScreen() override {}
void postPaintWindow(KWin::EffectWindow *) override {}
void prePaintScreen(KWin::ScreenPrePaintData &, int) override {}
void prePaintWindow(KWin::EffectWindow *, KWin::WindowPrePaintData &, int) override {}
void prePaintScreen(KWin::ScreenPrePaintData &, std::chrono::milliseconds) override {}
void prePaintWindow(KWin::EffectWindow *, KWin::WindowPrePaintData &, std::chrono::milliseconds) override {}
QByteArray readRootProperty(long int, long int, int) const override {
return QByteArray();
}
......
......@@ -681,16 +681,20 @@ void Compositor::performCompositing()
// 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);
if (m_framesToTestForSafety > 0 && (m_scene->compositingType() & OpenGLCompositing)) {
kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PreFrame);
}
m_renderTimer.start();
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
for (int screenId = 0; screenId < screens()->count(); ++screenId) {
m_scene->paint(screenId, repaints, windows);
m_scene->paint(screenId, repaints, windows, presentTime);
}
} else {
m_scene->paint(-1, repaints, windows);
m_scene->paint(-1, repaints, windows, presentTime);
}
m_timeSinceLastVBlank = m_renderTimer.elapsed();
if (m_framesToTestForSafety > 0) {
......
......@@ -363,10 +363,10 @@ void EffectsHandlerImpl::reconfigure()
}
// the idea is that effects call this function again which calls the next one
void EffectsHandlerImpl::prePaintScreen(ScreenPrePaintData& data, int time)
void EffectsHandlerImpl::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
{
if (m_currentPaintScreenIterator != m_activeEffects.constEnd()) {
(*m_currentPaintScreenIterator++)->prePaintScreen(data, time);
(*m_currentPaintScreenIterator++)->prePaintScreen(data, presentTime);
--m_currentPaintScreenIterator;
}
// no special final code
......@@ -406,10 +406,10 @@ void EffectsHandlerImpl::postPaintScreen()
// no special final code
}
void EffectsHandlerImpl::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
void EffectsHandlerImpl::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
{
if (m_currentPaintWindowIterator != m_activeEffects.constEnd()) {
(*m_currentPaintWindowIterator++)->prePaintWindow(w, data, time);
(*m_currentPaintWindowIterator++)->prePaintWindow(w, data, presentTime);
--m_currentPaintWindowIterator;
}
// no special final code
......
......@@ -59,14 +59,14 @@ class KWIN_EXPORT EffectsHandlerImpl : public EffectsHandler
public:
EffectsHandlerImpl(Compositor *compositor, Scene *scene);
~EffectsHandlerImpl() override;
void prePaintScreen(ScreenPrePaintData& data, int time) override;
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
void paintScreen(int mask, const QRegion &region, ScreenPaintData& data) override;
/**
* Special hook to perform a paintScreen but just with the windows on @p desktop.
*/
void paintDesktop(int desktop, int mask, QRegion region, ScreenPaintData& data);
void postPaintScreen() override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
void paintWindow(EffectWindow* w, int mask, const QRegion &region, WindowPaintData& data) override;
void postPaintWindow(EffectWindow* w) override;
void paintEffectFrame(EffectFrame* frame, const QRegion &region, double opacity, double frameOpacity) override;
......
......@@ -336,19 +336,19 @@ void ContrastEffect::uploadGeometry(GLVertexBuffer *vbo, const QRegion &region)
vbo->setAttribLayout(layout, 2, sizeof(QVector2D));
}
void ContrastEffect::prePaintScreen(ScreenPrePaintData &data, int time)
void ContrastEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
{
m_paintedArea = QRegion();
m_currentContrast = QRegion();
effects->prePaintScreen(data, time);
effects->prePaintScreen(data, presentTime);
}
void ContrastEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
void ContrastEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
{
// this effect relies on prePaintWindow being called in the bottom to top order
effects->prePaintWindow(w, data, time);
effects->prePaintWindow(w, data, presentTime);
if (!w->isPaintingEnabled()) {
return;
......
......@@ -37,8 +37,8 @@ public:
static QMatrix4x4 colorMatrix(qreal contrast, qreal intensity, qreal saturation);
void reconfigure(ReconfigureFlags flags) override;
void prePaintScreen(ScreenPrePaintData &data, int time) override;
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
void drawWindow(EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data) override;
void paintEffectFrame(EffectFrame *frame, const QRegion &region, double opacity, double frameOpacity) override;
......
......@@ -469,19 +469,19 @@ void BlurEffect::uploadGeometry(GLVertexBuffer *vbo, const QRegion &blurRegion,
vbo->setAttribLayout(layout, 2, sizeof(QVector2D));
}
void BlurEffect::prePaintScreen(ScreenPrePaintData &data, int time)
void BlurEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
{
m_paintedArea = QRegion();
m_currentBlur = QRegion();
effects->prePaintScreen(data, time);
effects->prePaintScreen(data, presentTime);
}
void BlurEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
void BlurEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
{
// this effect relies on prePaintWindow being called in the bottom to top order
effects->prePaintWindow(w, data, time);
effects->prePaintWindow(w, data, presentTime);
if (!w->isPaintingEnabled()) {
return;
......
......@@ -40,8 +40,8 @@ public:
static bool enabledByDefault();
void reconfigure(ReconfigureFlags flags) override;
void prePaintScreen(ScreenPrePaintData &data, int time) override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
void drawWindow(EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data) override;
void paintEffectFrame(EffectFrame *frame, const QRegion &region, double opacity, double frameOpacity) override;
......
......@@ -34,6 +34,7 @@ CoverSwitchEffect::CoverSwitchEffect()
, stop(false)
, stopRequested(false)
, startRequested(false)
, lastPresentTime(std::chrono::milliseconds::zero())
, zPosition(900.0)
, scaleFactor(0.0)
, direction(Left)
......@@ -103,17 +104,23 @@ void CoverSwitchEffect::reconfigure(ReconfigureFlags)
}
void CoverSwitchEffect::prePaintScreen(ScreenPrePaintData& data, int time)
void CoverSwitchEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
{
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
if (lastPresentTime.count()) {
delta = presentTime - lastPresentTime;
}
lastPresentTime = presentTime;
if (mActivated || stop || stopRequested) {
data.mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
if (animation || start || stop) {
timeLine.update(std::chrono::milliseconds(time));
timeLine.update(delta);
}
if (selected_window == nullptr)
abort();
}
effects->prePaintScreen(data, time);
effects->prePaintScreen(data, presentTime);
}
void CoverSwitchEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData& data)
......@@ -285,6 +292,7 @@ void CoverSwitchEffect::postPaintScreen()
}
referrencedWindows.clear();
currentWindowList.clear();
lastPresentTime = std::chrono::milliseconds::zero();
if (startRequested) {
startRequested = false;
mActivated = true;
......@@ -538,6 +546,7 @@ void CoverSwitchEffect::slotTabBoxClosed()
start = false;
animation = false;
timeLine.reset();
lastPresentTime = std::chrono::milliseconds::zero();
}
mActivated = false;
effects->unrefTabBox();
......@@ -907,6 +916,7 @@ void CoverSwitchEffect::abort()
}
effects->setActiveFullScreenEffect(nullptr);
timeLine.reset();
lastPresentTime = std::chrono::milliseconds::zero();
mActivated = false;
stop = false;
stopRequested = false;
......
......@@ -42,7 +42,7 @@ public:
~CoverSwitchEffect() override;
void reconfigure(ReconfigureFlags) override;
void prePaintScreen(ScreenPrePaintData &data, int time) override;
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
void paintScreen(int mask, const QRegion &region, ScreenPaintData &data) override;
void postPaintScreen() override;
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
......@@ -123,6 +123,7 @@ private:
bool stopRequested;
bool startRequested;
TimeLine timeLine;
std::chrono::milliseconds lastPresentTime;
QRect area;
float zPosition;
float scaleFactor;
......
......@@ -50,6 +50,7 @@ CubeEffect::CubeEffect()
, wallpaper(nullptr)
, texturedCaps(true)
, capTexture(nullptr)
, lastPresentTime(std::chrono::milliseconds::zero())
, reflectionPainting(false)
, activeScreen(0)
, bottomCap(false)
......@@ -360,8 +361,14 @@ void CubeEffect::startVerticalAnimation(VerticalAnimationState state)
verticalAnimationState = state;
}
void CubeEffect::prePaintScreen(ScreenPrePaintData& data, int time)
void CubeEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
{
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
if (lastPresentTime.count()) {
delta = presentTime - lastPresentTime;
}
lastPresentTime = presentTime;
if (activated) {
data.mask |= PAINT_SCREEN_TRANSFORMED | Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS | PAINT_SCREEN_BACKGROUND_FIRST;
if (animationState == AnimationState::None && !animations.empty()) {
......@@ -373,15 +380,15 @@ void CubeEffect::prePaintScreen(ScreenPrePaintData& data, int time)
if (animationState != AnimationState::None || verticalAnimationState != VerticalAnimationState::None) {
if (animationState != AnimationState::None) {
timeLine.update(std::chrono::milliseconds(time));
timeLine.update(delta);
}
if (verticalAnimationState != VerticalAnimationState::None) {
verticalTimeLine.update(std::chrono::milliseconds(time));
verticalTimeLine.update(delta);
}
rotateCube();
}
}
effects->prePaintScreen(data, time);
effects->prePaintScreen(data, presentTime);
}
void CubeEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData& data)
......@@ -973,6 +980,7 @@ void CubeEffect::postPaintScreen()
animations.clear();
verticalAnimationState = VerticalAnimationState::None;
verticalAnimations.clear();
lastPresentTime = std::chrono::milliseconds::zero();
} else {
if (!animations.empty())
startAnimation(animations.dequeue());
......@@ -991,10 +999,12 @@ void CubeEffect::postPaintScreen()
/* Repaint if there is any animation */
if (animation) {
effects->addRepaintFull();
} else {
lastPresentTime = std::chrono::milliseconds::zero();
}
}
void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
{
if (activated) {
if (cube_painting) {
......@@ -1046,7 +1056,7 @@ void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t
data.quads = data.quads.splitAtY(rect.height() - w->y());
}
data.setTransformed();
effects->prePaintWindow(w, data, time);
effects->prePaintWindow(w, data, presentTime);
return;
}
}
......@@ -1066,7 +1076,7 @@ void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t
data.quads = data.quads.splitAtY(rect.height() - w->y());
}
data.setTransformed();
effects->prePaintWindow(w, data, time);
effects->prePaintWindow(w, data, presentTime);
return;
}
}
......@@ -1074,7 +1084,7 @@ void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t
}
}
}
effects->prePaintWindow(w, data, time);
effects->prePaintWindow(w, data, presentTime);
}
void CubeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
......
......@@ -47,10 +47,10 @@ public:
CubeEffect();
~CubeEffect() override;
void reconfigure(ReconfigureFlags) override;
void prePaintScreen(ScreenPrePaintData& data, int time) override;
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
void paintScreen(int mask, const QRegion &region, ScreenPaintData& data) override;
void postPaintScreen() override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
bool borderActivated(ElectricBorder border) override;
void grabbedKeyboardEvent(QKeyEvent* e) override;
......@@ -200,6 +200,7 @@ private:
VerticalAnimationState verticalAnimationState;
TimeLine verticalTimeLine;
QQueue<VerticalAnimationState> verticalAnimations;
std::chrono::milliseconds lastPresentTime;
bool reflectionPainting;
std::chrono::milliseconds rotationDuration;
......
......@@ -22,6 +22,7 @@ namespace KWin
CubeSlideEffect::CubeSlideEffect()
: stickyPainting(false)
, lastPresentTime(std::chrono::milliseconds::zero())
, windowMoving(false)
, desktopChangedWhileMoving(false)
, progressRestriction(0.0f)
......@@ -64,15 +65,21 @@ void CubeSlideEffect::reconfigure(ReconfigureFlags)
useWindowMoving = CubeSlideConfig::useWindowMoving();
}
void CubeSlideEffect::prePaintScreen(ScreenPrePaintData& data, int time)
void CubeSlideEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
{
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
if (lastPresentTime.count()) {
delta = presentTime - lastPresentTime;
}
lastPresentTime = presentTime;
if (isActive()) {
data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS | PAINT_SCREEN_BACKGROUND_FIRST;
timeLine.setCurrentTime(timeLine.currentTime() + time);
timeLine.setCurrentTime(timeLine.currentTime() + delta.count());
if (windowMoving && timeLine.currentTime() > progressRestriction * (qreal)timeLine.duration())
timeLine.setCurrentTime(progressRestriction * (qreal)timeLine.duration());
}
effects->prePaintScreen(data, time);
effects->prePaintScreen(data, presentTime);
}
void CubeSlideEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData& data)
......@@ -169,7 +176,7 @@ void CubeSlideEffect::paintSlideCube(int mask, QRegion region, ScreenPaintData&
painting_desktop = effects->currentDesktop();
}
void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
{
if (stickyPainting) {
if (staticWindows.contains(w)) {
......@@ -180,7 +187,7 @@ void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data,
} else if (isActive() && cube_painting) {
if (staticWindows.contains(w)) {
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
effects->prePaintWindow(w, data, time);
effects->prePaintWindow(w, data, presentTime);
return;
}
QRect rect = effects->clientArea(FullArea, effects->activeScreen(), painting_desktop);
......@@ -230,7 +237,7 @@ void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data,
} else
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
}
effects->prePaintWindow(w, data, time);
effects->prePaintWindow(w, data, presentTime);
}
void CubeSlideEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
......@@ -375,6 +382,7 @@ void CubeSlideEffect::postPaintScreen()
w->setData(WindowForceBackgroundContrastRole, QVariant());
}
staticWindows.clear();
lastPresentTime = std::chrono::milliseconds::zero();
effects->setActiveFullScreenEffect(nullptr);
}
}
......@@ -572,6 +580,7 @@ void CubeSlideEffect::slotWindowStepUserMovedResized(EffectWindow* w)
windowMoving = false;
desktopChangedWhileMoving = false;
timeLine.setCurrentTime(0);
lastPresentTime = std::chrono::milliseconds::zero();
if (!slideRotations.isEmpty())
slideRotations.clear();
effects->setActiveFullScreenEffect(nullptr);
......@@ -652,6 +661,7 @@ void CubeSlideEffect::slotNumberDesktopsChanged()
slideRotations.clear();
staticWindows.clear();
lastPresentTime = std::chrono::milliseconds::zero();
effects->setActiveFullScreenEffect(nullptr);
}
......
......@@ -31,10 +31,10 @@ public:
CubeSlideEffect();
~CubeSlideEffect() override;
void reconfigure(ReconfigureFlags) override;
void prePaintScreen(ScreenPrePaintData& data, int time) override;
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
void paintScreen(int mask, const QRegion &region, ScreenPaintData& data) override;
void postPaintScreen() override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
bool isActive() const override;
......@@ -90,6 +90,7 @@ private:
bool stickyPainting;
QSet<EffectWindow*> staticWindows;
QTimeLine timeLine;
std::chrono::milliseconds lastPresentTime;
QQueue<RotationDirection> slideRotations;
bool dontSlidePanels;
bool dontSlideStickyWindows;
......
......@@ -49,6 +49,7 @@ DesktopGridEffect::DesktopGridEffect()
, windowMove(nullptr)
, windowMoveDiff()
, windowMoveElevateTimer(new QTimer(this))
, lastPresentTime(std::chrono::milliseconds::zero())
, gridSize()
, orientation(Qt::Horizontal)
, activeCell(1, 1)
......@@ -143,8 +144,17 @@ void DesktopGridEffect::reconfigure(ReconfigureFlags)
//-----------------------------------------------------------------------------
// Screen painting
void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, int time)
void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
{
// The animation code assumes that the time diff cannot be 0, let's work around it.
int time;
if (lastPresentTime.count()) {
time = std::max(1, int((presentTime - lastPresentTime).count()));
} else {
time = 1;
}
lastPresentTime = presentTime;
if (timeline.currentValue() != 0 || activated || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
if (activated)
timeline.setCurrentTime(timeline.currentTime() + time);
......@@ -173,7 +183,7 @@ void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, int time)
w->setData(WindowForceBlurRole, QVariant(true));
}
effects->prePaintScreen(data, time);
effects->prePaintScreen(data, presentTime);
}
void DesktopGridEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData& data)
......@@ -237,20 +247,31 @@ void DesktopGridEffect::paintScreen(int mask, const QRegion &region, ScreenPaint
void DesktopGridEffect::postPaintScreen()
{
if (activated ? timeline.currentValue() != 1 : timeline.currentValue() != 0)
bool resetLastPresentTime = true;
if (activated ? timeline.currentValue() != 1 : timeline.currentValue() != 0) {
effects->addRepaintFull(); // Repaint during zoom
if (isUsingPresentWindows() && isMotionManagerMovingWindows())
resetLastPresentTime = false;
}
if (isUsingPresentWindows() && isMotionManagerMovingWindows()) {
effects->addRepaintFull();
resetLastPresentTime = false;
}
if (activated) {
for (int i = 0; i < effects->numberOfDesktops(); i++) {
if (hoverTimeline[i]->currentValue() != 0.0 && hoverTimeline[i]->currentValue() != 1.0) {
// Repaint during soft highlighting
effects->addRepaintFull();
resetLastPresentTime = false;
break;
}
}
}
if (resetLastPresentTime) {
lastPresentTime = std::chrono::milliseconds::zero();
}
for (auto &w : effects->stackingOrder()) {
w->setData(WindowForceBlurRole, QVariant());
}
......@@ -261,7 +282,7 @@ void DesktopGridEffect::postPaintScreen()
//-----------------------------------------------------------------------------
// Window painting
void DesktopGridEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
void DesktopGridEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
{
if (timeline.currentValue() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
if (w->isOnDesktop(paintingDesktop)) {
......@@ -287,7 +308,7 @@ void DesktopGridEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data
} else
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
}
effects->prePaintWindow(w, data, time);
effects->prePaintWindow(w, data, presentTime);
}
void DesktopGridEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
......@@ -1218,6 +1239,7 @@ void DesktopGridEffect::finish()
if (keyboardGrab)
effects->ungrabKeyboard();
keyboardGrab = false;
lastPresentTime = std::chrono::milliseconds::zero();
effects->stopMouseInterception(this);
effects->setActiveFullScreenEffect(nullptr);
if (isUsingPresentWindows()) {
......
......@@ -39,10 +39,10 @@ public:
DesktopGridEffect();
~DesktopGridEffect() override;
void reconfigure(ReconfigureFlags) override;
void prePaintScreen(ScreenPrePaintData& data, int time) override;
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
void paintScreen(int mask, const QRegion &region, ScreenPaintData& data) override;
void postPaintScreen() override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
void windowInputMouseEvent(QEvent* e) override;
void grabbedKeyboardEvent(QKeyEvent* e) override;
......@@ -131,6 +131,7 @@ private:
QPoint windowMoveDiff;
QPoint dragStartPos;
QTimer *windowMoveElevateTimer;
std::chrono::milliseconds lastPresentTime;
// Soft highlighting
QList<QTimeLine*> hoverTimeline;
......
......@@ -82,9 +82,13 @@ void DimInactiveEffect::reconfigure(ReconfigureFlags flags)
effects->addRepaintFull();
}
void DimInactiveEffect::prePaintScreen(ScreenPrePaintData &data, int time)
void DimInactiveEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
{
const std::chrono::milliseconds delta(time);
std::chrono::milliseconds delta(0);