Set world framebuffer size based on minimum zoom.

This avoids reallocating buffers each time the player changes zoom level.
This commit is contained in:
Paul Chote
2021-05-15 13:52:12 +01:00
committed by reaperrr
parent bb15bd20c0
commit 0735345674
9 changed files with 138 additions and 9 deletions

View File

@@ -18,15 +18,19 @@ namespace OpenRA.Graphics
public sealed class HardwarePalette : IDisposable
{
public ITexture Texture { get; private set; }
public ITexture ColorShifts { get; private set; }
public int Height { get; private set; }
readonly Dictionary<string, ImmutablePalette> palettes = new Dictionary<string, ImmutablePalette>();
readonly Dictionary<string, MutablePalette> mutablePalettes = new Dictionary<string, MutablePalette>();
readonly Dictionary<string, int> indices = new Dictionary<string, int>();
byte[] buffer = new byte[0];
float[] colorShiftBuffer = new float[0];
public HardwarePalette()
{
Texture = Game.Renderer.Context.CreateTexture();
ColorShifts = Game.Renderer.Context.CreateTexture();
}
public bool Contains(string name)
@@ -55,14 +59,18 @@ namespace OpenRA.Graphics
if (palettes.ContainsKey(name))
throw new InvalidOperationException($"Palette {name} has already been defined");
int index = palettes.Count;
// PERF: the first row in the palette textures is reserved as a placeholder for non-indexed sprites
// that do not have a color-shift applied. This provides a quick shortcut to avoid querying the
// color-shift texture for every pixel only to find that most are not shifted.
var index = palettes.Count + 1;
indices.Add(name, index);
palettes.Add(name, p);
if (palettes.Count > Height)
if (index >= Height)
{
Height = Exts.NextPowerOf2(palettes.Count);
Height = Exts.NextPowerOf2(index + 1);
Array.Resize(ref buffer, Height * Palette.Size * 4);
Array.Resize(ref colorShiftBuffer, Height * 4);
}
if (allowModifiers)
@@ -82,6 +90,21 @@ namespace OpenRA.Graphics
CopyBufferToTexture();
}
public void SetColorShift(string name, float hueOffset, float satOffset, float minHue, float maxHue)
{
var index = GetPaletteIndex(name);
colorShiftBuffer[4 * index + 0] = hueOffset;
colorShiftBuffer[4 * index + 1] = satOffset;
colorShiftBuffer[4 * index + 2] = minHue;
colorShiftBuffer[4 * index + 3] = maxHue;
}
public bool HasColorShift(string name)
{
var index = GetPaletteIndex(name);
return colorShiftBuffer[4 * index + 2] != 0 || colorShiftBuffer[4 * index + 3] != 0;
}
public void Initialize()
{
CopyModifiablePalettesToBuffer();
@@ -102,6 +125,7 @@ namespace OpenRA.Graphics
void CopyBufferToTexture()
{
Texture.SetData(buffer, Palette.Size, Height);
ColorShifts.SetFloatData(colorShiftBuffer, 1, Height);
}
public void ApplyModifiers(IEnumerable<IPaletteModifier> paletteMods)
@@ -125,6 +149,7 @@ namespace OpenRA.Graphics
public void Dispose()
{
Texture.Dispose();
ColorShifts.Dispose();
}
}
}

View File

@@ -28,5 +28,7 @@ namespace OpenRA.Graphics
this.index = index;
this.hardwarePalette = hardwarePalette;
}
public bool HasColorShift => hardwarePalette.HasColorShift(Name);
}
}

View File

@@ -41,6 +41,12 @@ namespace OpenRA.Graphics
this.isDecoration = isDecoration;
this.tintModifiers = tintModifiers;
this.alpha = alpha;
// PERF: Remove useless palette assignments for RGBA sprites
// HACK: This is working around the fact that palettes are defined on traits rather than sequences
// and can be removed once this has been fixed
if (sprite.Channel == TextureChannel.RGBA && !(palette?.HasColorShift ?? false))
this.palette = null;
}
public WPos Pos => pos + offset;

View File

@@ -116,14 +116,28 @@ namespace OpenRA.Graphics
nv += 6;
}
float ResolveTextureIndex(Sprite s, PaletteReference pal)
{
if (pal == null)
return 0;
// PERF: Remove useless palette assignments for RGBA sprites
// HACK: This is working around the limitation that palettes are defined on traits rather than on sequences,
// and can be removed once this has been fixed
if (s.Channel == TextureChannel.RGBA && !pal.HasColorShift)
return 0;
return pal.TextureIndex;
}
public void DrawSprite(Sprite s, in float3 location, PaletteReference pal)
{
DrawSprite(s, location, pal.TextureIndex, s.Size);
DrawSprite(s, location, ResolveTextureIndex(s, pal), s.Size);
}
public void DrawSprite(Sprite s, in float3 location, PaletteReference pal, float3 size)
{
DrawSprite(s, location, pal.TextureIndex, size);
DrawSprite(s, location, ResolveTextureIndex(s, pal), size);
}
public void DrawSprite(Sprite s, in float3 a, in float3 b, in float3 c, in float3 d)
@@ -142,7 +156,7 @@ namespace OpenRA.Graphics
public void DrawSprite(Sprite s, in float3 location, PaletteReference pal, in float3 size, in float3 tint, float alpha)
{
DrawSprite(s, location, pal.TextureIndex, size, tint, alpha);
DrawSprite(s, location, ResolveTextureIndex(s, pal), size, tint, alpha);
}
public void DrawSprite(Sprite s, in float3 a, in float3 b, in float3 c, in float3 d, in float3 tint, float alpha)
@@ -189,9 +203,10 @@ namespace OpenRA.Graphics
nv += v.Length;
}
public void SetPalette(ITexture palette)
public void SetPalette(ITexture palette, ITexture colorShifts)
{
shader.SetTexture("Palette", palette);
shader.SetTexture("ColorShifts", colorShifts);
}
public void SetViewportParams(Size screen, float depthScale, float depthOffset, int2 scroll)

View File

@@ -164,6 +164,12 @@ namespace OpenRA.Graphics
throw new InvalidDataException("Attempted to add sprite with a different blend mode");
samplers = new int2(GetOrAddSheetIndex(sprite.Sheet), GetOrAddSheetIndex((sprite as SpriteWithSecondaryData)?.SecondarySheet));
// PERF: Remove useless palette assignments for RGBA sprites
// HACK: This is working around the limitation that palettes are defined on traits rather than on sequences,
// and can be removed once this has been fixed
if (sprite.Channel == TextureChannel.RGBA && !(palette?.HasColorShift ?? false))
palette = null;
}
else
{

View File

@@ -32,6 +32,12 @@ namespace OpenRA.Graphics
this.palette = palette;
this.scale = scale;
this.alpha = alpha;
// PERF: Remove useless palette assignments for RGBA sprites
// HACK: This is working around the fact that palettes are defined on traits rather than sequences
// and can be removed once this has been fixed
if (sprite.Channel == TextureChannel.RGBA && !(palette?.HasColorShift ?? false))
this.palette = null;
}
// Does not exist in the world, so a world positions don't make sense

View File

@@ -109,6 +109,11 @@ namespace OpenRA.Graphics
palettes[name].Palette = pal;
}
public void SetPaletteColorShift(string name, float hueOffset, float satOffset, float minHue, float maxHue)
{
palette.SetColorShift(name, hueOffset, satOffset, minHue, maxHue);
}
// PERF: Avoid LINQ.
void GenerateRenderables()
{