Merge pull request #7362 from RoosterDragon/fix-shared-font-sheetbuilder

Avoid a globally shared SheetBuilder in SpriteFont.
This commit is contained in:
Matthias Mailänder
2015-01-25 19:48:54 +01:00
3 changed files with 24 additions and 17 deletions

View File

@@ -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();
} }
} }
} }

View File

@@ -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;

View File

@@ -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);