Repository: unoplatform/uno
Pull request #20158: fix(android): Pause drawing when not rendering
Author: login: jeromelaban
Labels: name: platform/android 🤖
description: Categorizes an issue or PR as relevant to the Android platform
name: area/skia ✏️
description: Categorizes an issue or PR as relevant to Skia
Created: 2025-05-01T21:00:35Z | Merged: 2025-05-02T05:35:44Z

## PR Type

What kind of change does this PR introduce?
- Bugfix

## What is the new behavior?

Pause the render thread when the app is idle.

## PR Checklist

Please check if your PR fulfills the following requirements:

- [ ] Docs have been added/updated which fit [documentation template](https://github.com/unoplatform/uno/blob/master/doc/.feature-template.md) (for bug fixes / features)
- [ ] [Unit Tests and/or UI Tests](https://github.com/unoplatform/uno/blob/master/doc/articles/uno-development/working-with-the-samples-apps.md) for the changes have been added (for bug fixes / features) (if applicable)
- [ ] Validated PR `Screenshots Compare Test Run` results.
- [ ] Contains **NO** breaking changes
- [ ] Associated with an issue (GitHub or internal) and uses the [automatic close keywords](https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue).
- [ ] Commits must be following the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification.

<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below.
     Please note that breaking changes are likely to be rejected -->

## Other information

<!-- Please provide any additional information if necessary -->

Internal Issue (If applicable):
<!-- Link to relevant internal issue if applicable. All PRs should be associated with an issue (GitHub issue or internal) -->



Diff:
diff --git a/src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/ApplicationActivity.cs b/src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/ApplicationActivity.cs
index c26a3e0166c1..a0ed0f1ef402 100644
--- a/src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/ApplicationActivity.cs
+++ b/src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/ApplicationActivity.cs
@@ -265,7 +265,7 @@ protected override void OnStart()
 
 		internal void InvalidateRender()
 		{
-			_skCanvasView?.Invalidate();
+			_skCanvasView?.InvalidateRender();
 			RelativeLayout.Invalidate();
 		}
 
diff --git a/src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/UnoSKCanvasView.cs b/src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/UnoSKCanvasView.cs
index 29259542b5c0..7826670968a9 100644
--- a/src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/UnoSKCanvasView.cs
+++ b/src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/UnoSKCanvasView.cs
@@ -1,7 +1,7 @@
 ﻿// #define FPS_DISPLAY
 
 using System;
-using Windows.Graphics.Display;
+using System.Threading;
 using Android.Content;
 using Android.Graphics;
 using Android.Opengl;
@@ -11,12 +11,15 @@
 using Android.Views;
 using Android.Views.Autofill;
 using Android.Views.InputMethods;
+using AndroidX.Core.Graphics;
 using AndroidX.Core.View;
 using Javax.Microedition.Khronos.Opengles;
 using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Media;
 using SkiaSharp;
 using Uno.Foundation.Logging;
 using Uno.UI.Helpers;
+using Windows.Graphics.Display;
 
 namespace Uno.UI.Runtime.Skia.Android;
 
@@ -47,18 +50,34 @@ public UnoSKCanvasView(Context context) : base(context)
 		ViewCompat.SetAccessibilityDelegate(this, ExploreByTouchHelper);
 		Focusable = true;
 		FocusableInTouchMode = true;
+		PreserveEGLContextOnPause = true;
 		if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
 		{
 			ImportantForAutofill = ImportantForAutofill.Yes;
 		}
 
 		SetWillNotDraw(false);
+
+		// Start the render thread paused
+		RenderMode = Rendermode.WhenDirty;
+
+		CompositionTarget.RenderingActiveChanged += OnCompositionRenderingActiveChanged;
 	}
 
-	protected override void OnDraw(Canvas c)
+	private void OnCompositionRenderingActiveChanged()
 	{
-		base.OnDraw(c);
+		if (this.Log().IsEnabled(LogLevel.Trace))
+		{
+			this.Log().Trace($"OnCompositionRenderingActiveChanged: {CompositionTarget.IsRenderingActive}");
+		}
 
+		RenderMode = CompositionTarget.IsRenderingActive
+			? Rendermode.Continuously
+			: Rendermode.WhenDirty;
+	}
+
+	internal void InvalidateRender()
+	{
 		if (Microsoft.UI.Xaml.Window.CurrentSafe is not { RootElement: { } root } window)
 		{
 			return;
@@ -99,7 +118,12 @@ protected override void OnDraw(Canvas c)
 				new SKPaint { Color = SKColors.Red});
 #endif
 
-			_picture = recorder.EndRecording();
+			var picture = recorder.EndRecording();
+
+			Interlocked.Exchange(ref _picture, picture);
+
+			// Request the call of IRenderer.OnDrawFrame for one frame
+			RequestRender();
 		}
 	}
 
@@ -196,8 +220,15 @@ private class InternalRenderer(UnoSKCanvasView surfaceView) : Java.Lang.Object,
 
 		void IRenderer.OnDrawFrame(IGL10? gl)
 		{
+			var currentPicture = Volatile.Read(ref surfaceView._picture);
+
 			GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit | GLES20.GlStencilBufferBit);
 
+			if (currentPicture is null)
+			{
+				return;
+			}
+
 			// create the contexts if not done already
 			if (_context == null)
 			{
@@ -253,10 +284,7 @@ void IRenderer.OnDrawFrame(IGL10? gl)
 			using (new SKAutoCanvasRestore(canvas, true))
 			{
 				// start drawing
-				if (surfaceView._picture is { } picture)
-				{
-					canvas.DrawPicture(picture);
-				}
+				canvas.DrawPicture(currentPicture);
 			}
 
 			// flush the SkiaSharp contents to GL
@@ -272,6 +300,16 @@ void IRenderer.OnDrawFrame(IGL10? gl)
 			// else : we already drew directly on the OpenGL-backed canvas
 
 			_context!.Flush();
+
+			if (!CompositionTarget.IsRenderingActive && ReferenceEquals(currentPicture, Volatile.Read(ref surfaceView._picture)))
+			{
+				if (this.Log().IsEnabled(LogLevel.Trace))
+				{
+					this.Log().Trace("Suspend drawing");
+				}
+
+				surfaceView.RenderMode = Rendermode.WhenDirty;
+			}
 		}
 
 		void IRenderer.OnSurfaceChanged(IGL10? gl, int width, int height)


Reviews:
user: login: ramezgerges
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T21:10:07Z
user: login: ramezgerges
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T21:12:12Z
user: login: jeromelaban
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-01T21:21:05Z
user: login: jeromelaban
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-01T21:22:13Z
user: login: ajpinedam
body: Looks good.-
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T03:46:38Z

Review comments:
diff_hunk: @@ -99,7 +120,15 @@ protected override void OnDraw(Canvas c)
 				new SKPaint { Color = SKColors.Red});
 #endif
 
-			_picture = recorder.EndRecording();
+			var picture = recorder.EndRecording();
+
+			Interlocked.Exchange(ref _picture, picture);
+
+			if (this.Log().IsEnabled(LogLevel.Trace))
+			{
+				this.Log().Trace("Resume drawing");
+			}
+			RenderMode = Rendermode.Continuously;
path: src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/UnoSKCanvasView.cs
user: login: ramezgerges
body: Why do we need to set this here in addition to OnCompositionRenderingActiveChanged
created_at: 2025-05-01T21:10:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -272,6 +305,16 @@ void IRenderer.OnDrawFrame(IGL10? gl)
 			// else : we already drew directly on the OpenGL-backed canvas
 
 			_context!.Flush();
+
+			if (!CompositionTarget.IsRenderingActive && ReferenceEquals(currentPicture, Volatile.Read(ref surfaceView._picture)))
path: src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/UnoSKCanvasView.cs
user: login: ramezgerges
body: Same question. Also I'm not sure why the picture comparison is necessary. If the picture changed, this means that we should've invalidated the surface view and OnDraw will get called again soon enough.
created_at: 2025-05-01T21:12:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -99,7 +120,15 @@ protected override void OnDraw(Canvas c)
 				new SKPaint { Color = SKColors.Red});
 #endif
 
-			_picture = recorder.EndRecording();
+			var picture = recorder.EndRecording();
+
+			Interlocked.Exchange(ref _picture, picture);
+
+			if (this.Log().IsEnabled(LogLevel.Trace))
+			{
+				this.Log().Trace("Resume drawing");
+			}
+			RenderMode = Rendermode.Continuously;
path: src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/UnoSKCanvasView.cs
user: login: jeromelaban
body: We need this because of manual triggers of rendering, mouse moves, pointers, etc...
created_at: 2025-05-01T21:21:05Z
author_association: MEMBER
diff_hunk: @@ -272,6 +305,16 @@ void IRenderer.OnDrawFrame(IGL10? gl)
 			// else : we already drew directly on the OpenGL-backed canvas
 
 			_context!.Flush();
+
+			if (!CompositionTarget.IsRenderingActive && ReferenceEquals(currentPicture, Volatile.Read(ref surfaceView._picture)))
path: src/Uno.UI.Runtime.Skia.Android/Microsoft/UI/Xaml/UnoSKCanvasView.cs
user: login: jeromelaban
body: The picture comparison is necessary for race conditions, where the image may have been changed in between the beginning of the frame and the check we make, as the frame may have been requested manually for pointers or others.
created_at: 2025-05-01T21:22:13Z
author_association: MEMBER

PR comments:
user: login: jeromelaban
created_at: 2025-05-01T21:01:11Z
body: @mergifyio backport release/stable/6.0 
author_association: MEMBER
user: login: mergify[bot]
created_at: 2025-05-01T21:01:25Z
body: > backport release/stable/6.0

#### ✅ Backports have been created

<details>

* [#20162 fix(android): Pause drawing when not rendering (backport #20158)](https://github.com/unoplatform/uno/pull/20162) has been created for branch `release/stable/6.0`

</details>


<!---
DO NOT EDIT
-*- Mergify Payload -*-
{"command": "backport release/stable/6.0", "conclusion": "success", "action_is_running": true}
-*- Mergify Payload End -*-
-->
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-01T21:31:51Z
body: 🤖 Your WebAssembly Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-20158/index.html
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-01T21:43:08Z
body: 🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-20158/index.html
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-01T23:31:01Z
body: ⚠️⚠️ The build [163929](https://dev.azure.com/uno-platform//Uno%20Platform/_build/results?buildId=163929) has failed on Uno.UI - CI.
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-02T02:25:17Z
body: 🤖 Your WebAssembly Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-20158/index.html
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-02T02:40:21Z
body: 🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-20158/index.html
author_association: CONTRIBUTOR
user: login: nventive-devops
created_at: 2025-05-02T04:12:31Z
body: The [build 163953](https://dev.azure.com/uno-platform/Uno%20Platform/_build/results?buildId=163953) found UI Test snapshots differences: `android-28-net8`: **19**, `android-28-net8-Snap`: **41**, `ios`: **2**, `ios-Snap`: **32**, `skia-linux-screenshots`: **65**, `skia-windows-screenshots`: **61**, `wasm`: **42**, `wasm-automated-net9.0-WinUI-Benchmarks-automated`: **0**, `wasm-automated-net9.0-WinUI-Default-automated`: **18**, `wasm-automated-net9.0-WinUI-RuntimeTests-0`: **1**, `wasm-automated-net9.0-WinUI-RuntimeTests-1`: **0**, `wasm-automated-net9.0-WinUI-RuntimeTests-2`: **1**

<details>
<summary>Details</summary>


* `android-28-net8`: **19** changed over 824

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `CheckBox_DoubleTapValidation_Uno_UI_Samples_Content_UITests_ButtonTestsControl_CheckBox_IsEnabled_Automated`
  - `Detereminate_ProgressRing_Validation75_[#FF0000_#008000_#008000_#008000]_Progress-Ring-Value-75`
  - `DecimalFormatterTest_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage`
  - `Detereminate_ProgressRing_Validation50_[#FF0000_#008000_#008000_#FF0000]_Progress-Ring-Value-50`
  - `Detereminate_ProgressRing_Validation25_[#FF0000_#008000_#FF0000_#FF0000]_Progress-Ring-Value-25`
  - `ListView_SelectedItems_SamplesApp_Windows_UI_Xaml_Controls_ListView_ListViewSelectedItems`
  - `SequentialAnimations_SamplesApp_Windows_UI_Xaml_Media_Animation_SequentialAnimationsPage`
  - `MinMaxTest_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage`
  - `NavigateBackAndForthBetweenMenuItemsAndSettings_Fluent_SamplesApp_Samples_Microsoft_UI_Xaml_Controls_NavigationViewTests_FluentStyle_FluentStyle_NavigationViewSample`
  - `UpDownEnabledTest_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage`
  - `When_Parent_PointerMoved_After_drag_on_non-scrolling_ScrollViewer`
  - `When_Parent_PointerMoved_After_drag_on_ScrollViewer_-_touch`
  - `When_SingleSelectionWithItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_SingleSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_NoSelection_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `DoesNotInterfereWithHorizontalDrag_UITests_Microsoft_UI_Xaml_Controls_RefreshContainerTests_RefreshContainerHorizontalScroll`
  - `ProgressRing_Visibility_Collapsed_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220`
  - `ProgressRing_IsEnabled_Running_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220`
  - `WebView_NavigateToAnchor_Initial`
  </details>

* `android-28-net8-Snap`: **41** changed over 1067

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `Animations_UITests_Windows_UI_Xaml_Media_Animation_ColorAnimation_Fill_UITests_Windows_UI_Xaml_Media_Animation_ColorAnimation_Fill`
  - `MUX_NumberBox_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage`
  - `Animations_DoubleAnimation_TranslateX_GenericApp_Views_Content_UITests_Animations_DoubleAnimation_TranslateX`
  - `Border_Border_CornerRadius_Gradient_UITests_Windows_UI_Xaml_Controls_BorderTests_Border_CornerRadius_Gradient`
  - `Animations_UITests_Windows_UI_Xaml_Media_Animation_ColorAnimation_Background_UITests_Windows_UI_Xaml_Media_Animation_ColorAnimation_Background`
  - `Border_Border_CornerRadius_Clipping_UITests_Windows_UI_Xaml_Controls_BorderTests_Border_CornerRadius_Clipping`
  - `Image_UITests_Windows_UI_Xaml_Controls_ImageTests_SvgImageSource_NoSize_UITests_Windows_UI_Xaml_Controls_ImageTests_SvgImageSource_NoSize`
  - `Animations_DoubleAnimation_transforms_final_state_UITests_Windows_UI_Xaml_Media_Animation_DoubleAnimation_FinalState_Transforms`
  - `Gesture_Recognizer_Pointer_Events_test_bench_UITests_Shared_Windows_UI_Input_GestureRecognizer_PointersEvents`
  - `ListView_ListViewSelectedItems_SamplesApp_Windows_UI_Xaml_Controls_ListView_ListViewSelectedItems`
  - `Border_Border_CornerRadius_BorderThickness_UITests_Windows_UI_Xaml_Controls_BorderTests_Border_CornerRadius_BorderThickness`
  - `NavigationView_MUXControlsTestApp_NavigationViewTopNavPage_MUXControlsTestApp_NavigationViewTopNavPage`
  - `Scrolling_MUXControlsTestApp_ScrollViewDynamicPage_MUXControlsTestApp_ScrollViewDynamicPage`
  - `Animations_DoubleAnimation_VisualStates_Uno_UI_Samples_Content_UITests_Animations_DoubleAnimation_VisualStates`
  - `Animations_DoubleAnimation_RenderTransformOrigin_GenericApp_Views_Content_UITests_Animations_DoubleAnimation_RenderTransformOrigin`
  - `NavigationView_MUXControlsTestApp_NavigationViewRS4Page_MUXControlsTestApp_NavigationViewRS4Page`
  - `SwipeControl_MUXControlsTestApp_SwipeControlPage2_MUXControlsTestApp_SwipeControlPage2`
  - `Animations_DoubleAnimation_Opacity_TextBlock_GenericApp_Views_Content_UITests_Animations_DoubleAnimation_Opacity_TextBlock`
  - `Border_Border_Simple_Uno_UI_Samples_UITests_BorderTestsControl_Border_Simple`
  - `ListView_ListViewVariableItemHeight_SamplesApp_Windows_UI_Xaml_Controls_ListView_ListViewVariableItemHeight`
  </details>

* `ios`: **2** changed over 255

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `ProgressRing_Visibility_Collapsed_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220`
  - `ProgressRing_IsEnabled_Running_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220`
  </details>

* `ios-Snap`: **32** changed over 984

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `NavigationView_MUXControlsTestApp_NavigationViewMenuItemStretchPage_MUXControlsTestApp_NavigationViewMenuItemStretchPage`
  - `Default_Uno_UI_Samples_UITests_Image_Image_Margin_Uno_UI_Samples_UITests_Image_Image_Margin`
  - `Default_Uno_UI_Samples_UITests_Image_Image_UseTargetSize_Uno_UI_Samples_UITests_Image_Image_UseTargetSize`
  - `Image_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Equal_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Equal`
  - `Pickers_UITests_Windows_UI_Xaml_Controls_CalendarView_CalendarView_Theming_UITests_Windows_UI_Xaml_Controls_CalendarView_CalendarView_Theming`
  - `Brushes_ImageBrushStretch_Uno_UI_Samples_UITests_ImageBrushTestControl_ImageBrushStretch`
  - `MediaPlayerElement_Using_3gp_UITests_Shared_Windows_UI_Xaml_Controls_MediaPlayerElement_MediaPlayerElement_3gp_Extension`
  - `SwipeControl_MUXControlsTestApp_SwipeControlPage2_MUXControlsTestApp_SwipeControlPage2`
  - `Brushes_BorderImageBrush_Uno_UI_Samples_UITests_ImageBrushTestControl_BorderImageBrush`
  - `WebView_WebView2_NavigateToUri_SamplesApp_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_NavigateToUri`
  - `Image_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Horizontal_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Horizontal`
  - `Image_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Vertical_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Vertical`
  - `Image_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Alignment_SizeOnControl_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Alignment_SizeOnControl`
  - `Brushes_EllipsemaskingEllipseGrid_Uno_UI_Samples_UITests_ImageBrushTestControl_EllipsemaskingEllipseGrid`
  - `ColorPicker_ColorPickerSample_UITests_Microsoft_UI_Xaml_Controls_ColorPickerTests_ColorPickerSample`
  - `Brushes_ImageBrushWithCompositeTransform_Uno_UI_Samples_UITests_ImageBrushTestControl_ImageBrushWithCompositeTransform`
  - `MediaPlayerElement_Sources_UITests_Shared_Windows_UI_Xaml_Controls_MediaPlayerElement_MediaPlayerElement_Sources`
  - `WebView_UITests_Windows_UI_Xaml_Controls_WebView_WebView_Title_UITests_Windows_UI_Xaml_Controls_WebView_WebView_Title`
  - `WebView_WebView2_JavascriptInvoke_SamplesApp_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_JavascriptInvoke`
  - `WebView_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_Basic_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_Basic`
  </details>

* `skia-linux-screenshots`: **65** changed over 2244

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `DisplayInformation.png-dark`
  - `DisplayInformation.png`
  - `Buttons.png`
  - `ImageBrushInList.png-dark`
  - `ImageBrushInList.png`
  - `DoubleImageBrushInList.png-dark`
  - `DoubleImageBrushInList.png`
  - `Examples.png`
  - `ExpanderColorValidationPage.png-dark`
  - `ExpanderColorValidationPage.png`
  - `ButtonClippingTestsControl.png-dark`
  - `CalendarView_Theming.png`
  - `Focus_FocusVisual_Properties.png-dark`
  - `Focus_FocusVisual_Properties.png`
  - `Buttons.png-dark`
  - `AutoSuggestBox_Icons.png-dark`
  - `AutoSuggestBox_Icons.png`
  - `ImageWithLateSourceUniformToFill.png-dark`
  - `CalendarView_Theming.png-dark`
  - `CompositionEffectBrush.png-dark`
  </details>

* `skia-windows-screenshots`: **61** changed over 2244

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `CalendarView_Theming.png-dark`
  - `DisplayInformation.png`
  - `Buttons.png`
  - `ClipboardTests.png-dark`
  - `ClipboardTests.png`
  - `ImageBrushInList.png-dark`
  - `ImageBrushInList.png`
  - `ImageBrushLocalAsset.png-dark`
  - `ImageBrushLocalAsset.png`
  - `Examples.png-dark`
  - `Examples.png`
  - `Image_UseTargetSize.png-dark`
  - `Image_UseTargetSize.png`
  - `ExpanderColorValidationPage.png-dark`
  - `ExpanderColorValidationPage.png`
  - `ButtonClippingTestsControl.png`
  - `CalendarView_Theming.png`
  - `ButtonClippingTestsControl.png-dark`
  - `DoubleImageBrushInList.png-dark`
  - `DoubleImageBrushInList.png`
  </details>

* `wasm`: **42** changed over 1051

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `UITests.Shared.Windows_UI_Xaml_Controls.ListView.ListView_DataTemplateSelector`
  - `UITests.Windows_UI_Xaml_Controls.BorderTests.BorderWithNullBrushAndNonZeroThickness`
  - `SamplesApp.Windows_UI_Xaml.Clipping.DoubleAnimationClipping`
  - `SamplesApp.Windows_UI_Xaml_Controls.ListView.ListView_Inside_ListView`
  - `UITests.Windows_UI_Xaml_Controls.ImageTests.SvgImageSource_FromMsAppData`
  - `Uno.UI.Samples.Content.UITests.GridView.GridView_Item_TextBlock_And_Button`
  - `UITests.Shared.Windows_UI_Xaml_Controls.Button.Button_Events`
  - `UITests.Shared.Windows_UI_Xaml_Controls.ListView.ListView_With_ListViews_Count_Measure`
  - `UITests.Shared.Windows_UI_Xaml_Controls.Button.Overlapped_Buttons`
  - `UITests.Windows_UI_Xaml_Controls.ImageTests.BitmapImage_vs_SvgImageSource`
  - `UITests.Windows_UI_Xaml_Media.GradientBrushTests.GradientsPage`
  - `UITests.Shared.Windows_UI_Xaml_Controls.ContentDialogTests.ContentDialog_Closing`
  - `UITests.Windows_UI_Xaml.DragAndDrop.DragDrop_TestPage`
  - `UITests.Windows_UI_Xaml_Controls.CommandBar.CommandBar_Native_With_TextBox`
  - `UITests.Windows_UI_Xaml_Media_Animation.DoubleAnimation_FinalState_Opacity`
  - `SamplesApp.Windows_UI_Xaml_Controls.ListView.ListViewSelectedItems`
  - `SamplesApp.Windows_UI_Xaml_Controls.ListView.UndefinedHeightListView`
  - `UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Ogg_Extension`
  - `UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Minimal`
  - `UITests.Windows_UI_Xaml_Controls.CalendarView.CalendarView_Theming`
  </details>

* `wasm-automated-net9.0-WinUI-Benchmarks-automated`: **0** changed over 1

* `wasm-automated-net9.0-WinUI-Default-automated`: **18** changed over 876

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `When_HollowCircle2_UITests_Windows_UI_Input_PointersTests_HitTest_GeometryGroup`
  - `Default_StrokeThickness_MyEllipse`
  - `When_MaxLines_Then_AlignmentPositionIsCorrect_Uno_UI_Samples_Content_UITests_TextBlockControl_SimpleText_MaxLines_Two_With_Wrap`
  - `TestProgressRing_InitialState_UITests_Microsoft_UI_Xaml_Controls_ProgressRing_WinUIProgressRing_Features`
  - `ListView_SelectedItems_SamplesApp_Windows_UI_Xaml_Controls_ListView_ListViewSelectedItems`
  - `Default_StrokeThickness_MyPolyline`
  - `Default_StrokeThickness_MyPolygon`
  - `Default_StrokeThickness_MyLine`
  - `When_Padding_Is_Changed_Then_Cache_Is_Missed_UITests_Windows_UI_Xaml_Controls_TextBlockControl_TextBlock_MeasureCache`
  - `When_SingleSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_MultipleSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_TextTrimming_Is_Set_Then_Ellipsis_Is_Used_UITests_Windows_UI_Xaml_Controls_TextBlockControl_TextBlock_TextTrimming`
  - `Default_StrokeThickness_MyRect`
  - `When_Theme_Changed_No_Crash_UITests_Windows_UI_Xaml_Controls_CalendarView_CalendarView_Theming`
  - `ToggleCollapsedStateToVerifyClipping_UITests_Shared_Microsoft_UI_Xaml_Controls_ExpanderTests_ExpanderColorValidationPage`
  - `When_TransformToVisual_ScrollViewer_UITests_Shared_Windows_UI_Xaml_UIElementTests_TransformToVisual_ScrollViewer`
  - `Default_StrokeThickness_MyPath`
  - `SequentialAnimations_SamplesApp_Windows_UI_Xaml_Media_Animation_SequentialAnimationsPage`
  </details>

* `wasm-automated-net9.0-WinUI-RuntimeTests-0`: **1** changed over 1

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `RunRuntimeTests_SamplesApp_Samples_UnitTests_UnitTestsPage`
  </details>

* `wasm-automated-net9.0-WinUI-RuntimeTests-1`: **0** changed over 1

* `wasm-automated-net9.0-WinUI-RuntimeTests-2`: **1** changed over 1

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `RunRuntimeTests_SamplesApp_Samples_UnitTests_UnitTestsPage`
  </details>

</details>

author_association: CONTRIBUTOR