Skip to content

Commit

Permalink
feat: only "repaint" Visuals that actually changed
Browse files Browse the repository at this point in the history
  • Loading branch information
ramezgerges committed May 3, 2024
1 parent 703f3cb commit ec00c67
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 17 deletions.
12 changes: 11 additions & 1 deletion src/Uno.UI.Composition/Composition/ContainerVisual.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ partial void InitializePartial()
Children.CollectionChanged += (s, e) => IsChildrenRenderOrderDirty = true;
}

private protected override List<Visual>? GetChildrenInRenderOrder()
internal List<Visual> GetChildrenInRenderOrder()
{
if (IsChildrenRenderOrderDirty)
{
Expand Down Expand Up @@ -61,4 +61,14 @@ internal override bool SetMatrixDirty()

return false;
}

internal override void Render(in DrawingSession parentSession)
{
base.Render(in parentSession);

foreach (var child in GetChildrenInRenderOrder())
{
child.Render(in parentSession);
}
}
}
1 change: 1 addition & 0 deletions src/Uno.UI.Composition/Composition/Visual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ internal ICompositionTarget? CompositionTarget
private protected override void OnPropertyChangedCore(string? propertyName, bool isSubPropertyChange)
{
Compositor.InvalidateRender(this);
InvalidatePaint(); // TODO: only repaint when "dependent" properties are changed
}

internal override object GetAnimatableProperty(string propertyName, string subPropertyName)
Expand Down
40 changes: 27 additions & 13 deletions src/Uno.UI.Composition/Composition/Visual.skia.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#nullable enable
//#define TRACE_COMPOSITION

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
Expand All @@ -19,9 +20,24 @@ public partial class Visual : global::Microsoft.UI.Composition.CompositionObject
private int _zIndex;
private bool _matrixDirty = true;
private Matrix4x4 _totalMatrix = Matrix4x4.Identity;
private bool _requiresRepaint = true;
private SKPictureRecorder? _recorder;
private SKPicture? _picture;

/// <returns>true if wasn't dirty</returns>
internal virtual bool SetMatrixDirty() => _matrixDirty = true;
internal virtual bool SetMatrixDirty()
{
var matrixDirty = _matrixDirty;
_matrixDirty = true;
return !matrixDirty;
}

internal void InvalidatePaint()
{
_picture?.Dispose();
_picture = null;
_requiresRepaint = true;
}

/// <summary>
/// This is the final transformation matrix from the origin to this Visual.
Expand Down Expand Up @@ -160,15 +176,11 @@ internal void RenderRootVisual(SKSurface surface, bool ignoreLocation = false)
}
}

private protected virtual List<Visual>? GetChildrenInRenderOrder() => null;

internal List<Visual>? GetChildrenInRenderOrderTestingOnly() => GetChildrenInRenderOrder();

/// <summary>
/// Position a sub visual on the canvas and draw its content.
/// </summary>
/// <param name="parentSession">The drawing session of the <see cref="Parent"/> visual.</param>
internal void Render(in DrawingSession parentSession)
internal virtual void Render(in DrawingSession parentSession)
{
#if TRACE_COMPOSITION
var indent = int.TryParse(Comment?.Split(new char[] { '-' }, 2, StringSplitOptions.TrimEntries).FirstOrDefault(), out var depth)
Expand All @@ -183,15 +195,17 @@ internal void Render(in DrawingSession parentSession)
}

using var session = BeginDrawing(in parentSession);
Draw(in session);

if (GetChildrenInRenderOrder() is { } children)
if (_requiresRepaint)
{
foreach (var child in children)
{
child.Render(in session);
}
_requiresRepaint = false;
_recorder ??= new SKPictureRecorder();
var recorderSession = session with { Canvas = _recorder.BeginRecording(new SKRect(float.NegativeInfinity, float.NegativeInfinity, float.PositiveInfinity, float.PositiveInfinity)) };
// To debug what exactly gets repainted, replace the following line with `Draw(in session);`
Draw(in recorderSession);
_picture = _recorder.EndRecording();
}

session.Canvas.DrawPicture(_picture);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ public void When_Children_Change()
var shape = compositor.CreateShapeVisual();
containerVisual.Children.InsertAtTop(shape);
Assert.IsTrue(containerVisual.IsChildrenRenderOrderDirty);
var children = containerVisual.GetChildrenInRenderOrderTestingOnly();
var children = containerVisual.GetChildrenInRenderOrder();
Assert.IsFalse(containerVisual.IsChildrenRenderOrderDirty);
Assert.AreEqual(1, children.Count);

containerVisual.Children.InsertAtTop(compositor.CreateShapeVisual());
Assert.IsTrue(containerVisual.IsChildrenRenderOrderDirty);
children = containerVisual.GetChildrenInRenderOrderTestingOnly();
children = containerVisual.GetChildrenInRenderOrder();
Assert.IsFalse(containerVisual.IsChildrenRenderOrderDirty);
Assert.AreEqual(2, children.Count);

containerVisual.Children.Remove(shape);
Assert.IsTrue(containerVisual.IsChildrenRenderOrderDirty);
children = containerVisual.GetChildrenInRenderOrderTestingOnly();
children = containerVisual.GetChildrenInRenderOrder();
Assert.IsFalse(containerVisual.IsChildrenRenderOrderDirty);
Assert.AreEqual(1, children.Count);
}
Expand Down

0 comments on commit ec00c67

Please sign in to comment.