From 8e4bd7a213210feff42ade340a8be6624e9f5c64 Mon Sep 17 00:00:00 2001 From: Arlo Godfrey Date: Mon, 11 Dec 2023 21:02:42 -0600 Subject: [PATCH] Fixed compositor nullreference in WinUI 3 --- .../src/Brushes/BackdropGammaTransferBrush.cs | 11 +++++++++-- .../Media/src/Brushes/CanvasBrushBase.cs | 10 ++++++++-- .../Media/src/Brushes/ImageBlendBrush.cs | 13 ++++++++++--- .../src/Helpers/SurfaceLoader.Instance.cs | 7 ++++++- components/Media/src/Helpers/SurfaceLoader.cs | 4 ++++ .../PipelineBuilder.Initialization.cs | 7 ++++++- .../Media/src/Pipelines/PipelineBuilder.cs | 18 +++++++++++++++--- 7 files changed, 58 insertions(+), 12 deletions(-) diff --git a/components/Media/src/Brushes/BackdropGammaTransferBrush.cs b/components/Media/src/Brushes/BackdropGammaTransferBrush.cs index 1b7de60b..c0129f64 100644 --- a/components/Media/src/Brushes/BackdropGammaTransferBrush.cs +++ b/components/Media/src/Brushes/BackdropGammaTransferBrush.cs @@ -345,7 +345,14 @@ protected override void OnConnected() return; } - var backdrop = Window.Current.Compositor.CreateBackdropBrush(); + +#if WINUI2 + var compositor = Window.Current.Compositor; +#elif WINUI3 + var compositor = CompositionTarget.GetCompositorForCurrentThread(); +#endif + + var backdrop = compositor.CreateBackdropBrush(); // Use a Win2D blur affect applied to a CompositionBackdropBrush. var graphicsEffect = new GammaTransferEffect @@ -370,7 +377,7 @@ protected override void OnConnected() Source = new CompositionEffectSourceParameter("backdrop") }; - var effectFactory = Window.Current.Compositor.CreateEffectFactory(graphicsEffect, new[] + var effectFactory = compositor.CreateEffectFactory(graphicsEffect, new[] { "GammaTransfer.AlphaAmplitude", "GammaTransfer.AlphaExponent", diff --git a/components/Media/src/Brushes/CanvasBrushBase.cs b/components/Media/src/Brushes/CanvasBrushBase.cs index 55cd1be0..b841dd95 100644 --- a/components/Media/src/Brushes/CanvasBrushBase.cs +++ b/components/Media/src/Brushes/CanvasBrushBase.cs @@ -66,7 +66,13 @@ protected override void OnConnected() _graphics.RenderingDeviceReplaced -= CanvasDevice_RenderingDeviceReplaced; } - _graphics = CanvasComposition.CreateCompositionGraphicsDevice(Window.Current.Compositor, _device); +#if WINUI2 + var compositor = Window.Current.Compositor; +#elif WINUI3 + var compositor = CompositionTarget.GetCompositorForCurrentThread(); +#endif + + _graphics = CanvasComposition.CreateCompositionGraphicsDevice(compositor, _device); _graphics.RenderingDeviceReplaced += CanvasDevice_RenderingDeviceReplaced; // Delay creating composition resources until they're required. @@ -95,7 +101,7 @@ protected override void OnConnected() } } - _surfaceBrush = Window.Current.Compositor.CreateSurfaceBrush(surface); + _surfaceBrush = compositor.CreateSurfaceBrush(surface); _surfaceBrush.Stretch = CompositionStretch.Fill; CompositionBrush = _surfaceBrush; diff --git a/components/Media/src/Brushes/ImageBlendBrush.cs b/components/Media/src/Brushes/ImageBlendBrush.cs index 4f5123ba..8f541a46 100644 --- a/components/Media/src/Brushes/ImageBlendBrush.cs +++ b/components/Media/src/Brushes/ImageBlendBrush.cs @@ -126,6 +126,12 @@ private static void OnModeChanged(DependencyObject d, DependencyPropertyChangedE /// protected override void OnConnected() { +#if WINUI2 + var compositor = Window.Current.Compositor; +#elif WINUI3 + var compositor = CompositionTarget.GetCompositorForCurrentThread(); +#endif + // Delay creating composition resources until they're required. if (CompositionBrush == null && Source != null && Source is BitmapImage bitmap) { @@ -133,8 +139,9 @@ protected override void OnConnected() // If UriSource is invalid, StartLoadFromUri will return a blank texture. _surface = LoadedImageSurface.StartLoadFromUri(bitmap.UriSource); + // Load Surface onto SurfaceBrush - _surfaceBrush = Window.Current.Compositor.CreateSurfaceBrush(_surface); + _surfaceBrush = compositor.CreateSurfaceBrush(_surface); _surfaceBrush.Stretch = CompositionStretchFromStretch(Stretch); #if WINUI2 @@ -150,7 +157,7 @@ protected override void OnConnected() return; } - var backdrop = Window.Current.Compositor.CreateBackdropBrush(); + var backdrop = compositor.CreateBackdropBrush(); // Use a Win2D invert affect applied to a CompositionBackdropBrush. var graphicsEffect = new CanvasBlendEffect @@ -161,7 +168,7 @@ protected override void OnConnected() Foreground = new CompositionEffectSourceParameter("image") }; - var effectFactory = Window.Current.Compositor.CreateEffectFactory(graphicsEffect); + var effectFactory = compositor.CreateEffectFactory(graphicsEffect); var effectBrush = effectFactory.CreateBrush(); effectBrush.SetSourceParameter("backdrop", backdrop); diff --git a/components/Media/src/Helpers/SurfaceLoader.Instance.cs b/components/Media/src/Helpers/SurfaceLoader.Instance.cs index 013e4aad..97245ece 100644 --- a/components/Media/src/Helpers/SurfaceLoader.Instance.cs +++ b/components/Media/src/Helpers/SurfaceLoader.Instance.cs @@ -43,7 +43,12 @@ public sealed partial class SurfaceLoader : IDisposable /// A instance to use in the current window public static SurfaceLoader GetInstance() { - return GetInstance(Window.Current.Compositor); +#if WINUI2 + var compositor = Window.Current.Compositor; +#elif WINUI3 + var compositor = CompositionTarget.GetCompositorForCurrentThread(); +#endif + return GetInstance(compositor); } /// diff --git a/components/Media/src/Helpers/SurfaceLoader.cs b/components/Media/src/Helpers/SurfaceLoader.cs index ea40b913..813e65b8 100644 --- a/components/Media/src/Helpers/SurfaceLoader.cs +++ b/components/Media/src/Helpers/SurfaceLoader.cs @@ -44,7 +44,11 @@ public sealed partial class SurfaceLoader /// A that returns the loaded instance public static async Task LoadImageAsync(Uri uri, DpiMode dpiMode, CacheMode cacheMode = CacheMode.Default) { +#if WINUI2 var compositor = Window.Current.Compositor; +#elif WINUI3 + var compositor = CompositionTarget.GetCompositorForCurrentThread(); +#endif // Lock and check the cache first using (await Win2DMutex.LockAsync()) diff --git a/components/Media/src/Pipelines/PipelineBuilder.Initialization.cs b/components/Media/src/Pipelines/PipelineBuilder.Initialization.cs index 8997d397..12aa971a 100644 --- a/components/Media/src/Pipelines/PipelineBuilder.Initialization.cs +++ b/components/Media/src/Pipelines/PipelineBuilder.Initialization.cs @@ -46,7 +46,12 @@ public static PipelineBuilder FromBackdrop() { ValueTask Factory() { - var brush = BackdropBrushCache.GetValue(Window.Current.Compositor, c => c.CreateBackdropBrush()); +#if WINUI2 + var compositor = Window.Current.Compositor; +#elif WINUI3 + var compositor = CompositionTarget.GetCompositorForCurrentThread(); +#endif + var brush = BackdropBrushCache.GetValue(compositor, c => c.CreateBackdropBrush()); return new ValueTask(brush); } diff --git a/components/Media/src/Pipelines/PipelineBuilder.cs b/components/Media/src/Pipelines/PipelineBuilder.cs index 4057c7ea..ff5db887 100644 --- a/components/Media/src/Pipelines/PipelineBuilder.cs +++ b/components/Media/src/Pipelines/PipelineBuilder.cs @@ -160,6 +160,12 @@ private PipelineBuilder( [Pure] public async Task BuildAsync() { +#if WINUI2 + var compositor = Window.Current.Compositor; +#elif WINUI3 + var compositor = CompositionTarget.GetCompositorForCurrentThread(); +#endif + var effect = await this.sourceProducer() as IGraphicsEffect; // Validate the pipeline @@ -170,8 +176,8 @@ public async Task BuildAsync() // Build the effects factory var factory = this.animationProperties.Count > 0 - ? Window.Current.Compositor.CreateEffectFactory(effect, this.animationProperties) - : Window.Current.Compositor.CreateEffectFactory(effect); + ? compositor.CreateEffectFactory(effect, this.animationProperties) + : compositor.CreateEffectFactory(effect); // Create the effect factory and apply the final effect var effectBrush = factory.CreateBrush(); @@ -191,7 +197,13 @@ public async Task BuildAsync() /// A that returns the final instance to use public async Task AttachAsync(UIElement target, UIElement? reference = null) { - SpriteVisual visual = Window.Current.Compositor.CreateSpriteVisual(); +#if WINUI2 + var compositor = Window.Current.Compositor; +#elif WINUI3 + var compositor = CompositionTarget.GetCompositorForCurrentThread(); +#endif + + SpriteVisual visual = compositor.CreateSpriteVisual(); visual.Brush = await BuildAsync();