Skip to content

Commit

Permalink
Fixed acrylic brush crash on secondary windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Aug 10, 2017
1 parent 9eb8b5c commit 2300b98
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 9 deletions.
35 changes: 28 additions & 7 deletions UICompositionAnimations/Brushes/CustomAcrylicBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ private static async void OnModePropertyChanged(DependencyObject d, DependencyPr
}

/// <summary>
/// Gets or sets the blur amount for the effect (NOTE: this property is ignored when the active mode is <see cref="AcrylicEffectMode.HostBackdrop"/>)
/// Gets or sets the blur amount for the effect)
/// </summary>
/// <remarks>This property is ignored when the active mode is <see cref="AcrylicEffectMode.HostBackdrop"/></remarks>
public double BlurAmount
{
get { return GetValue(BlurAmountProperty).To<double>(); }
Expand Down Expand Up @@ -204,15 +205,28 @@ private static async void OnUnsupportedEffectFallbackColorPropertyChanged(Depend
}

/// <summary>
/// Gets or sets the <see cref="Uri"/> to the noise texture to use (NOTE: this must be initialized before using the brush)
/// Gets or sets the <see cref="Uri"/> to the noise texture to use
/// </summary>
/// <remarks>This property must be initialized before using the brush</remarks>
public Uri NoiseTextureUri { get; set; }

/// <summary>
/// Gets or sets the caching setting for the acrylic brush
/// </summary>
public BitmapCacheMode CacheMode { get; set; } = BitmapCacheMode.EnableCaching;

/// <summary>
/// Indicates whether or not to enable an additional safety procedure when loading the acrylic brush.
/// This property should be used for brushes being rendered on secondary windows that use a given acrylic mode for the first
/// time in the application, to prevent the internal cache from storing a brush instance that would cause the app to crash if
/// reused in the app primary window, due to the different <see cref="Windows.UI.Core.CoreDispatcher"/> associated with that window.
/// This property can stay disabled in most cases and should only be turned on when dealing with particular edge cases or issues
/// with secondary app windows.
/// </summary>
/// <remarks>Turning this property on disables the internal cache system for <see cref="CompositionBackdropBrush"/> instances.
/// This property, like the <see cref="NoiseTextureUri"/> property, must be initialized before using the brush</remarks>
public bool DispatchProtectionEnabled { get; set; }

#endregion

// Initialization semaphore (due to the Win2D image loading being asynchronous)
Expand Down Expand Up @@ -340,7 +354,7 @@ private async Task SetupEffectAsync()
{
// Manage the cache
await BackdropSemaphore.WaitAsync();
if (_BackdropInstance == null)
if (_BackdropInstance == null && !DispatchProtectionEnabled)
{
_BackdropInstance = Window.Current.Compositor.CreateBackdropBrush();
}
Expand All @@ -355,14 +369,18 @@ private async Task SetupEffectAsync()
Source = new CompositionEffectSourceParameter(nameof(BackdropReferenceParameterName))
};
animatableParameters.Add(BlurAmountParameterName);
sourceParameters.Add(nameof(BackdropReferenceParameterName), _BackdropInstance);
sourceParameters.Add(nameof(BackdropReferenceParameterName),
_BackdropInstance?.Dispatcher.HasThreadAccess == true
? _BackdropInstance
: Window.Current.Compositor.CreateBackdropBrush()); // Create a new instance when on a secondary window
BackdropSemaphore.Release();
}
else
{
// Manage the cache
await HostBackdropSemaphore.WaitAsync();
if (_HostBackdropCache == null)
if (_HostBackdropCache == null || // Cache not initialized yet
!_HostBackdropCache.Brush.Dispatcher.HasThreadAccess) // Cache initialized on another UI thread (different window)
{
// Prepare a luminosity to alpha effect to adjust the background contrast
CompositionBackdropBrush hostBackdropBrush = Window.Current.Compositor.CreateHostBackdropBrush();
Expand All @@ -383,8 +401,11 @@ private async Task SetupEffectAsync()
};
sourceParameters.Add(HostBackdropReferenceParameterName, hostBackdropBrush);

// Update the cache
_HostBackdropCache = new HostBackdropInstanceWrapper(baseEffect, hostBackdropBrush);
// Update the cache when needed
if (_HostBackdropCache == null && !DispatchProtectionEnabled)
{
_HostBackdropCache = new HostBackdropInstanceWrapper(baseEffect, hostBackdropBrush);
}
}
else
{
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.10.2.0")]
[assembly: AssemblyVersion("2.10.3.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
2 changes: 1 addition & 1 deletion UICompositionAnimations/UICompositionAnimations.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package>
<metadata>
<id>Sergio0694.UWP.UICompositionAnimations</id>
<version>2.10.2.0</version>
<version>2.10.3.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>
Expand Down

0 comments on commit 2300b98

Please sign in to comment.