Skip to content

Commit

Permalink
Merge pull request #5279 from peppy/less-transform-overhead
Browse files Browse the repository at this point in the history
Reduce overhead of transform processing when no transforms are present in a drawable
  • Loading branch information
smoogipoo authored Jul 1, 2022
2 parents 1ee6c01 + ff44ed7 commit 5612aa9
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 14 deletions.
11 changes: 10 additions & 1 deletion osu.Framework.Benchmarks/BenchmarkTransformUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace osu.Framework.Benchmarks
public class BenchmarkTransformUpdate : BenchmarkTest
{
private TestBox target;
private TestBox targetNoTransforms;

public override void SetUp()
{
Expand All @@ -23,7 +24,8 @@ public override void SetUp()

ManualClock clock;

target = new TestBox { Clock = new FramedClock(clock = new ManualClock()) };
targetNoTransforms = new TestBox { Clock = new FramedClock(clock = new ManualClock()) };
target = new TestBox { Clock = new FramedClock(clock) };

// transform one target member over a long period
target.RotateTo(360, transforms_count * 2);
Expand All @@ -36,6 +38,13 @@ public override void SetUp()
target.Clock.ProcessFrame();
}

[Benchmark]
public void UpdateTransformsWithNonePresent()
{
for (int i = 0; i < 10000; i++)
targetNoTransforms.UpdateTransforms();
}

[Benchmark]
public void UpdateTransformsWithManyPresent()
{
Expand Down
51 changes: 38 additions & 13 deletions osu.Framework/Graphics/Transforms/Transformable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public abstract class Transformable : ITransformable
/// <summary>
/// A lazily-initialized list of <see cref="Transform"/>s applied to this object.
/// </summary>
public IEnumerable<Transform> Transforms => targetGroupingTrackers.SelectMany(t => t.Transforms);
public IEnumerable<Transform> Transforms => targetGroupingTrackers?.SelectMany(t => t.Transforms) ?? Array.Empty<Transform>();

/// <summary>
/// Retrieves the <see cref="Transform"/>s for a given target member.
Expand All @@ -63,13 +63,16 @@ public double LatestTransformEndTime
//expiry should happen either at the end of the last transform or using the current sequence delay (whichever is highest).
double max = TransformStartTime;

foreach (var tracker in targetGroupingTrackers)
if (targetGroupingTrackers != null)
{
for (int i = 0; i < tracker.Transforms.Count; i++)
foreach (var tracker in targetGroupingTrackers)
{
var t = tracker.Transforms[i];
if (t.EndTime > max)
max = t.EndTime + 1; //adding 1ms here ensures we can expire on the current frame without issue.
for (int i = 0; i < tracker.Transforms.Count; i++)
{
var t = tracker.Transforms[i];
if (t.EndTime > max)
max = t.EndTime + 1; //adding 1ms here ensures we can expire on the current frame without issue.
}
}
}

Expand All @@ -88,37 +91,50 @@ public double LatestTransformEndTime
protected void UpdateTransforms()
{
TransformDelay = 0;

if (targetGroupingTrackers == null)
return;

updateTransforms(Time.Current);
}

private double lastUpdateTransformsTime;

private readonly List<TargetGroupingTransformTracker> targetGroupingTrackers = new List<TargetGroupingTransformTracker>();
private List<TargetGroupingTransformTracker> targetGroupingTrackers;

private TargetGroupingTransformTracker getTrackerFor(string targetMember)
{
foreach (var t in targetGroupingTrackers)
if (targetGroupingTrackers != null)
{
if (t.TargetMembers.Contains(targetMember))
return t;
foreach (var t in targetGroupingTrackers)
{
if (t.TargetMembers.Contains(targetMember))
return t;
}
}

return null;
}

private TargetGroupingTransformTracker getTrackerForGrouping(string targetGrouping, bool createIfNotExisting)
{
foreach (var t in targetGroupingTrackers)
if (targetGroupingTrackers != null)
{
if (t.TargetGrouping == targetGrouping)
return t;
foreach (var t in targetGroupingTrackers)
{
if (t.TargetGrouping == targetGrouping)
return t;
}
}

if (!createIfNotExisting)
return null;

var tracker = new TargetGroupingTransformTracker(this, targetGrouping);

targetGroupingTrackers ??= new List<TargetGroupingTransformTracker>();
targetGroupingTrackers.Add(tracker);

return tracker;
}

Expand All @@ -130,6 +146,9 @@ private TargetGroupingTransformTracker getTrackerForGrouping(string targetGroupi
/// <param name="forceRewindReprocess">Whether prior transforms should be reprocessed even if a rewind was not detected.</param>
private void updateTransforms(double time, bool forceRewindReprocess = false)
{
if (targetGroupingTrackers == null)
return;

bool rewinding = lastUpdateTransformsTime > time || forceRewindReprocess;
lastUpdateTransformsTime = time;

Expand Down Expand Up @@ -177,6 +196,9 @@ public virtual void ClearTransforms(bool propagateChildren = false, string targe
/// </param>
public virtual void ClearTransformsAfter(double time, bool propagateChildren = false, string targetMember = null)
{
if (targetGroupingTrackers == null)
return;

EnsureTransformMutationAllowed();

if (targetMember != null)
Expand Down Expand Up @@ -218,6 +240,9 @@ public virtual void ApplyTransformsAt(double time, bool propagateChildren = fals
/// </param>
public virtual void FinishTransforms(bool propagateChildren = false, string targetMember = null)
{
if (targetGroupingTrackers == null)
return;

EnsureTransformMutationAllowed();

if (targetMember != null)
Expand Down

0 comments on commit 5612aa9

Please sign in to comment.