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.
This commit is contained in:
Vlad Zahorodnii 2023-06-02 14:56:19 +03:00
parent e8904819b7
commit a43ffb8182
5 changed files with 16 additions and 47 deletions

View file

@ -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)
{
if (flag & AnimationEffect::Left) {
@ -514,13 +493,17 @@ void AnimationEffect::disconnectGeometryChanges()
void AnimationEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
{
Q_D(AnimationEffect);
AniMap::const_iterator entry = d->m_animations.constFind(w);
if (entry != d->m_animations.constEnd()) {
for (QList<AniData>::const_iterator anim = entry->first.constBegin(); anim != entry->first.constEnd(); ++anim) {
auto entry = d->m_animations.find(w);
if (entry != d->m_animations.end()) {
for (auto anim = entry->first.begin(); anim != entry->first.end(); ++anim) {
if (anim->startTime > clock() && !anim->waitAtSource) {
continue;
}
if (anim->frozenTime < 0) {
anim->timeLine.advance(presentTime);
}
if (anim->attribute == Opacity || anim->attribute == CrossFadePrevious) {
data.setTranslucent();
} else if (!(anim->attribute == Brightness || anim->attribute == Saturation)) {

View file

@ -322,7 +322,6 @@ public:
// Reimplemented from KWin::Effect.
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 paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
void postPaintScreen() override;

View file

@ -102,12 +102,6 @@ void GlideEffect::reconfigure(ReconfigureFlags flags)
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;
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)
{
if (m_animations.contains(w)) {
auto animationIt = m_animations.find(w);
if (animationIt != m_animations.end()) {
(*animationIt).timeLine.advance(presentTime);
data.setTransformed();
}

View file

@ -46,12 +46,6 @@ void MagicLampEffect::reconfigure(ReconfigureFlags)
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
// whole screen won't be repainted, resulting in artefacts.
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
// progress
if (m_animations.contains(w)) {
// We'll transform this window
auto animationIt = m_animations.find(w);
if (animationIt != m_animations.end()) {
(*animationIt).timeLine.advance(presentTime);
data.setTransformed();
}

View file

@ -74,12 +74,6 @@ void SheetEffect::reconfigure(ReconfigureFlags flags)
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;
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)
{
if (m_animations.contains(w)) {
auto animationIt = m_animations.find(w);
if (animationIt != m_animations.end()) {
(*animationIt).timeLine.advance(presentTime);
data.setTransformed();
}