From 519db10f610ede1d1db6e0dfbe9223809e6d6813 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Sat, 9 Mar 2024 09:46:33 +0000 Subject: [PATCH] Improve performance of R8Loader. The repeated small stream reads of ReadUInt16 generate a lot of overhead. Instead, consume the data in a single ReadBytes call and then unpack within the same buffer. --- OpenRA.Mods.D2k/SpriteLoaders/R8Loader.cs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/OpenRA.Mods.D2k/SpriteLoaders/R8Loader.cs b/OpenRA.Mods.D2k/SpriteLoaders/R8Loader.cs index 928aa36e4a..c91ec28101 100644 --- a/OpenRA.Mods.D2k/SpriteLoaders/R8Loader.cs +++ b/OpenRA.Mods.D2k/SpriteLoaders/R8Loader.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using OpenRA.Graphics; using OpenRA.Primitives; @@ -139,17 +140,12 @@ namespace OpenRA.Mods.D2k.SpriteLoaders Data = new byte[width * height * 4]; Type = SpriteFrameType.Bgra32; - unsafe + var data = MemoryMarshal.Cast(Data); + s.ReadBytes(Data.AsSpan()[..(Data.Length / 2)]); + for (var i = width * height - 1; i >= 0; i--) { - fixed (byte* bd = &Data[0]) - { - var data = (uint*)bd; - for (var i = 0; i < width * height; i++) - { - var packed = s.ReadUInt16(); - data[i] = (uint)((0xFF << 24) | ((packed & 0x7C00) << 9) | ((packed & 0x3E0) << 6) | ((packed & 0x1f) << 3)); - } - } + var packed = Data[i * 2 + 1] << 8 | Data[i * 2]; + data[i] = (uint)((0xFF << 24) | ((packed & 0x7C00) << 9) | ((packed & 0x3E0) << 6) | ((packed & 0x1f) << 3)); } } else @@ -166,9 +162,11 @@ namespace OpenRA.Mods.D2k.SpriteLoaders s.ReadUInt32(); Palette = new uint[256]; - for (var i = 0; i < 256; i++) + var palette = MemoryMarshal.Cast(Palette); + s.ReadBytes(palette[..(palette.Length / 2)]); + for (var i = 255; i >= 0; i--) { - var packed = s.ReadUInt16(); + var packed = palette[i * 2 + 1] << 8 | palette[i * 2]; Palette[i] = (uint)((0xFF << 24) | ((packed & 0x7C00) << 9) | ((packed & 0x3E0) << 6) | ((packed & 0x1f) << 3)); }