Merge pull request #7362 from RoosterDragon/fix-shared-font-sheetbuilder
Avoid a globally shared SheetBuilder in SpriteFont.
This commit is contained in:
@@ -37,6 +37,8 @@ namespace OpenRA.Graphics
|
|||||||
readonly Queue<IVertexBuffer<Vertex>> tempBuffers = new Queue<IVertexBuffer<Vertex>>();
|
readonly Queue<IVertexBuffer<Vertex>> tempBuffers = new Queue<IVertexBuffer<Vertex>>();
|
||||||
readonly Stack<Rectangle> scissorState = new Stack<Rectangle>();
|
readonly Stack<Rectangle> scissorState = new Stack<Rectangle>();
|
||||||
|
|
||||||
|
SheetBuilder fontSheetBuilder;
|
||||||
|
|
||||||
Size? lastResolution;
|
Size? lastResolution;
|
||||||
int2? lastScroll;
|
int2? lastScroll;
|
||||||
float? lastZoom;
|
float? lastZoom;
|
||||||
@@ -94,8 +96,13 @@ namespace OpenRA.Graphics
|
|||||||
public void InitializeFonts(Manifest m)
|
public void InitializeFonts(Manifest m)
|
||||||
{
|
{
|
||||||
using (new Support.PerfTimer("SpriteFonts"))
|
using (new Support.PerfTimer("SpriteFonts"))
|
||||||
|
{
|
||||||
|
if (fontSheetBuilder != null)
|
||||||
|
fontSheetBuilder.Dispose();
|
||||||
|
fontSheetBuilder = new SheetBuilder(SheetType.BGRA);
|
||||||
Fonts = m.Fonts.ToDictionary(x => x.Key,
|
Fonts = m.Fonts.ToDictionary(x => x.Key,
|
||||||
x => new SpriteFont(Platform.ResolvePath(x.Value.First), x.Value.Second)).AsReadOnly();
|
x => new SpriteFont(Platform.ResolvePath(x.Value.First), x.Value.Second, fontSheetBuilder)).AsReadOnly();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginFrame(int2 scroll, float zoom)
|
public void BeginFrame(int2 scroll, float zoom)
|
||||||
@@ -246,6 +253,8 @@ namespace OpenRA.Graphics
|
|||||||
foreach (var buffer in tempBuffers)
|
foreach (var buffer in tempBuffers)
|
||||||
buffer.Dispose();
|
buffer.Dispose();
|
||||||
tempBuffers.Clear();
|
tempBuffers.Clear();
|
||||||
|
if (fontSheetBuilder != null)
|
||||||
|
fontSheetBuilder.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
public sealed class SheetBuilder : IDisposable
|
public sealed class SheetBuilder : IDisposable
|
||||||
{
|
{
|
||||||
|
public readonly SheetType Type;
|
||||||
readonly List<Sheet> sheets = new List<Sheet>();
|
readonly List<Sheet> sheets = new List<Sheet>();
|
||||||
readonly SheetType type;
|
|
||||||
readonly Func<Sheet> allocateSheet;
|
readonly Func<Sheet> allocateSheet;
|
||||||
|
|
||||||
Sheet current;
|
Sheet current;
|
||||||
@@ -54,7 +54,7 @@ namespace OpenRA.Graphics
|
|||||||
public SheetBuilder(SheetType t, Func<Sheet> allocateSheet)
|
public SheetBuilder(SheetType t, Func<Sheet> allocateSheet)
|
||||||
{
|
{
|
||||||
channel = TextureChannel.Red;
|
channel = TextureChannel.Red;
|
||||||
type = t;
|
Type = t;
|
||||||
current = allocateSheet();
|
current = allocateSheet();
|
||||||
sheets.Add(current);
|
sheets.Add(current);
|
||||||
this.allocateSheet = allocateSheet;
|
this.allocateSheet = allocateSheet;
|
||||||
@@ -93,7 +93,7 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
TextureChannel? NextChannel(TextureChannel t)
|
TextureChannel? NextChannel(TextureChannel t)
|
||||||
{
|
{
|
||||||
var nextChannel = (int)t + (int)type;
|
var nextChannel = (int)t + (int)Type;
|
||||||
if (nextChannel > (int)TextureChannel.Alpha)
|
if (nextChannel > (int)TextureChannel.Alpha)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
|||||||
@@ -19,26 +19,27 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
public class SpriteFont
|
public class SpriteFont
|
||||||
{
|
{
|
||||||
static Library library = new Library();
|
static readonly Library Library = new Library();
|
||||||
static SheetBuilder builder;
|
|
||||||
|
|
||||||
readonly int size;
|
readonly int size;
|
||||||
|
readonly SheetBuilder builder;
|
||||||
readonly Func<string, float> lineWidth;
|
readonly Func<string, float> lineWidth;
|
||||||
|
readonly Face face;
|
||||||
|
readonly Cache<Pair<char, Color>, GlyphInfo> glyphs;
|
||||||
|
|
||||||
public SpriteFont(string name, int size)
|
public SpriteFont(string name, int size, SheetBuilder builder)
|
||||||
{
|
{
|
||||||
this.size = size;
|
if (builder.Type != SheetType.BGRA)
|
||||||
|
throw new ArgumentException("The sheet builder must create BGRA sheets.", "builder");
|
||||||
|
|
||||||
face = new Face(library, name);
|
this.size = size;
|
||||||
|
this.builder = builder;
|
||||||
|
|
||||||
|
face = new Face(Library, name);
|
||||||
face.SetPixelSizes((uint)size, (uint)size);
|
face.SetPixelSizes((uint)size, (uint)size);
|
||||||
|
|
||||||
glyphs = new Cache<Pair<char, Color>, GlyphInfo>(CreateGlyph, Pair<char, Color>.EqualityComparer);
|
glyphs = new Cache<Pair<char, Color>, GlyphInfo>(CreateGlyph, Pair<char, Color>.EqualityComparer);
|
||||||
|
|
||||||
// setup a SheetBuilder for our private use
|
|
||||||
// TODO: SheetBuilder state is leaked between mod switches
|
|
||||||
if (builder == null)
|
|
||||||
builder = new SheetBuilder(SheetType.BGRA);
|
|
||||||
Func<char, float> characterWidth = character => glyphs[Pair.New(character, Color.White)].Advance;
|
Func<char, float> characterWidth = character => glyphs[Pair.New(character, Color.White)].Advance;
|
||||||
lineWidth = line => line.Sum(characterWidth);
|
lineWidth = line => line.Sum(characterWidth);
|
||||||
|
|
||||||
@@ -96,9 +97,6 @@ namespace OpenRA.Graphics
|
|||||||
return new int2((int)Math.Ceiling(lines.Max(lineWidth)), lines.Length * size);
|
return new int2((int)Math.Ceiling(lines.Max(lineWidth)), lines.Length * size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache<Pair<char, Color>, GlyphInfo> glyphs;
|
|
||||||
Face face;
|
|
||||||
|
|
||||||
GlyphInfo CreateGlyph(Pair<char, Color> c)
|
GlyphInfo CreateGlyph(Pair<char, Color> c)
|
||||||
{
|
{
|
||||||
face.LoadChar(c.First, LoadFlags.Default, LoadTarget.Normal);
|
face.LoadChar(c.First, LoadFlags.Default, LoadTarget.Normal);
|
||||||
|
|||||||
Reference in New Issue
Block a user