Merge pull request #8729 from RoosterDragon/alloc-reductions

Reduce allocations
This commit is contained in:
Paul Chote
2015-07-18 12:28:07 +01:00
14 changed files with 86 additions and 48 deletions

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Graphics
readonly Renderer renderer; readonly Renderer renderer;
readonly IShader shader; readonly IShader shader;
readonly Action renderAction;
readonly Vertex[] vertices; readonly Vertex[] vertices;
int nv = 0; int nv = 0;
@@ -31,6 +32,11 @@ namespace OpenRA.Graphics
this.renderer = renderer; this.renderer = renderer;
this.shader = shader; this.shader = shader;
vertices = new Vertex[renderer.TempBufferSize]; vertices = new Vertex[renderer.TempBufferSize];
renderAction = () =>
{
renderer.SetLineWidth(LineWidth);
renderer.DrawBatch(vertices, nv, PrimitiveType.LineList);
};
} }
public float LineWidth public float LineWidth
@@ -54,11 +60,7 @@ namespace OpenRA.Graphics
if (nv > 0) if (nv > 0)
{ {
renderer.Device.SetBlendMode(BlendMode.Alpha); renderer.Device.SetBlendMode(BlendMode.Alpha);
shader.Render(() => shader.Render(renderAction);
{
renderer.SetLineWidth(LineWidth);
renderer.DrawBatch(vertices, nv, PrimitiveType.LineList);
});
renderer.Device.SetBlendMode(BlendMode.None); renderer.Device.SetBlendMode(BlendMode.None);
nv = 0; nv = 0;

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System;
using System.Drawing; using System.Drawing;
namespace OpenRA.Graphics namespace OpenRA.Graphics
@@ -16,6 +17,7 @@ namespace OpenRA.Graphics
{ {
readonly Renderer renderer; readonly Renderer renderer;
readonly IShader shader; readonly IShader shader;
readonly Action renderAction;
readonly Vertex[] vertices; readonly Vertex[] vertices;
int nv = 0; int nv = 0;
@@ -25,6 +27,7 @@ namespace OpenRA.Graphics
this.renderer = renderer; this.renderer = renderer;
this.shader = shader; this.shader = shader;
vertices = new Vertex[renderer.TempBufferSize]; vertices = new Vertex[renderer.TempBufferSize];
renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList);
} }
public void Flush() public void Flush()
@@ -32,7 +35,7 @@ namespace OpenRA.Graphics
if (nv > 0) if (nv > 0)
{ {
renderer.Device.SetBlendMode(BlendMode.Alpha); renderer.Device.SetBlendMode(BlendMode.Alpha);
shader.Render(() => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList)); shader.Render(renderAction);
renderer.Device.SetBlendMode(BlendMode.None); renderer.Device.SetBlendMode(BlendMode.None);
nv = 0; nv = 0;

View File

@@ -17,6 +17,7 @@ namespace OpenRA.Graphics
{ {
readonly Renderer renderer; readonly Renderer renderer;
readonly IShader shader; readonly IShader shader;
readonly Action renderAction;
readonly Vertex[] vertices; readonly Vertex[] vertices;
Sheet currentSheet; Sheet currentSheet;
@@ -28,6 +29,7 @@ namespace OpenRA.Graphics
this.renderer = renderer; this.renderer = renderer;
this.shader = shader; this.shader = shader;
vertices = new Vertex[renderer.TempBufferSize]; vertices = new Vertex[renderer.TempBufferSize];
renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList);
} }
public void Flush() public void Flush()
@@ -37,7 +39,7 @@ namespace OpenRA.Graphics
shader.SetTexture("DiffuseTexture", currentSheet.GetTexture()); shader.SetTexture("DiffuseTexture", currentSheet.GetTexture());
renderer.Device.SetBlendMode(currentBlend); renderer.Device.SetBlendMode(currentBlend);
shader.Render(() => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList)); shader.Render(renderAction);
renderer.Device.SetBlendMode(BlendMode.None); renderer.Device.SetBlendMode(BlendMode.None);
nv = 0; nv = 0;

View File

@@ -21,6 +21,10 @@ namespace OpenRA.Graphics
public static readonly Func<IRenderable, int> RenderableScreenZPositionComparisonKey = public static readonly Func<IRenderable, int> RenderableScreenZPositionComparisonKey =
r => ZPosition(r.Pos, r.ZOffset); r => ZPosition(r.Pos, r.ZOffset);
const int RangeCircleSegments = 32;
static readonly int[][] RangeCircleStartRotations = Exts.MakeArray(RangeCircleSegments, i => WRot.FromFacing(8 * i).AsMatrix());
static readonly int[][] RangeCircleEndRotations = Exts.MakeArray(RangeCircleSegments, i => WRot.FromFacing(8 * i + 6).AsMatrix());
public readonly World World; public readonly World World;
public readonly Theater Theater; public readonly Theater Theater;
public Viewport Viewport { get; private set; } public Viewport Viewport { get; private set; }
@@ -197,10 +201,10 @@ namespace OpenRA.Graphics
public void DrawRangeCircle(WPos pos, WDist range, Color c) public void DrawRangeCircle(WPos pos, WDist range, Color c)
{ {
var offset = new WVec(range.Length, 0, 0); var offset = new WVec(range.Length, 0, 0);
for (var i = 0; i < 32; i++) for (var i = 0; i < RangeCircleSegments; i++)
{ {
var pa = pos + offset.Rotate(WRot.FromFacing(8 * i)); var pa = pos + offset.Rotate(RangeCircleStartRotations[i]);
var pb = pos + offset.Rotate(WRot.FromFacing(8 * i + 6)); var pb = pos + offset.Rotate(RangeCircleEndRotations[i]);
Game.Renderer.WorldLineRenderer.DrawLine(ScreenPosition(pa), ScreenPosition(pb), c); Game.Renderer.WorldLineRenderer.DrawLine(ScreenPosition(pa), ScreenPosition(pb), c);
} }
} }
@@ -240,17 +244,28 @@ namespace OpenRA.Graphics
} }
// For scaling vectors to pixel sizes in the voxel renderer // For scaling vectors to pixel sizes in the voxel renderer
public float[] ScreenVector(WVec vec) public void ScreenVectorComponents(WVec vec, out float x, out float y, out float z)
{ {
var ts = Game.ModData.Manifest.TileSize; var ts = Game.ModData.Manifest.TileSize;
return new float[] { ts.Width * vec.X / 1024f, ts.Height * vec.Y / 1024f, ts.Height * vec.Z / 1024f, 1 }; x = ts.Width * vec.X / 1024f;
y = ts.Height * vec.Y / 1024f;
z = ts.Height * vec.Z / 1024f;
}
// For scaling vectors to pixel sizes in the voxel renderer
public float[] ScreenVector(WVec vec)
{
float x, y, z;
ScreenVectorComponents(vec, out x, out y, out z);
return new[] { x, y, z, 1f };
} }
public int2 ScreenPxOffset(WVec vec) public int2 ScreenPxOffset(WVec vec)
{ {
// Round to nearest pixel // Round to nearest pixel
var px = ScreenVector(vec); float x, y, z;
return new int2((int)Math.Round(px[0]), (int)Math.Round(px[1] - px[2])); ScreenVectorComponents(vec, out x, out y, out z);
return new int2((int)Math.Round(x), (int)Math.Round(y - z));
} }
public float ScreenZPosition(WPos pos, int offset) public float ScreenZPosition(WPos pos, int offset)

View File

@@ -32,6 +32,14 @@ namespace OpenRA.Traits
Ally = 4, Ally = 4,
} }
public static class StanceExts
{
public static bool HasStance(this Stance s, Stance stance)
{
return (s & stance) == stance;
}
}
[Flags] [Flags]
public enum ImpactType public enum ImpactType
{ {

View File

@@ -43,7 +43,12 @@ namespace OpenRA
public WVec Rotate(WRot rot) public WVec Rotate(WRot rot)
{ {
var mtx = rot.AsMatrix(); return Rotate(rot.AsMatrix());
}
public WVec Rotate(int[] rotationMatrix)
{
var mtx = rotationMatrix;
var lx = (long)X; var lx = (long)X;
var ly = (long)Y; var ly = (long)Y;
var lz = (long)Z; var lz = (long)Z;

View File

@@ -151,8 +151,9 @@ namespace OpenRA.Mods.Common.Graphics
var worldTransform = v.RotationFunc().Reverse().Aggregate(scaleTransform, var worldTransform = v.RotationFunc().Reverse().Aggregate(scaleTransform,
(x, y) => Util.MatrixMultiply(x, Util.MakeFloatMatrix(y.AsMatrix()))); (x, y) => Util.MatrixMultiply(x, Util.MakeFloatMatrix(y.AsMatrix())));
var pxOffset = wr.ScreenVector(v.OffsetFunc()); float sx, sy, sz;
var pxPos = pxOrigin + new float2(pxOffset[0], pxOffset[1]); wr.ScreenVectorComponents(v.OffsetFunc(), out sx, out sy, out sz);
var pxPos = pxOrigin + new float2(sx, sy);
var screenTransform = Util.MatrixMultiply(cameraTransform, worldTransform); var screenTransform = Util.MatrixMultiply(cameraTransform, worldTransform);
DrawBoundsBox(pxPos, screenTransform, bounds, Color.Yellow); DrawBoundsBox(pxPos, screenTransform, bounds, Color.Yellow);
} }
@@ -204,8 +205,9 @@ namespace OpenRA.Mods.Common.Graphics
var worldTransform = v.RotationFunc().Reverse().Aggregate(scaleTransform, var worldTransform = v.RotationFunc().Reverse().Aggregate(scaleTransform,
(x, y) => Util.MatrixMultiply(x, Util.MakeFloatMatrix(y.AsMatrix()))); (x, y) => Util.MatrixMultiply(x, Util.MakeFloatMatrix(y.AsMatrix())));
var pxOffset = wr.ScreenVector(v.OffsetFunc()); float sx, sy, sz;
var pxPos = pxOrigin + new float2(pxOffset[0], pxOffset[1]); wr.ScreenVectorComponents(v.OffsetFunc(), out sx, out sy, out sz);
var pxPos = pxOrigin + new float2(sx, sy);
var screenTransform = Util.MatrixMultiply(cameraTransform, worldTransform); var screenTransform = Util.MatrixMultiply(cameraTransform, worldTransform);
for (var i = 0; i < 8; i++) for (var i = 0; i < 8; i++)

View File

@@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Traits
return true; return true;
var stance = self.Owner.Stances[byPlayer]; var stance = self.Owner.Stances[byPlayer];
return info.AlwaysVisibleStances.HasFlag(stance) || visible[byPlayer]; return info.AlwaysVisibleStances.HasStance(stance) || visible[byPlayer];
} }
public void Tick(Actor self) public void Tick(Actor self)

View File

@@ -54,7 +54,7 @@ namespace OpenRA.Mods.Common.Traits
return true; return true;
var stance = self.Owner.Stances[byPlayer]; var stance = self.Owner.Stances[byPlayer];
return Info.AlwaysVisibleStances.HasFlag(stance) || IsVisibleInner(self, byPlayer); return Info.AlwaysVisibleStances.HasStance(stance) || IsVisibleInner(self, byPlayer);
} }
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r) public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)

View File

@@ -111,22 +111,22 @@ namespace OpenRA.Mods.Common.Traits
public class Passenger : IIssueOrder, IResolveOrder, IOrderVoice, INotifyRemovedFromWorld public class Passenger : IIssueOrder, IResolveOrder, IOrderVoice, INotifyRemovedFromWorld
{ {
public readonly PassengerInfo Info; public readonly PassengerInfo Info;
public Passenger(PassengerInfo info) { Info = info; } public Passenger(PassengerInfo info)
{
Info = info;
Func<Actor, bool> canTarget = IsCorrectCargoType;
Func<Actor, bool> useEnterCursor = CanEnter;
Orders = new EnterAlliedActorTargeter<Cargo>[]
{
new EnterTransportTargeter("EnterTransport", 5, canTarget, useEnterCursor, Info.AlternateTransportsMode),
new EnterTransportsTargeter("EnterTransports", 5, canTarget, useEnterCursor, Info.AlternateTransportsMode)
};
}
public Actor Transport; public Actor Transport;
public Cargo ReservedCargo { get; private set; } public Cargo ReservedCargo { get; private set; }
public IEnumerable<IOrderTargeter> Orders public IEnumerable<IOrderTargeter> Orders { get; private set; }
{
get
{
yield return new EnterTransportTargeter("EnterTransport", 5,
target => IsCorrectCargoType(target), target => CanEnter(target),
Info.AlternateTransportsMode);
yield return new EnterTransportsTargeter("EnterTransports", 5,
target => IsCorrectCargoType(target), target => CanEnter(target),
Info.AlternateTransportsMode);
}
}
public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued) public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
{ {

View File

@@ -10,6 +10,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Traits; using OpenRA.Traits;
@@ -87,27 +88,27 @@ namespace OpenRA.Mods.Common.Traits
public IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr) public IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr)
{ {
if (IsTraitDisabled) if (IsTraitDisabled)
yield break; return Enumerable.Empty<IRenderable>();
if (self.IsDead || !self.IsInWorld) if (self.IsDead || !self.IsInWorld)
yield break; return Enumerable.Empty<IRenderable>();
if (anim == null) if (anim == null)
yield break; return Enumerable.Empty<IRenderable>();
var allied = self.Owner.IsAlliedWith(self.World.RenderPlayer); var allied = self.Owner.IsAlliedWith(self.World.RenderPlayer);
if (!allied && !info.ShowToEnemies) if (!allied && !info.ShowToEnemies)
yield break; return Enumerable.Empty<IRenderable>();
if (allied && !info.ShowToAllies) if (allied && !info.ShowToAllies)
yield break; return Enumerable.Empty<IRenderable>();
if (!ShouldRender(self)) if (!ShouldRender(self))
yield break; return Enumerable.Empty<IRenderable>();
if (self.World.FogObscures(self)) if (self.World.FogObscures(self))
yield break; return Enumerable.Empty<IRenderable>();
var pxPos = wr.ScreenPxPosition(self.CenterPosition); var pxPos = wr.ScreenPxPosition(self.CenterPosition);
var actorBounds = self.Bounds; var actorBounds = self.Bounds;
@@ -150,7 +151,7 @@ namespace OpenRA.Mods.Common.Traits
anim.Tick(); anim.Tick();
yield return new SpriteRenderable(img, renderPos, WVec.Zero, info.ZOffset, wr.Palette(info.Palette), info.Scale, true); return new IRenderable[] { new SpriteRenderable(img, renderPos, WVec.Zero, info.ZOffset, wr.Palette(info.Palette), info.Scale, true) };
} }
} }
} }

View File

@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Traits
public string TooltipForPlayerStance(Stance stance) public string TooltipForPlayerStance(Stance stance)
{ {
if (stance == Stance.None || !GenericVisibility.HasFlag(stance)) if (stance == Stance.None || !GenericVisibility.HasStance(stance))
return Name; return Name;
if (GenericStancePrefix && stance == Stance.Ally) if (GenericStancePrefix && stance == Stance.Ally)

View File

@@ -95,7 +95,7 @@ namespace OpenRA.Mods.Common.Traits
return; return;
var stance = self.Owner.Stances[a.Owner]; var stance = self.Owner.Stances[a.Owner];
if (!info.ValidStances.HasFlag(stance)) if (!info.ValidStances.HasStance(stance))
return; return;
var um = a.TraitOrDefault<UpgradeManager>(); var um = a.TraitOrDefault<UpgradeManager>();
@@ -110,7 +110,7 @@ namespace OpenRA.Mods.Common.Traits
if ((produced.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= info.Range.LengthSquared) if ((produced.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= info.Range.LengthSquared)
{ {
var stance = self.Owner.Stances[produced.Owner]; var stance = self.Owner.Stances[produced.Owner];
if (!info.ValidStances.HasFlag(stance)) if (!info.ValidStances.HasStance(stance))
return; return;
var um = produced.TraitOrDefault<UpgradeManager>(); var um = produced.TraitOrDefault<UpgradeManager>();
@@ -127,7 +127,7 @@ namespace OpenRA.Mods.Common.Traits
return; return;
var stance = self.Owner.Stances[a.Owner]; var stance = self.Owner.Stances[a.Owner];
if (!info.ValidStances.HasFlag(stance)) if (!info.ValidStances.HasStance(stance))
return; return;
var um = a.TraitOrDefault<UpgradeManager>(); var um = a.TraitOrDefault<UpgradeManager>();

View File

@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Warheads
return false; return false;
var stance = firedBy.Owner.Stances[victim.Owner]; var stance = firedBy.Owner.Stances[victim.Owner];
if (!ValidStances.HasFlag(stance)) if (!ValidStances.HasStance(stance))
return false; return false;
// A target type is valid if it is in the valid targets list, and not in the invalid targets list. // A target type is valid if it is in the valid targets list, and not in the invalid targets list.
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Warheads
// AffectsParent checks do not make sense for FrozenActors, so skip to stance checks // AffectsParent checks do not make sense for FrozenActors, so skip to stance checks
var stance = firedBy.Owner.Stances[victim.Owner]; var stance = firedBy.Owner.Stances[victim.Owner];
if (!ValidStances.HasFlag(stance)) if (!ValidStances.HasStance(stance))
return false; return false;
// A target type is valid if it is in the valid targets list, and not in the invalid targets list. // A target type is valid if it is in the valid targets list, and not in the invalid targets list.