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