Skip to content

Commit

Permalink
Merge pull request #291 from sirdoombox/main
Browse files Browse the repository at this point in the history
Implement software rendering fallback.
  • Loading branch information
sirdoombox authored Sep 12, 2024
2 parents 1f0de91 + 5aae409 commit 525e65f
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 4 deletions.
5 changes: 5 additions & 0 deletions SukiUI.Demo/Controls/LoadingTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ protected override void Render(SKCanvas canvas, SKRect rect)
}
canvas.Restore();
}

protected override void RenderSoftware(SKCanvas canvas, SKRect rect)
{
throw new System.NotImplementedException();
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions SukiUI.Demo/Features/Effects/ShaderToyRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ protected override void Render(SKCanvas canvas, SKRect rect)
}
canvas.Restore();
}

protected override void RenderSoftware(SKCanvas canvas, SKRect rect)
{
throw new System.NotImplementedException();
}
}
}
}
1 change: 1 addition & 0 deletions SukiUI.Demo/SukiUIDemoViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ private void ToggleWindowLock()
[RelayCommand]
private void ToggleTitleBar()
{
TitleBarVisible = !TitleBarVisible;
ToastManager.CreateSimpleInfoToast()
.WithTitle($"Title Bar {(TitleBarVisible ? "Visible" : "Hidden")}")
.WithContent($"Window title bar has been {(TitleBarVisible ? "shown" : "hidden")}.")
Expand Down
14 changes: 13 additions & 1 deletion SukiUI/Controls/SukiBackground.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ public double TransitionTime
get => GetValue(TransitionTimeProperty);
set => SetValue(TransitionTimeProperty, value);
}

public static readonly StyledProperty<bool> ForceSoftwareRenderingProperty = AvaloniaProperty.Register<SukiBackground, bool>(nameof(ForceSoftwareRendering));

public bool ForceSoftwareRendering
{
get => GetValue(ForceSoftwareRenderingProperty);
set => SetValue(ForceSoftwareRenderingProperty, value);
}

private readonly EffectBackgroundDraw _draw;
private readonly IDisposable _observables;
Expand All @@ -96,9 +104,13 @@ public SukiBackground()
{
IsHitTestVisible = false;
_draw = new EffectBackgroundDraw(new Rect(0, 0, Bounds.Width, Bounds.Height));
var forceSwRenderingObs = this.GetObservable(ForceSoftwareRenderingProperty)
.Do(enabled => _draw.ForceSoftwareRendering = enabled)
.Select(_ => Unit.Default);
var transEnabledObs = this.GetObservable(TransitionsEnabledProperty)
.Do(enabled => _draw.TransitionsEnabled = enabled)
.Select(_ => Unit.Default);
.Select(_ => Unit.Default)
.Merge(forceSwRenderingObs);
var transTime = this.GetObservable(TransitionTimeProperty)
.Do(time => _draw.TransitionTime = time)
.Select(_ => Unit.Default)
Expand Down
3 changes: 2 additions & 1 deletion SukiUI/Controls/SukiWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
ShaderFile="{TemplateBinding BackgroundShaderFile}"
Style="{TemplateBinding BackgroundStyle}"
TransitionTime="{TemplateBinding BackgroundTransitionTime}"
TransitionsEnabled="{TemplateBinding BackgroundTransitionsEnabled}" />
TransitionsEnabled="{TemplateBinding BackgroundTransitionsEnabled}"
ForceSoftwareRendering="{TemplateBinding BackgroundForceSoftwareRendering}"/>
<Panel Background="White"
IsVisible="{DynamicResource IsLight}"
Opacity="0.1" />
Expand Down
12 changes: 12 additions & 0 deletions SukiUI/Controls/SukiWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,18 @@ public double BackgroundTransitionTime
AvaloniaProperty.Register<SukiWindow, Avalonia.Controls.Controls>(nameof(RightWindowTitleBarControls),
defaultValue: new Avalonia.Controls.Controls());

public static readonly StyledProperty<bool> BackgroundForceSoftwareRenderingProperty = AvaloniaProperty.Register<SukiWindow, bool>(nameof(BackgroundForceSoftwareRendering));

/// <summary>
/// Forces the background of the window to utilise software rendering.
/// This prevents use of any advanced effects or animations and provides only a flat background colour that changes with the theme.
/// </summary>
public bool BackgroundForceSoftwareRendering
{
get => GetValue(BackgroundForceSoftwareRenderingProperty);
set => SetValue(BackgroundForceSoftwareRenderingProperty, value);
}

/// <summary>
/// Controls that are displayed on the right side of the title bar,
/// to the left of the normal window control buttons. (Displays provided controls right-to-left)
Expand Down
10 changes: 10 additions & 0 deletions SukiUI/Utilities/Effects/EffectBackgroundDraw.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Diagnostics;
using Avalonia;
using Avalonia.Skia;
using Avalonia.Styling;
using SkiaSharp;

namespace SukiUI.Utilities.Effects
Expand Down Expand Up @@ -61,6 +63,14 @@ protected override void Render(SKCanvas canvas, SKRect rect)
}
}

protected override void RenderSoftware(SKCanvas canvas, SKRect rect)
{
if (ActiveVariant == ThemeVariant.Dark)
canvas.Clear(ActiveTheme.Background.ToSKColor());
else
canvas.Clear(new SKColorF(0.95f, 0.95f, 0.95f, 1f));
}

private static double InverseLerp(double start, double end, double value) =>
Math.Max(0, Math.Min(1, (value - start) / (end - start)));
}
Expand Down
24 changes: 22 additions & 2 deletions SukiUI/Utilities/Effects/EffectDrawBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Avalonia.Skia;
using Avalonia.Styling;
using SkiaSharp;
using SukiUI.Models;

namespace SukiUI.Utilities.Effects
{
Expand Down Expand Up @@ -39,11 +40,15 @@ public bool AnimationEnabled
_animationEnabled = value;
}
}

public bool ForceSoftwareRendering { get; set; }

protected float AnimationSpeedScale { get; set; } = 0.1f;

protected ThemeVariant ActiveVariant { get; private set; }

protected SukiColorTheme ActiveTheme { get; private set; }

protected float AnimationSeconds => (float)_animationTick.Elapsed.TotalSeconds;

private readonly Stopwatch _animationTick = Stopwatch.StartNew();
Expand All @@ -53,18 +58,33 @@ protected EffectDrawBase(Rect bounds)
Bounds = bounds;
var sTheme = SukiTheme.GetInstance();
sTheme.OnBaseThemeChanged += v => ActiveVariant = v;
ActiveVariant = SukiTheme.GetInstance().ActiveBaseTheme;
ActiveVariant = sTheme.ActiveBaseTheme;
sTheme.OnColorThemeChanged += t => ActiveTheme = t;
ActiveTheme = sTheme.ActiveColorTheme!;

}

public void Render(ImmediateDrawingContext context)
{
var leaseFeature = context.TryGetFeature<ISkiaSharpApiLeaseFeature>();
if (leaseFeature is null) throw new InvalidOperationException("Unable to lease Skia API");
using var lease = leaseFeature.Lease();
Render(lease.SkCanvas, SKRect.Create((float)Bounds.Width, (float)Bounds.Height));
var rect = SKRect.Create((float)Bounds.Width, (float)Bounds.Height);
if(lease.GrContext is null || ForceSoftwareRendering) // GrContext is null whenever
RenderSoftware(lease.SkCanvas, rect);
else
Render(lease.SkCanvas, rect);
}

/// <summary>
/// Called every frame to render content.
/// </summary>
protected abstract void Render(SKCanvas canvas, SKRect rect);

/// <summary>
/// Called every frame whenever the app falls back to software rendering (or <see cref="ForceSoftwareRendering"/> is enabled)
/// </summary>
protected abstract void RenderSoftware(SKCanvas canvas, SKRect rect);

protected SKShader? EffectWithUniforms(float alpha = 1f) =>
EffectWithUniforms(Effect, alpha);
Expand Down

0 comments on commit 525e65f

Please sign in to comment.