diff --git a/Modules/Background/Background.qml b/Modules/Background/Background.qml index e009d718e..88aab5ad9 100644 --- a/Modules/Background/Background.qml +++ b/Modules/Background/Background.qml @@ -123,7 +123,7 @@ Variants { smooth: true mipmap: false visible: false - cache: false + cache: true // Cached so Overview can share the same texture asynchronous: true onStatusChanged: { if (status === Image.Error) { @@ -141,7 +141,7 @@ Variants { smooth: true mipmap: false visible: false - cache: false + cache: false // Not cached - temporary during transitions asynchronous: true onStatusChanged: { if (status === Image.Error) { diff --git a/Modules/Background/Overview.qml b/Modules/Background/Overview.qml index b49ef4a96..b943ecb30 100644 --- a/Modules/Background/Overview.qml +++ b/Modules/Background/Overview.qml @@ -17,20 +17,15 @@ Loader { required property ShellScreen modelData property string wallpaper: "" - property string preprocessedWallpaper: "" // Pre-resized wallpaper from Background.qml for blur optimization - property string cachedWallpaper: "" - property string pendingWallpaper: "" + property string preprocessedWallpaper: "" // Pre-resized wallpaper from Background.qml property bool isSolidColor: false - property bool useQtBlur: false // Fallback when ImageMagick not available property color solidColor: Settings.data.wallpaper.solidColor - // Watch the actual tint color value, not just darkMode setting, since colors reload asynchronously property color tintColor: Settings.data.colorSchemes.darkMode ? Color.mSurface : Color.mOnSurface Component.onCompleted: { if (modelData) { Logger.d("Overview", "Loading overview for Niri on", modelData.name); } - setWallpaperInitial(); } Component.onDestruction: { @@ -38,65 +33,18 @@ Loader { } // External state management - wait for wallpaper processing to complete - // before starting blur, to avoid CPU contention on slower systems + // Reuses the same cached image as Background.qml for memory efficiency + GPU blur Connections { target: WallpaperService function onWallpaperProcessingComplete(screenName, path, cachedPath) { if (screenName === modelData.name) { - // Use pre-resized image for blur optimization (avoids re-reading/resizing 4K images) preprocessedWallpaper = cachedPath || ""; wallpaper = path; } } } - function setWallpaperInitial() { - // Overview now receives the initial wallpaper via wallpaperProcessingComplete signal - // from Background.qml, ensuring blur only starts after main wallpaper is processed. - // No direct wallpaper assignment needed here. - } - - function requestBlurredOverview() { - requestBlurredOverviewWithTint(tintColor.toString(), Settings.data.colorSchemes.darkMode); - } - - function requestBlurredOverviewWithTint(tint, isDarkMode) { - if (!wallpaper || isSolidColor) - return; - - const compositorScale = CompositorService.getDisplayScale(modelData.name); - const targetWidth = Math.round(modelData.width * compositorScale); - const targetHeight = Math.round(modelData.height * compositorScale); - - // Start fade out, then request new image - if (cachedWallpaper) { - fadeOutAnim.start(); - } - - // Use pre-resized image if available (optimization: avoids re-reading/resizing large images) - const sourceImage = preprocessedWallpaper || wallpaper; - - ImageCacheService.getBlurredOverview(sourceImage, targetWidth, targetHeight, tint, isDarkMode, function (path, success) { - if (path) { - useQtBlur = !success; // Use Qt blur fallback if ImageMagick failed - pendingWallpaper = path; - // If fade out is done or wasn't needed, apply immediately - if (!fadeOutAnim.running) { - applyPendingWallpaper(); - } - } - }); - } - - function applyPendingWallpaper() { - if (pendingWallpaper) { - cachedWallpaper = pendingWallpaper; - pendingWallpaper = ""; - fadeInAnim.start(); - } - } - - // Request cached wallpaper when source changes + // Handle wallpaper changes (solid color detection) onWallpaperChanged: { if (!wallpaper) return; @@ -106,27 +54,10 @@ Loader { isSolidColor = true; var colorStr = WallpaperService.getSolidColor(wallpaper); solidColor = colorStr; - cachedWallpaper = ""; return; } isSolidColor = false; - requestBlurredOverview(); - } - - // Watch for color reloads - use the actual Color properties directly to avoid stale values - Connections { - target: Color - function onMSurfaceChanged() { - if (!isSolidColor && wallpaper && Settings.data.colorSchemes.darkMode) { - requestBlurredOverviewWithTint(Color.mSurface.toString(), true); - } - } - function onMOnSurfaceChanged() { - if (!isSolidColor && wallpaper && !Settings.data.colorSchemes.darkMode) { - requestBlurredOverviewWithTint(Color.mOnSurface.toString(), false); - } - } } color: "transparent" @@ -154,20 +85,19 @@ Loader { } } - // Image background (pre-blurred and tinted by ImageMagick, or Qt fallback) + // Image background with GPU-based blur Image { id: bgImage anchors.fill: parent visible: !isSolidColor fillMode: Image.PreserveAspectCrop - source: cachedWallpaper + source: preprocessedWallpaper || wallpaper smooth: true mipmap: false - cache: false + cache: true // Shares texture with Background's currentWallpaper asynchronous: true - // Qt blur fallback when ImageMagick not available - layer.enabled: useQtBlur + layer.enabled: true layer.smooth: false layer.effect: MultiEffect { blurEnabled: true @@ -175,32 +105,12 @@ Loader { blurMax: 32 } - // Tint overlay for Qt blur fallback + // Tint overlay Rectangle { anchors.fill: parent - visible: useQtBlur color: tintColor opacity: 0.6 } - - NumberAnimation on opacity { - id: fadeOutAnim - running: false - from: 1 - to: 0 - duration: 200 - easing.type: Easing.OutQuad - onFinished: applyPendingWallpaper() - } - - NumberAnimation on opacity { - id: fadeInAnim - running: false - from: 0 - to: 1 - duration: 200 - easing.type: Easing.InQuad - } } } }