Skip to content

Commit

Permalink
Acrylic noise DPI scaling bug fixed, new custom DPI option added
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Jul 15, 2017
1 parent bd5e337 commit bdf6cdc
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 24,631 deletions.
6 changes: 3 additions & 3 deletions UICompositionAnimations/Behaviours/AcrylicEffectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static async Task<IGraphicsEffect> ConcatenateEffectWithTintAndBorderAsyn
[NotNull] Compositor compositor,
[NotNull] IGraphicsEffectSource source, [NotNull] IDictionary<String, CompositionBrush> parameters,
Color color, float colorMix,
[CanBeNull] CanvasControl canvas, [NotNull] Uri uri, CacheLoadingMode options)
[CanBeNull] CanvasControl canvas, [NotNull] Uri uri, BitmapCacheMode options)
{
// Setup the tint effect
ArithmeticCompositeEffect tint = new ArithmeticCompositeEffect
Expand All @@ -50,8 +50,8 @@ public static async Task<IGraphicsEffect> ConcatenateEffectWithTintAndBorderAsyn

// Get the noise brush using Win2D
CompositionSurfaceBrush noiseBitmap = canvas == null
? await Win2DImageHelper.LoadImageAsync(compositor, uri, options)
: await Win2DImageHelper.LoadImageAsync(compositor, canvas, uri, options);
? await Win2DImageHelper.LoadImageAsync(compositor, uri, options, BitmapDPIMode.CopyDisplayDPISettingsWith96AsLowerBound)
: await Win2DImageHelper.LoadImageAsync(compositor, canvas, uri, options, BitmapDPIMode.CopyDisplayDPISettingsWith96AsLowerBound);

// Make sure the Win2D brush was loaded correctly
if (noiseBitmap != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public static async ValueTask<AttachedStaticCompositionEffect<T>> AttachComposit
public static async Task<AttachedStaticCompositionEffect<T>> AttachCompositionInAppCustomAcrylicEffectAsync<TSource, T>(
[NotNull] this TSource element, [NotNull] T target, float blur, int ms, Color color, float colorMix, float? saturation,
[CanBeNull] CanvasControl canvas, [NotNull] Uri uri,
CacheLoadingMode options = CacheLoadingMode.EnableCaching, bool fadeIn = false, bool disposeOnUnload = false)
BitmapCacheMode options = BitmapCacheMode.EnableCaching, bool fadeIn = false, bool disposeOnUnload = false)
where TSource : FrameworkElement
where T : FrameworkElement
{
Expand Down Expand Up @@ -213,7 +213,7 @@ public static async ValueTask<AttachedStaticCompositionEffect<T>> AttachComposit
[ItemNotNull]
public static async Task<AttachedStaticCompositionEffect<T>> AttachCompositionCustomAcrylicEffectAsync<T>(
[NotNull] this T element, Color color, float colorMix,
[CanBeNull] CanvasControl canvas, [NotNull] Uri uri, CacheLoadingMode options = CacheLoadingMode.EnableCaching, bool disposeOnUnload = false)
[CanBeNull] CanvasControl canvas, [NotNull] Uri uri, BitmapCacheMode options = BitmapCacheMode.EnableCaching, bool disposeOnUnload = false)
where T : FrameworkElement
{
// Percentage check
Expand Down Expand Up @@ -289,7 +289,7 @@ public static async Task<AttachedStaticCompositionEffect<T>> AttachCompositionCu
public static async Task<AttachedToggleAcrylicEffect<T>> AttachCompositionCustomAcrylicToggleEffectAsync<T>(
[NotNull] this T element, Color color, float inAppColorMix, float hostColorMix,
AcrylicEffectMode mode, float blur, int ms,
[CanBeNull] CanvasControl canvas, [NotNull] Uri uri, CacheLoadingMode options = CacheLoadingMode.EnableCaching, bool disposeOnUnload = false)
[CanBeNull] CanvasControl canvas, [NotNull] Uri uri, BitmapCacheMode options = BitmapCacheMode.EnableCaching, bool disposeOnUnload = false)
where T : FrameworkElement
{
// Percentage check
Expand Down Expand Up @@ -511,7 +511,7 @@ public static async Task<AttachedAnimatableCompositionEffect<T>> AttachCompositi
[NotNull] this TSource element, [NotNull] T target,
float on, float off, bool initiallyVisible,
Color color, float colorMix, [CanBeNull] CanvasControl canvas, [NotNull] Uri uri,
CacheLoadingMode options = CacheLoadingMode.EnableCaching, bool disposeOnUnload = false)
BitmapCacheMode options = BitmapCacheMode.EnableCaching, bool disposeOnUnload = false)
where TSource : FrameworkElement
where T : FrameworkElement
{
Expand Down Expand Up @@ -584,7 +584,7 @@ public static async Task<AttachedCompositeAnimatableCompositionEffect<T>> Attach
float onSaturation, float offSaturation,
bool initiallyVisible,
Color color, float colorMix, [CanBeNull] CanvasControl canvas, [NotNull] Uri uri,
CacheLoadingMode options = CacheLoadingMode.EnableCaching, bool disposeOnUnload = false)
BitmapCacheMode options = BitmapCacheMode.EnableCaching, bool disposeOnUnload = false)
where TSource : FrameworkElement
where T : FrameworkElement
{
Expand Down
2 changes: 1 addition & 1 deletion UICompositionAnimations/Brushes/CustomAcrylicBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ private static async void OnUnsupportedEffectFallbackColorPropertyChanged(Depend
/// <summary>
/// Gets or sets the caching setting for the acrylic brush
/// </summary>
public CacheLoadingMode CacheMode { get; set; } = CacheLoadingMode.EnableCaching;
public BitmapCacheMode CacheMode { get; set; } = BitmapCacheMode.EnableCaching;

#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// <summary>
/// Indicates the cache mode to use when loading an item
/// </summary>
public enum CacheLoadingMode
public enum BitmapCacheMode
{
/// <summary>
/// The new item will be either loaded from the cache when possible, or saved in the cache for future use
Expand Down
28 changes: 28 additions & 0 deletions UICompositionAnimations/Enums/BitmapDPIMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace UICompositionAnimations.Enums
{
/// <summary>
/// Indicates the DPI mode to use to load an image
/// </summary>
public enum BitmapDPIMode
{
/// <summary>
/// Uses the original DPI settings of the loaded image
/// </summary>
UseSourceDPI,

/// <summary>
/// Uses the default value of 96 DPI
/// </summary>
Default96DPI,

/// <summary>
/// Overrides the image DPI settings with the current screen DPI value
/// </summary>
CopyDisplayDPISetting,

/// <summary>
/// Overrides the image DPI settings with the current screen DPI value and ensures the resulting value is at least 96
/// </summary>
CopyDisplayDPISettingsWith96AsLowerBound
}
}
61 changes: 47 additions & 14 deletions UICompositionAnimations/Helpers/Win2DImageHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Graphics.DirectX;
using Windows.Graphics.Display;
using Windows.Graphics.Imaging;
using Windows.UI;
using Windows.UI.Composition;
Expand Down Expand Up @@ -44,23 +45,25 @@ public static class Win2DImageHelper
/// Loads a <see cref="CompositionSurfaceBrush"/> instance with the target image from the shared <see cref="CanvasDevice"/> instance
/// </summary>
/// <param name="uri">The path to the image to load</param>
/// <param name="dpiMode">Indicates the desired DPI mode to use when loading the image</param>
[PublicAPI]
[Pure, ItemCanBeNull]
public static Task<CompositionSurfaceBrush> LoadImageAsync([NotNull] Uri uri)
public static Task<CompositionSurfaceBrush> LoadImageAsync([NotNull] Uri uri, BitmapDPIMode dpiMode)
{
return LoadImageAsync(Window.Current.Compositor, uri, CacheLoadingMode.DisableCaching);
return LoadImageAsync(Window.Current.Compositor, uri, BitmapCacheMode.DisableCaching, dpiMode);
}

/// <summary>
/// Loads a <see cref="CompositionSurfaceBrush"/> instance with the target image
/// </summary>
/// <param name="canvas">The <see cref="CanvasControl"/> to use to load the target image</param>
/// <param name="uri">The path to the image to load</param>
/// <param name="dpiMode">Indicates the desired DPI mode to use when loading the image</param>
[PublicAPI]
[Pure, ItemCanBeNull]
internal static Task<CompositionSurfaceBrush> LoadImageAsync([NotNull] this CanvasControl canvas, [NotNull] Uri uri)
public static Task<CompositionSurfaceBrush> LoadImageAsync([NotNull] this CanvasControl canvas, [NotNull] Uri uri, BitmapDPIMode dpiMode)
{
return LoadImageAsync(Window.Current.Compositor, canvas, uri, CacheLoadingMode.DisableCaching);
return LoadImageAsync(Window.Current.Compositor, canvas, uri, BitmapCacheMode.DisableCaching, dpiMode);
}

/// <summary>
Expand Down Expand Up @@ -90,12 +93,35 @@ public static async Task<IEnumerable<CompositionBrush>> ClearCacheAsync()
/// <param name="compositor">The compositor instance to use to create the final brush</param>
/// <param name="canvasDevice">The device to use to process the Win2D image</param>
/// <param name="uri">The path to the image to load</param>
/// <param name="dpiMode">Indicates the desired DPI mode to use when loading the image</param>
[ItemNotNull]
private static async Task<CompositionSurfaceBrush> LoadSurfaceBrushAsync([NotNull] ICanvasResourceCreator creator,
[NotNull] Compositor compositor, [NotNull] CanvasDevice canvasDevice, [NotNull] Uri uri)
[NotNull] Compositor compositor, [NotNull] CanvasDevice canvasDevice, [NotNull] Uri uri, BitmapDPIMode dpiMode)
{
using (CanvasBitmap bitmap = await CanvasBitmap.LoadAsync(creator, uri))
CanvasBitmap bitmap = null;
try
{
// Load the bitmap with the appropriate settings
switch (dpiMode)
{
case BitmapDPIMode.UseSourceDPI:
bitmap = await CanvasBitmap.LoadAsync(creator, uri);
break;
case BitmapDPIMode.Default96DPI:
bitmap = await CanvasBitmap.LoadAsync(creator, uri, 96);
break;
case BitmapDPIMode.CopyDisplayDPISetting:
float dpi = DisplayInformation.GetForCurrentView().LogicalDpi;
bitmap = await CanvasBitmap.LoadAsync(creator, uri, dpi);
break;
case BitmapDPIMode.CopyDisplayDPISettingsWith96AsLowerBound:
dpi = DisplayInformation.GetForCurrentView().LogicalDpi;
bitmap = await CanvasBitmap.LoadAsync(creator, uri, dpi >= 96 ? dpi : 96);
break;
default:
throw new ArgumentOutOfRangeException("Unsupported DPI mode");
}

// Get the device and the target surface
CompositionGraphicsDevice device = CanvasComposition.CreateCompositionGraphicsDevice(compositor, canvasDevice);
CompositionDrawingSurface surface = device.CreateDrawingSurface(default(Size),
Expand All @@ -116,6 +142,11 @@ private static async Task<CompositionSurfaceBrush> LoadSurfaceBrushAsync([NotNul
return brush;
}
}
finally
{
// Manual using block to allow the initial switch statement
bitmap?.Dispose();
}
}

/// <summary>
Expand All @@ -125,17 +156,18 @@ private static async Task<CompositionSurfaceBrush> LoadSurfaceBrushAsync([NotNul
/// <param name="canvas">The <see cref="CanvasControl"/> to use to load the target image</param>
/// <param name="uri">The path to the image to load</param>
/// <param name="options">Indicates whether or not to force the reload of the Win2D image</param>
/// <param name="dpiMode">Indicates the desired DPI mode to use when loading the image</param>
[ItemCanBeNull]
internal static async Task<CompositionSurfaceBrush> LoadImageAsync(
[NotNull] Compositor compositor, [NotNull] CanvasControl canvas, [NotNull] Uri uri, CacheLoadingMode options)
[NotNull] Compositor compositor, [NotNull] CanvasControl canvas, [NotNull] Uri uri, BitmapCacheMode options, BitmapDPIMode dpiMode)
{
TaskCompletionSource<CompositionSurfaceBrush> tcs = new TaskCompletionSource<CompositionSurfaceBrush>();
async Task<CompositionSurfaceBrush> LoadImageAsync(bool shouldThrow)
{
// Load the image - this will only succeed when there's an available Win2D device
try
{
return await LoadSurfaceBrushAsync(canvas, compositor, canvas.Device, uri);
return await LoadSurfaceBrushAsync(canvas, compositor, canvas.Device, uri, dpiMode);
}
catch when (!shouldThrow)
{
Expand Down Expand Up @@ -167,7 +199,7 @@ async void Canvas_CreateResources(CanvasControl sender, CanvasCreateResourcesEve

// Lock the semaphore and check the cache first
await Win2DSemaphore.WaitAsync();
if (options == CacheLoadingMode.EnableCaching && SurfacesCache.TryGetValue(uri, out CompositionSurfaceBrush cached))
if (options == BitmapCacheMode.EnableCaching && SurfacesCache.TryGetValue(uri, out CompositionSurfaceBrush cached))
{
Win2DSemaphore.Release();
return cached;
Expand Down Expand Up @@ -195,7 +227,7 @@ async void Canvas_CreateResources(CanvasControl sender, CanvasCreateResourcesEve

// Cache when needed and return the result
if (instance != null &&
options != CacheLoadingMode.DisableCaching &&
options != BitmapCacheMode.DisableCaching &&
!SurfacesCache.ContainsKey(uri)) SurfacesCache.Add(uri, instance);
Win2DSemaphore.Release();
return instance;
Expand All @@ -207,9 +239,10 @@ async void Canvas_CreateResources(CanvasControl sender, CanvasCreateResourcesEve
/// <param name="compositor">The compositor to use to render the Win2D image</param>
/// <param name="uri">The path to the image to load</param>
/// <param name="options">Indicates whether or not to force the reload of the Win2D image</param>
/// <param name="dpiMode">Indicates the desired DPI mode to use when loading the image</param>
[ItemCanBeNull]
internal static async Task<CompositionSurfaceBrush> LoadImageAsync(
[NotNull] Compositor compositor, [NotNull] Uri uri, CacheLoadingMode options)
[NotNull] Compositor compositor, [NotNull] Uri uri, BitmapCacheMode options, BitmapDPIMode dpiMode)
{
// Fix the Uri if it has been generated by the XAML designer
if (uri.Scheme.Equals("ms-resource"))
Expand All @@ -222,7 +255,7 @@ internal static async Task<CompositionSurfaceBrush> LoadImageAsync(

// Lock the semaphore and check the cache first
await Win2DSemaphore.WaitAsync();
if (options == CacheLoadingMode.EnableCaching && SurfacesCache.TryGetValue(uri, out CompositionSurfaceBrush cached))
if (options == BitmapCacheMode.EnableCaching && SurfacesCache.TryGetValue(uri, out CompositionSurfaceBrush cached))
{
Win2DSemaphore.Release();
return cached;
Expand All @@ -234,7 +267,7 @@ internal static async Task<CompositionSurfaceBrush> LoadImageAsync(
{
// This will throw and the canvas will re-initialize the Win2D device if needed
CanvasDevice sharedDevice = CanvasDevice.GetSharedDevice();
brush = await LoadSurfaceBrushAsync(sharedDevice, compositor, sharedDevice, uri);
brush = await LoadSurfaceBrushAsync(sharedDevice, compositor, sharedDevice, uri, dpiMode);
}
catch
{
Expand All @@ -244,7 +277,7 @@ internal static async Task<CompositionSurfaceBrush> LoadImageAsync(

// Cache when needed and return the result
if (brush != null &&
options != CacheLoadingMode.DisableCaching &&
options != BitmapCacheMode.DisableCaching &&
!SurfacesCache.ContainsKey(uri)) SurfacesCache.Add(uri, brush);
Win2DSemaphore.Release();
return brush;
Expand Down
2 changes: 1 addition & 1 deletion UICompositionAnimations/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.8.4.0")]
[assembly: AssemblyVersion("2.9.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
3 changes: 2 additions & 1 deletion UICompositionAnimations/UICompositionAnimations.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@
<Compile Include="Composition\CompositionManager.cs" />
<Compile Include="Composition\CubicBeizerEasingProvider.cs" />
<Compile Include="Enums\AcrylicBrushEffectState.cs" />
<Compile Include="Enums\CacheLoadingMode.cs" />
<Compile Include="Enums\BitmapDPIMode.cs" />
<Compile Include="Enums\BitmapCacheMode.cs" />
<Compile Include="Enums\EasingFunctionNames.cs" />
<Compile Include="Enums\ImplicitAnimationType.cs" />
<Compile Include="Helpers\ApiInformaitonHelper.cs" />
Expand Down
4 changes: 2 additions & 2 deletions UICompositionAnimations/UICompositionAnimations.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
<package >
<metadata>
<id>Sergio0694.UWP.UICompositionAnimations</id>
<version>2.8.4.0</version>
<version>2.9.0.0</version>
<title>UICompositionAnimations</title>
<description>A wrapper UWP PCL to work with Windows.UI.Composition and XAML animations, and Win2D effects</description>
<authors>Sergio Pedri</authors>
<owners>Sergio Pedri</owners>
<projectUrl>https://github.com/Sergio0694/UICompositionAnimations</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<releaseNotes>Custom acrylic brush fallback mode improved, bug fixes</releaseNotes>
<releaseNotes>New APIs available, bug fixes and code refactoring</releaseNotes>
<copyright>Copyright 2017</copyright>
<tags>uwp composition animations xaml csharp windows winrt universal app ui win2d graphics</tags>
</metadata>
Expand Down
Binary file not shown.
Empty file.
Empty file.
Empty file.
Loading

0 comments on commit bdf6cdc

Please sign in to comment.