[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("static {0}()", Settings.OutputClass);
sw.WriteLine("{"); sw.WriteLine("{");
sw.Indent(); 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.WriteLine("{");
sw.Indent(); sw.Indent();
foreach (var d in delegates.Values.Select(d => d.First())) foreach (var d in delegates.Values.Select(d => d.First()))
{ {
if (d.RequiresSlot(Settings)) 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.Unindent();
sw.WriteLine("};"); 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.Unindent();
sw.WriteLine("}"); sw.WriteLine("}");
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 readonly object sync_root = new object();
static IntPtr[] EntryPoints; static IntPtr[] EntryPoints;
static string[] EntryPointNames; static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#region Constructors #region Constructors
@ -27,6 +28,7 @@ namespace OpenTK.Graphics.ES11
{ {
EntryPointsInstance = EntryPoints; EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames; EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
} }
#endregion #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 readonly object sync_root = new object();
static IntPtr[] EntryPoints; static IntPtr[] EntryPoints;
static string[] EntryPointNames; static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#region Constructors #region Constructors
@ -55,6 +56,7 @@ namespace OpenTK.Graphics.ES20
{ {
EntryPointsInstance = EntryPoints; EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames; EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
} }
#endregion #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 readonly object sync_root = new object();
static IntPtr[] EntryPoints; static IntPtr[] EntryPoints;
static string[] EntryPointNames; static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#region Constructors #region Constructors
@ -55,6 +56,7 @@ namespace OpenTK.Graphics.ES30
{ {
EntryPointsInstance = EntryPoints; EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames; EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
} }
#endregion #endregion

View file

@ -45,7 +45,9 @@ namespace OpenTK.Graphics
/// Contains the list of API entry point names. /// Contains the list of API entry point names.
/// This field must be set by an inheriting class. /// This field must be set by an inheriting class.
/// </summary> /// </summary>
protected string[] EntryPointNamesInstance; protected byte[] EntryPointNamesInstance;
protected int[] EntryPointNameOffsetsInstance;
/// <summary> /// <summary>
/// Retrieves an unmanaged function pointer to the specified function. /// Retrieves an unmanaged function pointer to the specified function.
@ -81,9 +83,16 @@ namespace OpenTK.Graphics
throw new GraphicsContextMissingException(); throw new GraphicsContextMissingException();
IGraphicsContextInternal context_internal = context as IGraphicsContextInternal; 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 readonly object sync_root = new object();
static IntPtr[] EntryPoints; static IntPtr[] EntryPoints;
static string[] EntryPointNames; static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#endregion #endregion
@ -92,6 +93,7 @@ namespace OpenTK.Graphics.OpenGL
{ {
EntryPointsInstance = EntryPoints; EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames; EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
} }
#endregion #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 readonly object sync_root = new object();
static IntPtr[] EntryPoints; static IntPtr[] EntryPoints;
static string[] EntryPointNames; static byte[] EntryPointNames;
static int[] EntryPointNameOffsets;
#region Constructors #region Constructors
@ -55,6 +56,7 @@ namespace OpenTK.Graphics.OpenGL4
{ {
EntryPointsInstance = EntryPoints; EntryPointsInstance = EntryPoints;
EntryPointNamesInstance = EntryPointNames; EntryPointNamesInstance = EntryPointNames;
EntryPointNameOffsetsInstance = EntryPointNameOffsets;
} }
#endregion #endregion