mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 04:53:29 +01:00
further improve runtime texture packer performance by caching the first possible position for a request of a given size
This commit is contained in:
parent
61770d59b1
commit
16053d9d04
3 changed files with 17 additions and 9 deletions
|
@ -58,7 +58,7 @@ Improvements
|
||||||
- Premultiply textures when using RawContentManager
|
- Premultiply textures when using RawContentManager
|
||||||
- Allow enumerating all region names of a DataTextureAtlas
|
- Allow enumerating all region names of a DataTextureAtlas
|
||||||
- Cache RuntimeTexturePacker texture data while packing to improve performance
|
- Cache RuntimeTexturePacker texture data while packing to improve performance
|
||||||
- Improve RuntimeTexturePacker performance by checking against packed textures in the same order as packing
|
- Greatly improved RuntimeTexturePacker performance
|
||||||
|
|
||||||
Fixes
|
Fixes
|
||||||
- Fixed SoundEffectReader incorrectly claiming it could read ogg and mp3 files
|
- Fixed SoundEffectReader incorrectly claiming it could read ogg and mp3 files
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace MLEM.Data {
|
||||||
|
|
||||||
private readonly List<Request> texturesToPack = new List<Request>();
|
private readonly List<Request> texturesToPack = new List<Request>();
|
||||||
private readonly List<Request> alreadyPackedTextures = new List<Request>();
|
private readonly List<Request> alreadyPackedTextures = new List<Request>();
|
||||||
|
private readonly Dictionary<Point, Point> firstPossiblePosForSizeCache = new Dictionary<Point, Point>();
|
||||||
private readonly Dictionary<Texture2D, TextureData> dataCache = new Dictionary<Texture2D, TextureData>();
|
private readonly Dictionary<Texture2D, TextureData> dataCache = new Dictionary<Texture2D, TextureData>();
|
||||||
private readonly bool autoIncreaseMaxWidth;
|
private readonly bool autoIncreaseMaxWidth;
|
||||||
private readonly bool forcePowerOfTwo;
|
private readonly bool forcePowerOfTwo;
|
||||||
|
@ -168,6 +169,8 @@ namespace MLEM.Data {
|
||||||
var stopwatch = Stopwatch.StartNew();
|
var stopwatch = Stopwatch.StartNew();
|
||||||
foreach (var request in this.texturesToPack.OrderByDescending(t => t.Texture.Width * t.Texture.Height)) {
|
foreach (var request in this.texturesToPack.OrderByDescending(t => t.Texture.Width * t.Texture.Height)) {
|
||||||
request.PackedArea = this.FindFreeArea(request);
|
request.PackedArea = this.FindFreeArea(request);
|
||||||
|
// if this is the first position that this request fit in, no other requests of the same size will find a position before it
|
||||||
|
this.firstPossiblePosForSizeCache[request.PackedArea.Size] = request.PackedArea.Location;
|
||||||
this.alreadyPackedTextures.Add(request);
|
this.alreadyPackedTextures.Add(request);
|
||||||
}
|
}
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
|
@ -201,9 +204,7 @@ namespace MLEM.Data {
|
||||||
request.Texture.Texture.Dispose();
|
request.Texture.Texture.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.texturesToPack.Clear();
|
this.ClearTempCollections();
|
||||||
this.alreadyPackedTextures.Clear();
|
|
||||||
this.dataCache.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -212,11 +213,9 @@ namespace MLEM.Data {
|
||||||
public void Reset() {
|
public void Reset() {
|
||||||
this.PackedTexture?.Dispose();
|
this.PackedTexture?.Dispose();
|
||||||
this.PackedTexture = null;
|
this.PackedTexture = null;
|
||||||
this.texturesToPack.Clear();
|
|
||||||
this.alreadyPackedTextures.Clear();
|
|
||||||
this.dataCache.Clear();
|
|
||||||
this.LastCalculationTime = TimeSpan.Zero;
|
this.LastCalculationTime = TimeSpan.Zero;
|
||||||
this.LastPackTime = TimeSpan.Zero;
|
this.LastPackTime = TimeSpan.Zero;
|
||||||
|
this.ClearTempCollections();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
||||||
|
@ -229,7 +228,7 @@ namespace MLEM.Data {
|
||||||
size.X += request.Padding * 2;
|
size.X += request.Padding * 2;
|
||||||
size.Y += request.Padding * 2;
|
size.Y += request.Padding * 2;
|
||||||
|
|
||||||
var pos = new Point(0, 0);
|
var pos = this.firstPossiblePosForSizeCache.TryGetValue(size, out var first) ? first : Point.Zero;
|
||||||
var lowestY = int.MaxValue;
|
var lowestY = int.MaxValue;
|
||||||
while (true) {
|
while (true) {
|
||||||
var intersected = false;
|
var intersected = false;
|
||||||
|
@ -294,6 +293,13 @@ namespace MLEM.Data {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ClearTempCollections() {
|
||||||
|
this.texturesToPack.Clear();
|
||||||
|
this.alreadyPackedTextures.Clear();
|
||||||
|
this.firstPossiblePosForSizeCache.Clear();
|
||||||
|
this.dataCache.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
private static int ToPowerOfTwo(int value) {
|
private static int ToPowerOfTwo(int value) {
|
||||||
var ret = 1;
|
var ret = 1;
|
||||||
while (ret < value)
|
while (ret < value)
|
||||||
|
|
|
@ -329,7 +329,9 @@ namespace Sandbox {
|
||||||
Console.WriteLine($"Returned {r.Count} regions: {string.Join(", ", r.Select(kv => kv.Key + ": " + kv.Value.Area))}");
|
Console.WriteLine($"Returned {r.Count} regions: {string.Join(", ", r.Select(kv => kv.Key + ": " + kv.Value.Area))}");
|
||||||
}, 1, true);
|
}, 1, true);
|
||||||
packer.Pack(this.GraphicsDevice);
|
packer.Pack(this.GraphicsDevice);
|
||||||
packer.PackedTexture.SaveAsPng(File.Create("_Packed.png"), packer.PackedTexture.Width, packer.PackedTexture.Height);
|
|
||||||
|
using (var stream = File.Create("_Packed.png"))
|
||||||
|
packer.PackedTexture.SaveAsPng(stream, packer.PackedTexture.Width, packer.PackedTexture.Height);
|
||||||
|
|
||||||
this.OnDraw += (g, t) => {
|
this.OnDraw += (g, t) => {
|
||||||
this.SpriteBatch.Begin(samplerState: SamplerState.PointClamp);
|
this.SpriteBatch.Begin(samplerState: SamplerState.PointClamp);
|
||||||
|
|
Loading…
Reference in a new issue