diff --git a/autotests/integration/effects/translucency_test.cpp b/autotests/integration/effects/translucency_test.cpp --- a/autotests/integration/effects/translucency_test.cpp +++ b/autotests/integration/effects/translucency_test.cpp @@ -74,6 +74,7 @@ config->sync(); kwinApp()->setConfig(config); + qputenv("KWIN_EFFECTS_FORCE_ANIMATIONS", "1"); kwinApp()->start(); QVERIFY(workspaceCreatedSpy.wait()); QVERIFY(Compositor::self()); diff --git a/autotests/mock_effectshandler.h b/autotests/mock_effectshandler.h --- a/autotests/mock_effectshandler.h +++ b/autotests/mock_effectshandler.h @@ -229,5 +229,15 @@ KWayland::Server::Display *waylandDisplay() const override { return nullptr; } + + bool animationsSupported() const override { + return m_animationsSuported; + } + void setAnimationsSupported(bool set) { + m_animationsSuported = set; + } + +private: + bool m_animationsSuported = true; }; #endif diff --git a/autotests/test_builtin_effectloader.cpp b/autotests/test_builtin_effectloader.cpp --- a/autotests/test_builtin_effectloader.cpp +++ b/autotests/test_builtin_effectloader.cpp @@ -43,6 +43,11 @@ return nullptr; } +bool ScriptedEffect::supported() +{ + return true; +} + } class TestBuiltInEffectLoader : public QObject @@ -182,76 +187,87 @@ QTest::addColumn("name"); QTest::addColumn("expected"); QTest::addColumn("type"); + QTest::addColumn("animationsSupported"); const KWin::CompositingType xc = KWin::XRenderCompositing; const KWin::CompositingType oc = KWin::OpenGL2Compositing; - QTest::newRow("blur") << QStringLiteral("blur") << false << xc; + QTest::newRow("blur") << QStringLiteral("blur") << false << xc << true; // fails for GL as it does proper tests on what's supported and doesn't just check whether it's GL - QTest::newRow("blur-GL") << QStringLiteral("blur") << false << oc; - QTest::newRow("Contrast") << QStringLiteral("contrast") << false << xc; + QTest::newRow("blur-GL") << QStringLiteral("blur") << false << oc << true; + QTest::newRow("Contrast") << QStringLiteral("contrast") << false << xc << true; // fails for GL as it does proper tests on what's supported and doesn't just check whether it's GL - QTest::newRow("Contrast-GL") << QStringLiteral("contrast") << false << oc; - QTest::newRow("CoverSwitch") << QStringLiteral("coverswitch") << false << xc; - QTest::newRow("CoverSwitch-GL") << QStringLiteral("coverswitch") << true << oc; - QTest::newRow("Cube") << QStringLiteral("cube") << false << xc; - QTest::newRow("Cube-GL") << QStringLiteral("cube") << true << oc; - QTest::newRow("CubeSlide") << QStringLiteral("cubeslide") << false << xc; - QTest::newRow("CubeSlide-GL") << QStringLiteral("cubeslide") << true << oc; - QTest::newRow("DesktopGrid") << QStringLiteral("desktopgrid") << true << xc; - QTest::newRow("DimInactive") << QStringLiteral("diminactive") << true << xc; - QTest::newRow("DimScreen") << QStringLiteral("dimscreen") << true << xc; - QTest::newRow("FallApart") << QStringLiteral("fallapart") << false << xc; - QTest::newRow("FallApart-GL") << QStringLiteral("fallapart") << true << oc; - QTest::newRow("FlipSwitch") << QStringLiteral("flipswitch") << false << xc; - QTest::newRow("FlipSwitch-GL") << QStringLiteral("flipswitch") << true << oc; - QTest::newRow("Glide") << QStringLiteral("glide") << false << xc; - QTest::newRow("Glide-GL") << QStringLiteral("glide") << true << oc; - QTest::newRow("HighlightWindow") << QStringLiteral("highlightwindow") << true << xc; - QTest::newRow("Invert") << QStringLiteral("invert") << false << xc; - QTest::newRow("Invert-GL") << QStringLiteral("invert") << true << oc; - QTest::newRow("Kscreen") << QStringLiteral("kscreen") << true << xc; - QTest::newRow("Logout") << QStringLiteral("logout") << true << xc; - QTest::newRow("LookingGlass") << QStringLiteral("lookingglass") << false << xc; - QTest::newRow("LookingGlass-GL") << QStringLiteral("lookingglass") << true << oc; - QTest::newRow("MagicLamp") << QStringLiteral("magiclamp") << false << xc; - QTest::newRow("MagicLamp-GL") << QStringLiteral("magiclamp") << true << oc; - QTest::newRow("Magnifier") << QStringLiteral("magnifier") << true << xc; - QTest::newRow("MinimizeAnimation") << QStringLiteral("minimizeanimation") << true << xc; - QTest::newRow("MouseClick") << QStringLiteral("mouseclick") << true << xc; - QTest::newRow("MouseMark") << QStringLiteral("mousemark") << true << xc; - QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << true << xc; - QTest::newRow("Resize") << QStringLiteral("resize") << true << xc; - QTest::newRow("ScreenEdge") << QStringLiteral("screenedge") << true << xc; - QTest::newRow("ScreenShot") << QStringLiteral("screenshot") << true << xc; - QTest::newRow("Sheet") << QStringLiteral("sheet") << false << xc; - QTest::newRow("Sheet-GL") << QStringLiteral("sheet") << true << oc; - QTest::newRow("ShowFps") << QStringLiteral("showfps") << true << xc; - QTest::newRow("ShowPaint") << QStringLiteral("showpaint") << true << xc; - QTest::newRow("Slide") << QStringLiteral("slide") << true << xc; - QTest::newRow("SlideBack") << QStringLiteral("slideback") << true << xc; - QTest::newRow("SlidingPopups") << QStringLiteral("slidingpopups") << true << xc; - QTest::newRow("SnapHelper") << QStringLiteral("snaphelper") << true << xc; - QTest::newRow("StartupFeedback") << QStringLiteral("startupfeedback") << false << xc; - QTest::newRow("StartupFeedback-GL") << QStringLiteral("startupfeedback") << true << oc; - QTest::newRow("ThumbnailAside") << QStringLiteral("thumbnailaside") << true << xc; - QTest::newRow("TrackMouse") << QStringLiteral("trackmouse") << true << xc; - QTest::newRow("WindowGeometry") << QStringLiteral("windowgeometry") << true << xc; - QTest::newRow("WobblyWindows") << QStringLiteral("wobblywindows") << false << xc; - QTest::newRow("WobblyWindows-GL") << QStringLiteral("wobblywindows") << true << oc; - QTest::newRow("Zoom") << QStringLiteral("zoom") << true << xc; - QTest::newRow("Non Existing") << QStringLiteral("InvalidName") << false << xc; - QTest::newRow("Fade - Scripted") << QStringLiteral("fade") << false << xc; - QTest::newRow("Fade - Scripted + kwin4_effect") << QStringLiteral("kwin4_effect_fade") << false << xc; + QTest::newRow("Contrast-GL") << QStringLiteral("contrast") << false << oc << true; + QTest::newRow("CoverSwitch") << QStringLiteral("coverswitch") << false << xc << true; + QTest::newRow("CoverSwitch-GL") << QStringLiteral("coverswitch") << true << oc << true; + QTest::newRow("CoverSwitch-GL-no-anim") << QStringLiteral("coverswitch") << false << oc << false; + QTest::newRow("Cube") << QStringLiteral("cube") << false << xc << true; + QTest::newRow("Cube-GL") << QStringLiteral("cube") << true << oc << true; + QTest::newRow("CubeSlide") << QStringLiteral("cubeslide") << false << xc << true; + QTest::newRow("CubeSlide-GL") << QStringLiteral("cubeslide") << true << oc << true; + QTest::newRow("CubeSlide-GL-no-anim") << QStringLiteral("cubeslide") << false << oc << false; + QTest::newRow("DesktopGrid") << QStringLiteral("desktopgrid") << true << xc << true; + QTest::newRow("DimInactive") << QStringLiteral("diminactive") << true << xc << true; + QTest::newRow("DimScreen") << QStringLiteral("dimscreen") << true << xc << true; + QTest::newRow("FallApart") << QStringLiteral("fallapart") << false << xc << true; + QTest::newRow("FallApart-GL") << QStringLiteral("fallapart") << true << oc << true; + QTest::newRow("FlipSwitch") << QStringLiteral("flipswitch") << false << xc << true; + QTest::newRow("FlipSwitch-GL") << QStringLiteral("flipswitch") << true << oc << true; + QTest::newRow("FlipSwitch-GL-no-anim") << QStringLiteral("flipswitch") << false << oc << false; + QTest::newRow("Glide") << QStringLiteral("glide") << false << xc << true; + QTest::newRow("Glide-GL") << QStringLiteral("glide") << true << oc << true; + QTest::newRow("Glide-GL-no-anim") << QStringLiteral("glide") << false << oc << false; + QTest::newRow("HighlightWindow") << QStringLiteral("highlightwindow") << true << xc << true; + QTest::newRow("Invert") << QStringLiteral("invert") << false << xc << true; + QTest::newRow("Invert-GL") << QStringLiteral("invert") << true << oc << true; + QTest::newRow("Kscreen") << QStringLiteral("kscreen") << true << xc << true; + QTest::newRow("Logout") << QStringLiteral("logout") << true << xc << true; + QTest::newRow("LookingGlass") << QStringLiteral("lookingglass") << false << xc << true; + QTest::newRow("LookingGlass-GL") << QStringLiteral("lookingglass") << true << oc << true; + QTest::newRow("MagicLamp") << QStringLiteral("magiclamp") << false << xc << true; + QTest::newRow("MagicLamp-GL") << QStringLiteral("magiclamp") << true << oc << true; + QTest::newRow("MagicLamp-GL-no-anim") << QStringLiteral("magiclamp") << false << oc << false; + QTest::newRow("Magnifier") << QStringLiteral("magnifier") << true << xc << true; + QTest::newRow("MinimizeAnimation") << QStringLiteral("minimizeanimation") << true << xc << true; + QTest::newRow("MouseClick") << QStringLiteral("mouseclick") << true << xc << true; + QTest::newRow("MouseMark") << QStringLiteral("mousemark") << true << xc << true; + QTest::newRow("PresentWindows") << QStringLiteral("presentwindows") << true << xc << true; + QTest::newRow("Resize") << QStringLiteral("resize") << true << xc << true; + QTest::newRow("ScreenEdge") << QStringLiteral("screenedge") << true << xc << true; + QTest::newRow("ScreenShot") << QStringLiteral("screenshot") << true << xc << true; + QTest::newRow("Sheet") << QStringLiteral("sheet") << false << xc << true; + QTest::newRow("Sheet-GL") << QStringLiteral("sheet") << true << oc << true; + QTest::newRow("Sheet-GL-no-anim") << QStringLiteral("sheet") << false << oc << false; + QTest::newRow("ShowFps") << QStringLiteral("showfps") << true << xc << true; + QTest::newRow("ShowPaint") << QStringLiteral("showpaint") << true << xc << true; + QTest::newRow("Slide") << QStringLiteral("slide") << true << xc << true; + QTest::newRow("SlideBack") << QStringLiteral("slideback") << true << xc << true; + QTest::newRow("SlidingPopups") << QStringLiteral("slidingpopups") << true << xc << true; + QTest::newRow("SnapHelper") << QStringLiteral("snaphelper") << true << xc << true; + QTest::newRow("StartupFeedback") << QStringLiteral("startupfeedback") << false << xc << true; + QTest::newRow("StartupFeedback-GL") << QStringLiteral("startupfeedback") << true << oc << true; + QTest::newRow("ThumbnailAside") << QStringLiteral("thumbnailaside") << true << xc << true; + QTest::newRow("TrackMouse") << QStringLiteral("trackmouse") << true << xc << true; + QTest::newRow("WindowGeometry") << QStringLiteral("windowgeometry") << true << xc << true; + QTest::newRow("WobblyWindows") << QStringLiteral("wobblywindows") << false << xc << true; + QTest::newRow("WobblyWindows-GL") << QStringLiteral("wobblywindows") << true << oc << true; + QTest::newRow("WobblyWindows-GL-no-anim") << QStringLiteral("wobblywindows") << false << oc << false; + QTest::newRow("Zoom") << QStringLiteral("zoom") << true << xc << true; + QTest::newRow("Non Existing") << QStringLiteral("InvalidName") << false << xc << true; + QTest::newRow("Fade - Scripted") << QStringLiteral("fade") << false << xc << true; + QTest::newRow("Fade - Scripted + kwin4_effect") << QStringLiteral("kwin4_effect_fade") << false << xc << true; } void TestBuiltInEffectLoader::testSupported() { QFETCH(QString, name); QFETCH(bool, expected); QFETCH(KWin::CompositingType, type); + QFETCH(bool, animationsSupported); MockEffectsHandler mockHandler(type); + mockHandler.setAnimationsSupported(animationsSupported); + QCOMPARE(mockHandler.animationsSupported(), animationsSupported); KWin::BuiltInEffectLoader loader; QCOMPARE(loader.isEffectSupported(name), expected); } diff --git a/autotests/test_plugin_effectloader.cpp b/autotests/test_plugin_effectloader.cpp --- a/autotests/test_plugin_effectloader.cpp +++ b/autotests/test_plugin_effectloader.cpp @@ -42,6 +42,11 @@ return nullptr; } +bool ScriptedEffect::supported() +{ + return true; +} + } class TestPluginEffectLoader : public QObject diff --git a/autotests/test_scripted_effectloader.cpp b/autotests/test_scripted_effectloader.cpp --- a/autotests/test_scripted_effectloader.cpp +++ b/autotests/test_scripted_effectloader.cpp @@ -136,11 +136,17 @@ QFETCH(QString, name); QFETCH(bool, expected); + MockEffectsHandler mockHandler(KWin::XRenderCompositing); KWin::ScriptedEffectLoader loader; QCOMPARE(loader.hasEffect(name), expected); // each available effect should also be supported QCOMPARE(loader.isEffectSupported(name), expected); + + if (expected) { + mockHandler.setAnimationsSupported(false); + QVERIFY(!loader.isEffectSupported(name)); + } } void TestScriptedEffectLoader::testKnownEffects() diff --git a/effectloader.cpp b/effectloader.cpp --- a/effectloader.cpp +++ b/effectloader.cpp @@ -205,6 +205,9 @@ bool ScriptedEffectLoader::isEffectSupported(const QString &name) const { // scripted effects are in general supported + if (!ScriptedEffect::supported()) { + return false; + } return hasEffect(name); } @@ -239,6 +242,11 @@ return false; } + if (!ScriptedEffect::supported()) { + qCDebug(KWIN_CORE) << "Effect is not supported: " << name; + return false; + } + ScriptedEffect *e = ScriptedEffect::create(effect); if (!e) { qCDebug(KWIN_CORE) << "Could not initialize scripted effect: " << name; diff --git a/effects.h b/effects.h --- a/effects.h +++ b/effects.h @@ -226,6 +226,8 @@ KWayland::Server::Display *waylandDisplay() const override; + bool animationsSupported() const override; + Scene *scene() const { return m_scene; } diff --git a/effects.cpp b/effects.cpp --- a/effects.cpp +++ b/effects.cpp @@ -1505,6 +1505,16 @@ m_scene->doneOpenGLContextCurrent(); } +bool EffectsHandlerImpl::animationsSupported() const +{ + static const QByteArray forceEnvVar = qgetenv("KWIN_EFFECTS_FORCE_ANIMATIONS"); + if (!forceEnvVar.isEmpty()) { + static const int forceValue = forceEnvVar.toInt(); + return forceValue == 1; + } + return m_scene->animationsSupported(); +} + //**************************************** // EffectWindowImpl //**************************************** diff --git a/effects/coverswitch/coverswitch.cpp b/effects/coverswitch/coverswitch.cpp --- a/effects/coverswitch/coverswitch.cpp +++ b/effects/coverswitch/coverswitch.cpp @@ -80,7 +80,7 @@ bool CoverSwitchEffect::supported() { - return effects->isOpenGLCompositing(); + return effects->isOpenGLCompositing() && effects->animationsSupported(); } void CoverSwitchEffect::reconfigure(ReconfigureFlags) diff --git a/effects/cube/cubeslide.cpp b/effects/cube/cubeslide.cpp --- a/effects/cube/cubeslide.cpp +++ b/effects/cube/cubeslide.cpp @@ -49,7 +49,7 @@ bool CubeSlideEffect::supported() { - return effects->isOpenGLCompositing(); + return effects->isOpenGLCompositing() && effects->animationsSupported(); } void CubeSlideEffect::reconfigure(ReconfigureFlags) diff --git a/effects/fallapart/fallapart.cpp b/effects/fallapart/fallapart.cpp --- a/effects/fallapart/fallapart.cpp +++ b/effects/fallapart/fallapart.cpp @@ -28,7 +28,7 @@ bool FallApartEffect::supported() { - return effects->isOpenGLCompositing(); + return effects->isOpenGLCompositing() && effects->animationsSupported(); } FallApartEffect::FallApartEffect() diff --git a/effects/flipswitch/flipswitch.cpp b/effects/flipswitch/flipswitch.cpp --- a/effects/flipswitch/flipswitch.cpp +++ b/effects/flipswitch/flipswitch.cpp @@ -83,7 +83,7 @@ bool FlipSwitchEffect::supported() { - return effects->isOpenGLCompositing(); + return effects->isOpenGLCompositing() && effects->animationsSupported(); } void FlipSwitchEffect::reconfigure(ReconfigureFlags) diff --git a/effects/glide/glide.cpp b/effects/glide/glide.cpp --- a/effects/glide/glide.cpp +++ b/effects/glide/glide.cpp @@ -55,7 +55,7 @@ bool GlideEffect::supported() { - return effects->isOpenGLCompositing(); + return effects->isOpenGLCompositing() && effects->animationsSupported(); } void GlideEffect::reconfigure(ReconfigureFlags) diff --git a/effects/magiclamp/magiclamp.cpp b/effects/magiclamp/magiclamp.cpp --- a/effects/magiclamp/magiclamp.cpp +++ b/effects/magiclamp/magiclamp.cpp @@ -43,7 +43,7 @@ bool MagicLampEffect::supported() { - return effects->isOpenGLCompositing(); + return effects->isOpenGLCompositing() && effects->animationsSupported(); } void MagicLampEffect::reconfigure(ReconfigureFlags) diff --git a/effects/sheet/sheet.cpp b/effects/sheet/sheet.cpp --- a/effects/sheet/sheet.cpp +++ b/effects/sheet/sheet.cpp @@ -43,7 +43,7 @@ bool SheetEffect::supported() { - return effects->isOpenGLCompositing(); + return effects->isOpenGLCompositing() && effects->animationsSupported(); } void SheetEffect::reconfigure(ReconfigureFlags) diff --git a/effects/wobblywindows/wobblywindows.cpp b/effects/wobblywindows/wobblywindows.cpp --- a/effects/wobblywindows/wobblywindows.cpp +++ b/effects/wobblywindows/wobblywindows.cpp @@ -222,7 +222,7 @@ bool WobblyWindowsEffect::supported() { - return effects->isOpenGLCompositing(); + return effects->isOpenGLCompositing() && effects->animationsSupported(); } void WobblyWindowsEffect::setParameterSet(const ParameterSet& pset) diff --git a/libkwineffects/CMakeLists.txt b/libkwineffects/CMakeLists.txt --- a/libkwineffects/CMakeLists.txt +++ b/libkwineffects/CMakeLists.txt @@ -5,7 +5,7 @@ VARIABLE_PREFIX KWINEFFECTS VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kwineffects_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KWinEffectsConfigVersion.cmake" - SOVERSION 8 + SOVERSION 9 ) ### xrenderutils lib ### diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -1102,6 +1102,16 @@ virtual KWayland::Server::Display *waylandDisplay() const = 0; /** + * Whether animations are supported by the Scene. + * If this method returns @c false Effects are supposed to not + * animate transitions. + * + * @returns Whether the Scene can drive animations + * @since 5.8 + **/ + virtual bool animationsSupported() const = 0; + + /** * @return @ref KConfigGroup which holds given effect's config options **/ static KConfigGroup effectConfig(const QString& effectname); diff --git a/scene.h b/scene.h --- a/scene.h +++ b/scene.h @@ -149,6 +149,14 @@ virtual Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *) = 0; + /** + * Whether the Scene is able to drive animations. + * This is used as a hint to the effects system which effects can be supported. + * If the Scene performs software rendering it is supposed to return @c false, + * if rendering is hardware accelerated it should return @c true. + **/ + virtual bool animationsSupported() const = 0; + Q_SIGNALS: void frameRendered(); diff --git a/scene_opengl.h b/scene_opengl.h --- a/scene_opengl.h +++ b/scene_opengl.h @@ -63,6 +63,7 @@ Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override; virtual void triggerFence() override; virtual QMatrix4x4 projectionMatrix() const = 0; + bool animationsSupported() const override; void insertWait(); diff --git a/scene_opengl.cpp b/scene_opengl.cpp --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -956,6 +956,11 @@ return new SceneOpenGLDecorationRenderer(impl); } +bool SceneOpenGL::animationsSupported() const +{ + return !GLPlatform::instance()->isSoftwareEmulation(); +} + //**************************************** // SceneOpenGL2 //**************************************** diff --git a/scene_qpainter.h b/scene_qpainter.h --- a/scene_qpainter.h +++ b/scene_qpainter.h @@ -119,6 +119,10 @@ Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override; void screenGeometryChanged(const QSize &size) override; + bool animationsSupported() const override { + return false; + } + QPainter *painter(); QPainterBackend *backend() const { diff --git a/scene_xrender.h b/scene_xrender.h --- a/scene_xrender.h +++ b/scene_xrender.h @@ -169,6 +169,10 @@ } Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *client); + bool animationsSupported() const override { + return true; + } + static SceneXrender *createScene(QObject *parent); protected: virtual Scene::Window *createWindow(Toplevel *toplevel); diff --git a/scripting/scriptedeffect.h b/scripting/scriptedeffect.h --- a/scripting/scriptedeffect.h +++ b/scripting/scriptedeffect.h @@ -67,6 +67,7 @@ void setActiveConfig(const QString &name); static ScriptedEffect *create(const QString &effectName, const QString &pathToScript, int chainPosition); static ScriptedEffect *create(const KPluginMetaData &effect); + static bool supported(); virtual ~ScriptedEffect(); /** * Whether another effect has grabbed the @p w with the given @p grabRole. diff --git a/scripting/scriptedeffect.cpp b/scripting/scriptedeffect.cpp --- a/scripting/scriptedeffect.cpp +++ b/scripting/scriptedeffect.cpp @@ -450,6 +450,11 @@ return effect; } +bool ScriptedEffect::supported() +{ + return effects->animationsSupported(); +} + ScriptedEffect::ScriptedEffect() : AnimationEffect() , m_engine(new QScriptEngine(this))