From 69c409c20d3ead0738230f9c26fbbc21626b0482 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Mon, 5 Jan 2015 23:44:41 +0000 Subject: [PATCH] Speed up depth sorting of renderables. The OrderBy overload that takes an int generating key selector is faster than the one that requires a custom comparer. We extract a function from the ScreenZPosition function that determines the Z position of a WPos with an offset, but does not account for the tileset height. For the ordering function this is fine as only the relative magnitude of the comparison keys matter, so we don't need to spend time adjusting for the tileset height, as that won't affect the sort. --- OpenRA.Game/Graphics/Renderable.cs | 16 ---------------- OpenRA.Game/Graphics/WorldRenderer.cs | 13 ++++++++++--- .../Orders/PlaceBuildingOrderGenerator.cs | 3 +-- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/OpenRA.Game/Graphics/Renderable.cs b/OpenRA.Game/Graphics/Renderable.cs index e0290eeef1..d7e3f08792 100644 --- a/OpenRA.Game/Graphics/Renderable.cs +++ b/OpenRA.Game/Graphics/Renderable.cs @@ -14,22 +14,6 @@ using System.Linq; namespace OpenRA.Graphics { - public class RenderableComparer : IComparer - { - WorldRenderer wr; - public RenderableComparer(WorldRenderer wr) - { - this.wr = wr; - } - - public int Compare(IRenderable x, IRenderable y) - { - var xOrder = wr.ScreenZPosition(x.Pos, x.ZOffset); - var yOrder = wr.ScreenZPosition(y.Pos, y.ZOffset); - return xOrder.CompareTo(yOrder); - } - } - public interface IRenderable { WPos Pos { get; } diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 072adf1635..7442affaec 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -31,6 +31,9 @@ namespace OpenRA.Graphics public sealed class WorldRenderer : IDisposable { + public static readonly Func RenderableScreenZPositionComparisonKey = + r => ZPosition(r.Pos, r.ZOffset); + public readonly World World; public readonly Theater Theater; public Viewport Viewport { get; private set; } @@ -69,7 +72,6 @@ namespace OpenRA.Graphics List GenerateRenderables() { - var comparer = new RenderableComparer(this); var actors = World.ScreenMap.ActorsInBox(Viewport.TopLeft, Viewport.BottomRight) .Append(World.WorldActor) .ToList(); @@ -82,7 +84,7 @@ namespace OpenRA.Graphics if (World.OrderGenerator != null) worldRenderables = worldRenderables.Concat(World.OrderGenerator.Render(this, World)); - worldRenderables = worldRenderables.OrderBy(r => r, comparer); + worldRenderables = worldRenderables.OrderBy(RenderableScreenZPositionComparisonKey); // Effects are drawn on top of all actors // HACK: Effects aren't interleaved with actors. @@ -241,7 +243,12 @@ namespace OpenRA.Graphics public float ScreenZPosition(WPos pos, int offset) { var ts = Game.ModData.Manifest.TileSize; - return (pos.Y + pos.Z + offset) * ts.Height / 1024f; + return ZPosition(pos, offset) * ts.Height / 1024f; + } + + static int ZPosition(WPos pos, int offset) + { + return pos.Y + pos.Z + offset; } public WPos Position(int2 screenPx) diff --git a/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs b/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs index 62dc072dc7..0ae8124769 100644 --- a/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs @@ -127,11 +127,10 @@ namespace OpenRA.Mods.RA.Orders initialized = true; } - var comparer = new RenderableComparer(wr); var offset = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo); var previewRenderables = preview .SelectMany(p => p.Render(wr, offset)) - .OrderBy(r => r, comparer); + .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey); foreach (var r in previewRenderables) yield return r;