From 2300b98ceb6f7b97f71c89b30e08701a5175d260 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 10 Aug 2017 16:04:49 +0200 Subject: [PATCH] Fixed acrylic brush crash on secondary windows --- .../Brushes/CustomAcrylicBrush.cs | 35 +++++++++++++++---- .../Properties/AssemblyInfo.cs | 2 +- .../UICompositionAnimations.nuspec | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/UICompositionAnimations/Brushes/CustomAcrylicBrush.cs b/UICompositionAnimations/Brushes/CustomAcrylicBrush.cs index 0b5f1fd..6b20474 100644 --- a/UICompositionAnimations/Brushes/CustomAcrylicBrush.cs +++ b/UICompositionAnimations/Brushes/CustomAcrylicBrush.cs @@ -74,8 +74,9 @@ private static async void OnModePropertyChanged(DependencyObject d, DependencyPr } /// - /// Gets or sets the blur amount for the effect (NOTE: this property is ignored when the active mode is ) + /// Gets or sets the blur amount for the effect) /// + /// This property is ignored when the active mode is public double BlurAmount { get { return GetValue(BlurAmountProperty).To(); } @@ -204,8 +205,9 @@ private static async void OnUnsupportedEffectFallbackColorPropertyChanged(Depend } /// - /// Gets or sets the to the noise texture to use (NOTE: this must be initialized before using the brush) + /// Gets or sets the to the noise texture to use /// + /// This property must be initialized before using the brush public Uri NoiseTextureUri { get; set; } /// @@ -213,6 +215,18 @@ private static async void OnUnsupportedEffectFallbackColorPropertyChanged(Depend /// public BitmapCacheMode CacheMode { get; set; } = BitmapCacheMode.EnableCaching; + /// + /// 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 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. + /// + /// Turning this property on disables the internal cache system for instances. + /// This property, like the property, must be initialized before using the brush + public bool DispatchProtectionEnabled { get; set; } + #endregion // Initialization semaphore (due to the Win2D image loading being asynchronous) @@ -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(); } @@ -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(); @@ -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 { diff --git a/UICompositionAnimations/Properties/AssemblyInfo.cs b/UICompositionAnimations/Properties/AssemblyInfo.cs index 7ed62e1..94eaa0a 100644 --- a/UICompositionAnimations/Properties/AssemblyInfo.cs +++ b/UICompositionAnimations/Properties/AssemblyInfo.cs @@ -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)] \ No newline at end of file diff --git a/UICompositionAnimations/UICompositionAnimations.nuspec b/UICompositionAnimations/UICompositionAnimations.nuspec index 7fb8039..1f0dd37 100644 --- a/UICompositionAnimations/UICompositionAnimations.nuspec +++ b/UICompositionAnimations/UICompositionAnimations.nuspec @@ -2,7 +2,7 @@ Sergio0694.UWP.UICompositionAnimations - 2.10.2.0 + 2.10.3.0 UICompositionAnimations A wrapper UWP PCL to work with Windows.UI.Composition and XAML animations, and Win2D effects Sergio Pedri