Skip to content

Commit 5336791

Browse files
committed
Improve FluidBackgroundRenderer
1 parent 84f11e2 commit 5336791

2 files changed

Lines changed: 75 additions & 15 deletions

File tree

dev/DevWinUI.Shader/Renderers/Fluid/FluidBackgroundRenderer.Properties.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public partial class FluidBackgroundRenderer
88
{
99
private bool isFluidOverlayLightWaveEnabled = false;
1010
private bool isColorDitheringEnabled = true;
11+
public bool isStatic { get; set; } = false;
1112
private double fluidOverlayOpacity = 100.0;
1213
private Color fluidAccentColor1 = Colors.Blue;
1314
private Color fluidAccentColor2 = Colors.AliceBlue;
@@ -44,6 +45,21 @@ private static void OnIsColorDitheringEnabledChanged(DependencyObject d, Depende
4445
ctl.isColorDitheringEnabled = (bool)e.NewValue;
4546
}
4647

48+
public bool IsStatic
49+
{
50+
get { return (bool)GetValue(IsStaticProperty); }
51+
set { SetValue(IsStaticProperty, value); }
52+
}
53+
54+
public static readonly DependencyProperty IsStaticProperty =
55+
DependencyProperty.Register(nameof(IsStatic), typeof(bool), typeof(FluidBackgroundRenderer), new PropertyMetadata(false, OnIsStaticChanged));
56+
57+
private static void OnIsStaticChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
58+
{
59+
var ctl = (FluidBackgroundRenderer)d;
60+
ctl.isStatic = (bool)e.NewValue;
61+
}
62+
4763
public double Opacity
4864
{
4965
get { return (double)GetValue(OpacityProperty); }

dev/DevWinUI.Shader/Renderers/Fluid/FluidBackgroundRenderer.cs

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
using ComputeSharp.D2D1.WinUI;
1+
using System.Numerics;
2+
using ComputeSharp.D2D1.WinUI;
23
using Microsoft.Graphics.Canvas;
34
using Microsoft.Graphics.Canvas.Effects;
45
using Microsoft.Graphics.Canvas.UI;
56
using Microsoft.Graphics.Canvas.UI.Xaml;
67
using Microsoft.UI;
7-
using System.Numerics;
88
using Windows.UI;
99

1010
namespace DevWinUI;
@@ -38,6 +38,7 @@ public partial class FluidBackgroundRenderer : RendererBase
3838
private float3 _c1 = float3.Zero, _c2 = float3.Zero, _c3 = float3.Zero, _c4 = float3.Zero;
3939
private float _rnd1 = 0, _rnd2 = 0, _rnd3 = 0;
4040
private bool useHSVBlending = false;
41+
private CanvasRenderTarget? _cachedRenderTarget;
4142
public override void OnApplyTemplate()
4243
{
4344
UpdatePalette();
@@ -70,9 +71,11 @@ public override void Update(ICanvasAnimatedControl sender, CanvasAnimatedUpdateE
7071
_c4 = new float3(v4.X, v4.Y, v4.Z);
7172

7273
UpdateBreathing(currentBassEnergy, breathingIntensity);
73-
7474

75-
_timeAccumulator += (float)elapsedTime.TotalSeconds;
75+
if (!IsStatic)
76+
{
77+
_timeAccumulator += (float)elapsedTime.TotalSeconds;
78+
}
7679
}
7780

7881
public override void Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
@@ -86,29 +89,55 @@ public override void Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEvent
8689
float width = sender.ConvertDipsToPixels((float)sender.Size.Width, CanvasDpiRounding.Round);
8790
float height = sender.ConvertDipsToPixels((float)sender.Size.Height, CanvasDpiRounding.Round);
8891

89-
_fluidEffect.ConstantBuffer = new FluidBackgroundShader(
90-
new float2(width, height),
91-
_timeAccumulator,
92-
_c1, _c2, _c3, _c4,
93-
_rnd1, _rnd2, _rnd3,
94-
useHSVBlending,
95-
isFluidOverlayLightWaveEnabled,
96-
isColorDitheringEnabled
97-
);
92+
ICanvasImage? sourceToDraw;
93+
94+
if (IsStatic)
95+
{
96+
bool needsUpdateCache = _cachedRenderTarget == null ||
97+
_cachedRenderTarget.Size.Width != sender.Size.Width ||
98+
_cachedRenderTarget.Size.Height != sender.Size.Height;
99+
100+
if (needsUpdateCache)
101+
{
102+
UpdateShaderConstantBuffer(width, height);
103+
104+
_cachedRenderTarget?.Dispose();
105+
_cachedRenderTarget = new CanvasRenderTarget(sender, (float)sender.Size.Width, (float)sender.Size.Height, sender.Dpi);
106+
107+
using (var cacheDs = _cachedRenderTarget.CreateDrawingSession())
108+
{
109+
cacheDs.Clear(Colors.Transparent);
110+
cacheDs.DrawImage(_fluidEffect);
111+
}
112+
}
113+
114+
sourceToDraw = _cachedRenderTarget;
115+
}
116+
else
117+
{
118+
if (_cachedRenderTarget != null)
119+
{
120+
_cachedRenderTarget.Dispose();
121+
_cachedRenderTarget = null;
122+
}
123+
124+
UpdateShaderConstantBuffer(width, height);
125+
sourceToDraw = _fluidEffect;
126+
}
98127

99128
var center = new Vector2((float)sender.Size.Width / 2, (float)sender.Size.Height / 2);
100129

101130
ApplyBreathingTransform(ds, center, isBreathingEffectEnabled);
102131

103132
if (currentOpacity >= 1.0)
104133
{
105-
ds.DrawImage(_fluidEffect);
134+
ds.DrawImage(sourceToDraw);
106135
}
107136
else
108137
{
109138
using var opacityEffect = new OpacityEffect
110139
{
111-
Source = _fluidEffect,
140+
Source = sourceToDraw,
112141
Opacity = (float)currentOpacity
113142
};
114143
ds.DrawImage(opacityEffect);
@@ -117,10 +146,25 @@ public override void Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEvent
117146
ResetTransform(ds, isBreathingEffectEnabled);
118147
}
119148

149+
private void UpdateShaderConstantBuffer(float width, float height)
150+
{
151+
_fluidEffect!.ConstantBuffer = new FluidBackgroundShader(
152+
new float2(width, height),
153+
_timeAccumulator,
154+
_c1, _c2, _c3, _c4,
155+
_rnd1, _rnd2, _rnd3,
156+
useHSVBlending,
157+
isFluidOverlayLightWaveEnabled,
158+
isColorDitheringEnabled
159+
);
160+
}
161+
120162
public override void Dispose()
121163
{
122164
_fluidEffect?.Dispose();
123165
_fluidEffect = null;
166+
_cachedRenderTarget?.Dispose();
167+
_cachedRenderTarget = null;
124168
}
125169

126170
private void UpdatePalette()

0 commit comments

Comments
 (0)