Merged TextPrinter optimization changes from gw-next2 branch.
This commit is contained in:
parent
11fbdbf403
commit
deadbdf6cb
7 changed files with 57 additions and 45 deletions
|
@ -494,7 +494,7 @@ namespace OpenTK.Graphics
|
|||
{
|
||||
if (!disposed)
|
||||
{
|
||||
Debug.WriteLine("Disposing context {0}.", (this as IGraphicsContextInternal).Context.ToString());
|
||||
Debug.Print("Disposing context {0}.", (this as IGraphicsContextInternal).Context.ToString());
|
||||
lock (context_lock)
|
||||
{
|
||||
available_contexts.Remove((this as IGraphicsContextInternal).Context);
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace OpenTK.Platform.Windows
|
|||
{
|
||||
try
|
||||
{
|
||||
Debug.WriteLine("Using WGL_ARB_create_context...");
|
||||
Debug.Write("Using WGL_ARB_create_context... ");
|
||||
|
||||
List<int> attributes = new List<int>();
|
||||
attributes.Add((int)ArbCreateContext.MajorVersion);
|
||||
|
@ -111,6 +111,10 @@ namespace OpenTK.Platform.Windows
|
|||
currentWindow.DeviceContext,
|
||||
sharedContext != null ? (sharedContext as IGraphicsContextInternal).Context.Handle : IntPtr.Zero,
|
||||
attributes.ToArray()));
|
||||
if (renderContext == ContextHandle.Zero)
|
||||
Debug.Print("failed. (Error: {0})", Marshal.GetLastWin32Error());
|
||||
else
|
||||
Debug.Print("success!");
|
||||
}
|
||||
catch (EntryPointNotFoundException e) { Debug.Print(e.ToString()); }
|
||||
catch (NullReferenceException e) { Debug.Print(e.ToString()); }
|
||||
|
@ -119,7 +123,7 @@ namespace OpenTK.Platform.Windows
|
|||
if (renderContext == ContextHandle.Zero)
|
||||
{
|
||||
// Failed to create GL3-level context, fall back to GL2.
|
||||
Debug.Write("failed. Falling back to GL2... ");
|
||||
Debug.Write("Falling back to GL2... ");
|
||||
renderContext = new ContextHandle(Wgl.Imports.CreateContext(currentWindow.DeviceContext));
|
||||
if (renderContext == ContextHandle.Zero)
|
||||
renderContext = new ContextHandle(Wgl.Imports.CreateContext(currentWindow.DeviceContext));
|
||||
|
|
|
@ -134,11 +134,11 @@ namespace OpenTK.Graphics
|
|||
|
||||
#endregion
|
||||
|
||||
#region End
|
||||
|
||||
/// <summary>
|
||||
/// Restores the projection and modelview matrices to their previous state.
|
||||
/// </summary>
|
||||
#region End
|
||||
|
||||
void End();
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -81,7 +81,9 @@ namespace OpenTK.Graphics.Text
|
|||
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
|
||||
using (TextExtents extents = rasterizer.MeasureText(block))
|
||||
RectangleF position;
|
||||
|
||||
using (TextExtents extents = rasterizer.MeasureText(ref block))
|
||||
{
|
||||
// Build layout
|
||||
int current = 0;
|
||||
|
@ -96,31 +98,41 @@ namespace OpenTK.Graphics.Text
|
|||
Cache.Add(glyph, rasterizer, TextQuality);
|
||||
|
||||
CachedGlyphInfo info = Cache[glyph];
|
||||
RectangleF position = extents[current++];
|
||||
position = extents[current++];
|
||||
|
||||
// Use the real glyph width instead of the measured one (we want to achieve pixel perfect output).
|
||||
position.Size = info.Rectangle.Size;
|
||||
|
||||
if (!active_lists.ContainsKey(info.Texture))
|
||||
{
|
||||
if (inactive_lists.Count > 0)
|
||||
active_lists.Add(info.Texture, inactive_lists.Dequeue());
|
||||
{
|
||||
List<Vector2> list = inactive_lists.Dequeue();
|
||||
list.Clear();
|
||||
active_lists.Add(info.Texture, list);
|
||||
}
|
||||
else
|
||||
{
|
||||
active_lists.Add(info.Texture, new List<Vector2>());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Interleaved array: Vertex, TexCoord, Vertex, ...
|
||||
active_lists[info.Texture].Add(new Vector2(info.RectangleNormalized.Left, info.RectangleNormalized.Top));
|
||||
active_lists[info.Texture].Add(new Vector2(position.Left, position.Top));
|
||||
active_lists[info.Texture].Add(new Vector2(info.RectangleNormalized.Left, info.RectangleNormalized.Bottom));
|
||||
active_lists[info.Texture].Add(new Vector2(position.Left, position.Bottom));
|
||||
active_lists[info.Texture].Add(new Vector2(info.RectangleNormalized.Right, info.RectangleNormalized.Bottom));
|
||||
active_lists[info.Texture].Add(new Vector2(position.Right, position.Bottom));
|
||||
List<Vector2> current_list = active_lists[info.Texture];
|
||||
current_list.Add(new Vector2(info.RectangleNormalized.Left, info.RectangleNormalized.Top));
|
||||
current_list.Add(new Vector2(position.Left, position.Top));
|
||||
current_list.Add(new Vector2(info.RectangleNormalized.Left, info.RectangleNormalized.Bottom));
|
||||
current_list.Add(new Vector2(position.Left, position.Bottom));
|
||||
current_list.Add(new Vector2(info.RectangleNormalized.Right, info.RectangleNormalized.Bottom));
|
||||
current_list.Add(new Vector2(position.Right, position.Bottom));
|
||||
|
||||
active_lists[info.Texture].Add(new Vector2(info.RectangleNormalized.Right, info.RectangleNormalized.Bottom));
|
||||
active_lists[info.Texture].Add(new Vector2(position.Right, position.Bottom));
|
||||
active_lists[info.Texture].Add(new Vector2(info.RectangleNormalized.Right, info.RectangleNormalized.Top));
|
||||
active_lists[info.Texture].Add(new Vector2(position.Right, position.Top));
|
||||
active_lists[info.Texture].Add(new Vector2(info.RectangleNormalized.Left, info.RectangleNormalized.Top));
|
||||
active_lists[info.Texture].Add(new Vector2(position.Left, position.Top));
|
||||
current_list.Add(new Vector2(info.RectangleNormalized.Right, info.RectangleNormalized.Bottom));
|
||||
current_list.Add(new Vector2(position.Right, position.Bottom));
|
||||
current_list.Add(new Vector2(info.RectangleNormalized.Right, info.RectangleNormalized.Top));
|
||||
current_list.Add(new Vector2(position.Right, position.Top));
|
||||
current_list.Add(new Vector2(info.RectangleNormalized.Left, info.RectangleNormalized.Top));
|
||||
current_list.Add(new Vector2(position.Left, position.Top));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,13 +144,6 @@ namespace OpenTK.Graphics.Text
|
|||
|
||||
key.Bind();
|
||||
|
||||
//if (!legacy_mode)
|
||||
//{
|
||||
// GL.PushMatrix();
|
||||
// GL.GetFloat(GetPName.Viewport, viewport);
|
||||
// GL.Scale(2.0 / (viewport[2] - viewport[0]), -2.0 / (viewport[3] - viewport[1]), 1);
|
||||
//}
|
||||
|
||||
SetColor(color);
|
||||
|
||||
GL.Begin(BeginMode.Triangles);
|
||||
|
@ -150,15 +155,12 @@ namespace OpenTK.Graphics.Text
|
|||
}
|
||||
|
||||
GL.End();
|
||||
|
||||
//if (!legacy_mode)
|
||||
// GL.PopMatrix();
|
||||
}
|
||||
|
||||
// Clean layout
|
||||
foreach (List<Vector2> list in active_lists.Values)
|
||||
{
|
||||
list.Clear();
|
||||
//list.Clear();
|
||||
inactive_lists.Enqueue(list);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ namespace OpenTK.Graphics.Text
|
|||
{
|
||||
#region Fields
|
||||
|
||||
Dictionary<TextBlock, TextExtents> block_cache = new Dictionary<TextBlock, TextExtents>();
|
||||
// Note: as an optimization, we store the TextBlock hashcode instead of the TextBlock itself.
|
||||
Dictionary<int, TextExtents> block_cache = new Dictionary<int, TextExtents>();
|
||||
System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(new Bitmap(1, 1));
|
||||
|
||||
IntPtr[] regions = new IntPtr[GdiPlus.MaxMeasurableCharacterRanges];
|
||||
|
@ -130,23 +131,24 @@ namespace OpenTK.Graphics.Text
|
|||
|
||||
#region MeasureText
|
||||
|
||||
public TextExtents MeasureText(TextBlock block)
|
||||
public TextExtents MeasureText(ref TextBlock block)
|
||||
{
|
||||
return MeasureText(block, TextQuality.Default);
|
||||
return MeasureText(ref block, TextQuality.Default);
|
||||
}
|
||||
|
||||
public TextExtents MeasureText(TextBlock block, TextQuality quality)
|
||||
public TextExtents MeasureText(ref TextBlock block, TextQuality quality)
|
||||
{
|
||||
// First, check if we have cached this text block. Do not use block_cache.TryGetValue, to avoid thrashing
|
||||
// the user's TextBlockExtents struct.
|
||||
if (block_cache.ContainsKey(block))
|
||||
return block_cache[block];
|
||||
int hashcode = block.GetHashCode();
|
||||
if (block_cache.ContainsKey(hashcode))
|
||||
return block_cache[hashcode];
|
||||
|
||||
// If this block is not cached, we have to measure it and (potentially) place it in the cache.
|
||||
TextExtents extents = MeasureTextExtents(block, quality);
|
||||
TextExtents extents = MeasureTextExtents(ref block, quality);
|
||||
|
||||
if ((block.Options & TextPrinterOptions.NoCache) == 0)
|
||||
block_cache.Add(block, extents);
|
||||
block_cache.Add(hashcode, extents);
|
||||
|
||||
return extents;
|
||||
}
|
||||
|
@ -219,7 +221,7 @@ namespace OpenTK.Graphics.Text
|
|||
|
||||
#region MeasureTextExtents
|
||||
|
||||
TextExtents MeasureTextExtents(TextBlock block, TextQuality quality)
|
||||
TextExtents MeasureTextExtents(ref TextBlock block, TextQuality quality)
|
||||
{
|
||||
// Todo: Parse layout options:
|
||||
StringFormat format = block.Font.Italic ? measure_string_format : measure_string_format_tight;
|
||||
|
@ -288,7 +290,10 @@ namespace OpenTK.Graphics.Text
|
|||
}
|
||||
}
|
||||
|
||||
extents.BoundingBox = new RectangleF(extents[0].X, extents[0].Y, max_width, max_height);
|
||||
if (extents.Count > 0)
|
||||
extents.BoundingBox = new RectangleF(extents[0].X, extents[0].Y, max_width, max_height);
|
||||
else
|
||||
extents.BoundingBox = RectangleF.Empty;
|
||||
|
||||
return extents;
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ namespace OpenTK.Graphics.Text
|
|||
{
|
||||
Bitmap Rasterize(Glyph glyph);
|
||||
Bitmap Rasterize(Glyph glyph, TextQuality quality);
|
||||
TextExtents MeasureText(TextBlock block);
|
||||
TextExtents MeasureText(TextBlock block, TextQuality quality);
|
||||
TextExtents MeasureText(ref TextBlock block);
|
||||
TextExtents MeasureText(ref TextBlock block, TextQuality quality);
|
||||
void Clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,7 +209,8 @@ namespace OpenTK.Graphics
|
|||
if (!ValidateParameters(text, font, rect))
|
||||
return TextExtents.Empty;
|
||||
|
||||
return Rasterizer.MeasureText(new TextBlock(text, font, rect, options, alignment, direction));
|
||||
TextBlock block = new TextBlock(text, font, rect, options, alignment, direction);
|
||||
return Rasterizer.MeasureText(ref block);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -311,7 +312,7 @@ namespace OpenTK.Graphics
|
|||
if (font == null)
|
||||
throw new ArgumentNullException("font");
|
||||
if (rect.Width < 0 || rect.Height < 0)
|
||||
throw new ArgumentOutOfRangeException("size");
|
||||
throw new ArgumentOutOfRangeException("rect");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue