Skip to content

Commit

Permalink
Merge pull request unoplatform#14693 from ramezgerges/compositiontarg…
Browse files Browse the repository at this point in the history
…et_rendering

perf: use CompositionTarget to only render a specific target
  • Loading branch information
MartinZikmund authored Feb 7, 2024
2 parents ae8db97 + df35883 commit f274c49
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 40 deletions.
4 changes: 2 additions & 2 deletions src/Uno.UI.Composition/Composition/Compositor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ public CompositionMaskBrush CreateMaskBrush()
public CompositionNineGridBrush CreateNineGridBrush()
=> new CompositionNineGridBrush(this);

internal void InvalidateRender() => InvalidateRenderPartial();
internal void InvalidateRender(Visual visual) => InvalidateRenderPartial(visual);

partial void InvalidateRenderPartial();
partial void InvalidateRenderPartial(Visual visual);
}
}
13 changes: 2 additions & 11 deletions src/Uno.UI.Composition/Composition/Compositor.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ namespace Microsoft.UI.Composition;

public partial class Compositor
{
private bool _isDirty;

internal bool? IsSoftwareRenderer { get; set; }

internal void RenderRootVisual(SKSurface surface, ContainerVisual rootVisual)
Expand All @@ -19,18 +17,11 @@ internal void RenderRootVisual(SKSurface surface, ContainerVisual rootVisual)
throw new ArgumentNullException(nameof(rootVisual));
}

_isDirty = false;

rootVisual.RenderRootVisual(surface);
}

partial void InvalidateRenderPartial()
partial void InvalidateRenderPartial(Visual visual)
{
if (!_isDirty)
{
_isDirty = true;
// TODO: Invalidate each ContentRoot independently, including a root-specific dirty flag #8978
CoreApplication.QueueInvalidateRender();
}
CoreApplication.QueueInvalidateRender(visual.CompositionTarget);
}
}
16 changes: 8 additions & 8 deletions src/Uno.UI.Composition/Composition/Visual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public partial class Visual : CompositionObject, I3DTransformableObject
private bool _isVisible = true;
private float _opacity = 1.0f;
private CompositionCompositeMode _compositeMode;
private object? _compositionTarget; // this should be a Microsoft.UI.Xaml.Media.CompositionTarget

internal Visual(Compositor compositor) : base(compositor)
{
Expand Down Expand Up @@ -115,18 +116,17 @@ public Vector3 RotationAxis

public ContainerVisual? Parent { get; set; }

internal object? CompositionTarget
{
get => _compositionTarget ?? Parent?.CompositionTarget; // TODO: can this be cached?
set => _compositionTarget = value;
}

internal bool HasThemeShadow { get; set; }

private protected override void OnPropertyChangedCore(string? propertyName, bool isSubPropertyChange)
{
// TODO: Determine whether to invalidate renderer based on the fact whether we are attached to a CompositionTarget.
//bool isAttached = false;
//if (isAttached)
//{
// Compositor.InvalidateRender();
//}

Compositor.InvalidateRender();
Compositor.InvalidateRender(this);
}
}
}
2 changes: 1 addition & 1 deletion src/Uno.UI.Composition/Composition/Visual.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public Vector2 AnchorPoint
set
{
SetProperty(ref _anchorPoint, value);
Compositor.InvalidateRender();
Compositor.InvalidateRender(this);
}
}

Expand Down
24 changes: 14 additions & 10 deletions src/Uno.UI/UI/Xaml/Application.skia.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
#nullable enable

using System;
using System.Diagnostics;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Metadata;
using Microsoft.UI.Xaml.Controls.Primitives;
using Windows.ApplicationModel;
using Windows.Graphics.Display;
using Windows.UI.Core;
using Uno.Foundation.Logging;
using System.Threading;
using System.Globalization;
using Windows.ApplicationModel.Core;
using Windows.Globalization;
using Microsoft.UI.Xaml.Media;
using Uno.UI.Dispatching;
using Uno.UI.Xaml.Core;

Expand All @@ -34,12 +30,20 @@ partial void InitializePartial()

_ = CoreDispatcher.Main.RunAsync(CoreDispatcherPriority.Normal, Initialize);

CoreApplication.SetInvalidateRender(() =>
CoreApplication.SetInvalidateRender(compositionTarget =>
{
var roots = CoreServices.Instance.ContentRootCoordinator.ContentRoots;
for (int i = 0; i < roots.Count; i++)
Debug.Assert(compositionTarget is null or CompositionTarget);

if (compositionTarget is CompositionTarget { Root: { } root })
{
roots[i].XamlRoot?.QueueInvalidateRender();
foreach (var cRoot in CoreServices.Instance.ContentRootCoordinator.ContentRoots)
{
if (cRoot?.XamlRoot is { } xRoot && ReferenceEquals(xRoot.VisualTree.RootElement.Visual, root))
{
xRoot.QueueInvalidateRender();
return;
}
}
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ void CreateLayer(Action<CompositionSpriteShape, SKPath> builder, string name)
}
);

compositor.InvalidateRender();
compositor.InvalidateRender(visual);

return disposables;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Uno.UI/UI/Xaml/DependencyObjectStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1857,7 +1857,8 @@ private void InvokeCallbacks(
// Uno TODO: What should we do here for non-UIElements (if anything is needed)?
if (actualInstanceAlias is UIElement elt)
{
Microsoft.UI.Xaml.Hosting.ElementCompositionPreview.GetElementVisual(elt).Compositor.InvalidateRender();
var visual = Microsoft.UI.Xaml.Hosting.ElementCompositionPreview.GetElementVisual(elt);
visual.Compositor.InvalidateRender(visual);
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/Uno.UI/UI/Xaml/Internal/ContentRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
using Uno.UI.Xaml.Islands;
using Windows.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using static Microsoft/* UWP don't rename */.UI.Xaml.Controls._Tracing;

/*
Expand Down Expand Up @@ -70,6 +72,10 @@ public ContentRoot(ContentRootType type, Color backgroundColor, UIElement? rootE
FocusAdapter = new FocusAdapter(this);
FocusManager.SetFocusObserver(new FocusObserver(this));

CompositionTarget = new CompositionTarget();
CompositionTarget.Root = ElementCompositionPreview.GetElementVisual(VisualTree.RootElement);
CompositionTarget.Root.CompositionTarget = CompositionTarget;

switch (type)
{
case ContentRootType.CoreWindow:
Expand All @@ -81,6 +87,8 @@ public ContentRoot(ContentRootType type, Color backgroundColor, UIElement? rootE
}
}

internal CompositionTarget CompositionTarget { get; }

internal ContentRootType Type { get; }

/// <summary>
Expand Down
17 changes: 17 additions & 0 deletions src/Uno.UI/UI/Xaml/Media/CompositionTarget.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Microsoft.UI.Composition;
namespace Microsoft.UI.Xaml.Media;

public partial class CompositionTarget
{
private Visual _root;

internal Visual Root
{
get => _root;
set
{
_root = value;
_root.CompositionTarget = this;
}
}
}
15 changes: 9 additions & 6 deletions src/Uno.UWP/ApplicationModel/Core/CoreApplication.skia.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#nullable enable

using System;
using System.Diagnostics;
using Uno.Foundation.Logging;
using Uno.ApplicationModel.Core;
using Uno.Foundation.Extensibility;
Expand All @@ -9,7 +10,7 @@ namespace Windows.ApplicationModel.Core;

partial class CoreApplication
{
private static Action? _invalidateRender;
private static Action<object?>? _invalidateRender;
private static ICoreApplicationExtension? _coreApplicationExtension;

static partial void InitializePlatform()
Expand All @@ -32,10 +33,12 @@ private static void ExitPlatform()
}
}

internal static void SetInvalidateRender(Action invalidateRender)
// Currently we don't support multi-windowing, so we invalidate all XamlRoots
=> _invalidateRender ??= invalidateRender;
internal static void SetInvalidateRender(Action<object?> invalidateRender)
{
Debug.Assert(_invalidateRender is null);
_invalidateRender ??= invalidateRender;
}

internal static void QueueInvalidateRender()
=> _invalidateRender?.Invoke();
internal static void QueueInvalidateRender(object? visual)
=> _invalidateRender?.Invoke(visual);
}

0 comments on commit f274c49

Please sign in to comment.