diff --git a/Avalonia.sln b/Avalonia.sln
index 76d8a145244..f71a94888d5 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -186,6 +186,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Designer.HostApp.N
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.UnitTests", "tests\Avalonia.Skia.UnitTests\Avalonia.Skia.UnitTests.csproj", "{E1240B49-7B4B-4371-A00E-068778C5CF0B}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.OpenGL", "src\Avalonia.OpenGL\Avalonia.OpenGL.csproj", "{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
@@ -1663,6 +1665,30 @@ Global
{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|iPhone.Build.0 = Release|Any CPU
{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhone.Build.0 = Release|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/packages.cake b/packages.cake
index 9defa3004cd..fea45153f19 100644
--- a/packages.cake
+++ b/packages.cake
@@ -167,6 +167,7 @@ public class Packages
new [] { "./src/", "Avalonia.Logging.Serilog"},
new [] { "./src/", "Avalonia.Visuals"},
new [] { "./src/", "Avalonia.Styling"},
+ new [] { "./src/", "Avalonia.OpenGL"},
new [] { "./src/", "Avalonia.Themes.Default"},
new [] { "./src/Markup/", "Avalonia.Markup"},
new [] { "./src/Markup/", "Avalonia.Markup.Xaml"},
diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj
index bc068857ff1..3d13169aa81 100644
--- a/src/Avalonia.Base/Avalonia.Base.csproj
+++ b/src/Avalonia.Base/Avalonia.Base.csproj
@@ -3,6 +3,7 @@
netstandard2.0Avalonia.BaseAvalonia
+ True
diff --git a/src/Avalonia.Base/Platform/Interop/IDynamicLibraryLoader.cs b/src/Avalonia.Base/Platform/Interop/IDynamicLibraryLoader.cs
new file mode 100644
index 00000000000..8124ce6bc4c
--- /dev/null
+++ b/src/Avalonia.Base/Platform/Interop/IDynamicLibraryLoader.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace Avalonia.Platform.Interop
+{
+ public interface IDynamicLibraryLoader
+ {
+ IntPtr LoadLibrary(string dll);
+ IntPtr GetProcAddress(IntPtr dll, string proc, bool optional);
+ }
+
+ public class DynamicLibraryLoaderException : Exception
+ {
+ public DynamicLibraryLoaderException(string message) : base(message)
+ {
+
+ }
+ }
+}
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Utf8Buffer.cs b/src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs
similarity index 94%
rename from src/Gtk/Avalonia.Gtk3/Interop/Utf8Buffer.cs
rename to src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs
index c932aac9503..dc7a3e5634d 100644
--- a/src/Gtk/Avalonia.Gtk3/Interop/Utf8Buffer.cs
+++ b/src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs
@@ -2,9 +2,9 @@
using System.Runtime.InteropServices;
using System.Text;
-namespace Avalonia.Gtk3.Interop
+namespace Avalonia.Platform.Interop
{
- class Utf8Buffer : SafeHandle
+ public class Utf8Buffer : SafeHandle
{
private GCHandle _gchandle;
private byte[] _data;
diff --git a/src/Avalonia.OpenGL/Avalonia.OpenGL.csproj b/src/Avalonia.OpenGL/Avalonia.OpenGL.csproj
new file mode 100644
index 00000000000..310d0c8dba2
--- /dev/null
+++ b/src/Avalonia.OpenGL/Avalonia.OpenGL.csproj
@@ -0,0 +1,12 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.OpenGL/EglConsts.cs b/src/Avalonia.OpenGL/EglConsts.cs
new file mode 100644
index 00000000000..62fb3faef67
--- /dev/null
+++ b/src/Avalonia.OpenGL/EglConsts.cs
@@ -0,0 +1,196 @@
+// ReSharper disable UnusedMember.Global
+// ReSharper disable IdentifierTypo
+namespace Avalonia.OpenGL
+{
+ public static class EglConsts
+ {
+ public const int EGL_ALPHA_SIZE = 0x3021;
+ public const int EGL_BAD_ACCESS = 0x3002;
+ public const int EGL_BAD_ALLOC = 0x3003;
+ public const int EGL_BAD_ATTRIBUTE = 0x3004;
+ public const int EGL_BAD_CONFIG = 0x3005;
+ public const int EGL_BAD_CONTEXT = 0x3006;
+ public const int EGL_BAD_CURRENT_SURFACE = 0x3007;
+ public const int EGL_BAD_DISPLAY = 0x3008;
+ public const int EGL_BAD_MATCH = 0x3009;
+ public const int EGL_BAD_NATIVE_PIXMAP = 0x300A;
+ public const int EGL_BAD_NATIVE_WINDOW = 0x300B;
+ public const int EGL_BAD_PARAMETER = 0x300C;
+ public const int EGL_BAD_SURFACE = 0x300D;
+ public const int EGL_BLUE_SIZE = 0x3022;
+ public const int EGL_BUFFER_SIZE = 0x3020;
+ public const int EGL_CONFIG_CAVEAT = 0x3027;
+ public const int EGL_CONFIG_ID = 0x3028;
+ public const int EGL_CORE_NATIVE_ENGINE = 0x305B;
+ public const int EGL_DEPTH_SIZE = 0x3025;
+ public const int EGL_DONT_CARE = -1;
+ public const int EGL_DRAW = 0x3059;
+ public const int EGL_EXTENSIONS = 0x3055;
+ public const int EGL_FALSE = 0;
+ public const int EGL_GREEN_SIZE = 0x3023;
+ public const int EGL_HEIGHT = 0x3056;
+ public const int EGL_LARGEST_PBUFFER = 0x3058;
+ public const int EGL_LEVEL = 0x3029;
+ public const int EGL_MAX_PBUFFER_HEIGHT = 0x302A;
+ public const int EGL_MAX_PBUFFER_PIXELS = 0x302B;
+ public const int EGL_MAX_PBUFFER_WIDTH = 0x302C;
+ public const int EGL_NATIVE_RENDERABLE = 0x302D;
+ public const int EGL_NATIVE_VISUAL_ID = 0x302E;
+ public const int EGL_NATIVE_VISUAL_TYPE = 0x302F;
+ public const int EGL_NONE = 0x3038;
+ public const int EGL_NON_CONFORMANT_CONFIG = 0x3051;
+ public const int EGL_NOT_INITIALIZED = 0x3001;
+ public const int EGL_NO_CONTEXT = 0;
+ public const int EGL_NO_DISPLAY = 0;
+ public const int EGL_NO_SURFACE = 0;
+ public const int EGL_PBUFFER_BIT = 0x0001;
+ public const int EGL_PIXMAP_BIT = 0x0002;
+ public const int EGL_READ = 0x305A;
+ public const int EGL_RED_SIZE = 0x3024;
+ public const int EGL_SAMPLES = 0x3031;
+ public const int EGL_SAMPLE_BUFFERS = 0x3032;
+ public const int EGL_SLOW_CONFIG = 0x3050;
+ public const int EGL_STENCIL_SIZE = 0x3026;
+ public const int EGL_SUCCESS = 0x3000;
+ public const int EGL_SURFACE_TYPE = 0x3033;
+ public const int EGL_TRANSPARENT_BLUE_VALUE = 0x3035;
+ public const int EGL_TRANSPARENT_GREEN_VALUE = 0x3036;
+ public const int EGL_TRANSPARENT_RED_VALUE = 0x3037;
+ public const int EGL_TRANSPARENT_RGB = 0x3052;
+ public const int EGL_TRANSPARENT_TYPE = 0x3034;
+ public const int EGL_TRUE = 1;
+ public const int EGL_VENDOR = 0x3053;
+ public const int EGL_VERSION = 0x3054;
+ public const int EGL_WIDTH = 0x3057;
+ public const int EGL_WINDOW_BIT = 0x0004;
+
+ public const int EGL_BACK_BUFFER = 0x3084;
+ public const int EGL_BIND_TO_TEXTURE_RGB = 0x3039;
+ public const int EGL_BIND_TO_TEXTURE_RGBA = 0x303A;
+ public const int EGL_CONTEXT_LOST = 0x300E;
+ public const int EGL_MIN_SWAP_INTERVAL = 0x303B;
+ public const int EGL_MAX_SWAP_INTERVAL = 0x303C;
+ public const int EGL_MIPMAP_TEXTURE = 0x3082;
+ public const int EGL_MIPMAP_LEVEL = 0x3083;
+ public const int EGL_NO_TEXTURE = 0x305C;
+ public const int EGL_TEXTURE_2D = 0x305F;
+ public const int EGL_TEXTURE_FORMAT = 0x3080;
+ public const int EGL_TEXTURE_RGB = 0x305D;
+ public const int EGL_TEXTURE_RGBA = 0x305E;
+ public const int EGL_TEXTURE_TARGET = 0x3081;
+
+ public const int EGL_ALPHA_FORMAT = 0x3088;
+ public const int EGL_ALPHA_FORMAT_NONPRE = 0x308B;
+ public const int EGL_ALPHA_FORMAT_PRE = 0x308C;
+ public const int EGL_ALPHA_MASK_SIZE = 0x303E;
+ public const int EGL_BUFFER_PRESERVED = 0x3094;
+ public const int EGL_BUFFER_DESTROYED = 0x3095;
+ public const int EGL_CLIENT_APIS = 0x308D;
+ public const int EGL_COLORSPACE = 0x3087;
+ public const int EGL_COLORSPACE_sRGB = 0x3089;
+ public const int EGL_COLORSPACE_LINEAR = 0x308A;
+ public const int EGL_COLOR_BUFFER_TYPE = 0x303F;
+ public const int EGL_CONTEXT_CLIENT_TYPE = 0x3097;
+ public const int EGL_DISPLAY_SCALING = 10000;
+ public const int EGL_HORIZONTAL_RESOLUTION = 0x3090;
+ public const int EGL_LUMINANCE_BUFFER = 0x308F;
+ public const int EGL_LUMINANCE_SIZE = 0x303D;
+ public const int EGL_OPENGL_ES_BIT = 0x0001;
+ public const int EGL_OPENVG_BIT = 0x0002;
+ public const int EGL_OPENGL_ES_API = 0x30A0;
+ public const int EGL_OPENVG_API = 0x30A1;
+ public const int EGL_OPENVG_IMAGE = 0x3096;
+ public const int EGL_PIXEL_ASPECT_RATIO = 0x3092;
+ public const int EGL_RENDERABLE_TYPE = 0x3040;
+ public const int EGL_RENDER_BUFFER = 0x3086;
+ public const int EGL_RGB_BUFFER = 0x308E;
+ public const int EGL_SINGLE_BUFFER = 0x3085;
+ public const int EGL_SWAP_BEHAVIOR = 0x3093;
+ public const int EGL_UNKNOWN = -1;
+ public const int EGL_VERTICAL_RESOLUTION = 0x3091;
+ public const int EGL_CONFORMANT = 0x3042;
+ public const int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+ public const int EGL_MATCH_NATIVE_PIXMAP = 0x3041;
+ public const int EGL_OPENGL_ES2_BIT = 0x0004;
+ public const int EGL_VG_ALPHA_FORMAT = 0x3088;
+ public const int EGL_VG_ALPHA_FORMAT_NONPRE = 0x308B;
+ public const int EGL_VG_ALPHA_FORMAT_PRE = 0x308C;
+ public const int EGL_VG_ALPHA_FORMAT_PRE_BIT = 0x0040;
+ public const int EGL_VG_COLORSPACE = 0x3087;
+ public const int EGL_VG_COLORSPACE_sRGB = 0x3089;
+ public const int EGL_VG_COLORSPACE_LINEAR = 0x308A;
+ public const int EGL_VG_COLORSPACE_LINEAR_BIT = 0x0020;
+ public const int EGL_DEFAULT_DISPLAY = 0;
+ public const int EGL_MULTISAMPLE_RESOLVE_BOX_BIT = 0x0200;
+ public const int EGL_MULTISAMPLE_RESOLVE = 0x3099;
+ public const int EGL_MULTISAMPLE_RESOLVE_DEFAULT = 0x309A;
+ public const int EGL_MULTISAMPLE_RESOLVE_BOX = 0x309B;
+ public const int EGL_OPENGL_API = 0x30A2;
+ public const int EGL_OPENGL_BIT = 0x0008;
+ public const int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
+ public const int EGL_CONTEXT_MAJOR_VERSION = 0x3098;
+ public const int EGL_CONTEXT_MINOR_VERSION = 0x30FB;
+ public const int EGL_CONTEXT_OPENGL_PROFILE_MASK = 0x30FD;
+ public const int EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY = 0x31BD;
+ public const int EGL_NO_RESET_NOTIFICATION = 0x31BE;
+ public const int EGL_LOSE_CONTEXT_ON_RESET = 0x31BF;
+ public const int EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT = 0x00000001;
+ public const int EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT = 0x00000002;
+ public const int EGL_CONTEXT_OPENGL_DEBUG = 0x31B0;
+ public const int EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE = 0x31B1;
+ public const int EGL_CONTEXT_OPENGL_ROBUST_ACCESS = 0x31B2;
+ public const int EGL_OPENGL_ES3_BIT = 0x00000040;
+ public const int EGL_CL_EVENT_HANDLE = 0x309C;
+ public const int EGL_SYNC_CL_EVENT = 0x30FE;
+ public const int EGL_SYNC_CL_EVENT_COMPLETE = 0x30FF;
+ public const int EGL_SYNC_PRIOR_COMMANDS_COMPLETE = 0x30F0;
+ public const int EGL_SYNC_TYPE = 0x30F7;
+ public const int EGL_SYNC_STATUS = 0x30F1;
+ public const int EGL_SYNC_CONDITION = 0x30F8;
+ public const int EGL_SIGNALED = 0x30F2;
+ public const int EGL_UNSIGNALED = 0x30F3;
+
+ public const int EGL_SYNC_FLUSH_COMMANDS_BIT = 0x0001;
+
+ public const int EGL_TIMEOUT_EXPIRED = 0x30F5;
+ public const int EGL_CONDITION_SATISFIED = 0x30F6;
+ public const int EGL_NO_SYNC = 0;
+ public const int EGL_SYNC_FENCE = 0x30F9;
+ public const int EGL_GL_COLORSPACE = 0x309D;
+ public const int EGL_GL_COLORSPACE_SRGB = 0x3089;
+ public const int EGL_GL_COLORSPACE_LINEAR = 0x308A;
+ public const int EGL_GL_RENDERBUFFER = 0x30B9;
+ public const int EGL_GL_TEXTURE_2D = 0x30B1;
+ public const int EGL_GL_TEXTURE_LEVEL = 0x30BC;
+ public const int EGL_GL_TEXTURE_3D = 0x30B2;
+ public const int EGL_GL_TEXTURE_ZOFFSET = 0x30BD;
+ public const int EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x30B3;
+ public const int EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x30B4;
+ public const int EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x30B5;
+ public const int EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x30B6;
+ public const int EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x30B7;
+ public const int EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x30B8;
+ public const int EGL_IMAGE_PRESERVED = 0x30D2;
+ public const int EGL_NO_IMAGE = 0;
+
+
+ public const int EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE = 0x3207;
+ public const int EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE = 0x3208;
+
+ //EGL_ANGLE_platform_angle
+ public const int EGL_PLATFORM_ANGLE_ANGLE = 0x3202;
+ public const int EGL_PLATFORM_ANGLE_TYPE_ANGLE = 0x3203;
+ public const int EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE = 0x3204;
+ public const int EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE = 0x3205;
+ public const int EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED = 0x3451;
+ public const int EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE = 0x3206;
+ public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE = 0x320A;
+ public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE = 0x345E;
+
+ //EGL_ANGLE_platform_angle_d3d
+ public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE = 0x3209;
+ public const int EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE = 0x320F;
+ public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE = 0x320B;
+ public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE = 0x320C;
+ }
+}
diff --git a/src/Avalonia.OpenGL/EglDisplay.cs b/src/Avalonia.OpenGL/EglDisplay.cs
new file mode 100644
index 00000000000..ea0a9bf0875
--- /dev/null
+++ b/src/Avalonia.OpenGL/EglDisplay.cs
@@ -0,0 +1,205 @@
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+using Avalonia.Platform.Interop;
+using static Avalonia.OpenGL.EglConsts;
+
+namespace Avalonia.OpenGL
+{
+ public class EglDisplay : IGlDisplay
+ {
+ private readonly EglInterface _egl;
+ private readonly IntPtr _display;
+ private readonly IntPtr _config;
+ private readonly int[] _contextAttributes;
+
+ public EglDisplay(EglInterface egl)
+ {
+ _egl = egl;
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && _egl.GetPlatformDisplayEXT != null)
+ {
+ foreach (var dapi in new[] {EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE})
+ {
+ _display = _egl.GetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, IntPtr.Zero, new[]
+ {
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, dapi, EGL_NONE
+ });
+ if(_display != IntPtr.Zero)
+ break;
+ }
+ }
+
+ if (_display == IntPtr.Zero)
+ _display = _egl.GetDisplay(IntPtr.Zero);
+
+ if(_display == IntPtr.Zero)
+ throw new OpenGlException("eglGetDisplay failed");
+
+ if (!_egl.Initialize(_display, out var major, out var minor))
+ throw new OpenGlException("eglInitialize failed");
+
+ foreach (var cfg in new[]
+ {
+ new
+ {
+ Attributes = new[] {EGL_NONE},
+ Api = EGL_OPENGL_API,
+ RenderableTypeBit = EGL_OPENGL_BIT,
+ Type = GlDisplayType.OpenGL2
+ },
+ new
+ {
+ Attributes = new[]
+ {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ },
+ Api = EGL_OPENGL_ES_API,
+ RenderableTypeBit = EGL_OPENGL_ES2_BIT,
+ Type = GlDisplayType.OpenGLES2
+ }
+ })
+ {
+ if (!_egl.BindApi(cfg.Api))
+ continue;
+
+ var attribs = new[]
+ {
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_RENDERABLE_TYPE, cfg.RenderableTypeBit,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_STENCIL_SIZE, 8,
+ EGL_DEPTH_SIZE, 8,
+ EGL_NONE
+ };
+ if (!_egl.ChooseConfig(_display, attribs, out _config, 1, out int numConfigs))
+ continue;
+ if (numConfigs == 0)
+ continue;
+ _contextAttributes = cfg.Attributes;
+ Type = cfg.Type;
+ }
+
+ if (_contextAttributes == null)
+ throw new OpenGlException("No suitable EGL config was found");
+
+ GlInterface = new GlInterface((proc, optional) =>
+ {
+
+ using (var u = new Utf8Buffer(proc))
+ {
+ var rv = _egl.GetProcAddress(u);
+ if (rv == IntPtr.Zero && !optional)
+ throw new OpenGlException("Missing function " + proc);
+ return rv;
+ }
+ });
+ }
+
+ public EglDisplay() : this(new EglInterface())
+ {
+
+ }
+
+ public GlDisplayType Type { get; }
+ public GlInterface GlInterface { get; }
+ public IGlContext CreateContext(IGlContext share)
+ {
+ var shareCtx = (EglContext)share;
+ var ctx = _egl.CreateContext(_display, _config, shareCtx?.Context ?? IntPtr.Zero, _contextAttributes);
+ if (ctx == IntPtr.Zero)
+ throw new OpenGlException("eglCreateContext failed");
+ var surf = _egl.CreatePBufferSurface(_display, _config, new[]
+ {
+ EGL_WIDTH, 1,
+ EGL_HEIGHT, 1,
+ EGL_NONE
+ });
+ if (surf == IntPtr.Zero)
+ throw new OpenGlException("eglCreatePbufferSurface failed");
+ var rv = new EglContext(this, ctx, surf);
+ rv.MakeCurrent(null);
+ return rv;
+ }
+
+ public void ClearContext()
+ {
+ if (!_egl.MakeCurrent(_display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero))
+ throw new OpenGlException("eglMakeCurrent failed");
+ }
+
+ public IGlSurface CreateWindowSurface(IntPtr window)
+ {
+ var s = _egl.CreateWindowSurface(_display, _config, window, new[] {EGL_NONE, EGL_NONE});
+ if (s == IntPtr.Zero)
+ throw new OpenGlException("eglCreateWindowSurface failed");
+ return new EglSurface(this, s);
+ }
+
+ public int SampleCount
+ {
+ get
+ {
+ _egl.GetConfigAttrib(_display, _config, EGL_SAMPLES, out var rv);
+ return rv;
+ }
+ }
+
+ public int StencilSize
+ {
+ get
+ {
+ _egl.GetConfigAttrib(_display, _config, EGL_STENCIL_SIZE, out var rv);
+ return rv;
+ }
+ }
+
+ class EglSurface : SafeHandle, IGlSurface
+ {
+ private readonly EglDisplay _display;
+
+ public EglSurface(EglDisplay display, IntPtr surface) : base(surface, true)
+ {
+ _display = display;
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ _display._egl.DestroySurface(_display._display, handle);
+ return true;
+ }
+
+ public override bool IsInvalid => handle == IntPtr.Zero;
+
+ public IGlDisplay Display => _display;
+ public void SwapBuffers() => _display._egl.SwapBuffers(_display._display, handle);
+ }
+
+ class EglContext : IGlContext
+ {
+ private readonly EglDisplay _disp;
+
+ public EglContext(EglDisplay display, IntPtr ctx, IntPtr offscreenSurface)
+ {
+ _disp = display;
+ Context = ctx;
+ OffscreenSurface = offscreenSurface;
+ }
+
+ public IntPtr Context { get; }
+ public IntPtr OffscreenSurface { get; }
+ public IGlDisplay Display => _disp;
+
+ public void MakeCurrent(IGlSurface surface)
+ {
+ var surf = ((EglSurface)surface)?.DangerousGetHandle() ?? OffscreenSurface;
+ if (!_disp._egl.MakeCurrent(_disp._display, surf, surf, Context))
+ throw new OpenGlException("eglMakeCurrent failed");
+ }
+ }
+ }
+}
diff --git a/src/Avalonia.OpenGL/EglGlPlatformFeature.cs b/src/Avalonia.OpenGL/EglGlPlatformFeature.cs
new file mode 100644
index 00000000000..535e32924e3
--- /dev/null
+++ b/src/Avalonia.OpenGL/EglGlPlatformFeature.cs
@@ -0,0 +1,39 @@
+using System;
+using Avalonia.Logging;
+
+namespace Avalonia.OpenGL
+{
+ public class EglGlPlatformFeature : IWindowingPlatformGlFeature
+ {
+ public IGlDisplay Display { get; set; }
+ public IGlContext ImmediateContext { get; set; }
+ public IGlContext DeferredContext { get; set; }
+
+ public static void TryInitialize()
+ {
+ var feature = TryCreate();
+ if (feature != null)
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(feature);
+ }
+
+ public static EglGlPlatformFeature TryCreate()
+ {
+ try
+ {
+ var disp = new EglDisplay();
+ var ctx = disp.CreateContext(null);
+ return new EglGlPlatformFeature
+ {
+ Display = disp,
+ ImmediateContext = ctx,
+ DeferredContext = disp.CreateContext(ctx)
+ };
+ }
+ catch(Exception e)
+ {
+ Logger.Error("OpenGL", null, "Unable to initialize EGL-based rendering: {0}", e);
+ return null;
+ }
+ }
+ }
+}
diff --git a/src/Avalonia.OpenGL/EglGlPlatformSurface.cs b/src/Avalonia.OpenGL/EglGlPlatformSurface.cs
new file mode 100644
index 00000000000..19894e4ec5b
--- /dev/null
+++ b/src/Avalonia.OpenGL/EglGlPlatformSurface.cs
@@ -0,0 +1,80 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+ public class EglGlPlatformSurface : IGlPlatformSurface
+ {
+ public interface IEglWindowGlPlatformSurfaceInfo
+ {
+ IntPtr Handle { get; }
+ // TODO: Change to PixelSize struct once https://github.com/AvaloniaUI/Avalonia/pull/1889 is merged
+ System.Drawing.Size PixelSize { get; }
+ double Scaling { get; }
+ }
+
+ private readonly EglDisplay _display;
+ private readonly IGlContext _context;
+ private readonly IEglWindowGlPlatformSurfaceInfo _info;
+
+ public EglGlPlatformSurface(EglDisplay display, IGlContext context, IEglWindowGlPlatformSurfaceInfo info)
+ {
+ _display = display;
+ _context = context;
+ _info = info;
+ }
+
+ public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget()
+ {
+ var glSurface = _display.CreateWindowSurface(_info.Handle);
+ return new RenderTarget(_context, glSurface, _info);
+ }
+
+ class RenderTarget : IGlPlatformSurfaceRenderTarget
+ {
+ private readonly IGlContext _context;
+ private readonly IGlSurface _glSurface;
+ private readonly IEglWindowGlPlatformSurfaceInfo _info;
+
+ public RenderTarget(IGlContext context, IGlSurface glSurface, IEglWindowGlPlatformSurfaceInfo info)
+ {
+ _context = context;
+ _glSurface = glSurface;
+ _info = info;
+ }
+
+ public void Dispose() => _glSurface.Dispose();
+
+ public IGlPlatformSurfaceRenderingSession BeginDraw()
+ {
+ _context.MakeCurrent(_glSurface);
+ return new Session(_context, _glSurface, _info);
+ }
+
+ class Session : IGlPlatformSurfaceRenderingSession
+ {
+ private readonly IGlContext _context;
+ private readonly IGlSurface _glSurface;
+ private readonly IEglWindowGlPlatformSurfaceInfo _info;
+
+ public Session(IGlContext context, IGlSurface glSurface, IEglWindowGlPlatformSurfaceInfo info)
+ {
+ _context = context;
+ _glSurface = glSurface;
+ _info = info;
+ }
+
+ public void Dispose()
+ {
+ _context.Display.GlInterface.Flush();
+ _glSurface.SwapBuffers();
+ _context.Display.ClearContext();
+ }
+
+ public IGlDisplay Display => _context.Display;
+ public System.Drawing.Size PixelSize => _info.PixelSize;
+ public double Scaling => _info.Scaling;
+ }
+ }
+ }
+}
+
diff --git a/src/Avalonia.OpenGL/EglInterface.cs b/src/Avalonia.OpenGL/EglInterface.cs
new file mode 100644
index 00000000000..535f66ee1f5
--- /dev/null
+++ b/src/Avalonia.OpenGL/EglInterface.cs
@@ -0,0 +1,93 @@
+using System;
+using Avalonia.Platform;
+using Avalonia.Platform.Interop;
+using static Avalonia.OpenGL.EglConsts;
+
+namespace Avalonia.OpenGL
+{
+ public class EglInterface : GlInterfaceBase
+ {
+ public EglInterface() : base(Load())
+ {
+
+ }
+
+ public EglInterface(string library) : base(Load(library))
+ {
+ }
+
+ static Func Load()
+ {
+ var os = AvaloniaLocator.Current.GetService().GetRuntimeInfo().OperatingSystem;
+ if(os == OperatingSystemType.Linux || os == OperatingSystemType.Android)
+ return Load("libEGL.so.1");
+ if (os == OperatingSystemType.WinNT)
+ return Load(@"libegl.dll");
+ throw new PlatformNotSupportedException();
+ }
+
+ static Func Load(string library)
+ {
+ var dyn = AvaloniaLocator.Current.GetService();
+ var lib = dyn.LoadLibrary(library);
+ return (s, o) => dyn.GetProcAddress(lib, s, o);
+ }
+
+ // ReSharper disable UnassignedGetOnlyAutoProperty
+ public delegate IntPtr EglGetDisplay(IntPtr nativeDisplay);
+ [EntryPoint("eglGetDisplay")]
+ public EglGetDisplay GetDisplay { get; }
+
+ public delegate IntPtr EglGetPlatformDisplayEXT(int platform, IntPtr nativeDisplay, int[] attrs);
+ [EntryPoint("eglGetPlatformDisplayEXT", true)]
+ public EglGetPlatformDisplayEXT GetPlatformDisplayEXT { get; }
+
+ public delegate bool EglInitialize(IntPtr display, out int major, out int minor);
+ [EntryPoint("eglInitialize")]
+ public EglInitialize Initialize { get; }
+
+ public delegate IntPtr EglGetProcAddress(Utf8Buffer proc);
+ [EntryPoint("eglGetProcAddress")]
+ public EglGetProcAddress GetProcAddress { get; }
+
+ public delegate bool EglBindApi(int api);
+ [EntryPoint("eglBindAPI")]
+ public EglBindApi BindApi { get; }
+
+ public delegate bool EglChooseConfig(IntPtr display, int[] attribs,
+ out IntPtr surfaceConfig, int numConfigs, out int choosenConfig);
+ [EntryPoint("eglChooseConfig")]
+ public EglChooseConfig ChooseConfig { get; }
+
+ public delegate IntPtr EglCreateContext(IntPtr display, IntPtr config,
+ IntPtr share, int[] attrs);
+ [EntryPoint("eglCreateContext")]
+ public EglCreateContext CreateContext { get; }
+
+ public delegate IntPtr EglCreatePBufferSurface(IntPtr display, IntPtr config, int[] attrs);
+ [EntryPoint("eglCreatePbufferSurface")]
+ public EglCreatePBufferSurface CreatePBufferSurface { get; }
+
+ public delegate bool EglMakeCurrent(IntPtr display, IntPtr draw, IntPtr read, IntPtr context);
+ [EntryPoint("eglMakeCurrent")]
+ public EglMakeCurrent MakeCurrent { get; }
+
+ public delegate void EglDisplaySurfaceVoidDelegate(IntPtr display, IntPtr surface);
+ [EntryPoint("eglDestroySurface")]
+ public EglDisplaySurfaceVoidDelegate DestroySurface { get; }
+
+ [EntryPoint("eglSwapBuffers")]
+ public EglDisplaySurfaceVoidDelegate SwapBuffers { get; }
+
+ public delegate IntPtr
+ EglCreateWindowSurface(IntPtr display, IntPtr config, IntPtr window, int[] attrs);
+ [EntryPoint("eglCreateWindowSurface")]
+ public EglCreateWindowSurface CreateWindowSurface { get; }
+
+ public delegate bool EglGetConfigAttrib(IntPtr display, IntPtr config, int attr, out int rv);
+ [EntryPoint("eglGetConfigAttrib")]
+ public EglGetConfigAttrib GetConfigAttrib { get; }
+
+ // ReSharper restore UnassignedGetOnlyAutoProperty
+ }
+}
diff --git a/src/Avalonia.OpenGL/EntryPointAttribute.cs b/src/Avalonia.OpenGL/EntryPointAttribute.cs
new file mode 100644
index 00000000000..241f517df9a
--- /dev/null
+++ b/src/Avalonia.OpenGL/EntryPointAttribute.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+ class EntryPointAttribute : Attribute
+ {
+ public string EntryPoint { get; }
+ public bool Optional { get; }
+
+ public EntryPointAttribute(string entryPoint, bool optional = false)
+ {
+ EntryPoint = entryPoint;
+ Optional = optional;
+ }
+ }
+}
diff --git a/src/Avalonia.OpenGL/GlConsts.cs b/src/Avalonia.OpenGL/GlConsts.cs
new file mode 100644
index 00000000000..3084a6f9588
--- /dev/null
+++ b/src/Avalonia.OpenGL/GlConsts.cs
@@ -0,0 +1,789 @@
+// ReSharper disable UnusedMember.Global
+// ReSharper disable IdentifierTypo
+namespace Avalonia.OpenGL
+{
+ public static class GlConsts
+ {
+ public const int GL_BYTE = 0x1400;
+ public const int GL_UNSIGNED_BYTE = 0x1401;
+ public const int GL_SHORT = 0x1402;
+ public const int GL_UNSIGNED_SHORT = 0x1403;
+ public const int GL_INT = 0x1404;
+ public const int GL_UNSIGNED_INT = 0x1405;
+ public const int GL_FLOAT = 0x1406;
+ public const int GL_2_BYTES = 0x1407;
+ public const int GL_3_BYTES = 0x1408;
+ public const int GL_4_BYTES = 0x1409;
+ public const int GL_DOUBLE = 0x140A;
+ public const int GL_POINTS = 0x0000;
+ public const int GL_LINES = 0x0001;
+ public const int GL_LINE_LOOP = 0x0002;
+ public const int GL_LINE_STRIP = 0x0003;
+ public const int GL_TRIANGLES = 0x0004;
+ public const int GL_TRIANGLE_STRIP = 0x0005;
+ public const int GL_TRIANGLE_FAN = 0x0006;
+ public const int GL_QUADS = 0x0007;
+ public const int GL_QUAD_STRIP = 0x0008;
+ public const int GL_POLYGON = 0x0009;
+ public const int GL_VERTEX_ARRAY = 0x8074;
+ public const int GL_NORMAL_ARRAY = 0x8075;
+ public const int GL_COLOR_ARRAY = 0x8076;
+ public const int GL_INDEX_ARRAY = 0x8077;
+ public const int GL_TEXTURE_COORD_ARRAY = 0x8078;
+ public const int GL_EDGE_FLAG_ARRAY = 0x8079;
+ public const int GL_VERTEX_ARRAY_SIZE = 0x807A;
+ public const int GL_VERTEX_ARRAY_TYPE = 0x807B;
+ public const int GL_VERTEX_ARRAY_STRIDE = 0x807C;
+ public const int GL_NORMAL_ARRAY_TYPE = 0x807E;
+ public const int GL_NORMAL_ARRAY_STRIDE = 0x807F;
+ public const int GL_COLOR_ARRAY_SIZE = 0x8081;
+ public const int GL_COLOR_ARRAY_TYPE = 0x8082;
+ public const int GL_COLOR_ARRAY_STRIDE = 0x8083;
+ public const int GL_INDEX_ARRAY_TYPE = 0x8085;
+ public const int GL_INDEX_ARRAY_STRIDE = 0x8086;
+ public const int GL_TEXTURE_COORD_ARRAY_SIZE = 0x8088;
+ public const int GL_TEXTURE_COORD_ARRAY_TYPE = 0x8089;
+ public const int GL_TEXTURE_COORD_ARRAY_STRIDE = 0x808A;
+ public const int GL_EDGE_FLAG_ARRAY_STRIDE = 0x808C;
+ public const int GL_VERTEX_ARRAY_POINTER = 0x808E;
+ public const int GL_NORMAL_ARRAY_POINTER = 0x808F;
+ public const int GL_COLOR_ARRAY_POINTER = 0x8090;
+ public const int GL_INDEX_ARRAY_POINTER = 0x8091;
+ public const int GL_TEXTURE_COORD_ARRAY_POINTER = 0x8092;
+ public const int GL_EDGE_FLAG_ARRAY_POINTER = 0x8093;
+ public const int GL_V2F = 0x2A20;
+ public const int GL_V3F = 0x2A21;
+ public const int GL_C4UB_V2F = 0x2A22;
+ public const int GL_C4UB_V3F = 0x2A23;
+ public const int GL_C3F_V3F = 0x2A24;
+ public const int GL_N3F_V3F = 0x2A25;
+ public const int GL_C4F_N3F_V3F = 0x2A26;
+ public const int GL_T2F_V3F = 0x2A27;
+ public const int GL_T4F_V4F = 0x2A28;
+ public const int GL_T2F_C4UB_V3F = 0x2A29;
+ public const int GL_T2F_C3F_V3F = 0x2A2A;
+ public const int GL_T2F_N3F_V3F = 0x2A2B;
+ public const int GL_T2F_C4F_N3F_V3F = 0x2A2C;
+ public const int GL_T4F_C4F_N3F_V4F = 0x2A2D;
+ public const int GL_MATRIX_MODE = 0x0BA0;
+ public const int GL_MODELVIEW = 0x1700;
+ public const int GL_PROJECTION = 0x1701;
+ public const int GL_TEXTURE = 0x1702;
+ public const int GL_POINT_SMOOTH = 0x0B10;
+ public const int GL_POINT_SIZE = 0x0B11;
+ public const int GL_POINT_SIZE_GRANULARITY = 0x0B13;
+ public const int GL_POINT_SIZE_RANGE = 0x0B12;
+ public const int GL_LINE_SMOOTH = 0x0B20;
+ public const int GL_LINE_STIPPLE = 0x0B24;
+ public const int GL_LINE_STIPPLE_PATTERN = 0x0B25;
+ public const int GL_LINE_STIPPLE_REPEAT = 0x0B26;
+ public const int GL_LINE_WIDTH = 0x0B21;
+ public const int GL_LINE_WIDTH_GRANULARITY = 0x0B23;
+ public const int GL_LINE_WIDTH_RANGE = 0x0B22;
+ public const int GL_POINT = 0x1B00;
+ public const int GL_LINE = 0x1B01;
+ public const int GL_FILL = 0x1B02;
+ public const int GL_CW = 0x0900;
+ public const int GL_CCW = 0x0901;
+ public const int GL_FRONT = 0x0404;
+ public const int GL_BACK = 0x0405;
+ public const int GL_POLYGON_MODE = 0x0B40;
+ public const int GL_POLYGON_SMOOTH = 0x0B41;
+ public const int GL_POLYGON_STIPPLE = 0x0B42;
+ public const int GL_EDGE_FLAG = 0x0B43;
+ public const int GL_CULL_FACE = 0x0B44;
+ public const int GL_CULL_FACE_MODE = 0x0B45;
+ public const int GL_FRONT_FACE = 0x0B46;
+ public const int GL_POLYGON_OFFSET_FACTOR = 0x8038;
+ public const int GL_POLYGON_OFFSET_UNITS = 0x2A00;
+ public const int GL_POLYGON_OFFSET_POINT = 0x2A01;
+ public const int GL_POLYGON_OFFSET_LINE = 0x2A02;
+ public const int GL_POLYGON_OFFSET_FILL = 0x8037;
+ public const int GL_COMPILE = 0x1300;
+ public const int GL_COMPILE_AND_EXECUTE = 0x1301;
+ public const int GL_LIST_BASE = 0x0B32;
+ public const int GL_LIST_INDEX = 0x0B33;
+ public const int GL_LIST_MODE = 0x0B30;
+ public const int GL_NEVER = 0x0200;
+ public const int GL_LESS = 0x0201;
+ public const int GL_EQUAL = 0x0202;
+ public const int GL_LEQUAL = 0x0203;
+ public const int GL_GREATER = 0x0204;
+ public const int GL_NOTEQUAL = 0x0205;
+ public const int GL_GEQUAL = 0x0206;
+ public const int GL_ALWAYS = 0x0207;
+ public const int GL_DEPTH_TEST = 0x0B71;
+ public const int GL_DEPTH_BITS = 0x0D56;
+ public const int GL_DEPTH_CLEAR_VALUE = 0x0B73;
+ public const int GL_DEPTH_FUNC = 0x0B74;
+ public const int GL_DEPTH_RANGE = 0x0B70;
+ public const int GL_DEPTH_WRITEMASK = 0x0B72;
+ public const int GL_DEPTH_COMPONENT = 0x1902;
+ public const int GL_LIGHTING = 0x0B50;
+ public const int GL_LIGHT0 = 0x4000;
+ public const int GL_LIGHT1 = 0x4001;
+ public const int GL_LIGHT2 = 0x4002;
+ public const int GL_LIGHT3 = 0x4003;
+ public const int GL_LIGHT4 = 0x4004;
+ public const int GL_LIGHT5 = 0x4005;
+ public const int GL_LIGHT6 = 0x4006;
+ public const int GL_LIGHT7 = 0x4007;
+ public const int GL_SPOT_EXPONENT = 0x1205;
+ public const int GL_SPOT_CUTOFF = 0x1206;
+ public const int GL_CONSTANT_ATTENUATION = 0x1207;
+ public const int GL_LINEAR_ATTENUATION = 0x1208;
+ public const int GL_QUADRATIC_ATTENUATION = 0x1209;
+ public const int GL_AMBIENT = 0x1200;
+ public const int GL_DIFFUSE = 0x1201;
+ public const int GL_SPECULAR = 0x1202;
+ public const int GL_SHININESS = 0x1601;
+ public const int GL_EMISSION = 0x1600;
+ public const int GL_POSITION = 0x1203;
+ public const int GL_SPOT_DIRECTION = 0x1204;
+ public const int GL_AMBIENT_AND_DIFFUSE = 0x1602;
+ public const int GL_COLOR_INDEXES = 0x1603;
+ public const int GL_LIGHT_MODEL_TWO_SIDE = 0x0B52;
+ public const int GL_LIGHT_MODEL_LOCAL_VIEWER = 0x0B51;
+ public const int GL_LIGHT_MODEL_AMBIENT = 0x0B53;
+ public const int GL_FRONT_AND_BACK = 0x0408;
+ public const int GL_SHADE_MODEL = 0x0B54;
+ public const int GL_FLAT = 0x1D00;
+ public const int GL_SMOOTH = 0x1D01;
+ public const int GL_COLOR_MATERIAL = 0x0B57;
+ public const int GL_COLOR_MATERIAL_FACE = 0x0B55;
+ public const int GL_COLOR_MATERIAL_PARAMETER = 0x0B56;
+ public const int GL_NORMALIZE = 0x0BA1;
+ public const int GL_CLIP_PLANE0 = 0x3000;
+ public const int GL_CLIP_PLANE1 = 0x3001;
+ public const int GL_CLIP_PLANE2 = 0x3002;
+ public const int GL_CLIP_PLANE3 = 0x3003;
+ public const int GL_CLIP_PLANE4 = 0x3004;
+ public const int GL_CLIP_PLANE5 = 0x3005;
+ public const int GL_ACCUM_RED_BITS = 0x0D58;
+ public const int GL_ACCUM_GREEN_BITS = 0x0D59;
+ public const int GL_ACCUM_BLUE_BITS = 0x0D5A;
+ public const int GL_ACCUM_ALPHA_BITS = 0x0D5B;
+ public const int GL_ACCUM_CLEAR_VALUE = 0x0B80;
+ public const int GL_ACCUM = 0x0100;
+ public const int GL_ADD = 0x0104;
+ public const int GL_LOAD = 0x0101;
+ public const int GL_MULT = 0x0103;
+ public const int GL_RETURN = 0x0102;
+ public const int GL_ALPHA_TEST = 0x0BC0;
+ public const int GL_ALPHA_TEST_REF = 0x0BC2;
+ public const int GL_ALPHA_TEST_FUNC = 0x0BC1;
+ public const int GL_BLEND = 0x0BE2;
+ public const int GL_BLEND_SRC = 0x0BE1;
+ public const int GL_BLEND_DST = 0x0BE0;
+ public const int GL_SRC_COLOR = 0x0300;
+ public const int GL_ONE_MINUS_SRC_COLOR = 0x0301;
+ public const int GL_SRC_ALPHA = 0x0302;
+ public const int GL_ONE_MINUS_SRC_ALPHA = 0x0303;
+ public const int GL_DST_ALPHA = 0x0304;
+ public const int GL_ONE_MINUS_DST_ALPHA = 0x0305;
+ public const int GL_DST_COLOR = 0x0306;
+ public const int GL_ONE_MINUS_DST_COLOR = 0x0307;
+ public const int GL_SRC_ALPHA_SATURATE = 0x0308;
+ public const int GL_FEEDBACK = 0x1C01;
+ public const int GL_RENDER = 0x1C00;
+ public const int GL_SELECT = 0x1C02;
+ public const int GL_2D = 0x0600;
+ public const int GL_3D = 0x0601;
+ public const int GL_3D_COLOR = 0x0602;
+ public const int GL_3D_COLOR_TEXTURE = 0x0603;
+ public const int GL_4D_COLOR_TEXTURE = 0x0604;
+ public const int GL_POINT_TOKEN = 0x0701;
+ public const int GL_LINE_TOKEN = 0x0702;
+ public const int GL_LINE_RESET_TOKEN = 0x0707;
+ public const int GL_POLYGON_TOKEN = 0x0703;
+ public const int GL_BITMAP_TOKEN = 0x0704;
+ public const int GL_DRAW_PIXEL_TOKEN = 0x0705;
+ public const int GL_COPY_PIXEL_TOKEN = 0x0706;
+ public const int GL_PASS_THROUGH_TOKEN = 0x0700;
+ public const int GL_FEEDBACK_BUFFER_POINTER = 0x0DF0;
+ public const int GL_FEEDBACK_BUFFER_SIZE = 0x0DF1;
+ public const int GL_FEEDBACK_BUFFER_TYPE = 0x0DF2;
+ public const int GL_SELECTION_BUFFER_POINTER = 0x0DF3;
+ public const int GL_SELECTION_BUFFER_SIZE = 0x0DF4;
+ public const int GL_FOG = 0x0B60;
+ public const int GL_FOG_MODE = 0x0B65;
+ public const int GL_FOG_DENSITY = 0x0B62;
+ public const int GL_FOG_COLOR = 0x0B66;
+ public const int GL_FOG_INDEX = 0x0B61;
+ public const int GL_FOG_START = 0x0B63;
+ public const int GL_FOG_END = 0x0B64;
+ public const int GL_LINEAR = 0x2601;
+ public const int GL_EXP = 0x0800;
+ public const int GL_EXP2 = 0x0801;
+ public const int GL_LOGIC_OP = 0x0BF1;
+ public const int GL_INDEX_LOGIC_OP = 0x0BF1;
+ public const int GL_COLOR_LOGIC_OP = 0x0BF2;
+ public const int GL_LOGIC_OP_MODE = 0x0BF0;
+ public const int GL_CLEAR = 0x1500;
+ public const int GL_SET = 0x150F;
+ public const int GL_COPY = 0x1503;
+ public const int GL_COPY_INVERTED = 0x150C;
+ public const int GL_NOOP = 0x1505;
+ public const int GL_INVERT = 0x150A;
+ public const int GL_AND = 0x1501;
+ public const int GL_NAND = 0x150E;
+ public const int GL_OR = 0x1507;
+ public const int GL_NOR = 0x1508;
+ public const int GL_XOR = 0x1506;
+ public const int GL_EQUIV = 0x1509;
+ public const int GL_AND_REVERSE = 0x1502;
+ public const int GL_AND_INVERTED = 0x1504;
+ public const int GL_OR_REVERSE = 0x150B;
+ public const int GL_OR_INVERTED = 0x150D;
+ public const int GL_STENCIL_BITS = 0x0D57;
+ public const int GL_STENCIL_TEST = 0x0B90;
+ public const int GL_STENCIL_CLEAR_VALUE = 0x0B91;
+ public const int GL_STENCIL_FUNC = 0x0B92;
+ public const int GL_STENCIL_VALUE_MASK = 0x0B93;
+ public const int GL_STENCIL_FAIL = 0x0B94;
+ public const int GL_STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+ public const int GL_STENCIL_PASS_DEPTH_PASS = 0x0B96;
+ public const int GL_STENCIL_REF = 0x0B97;
+ public const int GL_STENCIL_WRITEMASK = 0x0B98;
+ public const int GL_STENCIL_INDEX = 0x1901;
+ public const int GL_KEEP = 0x1E00;
+ public const int GL_REPLACE = 0x1E01;
+ public const int GL_INCR = 0x1E02;
+ public const int GL_DECR = 0x1E03;
+ public const int GL_LEFT = 0x0406;
+ public const int GL_RIGHT = 0x0407;
+ public const int GL_FRONT_LEFT = 0x0400;
+ public const int GL_FRONT_RIGHT = 0x0401;
+ public const int GL_BACK_LEFT = 0x0402;
+ public const int GL_BACK_RIGHT = 0x0403;
+ public const int GL_AUX0 = 0x0409;
+ public const int GL_AUX1 = 0x040A;
+ public const int GL_AUX2 = 0x040B;
+ public const int GL_AUX3 = 0x040C;
+ public const int GL_COLOR_INDEX = 0x1900;
+ public const int GL_RED = 0x1903;
+ public const int GL_GREEN = 0x1904;
+ public const int GL_BLUE = 0x1905;
+ public const int GL_ALPHA = 0x1906;
+ public const int GL_LUMINANCE = 0x1909;
+ public const int GL_LUMINANCE_ALPHA = 0x190A;
+ public const int GL_ALPHA_BITS = 0x0D55;
+ public const int GL_RED_BITS = 0x0D52;
+ public const int GL_GREEN_BITS = 0x0D53;
+ public const int GL_BLUE_BITS = 0x0D54;
+ public const int GL_INDEX_BITS = 0x0D51;
+ public const int GL_SUBPIXEL_BITS = 0x0D50;
+ public const int GL_AUX_BUFFERS = 0x0C00;
+ public const int GL_READ_BUFFER = 0x0C02;
+ public const int GL_DRAW_BUFFER = 0x0C01;
+ public const int GL_DOUBLEBUFFER = 0x0C32;
+ public const int GL_STEREO = 0x0C33;
+ public const int GL_BITMAP = 0x1A00;
+ public const int GL_COLOR = 0x1800;
+ public const int GL_DEPTH = 0x1801;
+ public const int GL_STENCIL = 0x1802;
+ public const int GL_DITHER = 0x0BD0;
+ public const int GL_RGB = 0x1907;
+ public const int GL_RGBA = 0x1908;
+ public const int GL_MAX_LIST_NESTING = 0x0B31;
+ public const int GL_MAX_EVAL_ORDER = 0x0D30;
+ public const int GL_MAX_LIGHTS = 0x0D31;
+ public const int GL_MAX_CLIP_PLANES = 0x0D32;
+ public const int GL_MAX_TEXTURE_SIZE = 0x0D33;
+ public const int GL_MAX_PIXEL_MAP_TABLE = 0x0D34;
+ public const int GL_MAX_ATTRIB_STACK_DEPTH = 0x0D35;
+ public const int GL_MAX_MODELVIEW_STACK_DEPTH = 0x0D36;
+ public const int GL_MAX_NAME_STACK_DEPTH = 0x0D37;
+ public const int GL_MAX_PROJECTION_STACK_DEPTH = 0x0D38;
+ public const int GL_MAX_TEXTURE_STACK_DEPTH = 0x0D39;
+ public const int GL_MAX_VIEWPORT_DIMS = 0x0D3A;
+ public const int GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = 0x0D3B;
+ public const int GL_ATTRIB_STACK_DEPTH = 0x0BB0;
+ public const int GL_CLIENT_ATTRIB_STACK_DEPTH = 0x0BB1;
+ public const int GL_COLOR_CLEAR_VALUE = 0x0C22;
+ public const int GL_COLOR_WRITEMASK = 0x0C23;
+ public const int GL_CURRENT_INDEX = 0x0B01;
+ public const int GL_CURRENT_COLOR = 0x0B00;
+ public const int GL_CURRENT_NORMAL = 0x0B02;
+ public const int GL_CURRENT_RASTER_COLOR = 0x0B04;
+ public const int GL_CURRENT_RASTER_DISTANCE = 0x0B09;
+ public const int GL_CURRENT_RASTER_INDEX = 0x0B05;
+ public const int GL_CURRENT_RASTER_POSITION = 0x0B07;
+ public const int GL_CURRENT_RASTER_TEXTURE_COORDS = 0x0B06;
+ public const int GL_CURRENT_RASTER_POSITION_VALID = 0x0B08;
+ public const int GL_CURRENT_TEXTURE_COORDS = 0x0B03;
+ public const int GL_INDEX_CLEAR_VALUE = 0x0C20;
+ public const int GL_INDEX_MODE = 0x0C30;
+ public const int GL_INDEX_WRITEMASK = 0x0C21;
+ public const int GL_MODELVIEW_MATRIX = 0x0BA6;
+ public const int GL_MODELVIEW_STACK_DEPTH = 0x0BA3;
+ public const int GL_NAME_STACK_DEPTH = 0x0D70;
+ public const int GL_PROJECTION_MATRIX = 0x0BA7;
+ public const int GL_PROJECTION_STACK_DEPTH = 0x0BA4;
+ public const int GL_RENDER_MODE = 0x0C40;
+ public const int GL_RGBA_MODE = 0x0C31;
+ public const int GL_TEXTURE_MATRIX = 0x0BA8;
+ public const int GL_TEXTURE_STACK_DEPTH = 0x0BA5;
+ public const int GL_VIEWPORT = 0x0BA2;
+ public const int GL_AUTO_NORMAL = 0x0D80;
+ public const int GL_MAP1_COLOR_4 = 0x0D90;
+ public const int GL_MAP1_INDEX = 0x0D91;
+ public const int GL_MAP1_NORMAL = 0x0D92;
+ public const int GL_MAP1_TEXTURE_COORD_1 = 0x0D93;
+ public const int GL_MAP1_TEXTURE_COORD_2 = 0x0D94;
+ public const int GL_MAP1_TEXTURE_COORD_3 = 0x0D95;
+ public const int GL_MAP1_TEXTURE_COORD_4 = 0x0D96;
+ public const int GL_MAP1_VERTEX_3 = 0x0D97;
+ public const int GL_MAP1_VERTEX_4 = 0x0D98;
+ public const int GL_MAP2_COLOR_4 = 0x0DB0;
+ public const int GL_MAP2_INDEX = 0x0DB1;
+ public const int GL_MAP2_NORMAL = 0x0DB2;
+ public const int GL_MAP2_TEXTURE_COORD_1 = 0x0DB3;
+ public const int GL_MAP2_TEXTURE_COORD_2 = 0x0DB4;
+ public const int GL_MAP2_TEXTURE_COORD_3 = 0x0DB5;
+ public const int GL_MAP2_TEXTURE_COORD_4 = 0x0DB6;
+ public const int GL_MAP2_VERTEX_3 = 0x0DB7;
+ public const int GL_MAP2_VERTEX_4 = 0x0DB8;
+ public const int GL_MAP1_GRID_DOMAIN = 0x0DD0;
+ public const int GL_MAP1_GRID_SEGMENTS = 0x0DD1;
+ public const int GL_MAP2_GRID_DOMAIN = 0x0DD2;
+ public const int GL_MAP2_GRID_SEGMENTS = 0x0DD3;
+ public const int GL_COEFF = 0x0A00;
+ public const int GL_ORDER = 0x0A01;
+ public const int GL_DOMAIN = 0x0A02;
+ public const int GL_PERSPECTIVE_CORRECTION_HINT = 0x0C50;
+ public const int GL_POINT_SMOOTH_HINT = 0x0C51;
+ public const int GL_LINE_SMOOTH_HINT = 0x0C52;
+ public const int GL_POLYGON_SMOOTH_HINT = 0x0C53;
+ public const int GL_FOG_HINT = 0x0C54;
+ public const int GL_DONT_CARE = 0x1100;
+ public const int GL_FASTEST = 0x1101;
+ public const int GL_NICEST = 0x1102;
+ public const int GL_SCISSOR_BOX = 0x0C10;
+ public const int GL_SCISSOR_TEST = 0x0C11;
+ public const int GL_MAP_COLOR = 0x0D10;
+ public const int GL_MAP_STENCIL = 0x0D11;
+ public const int GL_INDEX_SHIFT = 0x0D12;
+ public const int GL_INDEX_OFFSET = 0x0D13;
+ public const int GL_RED_SCALE = 0x0D14;
+ public const int GL_RED_BIAS = 0x0D15;
+ public const int GL_GREEN_SCALE = 0x0D18;
+ public const int GL_GREEN_BIAS = 0x0D19;
+ public const int GL_BLUE_SCALE = 0x0D1A;
+ public const int GL_BLUE_BIAS = 0x0D1B;
+ public const int GL_ALPHA_SCALE = 0x0D1C;
+ public const int GL_ALPHA_BIAS = 0x0D1D;
+ public const int GL_DEPTH_SCALE = 0x0D1E;
+ public const int GL_DEPTH_BIAS = 0x0D1F;
+ public const int GL_PIXEL_MAP_S_TO_S_SIZE = 0x0CB1;
+ public const int GL_PIXEL_MAP_I_TO_I_SIZE = 0x0CB0;
+ public const int GL_PIXEL_MAP_I_TO_R_SIZE = 0x0CB2;
+ public const int GL_PIXEL_MAP_I_TO_G_SIZE = 0x0CB3;
+ public const int GL_PIXEL_MAP_I_TO_B_SIZE = 0x0CB4;
+ public const int GL_PIXEL_MAP_I_TO_A_SIZE = 0x0CB5;
+ public const int GL_PIXEL_MAP_R_TO_R_SIZE = 0x0CB6;
+ public const int GL_PIXEL_MAP_G_TO_G_SIZE = 0x0CB7;
+ public const int GL_PIXEL_MAP_B_TO_B_SIZE = 0x0CB8;
+ public const int GL_PIXEL_MAP_A_TO_A_SIZE = 0x0CB9;
+ public const int GL_PIXEL_MAP_S_TO_S = 0x0C71;
+ public const int GL_PIXEL_MAP_I_TO_I = 0x0C70;
+ public const int GL_PIXEL_MAP_I_TO_R = 0x0C72;
+ public const int GL_PIXEL_MAP_I_TO_G = 0x0C73;
+ public const int GL_PIXEL_MAP_I_TO_B = 0x0C74;
+ public const int GL_PIXEL_MAP_I_TO_A = 0x0C75;
+ public const int GL_PIXEL_MAP_R_TO_R = 0x0C76;
+ public const int GL_PIXEL_MAP_G_TO_G = 0x0C77;
+ public const int GL_PIXEL_MAP_B_TO_B = 0x0C78;
+ public const int GL_PIXEL_MAP_A_TO_A = 0x0C79;
+ public const int GL_PACK_ALIGNMENT = 0x0D05;
+ public const int GL_PACK_LSB_FIRST = 0x0D01;
+ public const int GL_PACK_ROW_LENGTH = 0x0D02;
+ public const int GL_PACK_SKIP_PIXELS = 0x0D04;
+ public const int GL_PACK_SKIP_ROWS = 0x0D03;
+ public const int GL_PACK_SWAP_BYTES = 0x0D00;
+ public const int GL_UNPACK_ALIGNMENT = 0x0CF5;
+ public const int GL_UNPACK_LSB_FIRST = 0x0CF1;
+ public const int GL_UNPACK_ROW_LENGTH = 0x0CF2;
+ public const int GL_UNPACK_SKIP_PIXELS = 0x0CF4;
+ public const int GL_UNPACK_SKIP_ROWS = 0x0CF3;
+ public const int GL_UNPACK_SWAP_BYTES = 0x0CF0;
+ public const int GL_ZOOM_X = 0x0D16;
+ public const int GL_ZOOM_Y = 0x0D17;
+ public const int GL_TEXTURE_ENV = 0x2300;
+ public const int GL_TEXTURE_ENV_MODE = 0x2200;
+ public const int GL_TEXTURE_1D = 0x0DE0;
+ public const int GL_TEXTURE_2D = 0x0DE1;
+ public const int GL_TEXTURE_WRAP_S = 0x2802;
+ public const int GL_TEXTURE_WRAP_T = 0x2803;
+ public const int GL_TEXTURE_MAG_FILTER = 0x2800;
+ public const int GL_TEXTURE_MIN_FILTER = 0x2801;
+ public const int GL_TEXTURE_ENV_COLOR = 0x2201;
+ public const int GL_TEXTURE_GEN_S = 0x0C60;
+ public const int GL_TEXTURE_GEN_T = 0x0C61;
+ public const int GL_TEXTURE_GEN_R = 0x0C62;
+ public const int GL_TEXTURE_GEN_Q = 0x0C63;
+ public const int GL_TEXTURE_GEN_MODE = 0x2500;
+ public const int GL_TEXTURE_BORDER_COLOR = 0x1004;
+ public const int GL_TEXTURE_WIDTH = 0x1000;
+ public const int GL_TEXTURE_HEIGHT = 0x1001;
+ public const int GL_TEXTURE_BORDER = 0x1005;
+ public const int GL_TEXTURE_COMPONENTS = 0x1003;
+ public const int GL_TEXTURE_RED_SIZE = 0x805C;
+ public const int GL_TEXTURE_GREEN_SIZE = 0x805D;
+ public const int GL_TEXTURE_BLUE_SIZE = 0x805E;
+ public const int GL_TEXTURE_ALPHA_SIZE = 0x805F;
+ public const int GL_TEXTURE_LUMINANCE_SIZE = 0x8060;
+ public const int GL_TEXTURE_INTENSITY_SIZE = 0x8061;
+ public const int GL_NEAREST_MIPMAP_NEAREST = 0x2700;
+ public const int GL_NEAREST_MIPMAP_LINEAR = 0x2702;
+ public const int GL_LINEAR_MIPMAP_NEAREST = 0x2701;
+ public const int GL_LINEAR_MIPMAP_LINEAR = 0x2703;
+ public const int GL_OBJECT_LINEAR = 0x2401;
+ public const int GL_OBJECT_PLANE = 0x2501;
+ public const int GL_EYE_LINEAR = 0x2400;
+ public const int GL_EYE_PLANE = 0x2502;
+ public const int GL_SPHERE_MAP = 0x2402;
+ public const int GL_DECAL = 0x2101;
+ public const int GL_MODULATE = 0x2100;
+ public const int GL_NEAREST = 0x2600;
+ public const int GL_REPEAT = 0x2901;
+ public const int GL_CLAMP = 0x2900;
+ public const int GL_S = 0x2000;
+ public const int GL_T = 0x2001;
+ public const int GL_R = 0x2002;
+ public const int GL_Q = 0x2003;
+ public const int GL_VENDOR = 0x1F00;
+ public const int GL_RENDERER = 0x1F01;
+ public const int GL_VERSION = 0x1F02;
+ public const int GL_EXTENSIONS = 0x1F03;
+ public const int GL_INVALID_ENUM = 0x0500;
+ public const int GL_INVALID_VALUE = 0x0501;
+ public const int GL_INVALID_OPERATION = 0x0502;
+ public const int GL_STACK_OVERFLOW = 0x0503;
+ public const int GL_STACK_UNDERFLOW = 0x0504;
+ public const int GL_OUT_OF_MEMORY = 0x0505;
+ public const int GL_CURRENT_BIT = 0x00000001;
+ public const int GL_POINT_BIT = 0x00000002;
+ public const int GL_LINE_BIT = 0x00000004;
+ public const int GL_POLYGON_BIT = 0x00000008;
+ public const int GL_POLYGON_STIPPLE_BIT = 0x00000010;
+ public const int GL_PIXEL_MODE_BIT = 0x00000020;
+ public const int GL_LIGHTING_BIT = 0x00000040;
+ public const int GL_FOG_BIT = 0x00000080;
+ public const int GL_DEPTH_BUFFER_BIT = 0x00000100;
+ public const int GL_ACCUM_BUFFER_BIT = 0x00000200;
+ public const int GL_STENCIL_BUFFER_BIT = 0x00000400;
+ public const int GL_VIEWPORT_BIT = 0x00000800;
+ public const int GL_TRANSFORM_BIT = 0x00001000;
+ public const int GL_ENABLE_BIT = 0x00002000;
+ public const int GL_COLOR_BUFFER_BIT = 0x00004000;
+ public const int GL_HINT_BIT = 0x00008000;
+ public const int GL_EVAL_BIT = 0x00010000;
+ public const int GL_LIST_BIT = 0x00020000;
+ public const int GL_TEXTURE_BIT = 0x00040000;
+ public const int GL_SCISSOR_BIT = 0x00080000;
+ public const int GL_ALL_ATTRIB_BITS = -1;
+ public const int GL_PROXY_TEXTURE_1D = 0x8063;
+ public const int GL_PROXY_TEXTURE_2D = 0x8064;
+ public const int GL_TEXTURE_PRIORITY = 0x8066;
+ public const int GL_TEXTURE_RESIDENT = 0x8067;
+ public const int GL_TEXTURE_BINDING_1D = 0x8068;
+ public const int GL_TEXTURE_BINDING_2D = 0x8069;
+ public const int GL_TEXTURE_INTERNAL_FORMAT = 0x1003;
+ public const int GL_ALPHA4 = 0x803B;
+ public const int GL_ALPHA8 = 0x803C;
+ public const int GL_ALPHA12 = 0x803D;
+ public const int GL_ALPHA16 = 0x803E;
+ public const int GL_LUMINANCE4 = 0x803F;
+ public const int GL_LUMINANCE8 = 0x8040;
+ public const int GL_LUMINANCE12 = 0x8041;
+ public const int GL_LUMINANCE16 = 0x8042;
+ public const int GL_LUMINANCE4_ALPHA4 = 0x8043;
+ public const int GL_LUMINANCE6_ALPHA2 = 0x8044;
+ public const int GL_LUMINANCE8_ALPHA8 = 0x8045;
+ public const int GL_LUMINANCE12_ALPHA4 = 0x8046;
+ public const int GL_LUMINANCE12_ALPHA12 = 0x8047;
+ public const int GL_LUMINANCE16_ALPHA16 = 0x8048;
+ public const int GL_INTENSITY = 0x8049;
+ public const int GL_INTENSITY4 = 0x804A;
+ public const int GL_INTENSITY8 = 0x804B;
+ public const int GL_INTENSITY12 = 0x804C;
+ public const int GL_INTENSITY16 = 0x804D;
+ public const int GL_R3_G3_B2 = 0x2A10;
+ public const int GL_RGB4 = 0x804F;
+ public const int GL_RGB5 = 0x8050;
+ public const int GL_RGB8 = 0x8051;
+ public const int GL_RGB10 = 0x8052;
+ public const int GL_RGB12 = 0x8053;
+ public const int GL_RGB16 = 0x8054;
+ public const int GL_RGBA2 = 0x8055;
+ public const int GL_RGBA4 = 0x8056;
+ public const int GL_RGB5_A1 = 0x8057;
+ public const int GL_RGBA8 = 0x8058;
+ public const int GL_RGB10_A2 = 0x8059;
+ public const int GL_RGBA12 = 0x805A;
+ public const int GL_RGBA16 = 0x805B;
+ public const int GL_CLIENT_PIXEL_STORE_BIT = 0x00000001;
+ public const int GL_CLIENT_VERTEX_ARRAY_BIT = 0x00000002;
+ public const int GL_ALL_CLIENT_ATTRIB_BITS = -1;
+ public const int GL_CLIENT_ALL_ATTRIB_BITS = -1;
+ public const int GL_RESCALE_NORMAL = 0x803A;
+ public const int GL_CLAMP_TO_EDGE = 0x812F;
+ public const int GL_MAX_ELEMENTS_VERTICES = 0x80E8;
+ public const int GL_MAX_ELEMENTS_INDICES = 0x80E9;
+ public const int GL_BGR = 0x80E0;
+ public const int GL_BGRA = 0x80E1;
+ public const int GL_UNSIGNED_BYTE_3_3_2 = 0x8032;
+ public const int GL_UNSIGNED_BYTE_2_3_3_REV = 0x8362;
+ public const int GL_UNSIGNED_SHORT_5_6_5 = 0x8363;
+ public const int GL_UNSIGNED_SHORT_5_6_5_REV = 0x8364;
+ public const int GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033;
+ public const int GL_UNSIGNED_SHORT_4_4_4_4_REV = 0x8365;
+ public const int GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034;
+ public const int GL_UNSIGNED_SHORT_1_5_5_5_REV = 0x8366;
+ public const int GL_UNSIGNED_INT_8_8_8_8 = 0x8035;
+ public const int GL_UNSIGNED_INT_8_8_8_8_REV = 0x8367;
+ public const int GL_UNSIGNED_INT_10_10_10_2 = 0x8036;
+ public const int GL_UNSIGNED_INT_2_10_10_10_REV = 0x8368;
+ public const int GL_LIGHT_MODEL_COLOR_CONTROL = 0x81F8;
+ public const int GL_SINGLE_COLOR = 0x81F9;
+ public const int GL_SEPARATE_SPECULAR_COLOR = 0x81FA;
+ public const int GL_TEXTURE_MIN_LOD = 0x813A;
+ public const int GL_TEXTURE_MAX_LOD = 0x813B;
+ public const int GL_TEXTURE_BASE_LEVEL = 0x813C;
+ public const int GL_TEXTURE_MAX_LEVEL = 0x813D;
+ public const int GL_SMOOTH_POINT_SIZE_RANGE = 0x0B12;
+ public const int GL_SMOOTH_POINT_SIZE_GRANULARITY = 0x0B13;
+ public const int GL_SMOOTH_LINE_WIDTH_RANGE = 0x0B22;
+ public const int GL_SMOOTH_LINE_WIDTH_GRANULARITY = 0x0B23;
+ public const int GL_ALIASED_POINT_SIZE_RANGE = 0x846D;
+ public const int GL_ALIASED_LINE_WIDTH_RANGE = 0x846E;
+ public const int GL_PACK_SKIP_IMAGES = 0x806B;
+ public const int GL_PACK_IMAGE_HEIGHT = 0x806C;
+ public const int GL_UNPACK_SKIP_IMAGES = 0x806D;
+ public const int GL_UNPACK_IMAGE_HEIGHT = 0x806E;
+ public const int GL_TEXTURE_3D = 0x806F;
+ public const int GL_PROXY_TEXTURE_3D = 0x8070;
+ public const int GL_TEXTURE_DEPTH = 0x8071;
+ public const int GL_TEXTURE_WRAP_R = 0x8072;
+ public const int GL_MAX_3D_TEXTURE_SIZE = 0x8073;
+ public const int GL_TEXTURE_BINDING_3D = 0x806A;
+ public const int GL_CONSTANT_COLOR = 0x8001;
+ public const int GL_ONE_MINUS_CONSTANT_COLOR = 0x8002;
+ public const int GL_CONSTANT_ALPHA = 0x8003;
+ public const int GL_ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+ public const int GL_COLOR_TABLE = 0x80D0;
+ public const int GL_POST_CONVOLUTION_COLOR_TABLE = 0x80D1;
+ public const int GL_POST_COLOR_MATRIX_COLOR_TABLE = 0x80D2;
+ public const int GL_PROXY_COLOR_TABLE = 0x80D3;
+ public const int GL_PROXY_POST_CONVOLUTION_COLOR_TABLE = 0x80D4;
+ public const int GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = 0x80D5;
+ public const int GL_COLOR_TABLE_SCALE = 0x80D6;
+ public const int GL_COLOR_TABLE_BIAS = 0x80D7;
+ public const int GL_COLOR_TABLE_FORMAT = 0x80D8;
+ public const int GL_COLOR_TABLE_WIDTH = 0x80D9;
+ public const int GL_COLOR_TABLE_RED_SIZE = 0x80DA;
+ public const int GL_COLOR_TABLE_GREEN_SIZE = 0x80DB;
+ public const int GL_COLOR_TABLE_BLUE_SIZE = 0x80DC;
+ public const int GL_COLOR_TABLE_ALPHA_SIZE = 0x80DD;
+ public const int GL_COLOR_TABLE_LUMINANCE_SIZE = 0x80DE;
+ public const int GL_COLOR_TABLE_INTENSITY_SIZE = 0x80DF;
+ public const int GL_CONVOLUTION_1D = 0x8010;
+ public const int GL_CONVOLUTION_2D = 0x8011;
+ public const int GL_SEPARABLE_2D = 0x8012;
+ public const int GL_CONVOLUTION_BORDER_MODE = 0x8013;
+ public const int GL_CONVOLUTION_FILTER_SCALE = 0x8014;
+ public const int GL_CONVOLUTION_FILTER_BIAS = 0x8015;
+ public const int GL_REDUCE = 0x8016;
+ public const int GL_CONVOLUTION_FORMAT = 0x8017;
+ public const int GL_CONVOLUTION_WIDTH = 0x8018;
+ public const int GL_CONVOLUTION_HEIGHT = 0x8019;
+ public const int GL_MAX_CONVOLUTION_WIDTH = 0x801A;
+ public const int GL_MAX_CONVOLUTION_HEIGHT = 0x801B;
+ public const int GL_POST_CONVOLUTION_RED_SCALE = 0x801C;
+ public const int GL_POST_CONVOLUTION_GREEN_SCALE = 0x801D;
+ public const int GL_POST_CONVOLUTION_BLUE_SCALE = 0x801E;
+ public const int GL_POST_CONVOLUTION_ALPHA_SCALE = 0x801F;
+ public const int GL_POST_CONVOLUTION_RED_BIAS = 0x8020;
+ public const int GL_POST_CONVOLUTION_GREEN_BIAS = 0x8021;
+ public const int GL_POST_CONVOLUTION_BLUE_BIAS = 0x8022;
+ public const int GL_POST_CONVOLUTION_ALPHA_BIAS = 0x8023;
+ public const int GL_CONSTANT_BORDER = 0x8151;
+ public const int GL_REPLICATE_BORDER = 0x8153;
+ public const int GL_CONVOLUTION_BORDER_COLOR = 0x8154;
+ public const int GL_COLOR_MATRIX = 0x80B1;
+ public const int GL_COLOR_MATRIX_STACK_DEPTH = 0x80B2;
+ public const int GL_MAX_COLOR_MATRIX_STACK_DEPTH = 0x80B3;
+ public const int GL_POST_COLOR_MATRIX_RED_SCALE = 0x80B4;
+ public const int GL_POST_COLOR_MATRIX_GREEN_SCALE = 0x80B5;
+ public const int GL_POST_COLOR_MATRIX_BLUE_SCALE = 0x80B6;
+ public const int GL_POST_COLOR_MATRIX_ALPHA_SCALE = 0x80B7;
+ public const int GL_POST_COLOR_MATRIX_RED_BIAS = 0x80B8;
+ public const int GL_POST_COLOR_MATRIX_GREEN_BIAS = 0x80B9;
+ public const int GL_POST_COLOR_MATRIX_BLUE_BIAS = 0x80BA;
+ public const int GL_POST_COLOR_MATRIX_ALPHA_BIAS = 0x80BB;
+ public const int GL_HISTOGRAM = 0x8024;
+ public const int GL_PROXY_HISTOGRAM = 0x8025;
+ public const int GL_HISTOGRAM_WIDTH = 0x8026;
+ public const int GL_HISTOGRAM_FORMAT = 0x8027;
+ public const int GL_HISTOGRAM_RED_SIZE = 0x8028;
+ public const int GL_HISTOGRAM_GREEN_SIZE = 0x8029;
+ public const int GL_HISTOGRAM_BLUE_SIZE = 0x802A;
+ public const int GL_HISTOGRAM_ALPHA_SIZE = 0x802B;
+ public const int GL_HISTOGRAM_LUMINANCE_SIZE = 0x802C;
+ public const int GL_HISTOGRAM_SINK = 0x802D;
+ public const int GL_MINMAX = 0x802E;
+ public const int GL_MINMAX_FORMAT = 0x802F;
+ public const int GL_MINMAX_SINK = 0x8030;
+ public const int GL_TABLE_TOO_LARGE = 0x8031;
+ public const int GL_BLEND_EQUATION = 0x8009;
+ public const int GL_MIN = 0x8007;
+ public const int GL_MAX = 0x8008;
+ public const int GL_FUNC_ADD = 0x8006;
+ public const int GL_FUNC_SUBTRACT = 0x800A;
+ public const int GL_FUNC_REVERSE_SUBTRACT = 0x800B;
+ public const int GL_BLEND_COLOR = 0x8005;
+ public const int GL_TEXTURE0 = 0x84C0;
+ public const int GL_TEXTURE1 = 0x84C1;
+ public const int GL_TEXTURE2 = 0x84C2;
+ public const int GL_TEXTURE3 = 0x84C3;
+ public const int GL_TEXTURE4 = 0x84C4;
+ public const int GL_TEXTURE5 = 0x84C5;
+ public const int GL_TEXTURE6 = 0x84C6;
+ public const int GL_TEXTURE7 = 0x84C7;
+ public const int GL_TEXTURE8 = 0x84C8;
+ public const int GL_TEXTURE9 = 0x84C9;
+ public const int GL_TEXTURE10 = 0x84CA;
+ public const int GL_TEXTURE11 = 0x84CB;
+ public const int GL_TEXTURE12 = 0x84CC;
+ public const int GL_TEXTURE13 = 0x84CD;
+ public const int GL_TEXTURE14 = 0x84CE;
+ public const int GL_TEXTURE15 = 0x84CF;
+ public const int GL_TEXTURE16 = 0x84D0;
+ public const int GL_TEXTURE17 = 0x84D1;
+ public const int GL_TEXTURE18 = 0x84D2;
+ public const int GL_TEXTURE19 = 0x84D3;
+ public const int GL_TEXTURE20 = 0x84D4;
+ public const int GL_TEXTURE21 = 0x84D5;
+ public const int GL_TEXTURE22 = 0x84D6;
+ public const int GL_TEXTURE23 = 0x84D7;
+ public const int GL_TEXTURE24 = 0x84D8;
+ public const int GL_TEXTURE25 = 0x84D9;
+ public const int GL_TEXTURE26 = 0x84DA;
+ public const int GL_TEXTURE27 = 0x84DB;
+ public const int GL_TEXTURE28 = 0x84DC;
+ public const int GL_TEXTURE29 = 0x84DD;
+ public const int GL_TEXTURE30 = 0x84DE;
+ public const int GL_TEXTURE31 = 0x84DF;
+ public const int GL_ACTIVE_TEXTURE = 0x84E0;
+ public const int GL_CLIENT_ACTIVE_TEXTURE = 0x84E1;
+ public const int GL_MAX_TEXTURE_UNITS = 0x84E2;
+ public const int GL_NORMAL_MAP = 0x8511;
+ public const int GL_REFLECTION_MAP = 0x8512;
+ public const int GL_TEXTURE_CUBE_MAP = 0x8513;
+ public const int GL_TEXTURE_BINDING_CUBE_MAP = 0x8514;
+ public const int GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+ public const int GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+ public const int GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+ public const int GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+ public const int GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+ public const int GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+ public const int GL_PROXY_TEXTURE_CUBE_MAP = 0x851B;
+ public const int GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+ public const int GL_COMPRESSED_ALPHA = 0x84E9;
+ public const int GL_COMPRESSED_LUMINANCE = 0x84EA;
+ public const int GL_COMPRESSED_LUMINANCE_ALPHA = 0x84EB;
+ public const int GL_COMPRESSED_INTENSITY = 0x84EC;
+ public const int GL_COMPRESSED_RGB = 0x84ED;
+ public const int GL_COMPRESSED_RGBA = 0x84EE;
+ public const int GL_TEXTURE_COMPRESSION_HINT = 0x84EF;
+ public const int GL_TEXTURE_COMPRESSED_IMAGE_SIZE = 0x86A0;
+ public const int GL_TEXTURE_COMPRESSED = 0x86A1;
+ public const int GL_NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2;
+ public const int GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+ public const int GL_MULTISAMPLE = 0x809D;
+ public const int GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+ public const int GL_SAMPLE_ALPHA_TO_ONE = 0x809F;
+ public const int GL_SAMPLE_COVERAGE = 0x80A0;
+ public const int GL_SAMPLE_BUFFERS = 0x80A8;
+ public const int GL_SAMPLES = 0x80A9;
+ public const int GL_SAMPLE_COVERAGE_VALUE = 0x80AA;
+ public const int GL_SAMPLE_COVERAGE_INVERT = 0x80AB;
+ public const int GL_MULTISAMPLE_BIT = 0x20000000;
+ public const int GL_TRANSPOSE_MODELVIEW_MATRIX = 0x84E3;
+ public const int GL_TRANSPOSE_PROJECTION_MATRIX = 0x84E4;
+ public const int GL_TRANSPOSE_TEXTURE_MATRIX = 0x84E5;
+ public const int GL_TRANSPOSE_COLOR_MATRIX = 0x84E6;
+ public const int GL_COMBINE = 0x8570;
+ public const int GL_COMBINE_RGB = 0x8571;
+ public const int GL_COMBINE_ALPHA = 0x8572;
+ public const int GL_SOURCE0_RGB = 0x8580;
+ public const int GL_SOURCE1_RGB = 0x8581;
+ public const int GL_SOURCE2_RGB = 0x8582;
+ public const int GL_SOURCE0_ALPHA = 0x8588;
+ public const int GL_SOURCE1_ALPHA = 0x8589;
+ public const int GL_SOURCE2_ALPHA = 0x858A;
+ public const int GL_OPERAND0_RGB = 0x8590;
+ public const int GL_OPERAND1_RGB = 0x8591;
+ public const int GL_OPERAND2_RGB = 0x8592;
+ public const int GL_OPERAND0_ALPHA = 0x8598;
+ public const int GL_OPERAND1_ALPHA = 0x8599;
+ public const int GL_OPERAND2_ALPHA = 0x859A;
+ public const int GL_RGB_SCALE = 0x8573;
+ public const int GL_ADD_SIGNED = 0x8574;
+ public const int GL_INTERPOLATE = 0x8575;
+ public const int GL_SUBTRACT = 0x84E7;
+ public const int GL_CONSTANT = 0x8576;
+ public const int GL_PRIMARY_COLOR = 0x8577;
+ public const int GL_PREVIOUS = 0x8578;
+ public const int GL_DOT3_RGB = 0x86AE;
+ public const int GL_DOT3_RGBA = 0x86AF;
+ public const int GL_CLAMP_TO_BORDER = 0x812D;
+ public const int GL_TEXTURE0_ARB = 0x84C0;
+ public const int GL_TEXTURE1_ARB = 0x84C1;
+ public const int GL_TEXTURE2_ARB = 0x84C2;
+ public const int GL_TEXTURE3_ARB = 0x84C3;
+ public const int GL_TEXTURE4_ARB = 0x84C4;
+ public const int GL_TEXTURE5_ARB = 0x84C5;
+ public const int GL_TEXTURE6_ARB = 0x84C6;
+ public const int GL_TEXTURE7_ARB = 0x84C7;
+ public const int GL_TEXTURE8_ARB = 0x84C8;
+ public const int GL_TEXTURE9_ARB = 0x84C9;
+ public const int GL_TEXTURE10_ARB = 0x84CA;
+ public const int GL_TEXTURE11_ARB = 0x84CB;
+ public const int GL_TEXTURE12_ARB = 0x84CC;
+ public const int GL_TEXTURE13_ARB = 0x84CD;
+ public const int GL_TEXTURE14_ARB = 0x84CE;
+ public const int GL_TEXTURE15_ARB = 0x84CF;
+ public const int GL_TEXTURE16_ARB = 0x84D0;
+ public const int GL_TEXTURE17_ARB = 0x84D1;
+ public const int GL_TEXTURE18_ARB = 0x84D2;
+ public const int GL_TEXTURE19_ARB = 0x84D3;
+ public const int GL_TEXTURE20_ARB = 0x84D4;
+ public const int GL_TEXTURE21_ARB = 0x84D5;
+ public const int GL_TEXTURE22_ARB = 0x84D6;
+ public const int GL_TEXTURE23_ARB = 0x84D7;
+ public const int GL_TEXTURE24_ARB = 0x84D8;
+ public const int GL_TEXTURE25_ARB = 0x84D9;
+ public const int GL_TEXTURE26_ARB = 0x84DA;
+ public const int GL_TEXTURE27_ARB = 0x84DB;
+ public const int GL_TEXTURE28_ARB = 0x84DC;
+ public const int GL_TEXTURE29_ARB = 0x84DD;
+ public const int GL_TEXTURE30_ARB = 0x84DE;
+ public const int GL_TEXTURE31_ARB = 0x84DF;
+ public const int GL_ACTIVE_TEXTURE_ARB = 0x84E0;
+ public const int GL_CLIENT_ACTIVE_TEXTURE_ARB = 0x84E1;
+ public const int GL_MAX_TEXTURE_UNITS_ARB = 0x84E2;
+ public const int GL_DEPTH_STENCIL_MESA = 0x8750;
+ public const int GL_UNSIGNED_INT_24_8_MESA = 0x8751;
+ public const int GL_UNSIGNED_INT_8_24_REV_MESA = 0x8752;
+ public const int GL_UNSIGNED_SHORT_15_1_MESA = 0x8753;
+ public const int GL_UNSIGNED_SHORT_1_15_REV_MESA = 0x8754;
+ public const int GL_ALPHA_BLEND_EQUATION_ATI = 0x883D;
+
+
+ // glext.h
+
+ public const int GL_FRAMEBUFFER_BINDING = 0x8CA6;
+ }
+}
diff --git a/src/Avalonia.OpenGL/GlDisplayType.cs b/src/Avalonia.OpenGL/GlDisplayType.cs
new file mode 100644
index 00000000000..2e5178bc37a
--- /dev/null
+++ b/src/Avalonia.OpenGL/GlDisplayType.cs
@@ -0,0 +1,8 @@
+namespace Avalonia.OpenGL
+{
+ public enum GlDisplayType
+ {
+ OpenGL2,
+ OpenGLES2
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.OpenGL/GlInterface.cs b/src/Avalonia.OpenGL/GlInterface.cs
new file mode 100644
index 00000000000..60dc5381d4c
--- /dev/null
+++ b/src/Avalonia.OpenGL/GlInterface.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Avalonia.OpenGL
+{
+ public delegate IntPtr GlGetProcAddressDelegate(string procName);
+
+ public class GlInterface : GlInterfaceBase
+ {
+ private readonly Func _getProcAddress;
+
+ public GlInterface(Func getProcAddress) : base(getProcAddress)
+ {
+ _getProcAddress = getProcAddress;
+ }
+
+ public IntPtr GetProcAddress(string proc) => _getProcAddress(proc, true);
+
+ public T GetProcAddress(string proc) => Marshal.GetDelegateForFunctionPointer(GetProcAddress(proc));
+
+ // ReSharper disable UnassignedGetOnlyAutoProperty
+
+ public delegate void GlClearStencil(int s);
+ [EntryPoint("glClearStencil")]
+ public GlClearStencil ClearStencil { get; }
+
+ public delegate void GlClearColor(int r, int g, int b, int a);
+ [EntryPoint("glClearColor")]
+ public GlClearColor ClearColor { get; }
+
+ public delegate void GlClear(int bits);
+ [EntryPoint("glClear")]
+ public GlClear Clear { get; }
+
+ public delegate void GlViewport(int x, int y, int width, int height);
+ [EntryPoint("glViewport")]
+ public GlViewport Viewport { get; }
+
+ [EntryPoint("glFlush")]
+ public Action Flush { get; }
+
+ public delegate void GlGetIntegerv(int name, out int rv);
+ [EntryPoint("glGetIntegerv")]
+ public GlGetIntegerv GetIntegerv { get; }
+
+ // ReSharper restore UnassignedGetOnlyAutoProperty
+ }
+}
diff --git a/src/Avalonia.OpenGL/GlInterfaceBase.cs b/src/Avalonia.OpenGL/GlInterfaceBase.cs
new file mode 100644
index 00000000000..33191a65678
--- /dev/null
+++ b/src/Avalonia.OpenGL/GlInterfaceBase.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+namespace Avalonia.OpenGL
+{
+ public class GlInterfaceBase
+ {
+ public GlInterfaceBase(Func getProcAddress)
+ {
+ foreach (var prop in this.GetType().GetProperties())
+ {
+ var a = prop.GetCustomAttribute();
+ if (a != null)
+ {
+ var fieldName = $"<{prop.Name}>k__BackingField";
+ var field = prop.DeclaringType.GetField(fieldName,
+ BindingFlags.Instance | BindingFlags.NonPublic);
+ if (field == null)
+ throw new InvalidProgramException($"Expected property {prop.Name} to have {fieldName}");
+ var proc = getProcAddress(a.EntryPoint, a.Optional);
+ if (proc != IntPtr.Zero)
+ field.SetValue(this, Marshal.GetDelegateForFunctionPointer(proc, prop.PropertyType));
+ }
+ }
+ }
+ }
+}
diff --git a/src/Avalonia.OpenGL/IGlContext.cs b/src/Avalonia.OpenGL/IGlContext.cs
new file mode 100644
index 00000000000..954567fe2e5
--- /dev/null
+++ b/src/Avalonia.OpenGL/IGlContext.cs
@@ -0,0 +1,8 @@
+namespace Avalonia.OpenGL
+{
+ public interface IGlContext
+ {
+ IGlDisplay Display { get; }
+ void MakeCurrent(IGlSurface surface);
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.OpenGL/IGlDisplay.cs b/src/Avalonia.OpenGL/IGlDisplay.cs
new file mode 100644
index 00000000000..e7568bd5e7f
--- /dev/null
+++ b/src/Avalonia.OpenGL/IGlDisplay.cs
@@ -0,0 +1,11 @@
+namespace Avalonia.OpenGL
+{
+ public interface IGlDisplay
+ {
+ GlDisplayType Type { get; }
+ GlInterface GlInterface { get; }
+ void ClearContext();
+ int SampleCount { get; }
+ int StencilSize { get; }
+ }
+}
diff --git a/src/Avalonia.OpenGL/IGlPlatformSurface.cs b/src/Avalonia.OpenGL/IGlPlatformSurface.cs
new file mode 100644
index 00000000000..22d36b44724
--- /dev/null
+++ b/src/Avalonia.OpenGL/IGlPlatformSurface.cs
@@ -0,0 +1,7 @@
+namespace Avalonia.OpenGL
+{
+ public interface IGlPlatformSurface
+ {
+ IGlPlatformSurfaceRenderTarget CreateGlRenderTarget();
+ }
+}
diff --git a/src/Avalonia.OpenGL/IGlPlatformSurfaceRenderTarget.cs b/src/Avalonia.OpenGL/IGlPlatformSurfaceRenderTarget.cs
new file mode 100644
index 00000000000..53da93315ca
--- /dev/null
+++ b/src/Avalonia.OpenGL/IGlPlatformSurfaceRenderTarget.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+ public interface IGlPlatformSurfaceRenderTarget : IDisposable
+ {
+ IGlPlatformSurfaceRenderingSession BeginDraw();
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.OpenGL/IGlPlatformSurfaceRenderingSession.cs b/src/Avalonia.OpenGL/IGlPlatformSurfaceRenderingSession.cs
new file mode 100644
index 00000000000..22641d7b539
--- /dev/null
+++ b/src/Avalonia.OpenGL/IGlPlatformSurfaceRenderingSession.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+ public interface IGlPlatformSurfaceRenderingSession : IDisposable
+ {
+ IGlDisplay Display { get; }
+ // TODO: Change to PixelSize struct once https://github.com/AvaloniaUI/Avalonia/pull/1889 is merged
+ System.Drawing.Size PixelSize { get; }
+ double Scaling { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.OpenGL/IGlSurface.cs b/src/Avalonia.OpenGL/IGlSurface.cs
new file mode 100644
index 00000000000..499d0a3c90a
--- /dev/null
+++ b/src/Avalonia.OpenGL/IGlSurface.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+ public interface IGlSurface : IDisposable
+ {
+ IGlDisplay Display { get; }
+ void SwapBuffers();
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.OpenGL/IWindowingPlatformGlFeature.cs b/src/Avalonia.OpenGL/IWindowingPlatformGlFeature.cs
new file mode 100644
index 00000000000..2c4a8b64b37
--- /dev/null
+++ b/src/Avalonia.OpenGL/IWindowingPlatformGlFeature.cs
@@ -0,0 +1,7 @@
+namespace Avalonia.OpenGL
+{
+ public interface IWindowingPlatformGlFeature
+ {
+ IGlContext ImmediateContext { get; }
+ }
+}
diff --git a/src/Avalonia.OpenGL/OpenGlException.cs b/src/Avalonia.OpenGL/OpenGlException.cs
new file mode 100644
index 00000000000..7ba539a2b2c
--- /dev/null
+++ b/src/Avalonia.OpenGL/OpenGlException.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+ public class OpenGlException : Exception
+ {
+ public OpenGlException(string message) : base(message)
+ {
+
+ }
+ }
+}
diff --git a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
index ef043959adc..aa569a5e6a6 100644
--- a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
+++ b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
@@ -9,6 +9,7 @@
+
\ No newline at end of file
diff --git a/src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs b/src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs
index a3e7590cf5f..a8606737327 100644
--- a/src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs
+++ b/src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs
@@ -3,6 +3,7 @@
using System.Threading.Tasks;
using Avalonia.Gtk3.Interop;
using Avalonia.Input.Platform;
+using Avalonia.Platform.Interop;
namespace Avalonia.Gtk3
{
diff --git a/src/Gtk/Avalonia.Gtk3/CursorFactory.cs b/src/Gtk/Avalonia.Gtk3/CursorFactory.cs
index d6a3c1f2604..a28b1cbb1ae 100644
--- a/src/Gtk/Avalonia.Gtk3/CursorFactory.cs
+++ b/src/Gtk/Avalonia.Gtk3/CursorFactory.cs
@@ -3,6 +3,7 @@
using Avalonia.Gtk3.Interop;
using Avalonia.Input;
using Avalonia.Platform;
+using Avalonia.Platform.Interop;
using CursorType = Avalonia.Gtk3.GdkCursorType;
namespace Avalonia.Gtk3
{
diff --git a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs b/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
index bbb6a01c052..e2e8a346769 100644
--- a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
+++ b/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
@@ -7,7 +7,9 @@
using Avalonia.Gtk3.Interop;
using Avalonia.Input;
using Avalonia.Input.Platform;
+using Avalonia.OpenGL;
using Avalonia.Platform;
+using Avalonia.Platform.Interop;
using Avalonia.Rendering;
using Avalonia.Threading;
@@ -22,8 +24,33 @@ public class Gtk3Platform : IWindowingPlatform, IPlatformSettings, IPlatformThre
internal static string DisplayClassName;
public static bool UseDeferredRendering = true;
private static bool s_gtkInitialized;
- public static void Initialize()
+
+ static bool EnvOption(string option, bool def, bool? specified)
+ {
+ bool? Parse(string env)
+ {
+ var v = Environment.GetEnvironmentVariable("AVALONIA_GTK3_" + env);
+ if (v == null)
+ return null;
+ if (v.ToLowerInvariant() == "false" || v == "0")
+ return false;
+ return true;
+ }
+
+ var overridden = Parse(option + "_OVERRIDE");
+ if (overridden.HasValue)
+ return overridden.Value;
+ if (specified.HasValue)
+ return specified.Value;
+ var envValue = Parse(option);
+ return envValue ?? def;
+ }
+
+ public static void Initialize(Gtk3PlatformOptions options)
{
+ Resolver.Custom = options.CustomResolver;
+ UseDeferredRendering = EnvOption("USE_DEFERRED_RENDERING", true, options.UseDeferredRendering);
+ var useGpu = EnvOption("USE_GPU", false, options.UseGpuAcceleration);
if (!s_gtkInitialized)
{
try
@@ -55,7 +82,8 @@ public static void Initialize()
.Bind().ToConstant(new RenderLoop())
.Bind().ToConstant(new DefaultRenderTimer(60))
.Bind().ToConstant(new PlatformIconLoader());
-
+ if (useGpu)
+ EglGlPlatformFeature.TryInitialize();
}
public IWindowImpl CreateWindow() => new WindowImpl();
@@ -116,18 +144,24 @@ public void Signal(DispatcherPriority prio)
public bool CurrentThreadIsLoopThread => s_tlsMarker;
}
+
+ public class Gtk3PlatformOptions
+ {
+ public bool? UseDeferredRendering { get; set; }
+ public bool? UseGpuAcceleration { get; set; }
+ public ICustomGtk3NativeLibraryResolver CustomResolver { get; set; }
+ }
}
namespace Avalonia
{
public static class Gtk3AppBuilderExtensions
{
- public static T UseGtk3(this AppBuilderBase builder, bool deferredRendering = true, ICustomGtk3NativeLibraryResolver resolver = null)
+ public static T UseGtk3(this AppBuilderBase builder, Gtk3PlatformOptions options = null)
where T : AppBuilderBase, new()
{
- Resolver.Custom = resolver;
- Gtk3Platform.UseDeferredRendering = deferredRendering;
- return builder.UseWindowingSubsystem(Gtk3Platform.Initialize, "GTK3");
+ return builder.UseWindowingSubsystem(() => Gtk3Platform.Initialize(options ?? new Gtk3PlatformOptions()),
+ "GTK3");
}
}
}
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/GException.cs b/src/Gtk/Avalonia.Gtk3/Interop/GException.cs
index b0c171089ea..5ff6cbe8edc 100644
--- a/src/Gtk/Avalonia.Gtk3/Interop/GException.cs
+++ b/src/Gtk/Avalonia.Gtk3/Interop/GException.cs
@@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
+using Avalonia.Platform.Interop;
namespace Avalonia.Gtk3.Interop
{
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
index 914d0feafca..98a73a98a99 100644
--- a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
+++ b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
@@ -2,6 +2,7 @@
using System;
using System.Runtime.InteropServices;
using Avalonia.Controls;
+using Avalonia.Platform.Interop;
using gdouble = System.Double;
using gint = System.Int32;
using gint16 = System.Int16;
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs b/src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs
index 989a96a4f0b..322b9bdfaed 100644
--- a/src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs
+++ b/src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs
@@ -2,6 +2,7 @@
using System.IO;
using System.Runtime.InteropServices;
using Avalonia.Platform;
+using Avalonia.Platform.Interop;
namespace Avalonia.Gtk3.Interop
{
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs b/src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs
index 57c8ac7c3a7..c39cb9e394d 100644
--- a/src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs
+++ b/src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs
@@ -5,6 +5,7 @@
using System.Reflection;
using System.Runtime.InteropServices;
using Avalonia.Platform;
+using Avalonia.Platform.Interop;
namespace Avalonia.Gtk3.Interop
{
@@ -82,7 +83,7 @@ static string GetDllName(GtkDll dll)
}
}
- static IntPtr LoadDll(IDynLoader loader, GtkDll dll)
+ static IntPtr LoadDll(IDynamicLibraryLoader loader, GtkDll dll)
{
var exceptions = new List();
@@ -118,7 +119,7 @@ static IntPtr LoadDll(IDynLoader loader, GtkDll dll)
public static void Resolve(string basePath = null)
{
- var loader = Platform.Value == OperatingSystemType.WinNT ? (IDynLoader)new Win32Loader() : new UnixLoader();
+ var loader = AvaloniaLocator.Current.GetService();
var dlls = Enum.GetValues(typeof(GtkDll)).Cast().ToDictionary(x => x, x => LoadDll(loader, x));
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Signal.cs b/src/Gtk/Avalonia.Gtk3/Interop/Signal.cs
index bc555585517..8eaca931524 100644
--- a/src/Gtk/Avalonia.Gtk3/Interop/Signal.cs
+++ b/src/Gtk/Avalonia.Gtk3/Interop/Signal.cs
@@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
+using Avalonia.Platform.Interop;
namespace Avalonia.Gtk3.Interop
{
diff --git a/src/Gtk/Avalonia.Gtk3/SystemDialogs.cs b/src/Gtk/Avalonia.Gtk3/SystemDialogs.cs
index d4bd878d539..5e6615f92d1 100644
--- a/src/Gtk/Avalonia.Gtk3/SystemDialogs.cs
+++ b/src/Gtk/Avalonia.Gtk3/SystemDialogs.cs
@@ -7,6 +7,7 @@
using Avalonia.Controls.Platform;
using Avalonia.Gtk3.Interop;
using Avalonia.Platform;
+using Avalonia.Platform.Interop;
namespace Avalonia.Gtk3
{
diff --git a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs
index 67ddcf1e5f6..0ec4047086f 100644
--- a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs
+++ b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs
@@ -7,18 +7,21 @@
using Avalonia.Gtk3.Interop;
using Avalonia.Input;
using Avalonia.Input.Raw;
+using Avalonia.OpenGL;
using Avalonia.Platform;
+using Avalonia.Platform.Interop;
using Avalonia.Rendering;
using Avalonia.Threading;
namespace Avalonia.Gtk3
{
- abstract class WindowBaseImpl : IWindowBaseImpl, IPlatformHandle
+ abstract class WindowBaseImpl : IWindowBaseImpl, IPlatformHandle, EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo
{
public readonly GtkWindow GtkWidget;
private IInputRoot _inputRoot;
private readonly GtkImContext _imContext;
private readonly FramebufferManager _framebuffer;
+ private readonly EglGlPlatformSurface _egl;
protected readonly List Disposables = new List();
private Size _lastSize;
private Point _lastPosition;
@@ -36,7 +39,13 @@ public WindowBaseImpl(GtkWindow gtkWidget)
{
GtkWidget = gtkWidget;
- _framebuffer = new FramebufferManager(this);
+
+ var glf = AvaloniaLocator.Current.GetService() as EglGlPlatformFeature;
+ if (glf != null)
+ _egl = new EglGlPlatformSurface((EglDisplay)glf.Display, glf.DeferredContext, this);
+ else
+ _framebuffer = new FramebufferManager(this);
+
_imContext = Native.GtkImMulticontextNew();
Disposables.Add(_imContext);
Native.GtkWidgetSetEvents(gtkWidget, 0xFFFFFE);
@@ -57,12 +66,15 @@ public WindowBaseImpl(GtkWindow gtkWidget)
Native.GtkWidgetRealize(gtkWidget);
GdkWindowHandle = this.Handle.Handle;
_lastSize = ClientSize;
- if (Gtk3Platform.UseDeferredRendering)
+
+ if (_egl != null)
+ Native.GtkWidgetSetDoubleBuffered(gtkWidget, false);
+ else if (Gtk3Platform.UseDeferredRendering)
{
Native.GtkWidgetSetDoubleBuffered(gtkWidget, false);
_gcHandle = GCHandle.Alloc(this);
- _tickCallback = Native.GtkWidgetAddTickCallback(GtkWidget, PinnedStaticCallback, GCHandle.ToIntPtr(_gcHandle), IntPtr.Zero);
-
+ _tickCallback = Native.GtkWidgetAddTickCallback(GtkWidget, PinnedStaticCallback,
+ GCHandle.ToIntPtr(_gcHandle), IntPtr.Zero);
}
}
@@ -488,7 +500,7 @@ public Point Position
}
IntPtr IPlatformHandle.Handle => Native.GetNativeGdkWindowHandle(Native.GtkWidgetGetWindow(GtkWidget));
- public IEnumerable