[Bind][ES][GL] Output entry points as byte[]

Moving from string[] to byte[] reduces startup memory allocations
tremendously (up to 70% lower memory use on Windows!)
This commit is contained in:
thefiddler 2014-04-25 17:25:20 +02:00
parent c1f284f101
commit 6257858d54
12 changed files with 92559 additions and 147857 deletions

View file

@ -168,19 +168,42 @@ namespace Bind
sw.WriteLine("static {0}()", Settings.OutputClass);
sw.WriteLine("{");
sw.Indent();
sw.WriteLine("EntryPointNames = new string[]", delegates.Count);
// Write entry point names.
// Instead of strings, which are costly to construct,
// we use a 1d array of ASCII bytes. Names are laid out
// sequentially, with a nul-terminator between them.
sw.WriteLine("EntryPointNames = new byte[]", delegates.Count);
sw.WriteLine("{");
sw.Indent();
foreach (var d in delegates.Values.Select(d => d.First()))
{
if (d.RequiresSlot(Settings))
{
sw.WriteLine("\"{0}{1}\",", Settings.FunctionPrefix, d.Name);
var name = Settings.FunctionPrefix + d.Name;
sw.WriteLine("{0}, 0,", String.Join(", ",
System.Text.Encoding.ASCII.GetBytes(name).Select(b => b.ToString()).ToArray()));
}
}
sw.Unindent();
sw.WriteLine("};");
sw.WriteLine("EntryPoints = new IntPtr[EntryPointNames.Length];");
// Write entry point name offsets.
// This is an array of offsets into the EntryPointNames[] array above.
sw.WriteLine("EntryPointNameOffsets = new int[]", delegates.Count);
sw.WriteLine("{");
sw.Indent();
int offset = 0;
foreach (var d in delegates.Values.Select(d => d.First()))
{
if (d.RequiresSlot(Settings))
{
sw.WriteLine("{0},", offset);
var name = Settings.FunctionPrefix + d.Name;
offset += name.Length + 1;
}
}
sw.Unindent();
sw.WriteLine("};");
sw.WriteLine("EntryPoints = new IntPtr[EntryPointNameOffsets.Length];");
sw.Unindent();
sw.WriteLine("}");
sw.WriteLine();

File diff suppressed because it is too large Load diff

View file

@ -16,7 +16,8 @@ namespace OpenTK.Graphics.ES11
static readonly object sync_root = new object();
static IntPtr[] EntryPoints;
static string[] EntryPointNames;
static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#region Constructors
@ -27,6 +28,7 @@ namespace OpenTK.Graphics.ES11
{
EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
}
#endregion

File diff suppressed because it is too large Load diff

View file

@ -44,7 +44,8 @@ namespace OpenTK.Graphics.ES20
static readonly object sync_root = new object();
static IntPtr[] EntryPoints;
static string[] EntryPointNames;
static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#region Constructors
@ -55,6 +56,7 @@ namespace OpenTK.Graphics.ES20
{
EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
}
#endregion

File diff suppressed because it is too large Load diff

View file

@ -44,7 +44,8 @@ namespace OpenTK.Graphics.ES30
static readonly object sync_root = new object();
static IntPtr[] EntryPoints;
static string[] EntryPointNames;
static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#region Constructors
@ -55,6 +56,7 @@ namespace OpenTK.Graphics.ES30
{
EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
}
#endregion

View file

@ -45,7 +45,9 @@ namespace OpenTK.Graphics
/// Contains the list of API entry point names.
/// This field must be set by an inheriting class.
/// </summary>
protected string[] EntryPointNamesInstance;
protected byte[] EntryPointNamesInstance;
protected int[] EntryPointNameOffsetsInstance;
/// <summary>
/// Retrieves an unmanaged function pointer to the specified function.
@ -81,9 +83,16 @@ namespace OpenTK.Graphics
throw new GraphicsContextMissingException();
IGraphicsContextInternal context_internal = context as IGraphicsContextInternal;
for (int i = 0; i < EntryPointsInstance.Length; i++)
unsafe
{
EntryPointsInstance[i] = context_internal.GetAddress(EntryPointNamesInstance[i]);
fixed (byte* name = EntryPointNamesInstance)
{
for (int i = 0; i < EntryPointsInstance.Length; i++)
{
EntryPointsInstance[i] = context_internal.GetAddress(
new IntPtr(name + EntryPointNameOffsetsInstance[i]));
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -79,7 +79,8 @@ namespace OpenTK.Graphics.OpenGL
static readonly object sync_root = new object();
static IntPtr[] EntryPoints;
static string[] EntryPointNames;
static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#endregion
@ -92,6 +93,7 @@ namespace OpenTK.Graphics.OpenGL
{
EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
}
#endregion

File diff suppressed because it is too large Load diff

View file

@ -44,7 +44,8 @@ namespace OpenTK.Graphics.OpenGL4
static readonly object sync_root = new object();
static IntPtr[] EntryPoints;
static string[] EntryPointNames;
static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#region Constructors
@ -55,6 +56,7 @@ namespace OpenTK.Graphics.OpenGL4
{
EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
}
#endregion