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 Stack<Rectangle> scissorState = new Stack<Rectangle>();
SheetBuilder fontSheetBuilder;
Size? lastResolution;
int2? lastScroll;
float? lastZoom;
@@ -94,8 +96,13 @@ namespace OpenRA.Graphics
public void InitializeFonts(Manifest m)
{
using (new Support.PerfTimer("SpriteFonts"))
{
if (fontSheetBuilder != null)
fontSheetBuilder.Dispose();
fontSheetBuilder = new SheetBuilder(SheetType.BGRA);
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)
@@ -246,6 +253,8 @@ namespace OpenRA.Graphics
foreach (var buffer in tempBuffers)
buffer.Dispose();
tempBuffers.Clear();
if (fontSheetBuilder != null)
fontSheetBuilder.Dispose();
}
}
}

View File

@@ -31,8 +31,8 @@ namespace OpenRA.Graphics
public sealed class SheetBuilder : IDisposable
{
public readonly SheetType Type;
readonly List<Sheet> sheets = new List<Sheet>();
readonly SheetType type;
readonly Func<Sheet> allocateSheet;
Sheet current;
@@ -54,7 +54,7 @@ namespace OpenRA.Graphics
public SheetBuilder(SheetType t, Func<Sheet> allocateSheet)
{
channel = TextureChannel.Red;
type = t;
Type = t;
current = allocateSheet();
sheets.Add(current);
this.allocateSheet = allocateSheet;
@@ -93,7 +93,7 @@ namespace OpenRA.Graphics
TextureChannel? NextChannel(TextureChannel t)
{
var nextChannel = (int)t + (int)type;
var nextChannel = (int)t + (int)Type;
if (nextChannel > (int)TextureChannel.Alpha)
return null;

View File

@@ -19,26 +19,27 @@ namespace OpenRA.Graphics
{
public class SpriteFont
{
static Library library = new Library();
static SheetBuilder builder;
static readonly Library Library = new Library();
readonly int size;
readonly SheetBuilder builder;
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);
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;
lineWidth = line => line.Sum(characterWidth);
@@ -96,9 +97,6 @@ namespace OpenRA.Graphics
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)
{
face.LoadChar(c.First, LoadFlags.Default, LoadTarget.Normal);