Advance window animations in prePaintWindow()

This will ensure that the window animation is advanced only if the
window is painted. I'd like to rely on this to allow effects schedule
animations as soon as Workspace::windowAdded signal is emitted.

As is, the issue with delaying EffectsHandler::windowAdded is that we
don't filter out all "not ready" windows, which breaks some effects
because EffectWindows are leaked in some properties but no
EffectsHandler::windowRemoved signal is emitted so those effects can
perform cleanup. Fixing that by the means of ensuring that only renderable
EffectWindows are exposed is hard too, and it would also mean that
effects need to use their own api, which I would like to avoid and port
the effects to kwin core apis instead.
remotes/origin/work/d_ed/transform_crash
Vlad Zahorodnii 3 years ago
parent e8904819b7
commit a43ffb8182
  1. 31
      src/libkwineffects/kwinanimationeffect.cpp
  2. 1
      src/libkwineffects/kwinanimationeffect.h
  3. 10
      src/plugins/glide/glide.cpp
  4. 11
      src/plugins/magiclamp/magiclamp.cpp
  5. 10
      src/plugins/sheet/sheet.cpp

@ -441,27 +441,6 @@ void AnimationEffect::genericAnimation(EffectWindow *w, WindowPaintData &data, f
{ {
} }
void AnimationEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
{
Q_D(AnimationEffect);
if (d->m_animations.isEmpty()) {
effects->prePaintScreen(data, presentTime);
return;
}
for (auto entry = d->m_animations.begin(); entry != d->m_animations.end(); ++entry) {
for (auto anim = entry->first.begin(); anim != entry->first.end(); ++anim) {
if (anim->startTime <= clock()) {
if (anim->frozenTime < 0) {
anim->timeLine.advance(presentTime);
}
}
}
}
effects->prePaintScreen(data, presentTime);
}
static qreal xCoord(const QRectF &r, int flag) static qreal xCoord(const QRectF &r, int flag)
{ {
if (flag & AnimationEffect::Left) { if (flag & AnimationEffect::Left) {
@ -514,13 +493,17 @@ void AnimationEffect::disconnectGeometryChanges()
void AnimationEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) void AnimationEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
{ {
Q_D(AnimationEffect); Q_D(AnimationEffect);
AniMap::const_iterator entry = d->m_animations.constFind(w); auto entry = d->m_animations.find(w);
if (entry != d->m_animations.constEnd()) { if (entry != d->m_animations.end()) {
for (QList<AniData>::const_iterator anim = entry->first.constBegin(); anim != entry->first.constEnd(); ++anim) { for (auto anim = entry->first.begin(); anim != entry->first.end(); ++anim) {
if (anim->startTime > clock() && !anim->waitAtSource) { if (anim->startTime > clock() && !anim->waitAtSource) {
continue; continue;
} }
if (anim->frozenTime < 0) {
anim->timeLine.advance(presentTime);
}
if (anim->attribute == Opacity || anim->attribute == CrossFadePrevious) { if (anim->attribute == Opacity || anim->attribute == CrossFadePrevious) {
data.setTranslucent(); data.setTranslucent();
} else if (!(anim->attribute == Brightness || anim->attribute == Saturation)) { } else if (!(anim->attribute == Brightness || anim->attribute == Saturation)) {

@ -322,7 +322,6 @@ public:
// Reimplemented from KWin::Effect. // Reimplemented from KWin::Effect.
QString debug(const QString &parameter) const override; QString debug(const QString &parameter) const override;
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override; void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override; void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
void postPaintScreen() override; void postPaintScreen() override;

@ -102,12 +102,6 @@ void GlideEffect::reconfigure(ReconfigureFlags flags)
void GlideEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) void GlideEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
{ {
auto animationIt = m_animations.begin();
while (animationIt != m_animations.end()) {
(*animationIt).timeLine.advance(presentTime);
++animationIt;
}
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
effects->prePaintScreen(data, presentTime); effects->prePaintScreen(data, presentTime);
@ -115,7 +109,9 @@ void GlideEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::millisec
void GlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) void GlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
{ {
if (m_animations.contains(w)) { auto animationIt = m_animations.find(w);
if (animationIt != m_animations.end()) {
(*animationIt).timeLine.advance(presentTime);
data.setTransformed(); data.setTransformed();
} }

@ -46,12 +46,6 @@ void MagicLampEffect::reconfigure(ReconfigureFlags)
void MagicLampEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) void MagicLampEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
{ {
auto animationIt = m_animations.begin();
while (animationIt != m_animations.end()) {
(*animationIt).timeLine.advance(presentTime);
++animationIt;
}
// We need to mark the screen windows as transformed. Otherwise the // We need to mark the screen windows as transformed. Otherwise the
// whole screen won't be repainted, resulting in artefacts. // whole screen won't be repainted, resulting in artefacts.
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
@ -63,8 +57,9 @@ void MagicLampEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data,
{ {
// Schedule window for transformation if the animation is still in // Schedule window for transformation if the animation is still in
// progress // progress
if (m_animations.contains(w)) { auto animationIt = m_animations.find(w);
// We'll transform this window if (animationIt != m_animations.end()) {
(*animationIt).timeLine.advance(presentTime);
data.setTransformed(); data.setTransformed();
} }

@ -74,12 +74,6 @@ void SheetEffect::reconfigure(ReconfigureFlags flags)
void SheetEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) void SheetEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
{ {
auto animationIt = m_animations.begin();
while (animationIt != m_animations.end()) {
(*animationIt).timeLine.advance(presentTime);
++animationIt;
}
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
effects->prePaintScreen(data, presentTime); effects->prePaintScreen(data, presentTime);
@ -87,7 +81,9 @@ void SheetEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::millisec
void SheetEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) void SheetEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
{ {
if (m_animations.contains(w)) { auto animationIt = m_animations.find(w);
if (animationIt != m_animations.end()) {
(*animationIt).timeLine.advance(presentTime);
data.setTransformed(); data.setTransformed();
} }

Loading…
Cancel
Save