Browse Source

OpenGL/EGL rendering support in Skia/GTK backends

Nikita Tsukanov 7 years ago
parent
commit
4c9c0c0c40

+ 12 - 0
src/Avalonia.OpenGL/Avalonia.OpenGL.csproj

@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFramework>netstandard2.0</TargetFramework>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
+      <ProjectReference Include="..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
+    </ItemGroup>
+
+</Project>

+ 178 - 0
src/Avalonia.OpenGL/EglConsts.cs

@@ -0,0 +1,178 @@
+// 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;
+
+
+    }
+}

+ 181 - 0
src/Avalonia.OpenGL/EglDisplay.cs

@@ -0,0 +1,181 @@
+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;
+            _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_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 =>
+            {
+                using (var u = new Utf8Buffer(proc))
+                    return _egl.GetProcAddress(u);
+            });
+        }
+
+        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");
+            }
+        }
+    }
+
+    
+}

+ 32 - 0
src/Avalonia.OpenGL/EglGlPlatformFeature.cs

@@ -0,0 +1,32 @@
+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()
+        {
+            try
+            {
+                var disp = new EglDisplay();
+                var ctx = disp.CreateContext(null);
+                AvaloniaLocator.CurrentMutable.Bind<IWindowingPlatformGlFeature>().ToConstant(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);
+            }
+        }
+    }
+}

+ 82 - 0
src/Avalonia.OpenGL/EglGlPlatformSurface.cs

@@ -0,0 +1,82 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+    public interface IEglWindowGlPlatformSurfaceInfo
+    {
+        IntPtr Handle { get; }
+        int PixelWidth { get; }
+        int PixelHeight { get; }
+        Vector Dpi { get; }
+        
+    }
+    
+    public class EglGlPlatformSurface : IGlPlatformSurface
+    {
+        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 int PixelWidth => _info.PixelWidth;
+                public int PixelHeight => _info.PixelHeight;
+                public Vector Dpi => _info.Dpi;
+            }
+        }
+    }
+}

+ 91 - 0
src/Avalonia.OpenGL/EglInterface.cs

@@ -0,0 +1,91 @@
+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<string, IntPtr> Load()
+        {
+            var os = AvaloniaLocator.Current.GetService<IRuntimePlatform>().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<string, IntPtr> Load(string library)
+        {
+            var dyn = AvaloniaLocator.Current.GetService<IDynamicLibraryLoader>();
+            var lib = dyn.LoadLibrary(library);
+            return s => dyn.GetProcAddress(lib, s, false);
+        }
+        
+        
+        // ReSharper disable UnassignedGetOnlyAutoProperty
+        public delegate IntPtr EglGetDisplay(IntPtr nativeDisplay);
+        [EntryPoint("eglGetDisplay")]
+        public EglGetDisplay GetDisplay { 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
+
+    }
+}

+ 14 - 0
src/Avalonia.OpenGL/EntryPointAttribute.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+    class EntryPointAttribute : Attribute
+    {
+        public string EntryPoint { get; }
+
+        public EntryPointAttribute(string entryPoint)
+        {
+            EntryPoint = entryPoint;
+        }
+    }
+}

+ 789 - 0
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;
+    }
+}

+ 50 - 0
src/Avalonia.OpenGL/GlInterface.cs

@@ -0,0 +1,50 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Avalonia.OpenGL
+{
+    public delegate IntPtr GlGetProcAddressDelegate(string procName);
+    
+    public class GlInterface : GlInterfaceBase
+    {
+        private readonly Func<string, IntPtr> _getProcAddress;
+
+
+        public GlInterface(Func<string, IntPtr> getProcAddress) : base(getProcAddress)
+        {
+            _getProcAddress = getProcAddress;
+        }
+
+        public IntPtr GetProcAddress(string proc) => _getProcAddress(proc);
+
+        public T GetProcAddress<T>(string proc) => Marshal.GetDelegateForFunctionPointer<T>(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
+    }
+}

+ 27 - 0
src/Avalonia.OpenGL/GlInterfaceBase.cs

@@ -0,0 +1,27 @@
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+namespace Avalonia.OpenGL
+{
+    public class GlInterfaceBase
+    {
+        public GlInterfaceBase(Func<string, IntPtr> getProcAddress)
+        {
+            foreach (var prop in this.GetType().GetProperties())
+            {
+                var a = prop.GetCustomAttribute<EntryPointAttribute>();
+                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}");
+                    field.SetValue(this,
+                        Marshal.GetDelegateForFunctionPointer(getProcAddress(a.EntryPoint), prop.PropertyType));
+                }
+            }
+        }
+    }
+}

+ 31 - 0
src/Avalonia.OpenGL/IGlDisplay.cs

@@ -0,0 +1,31 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+    public interface IGlDisplay
+    {
+        GlDisplayType Type { get; }
+        GlInterface GlInterface { get; }
+        void ClearContext();
+        int SampleCount { get; }
+        int StencilSize { get; }
+    }
+    
+    public enum GlDisplayType
+    {
+        OpenGL2,
+        OpenGLES2
+    }
+
+    public interface IGlContext
+    {
+        IGlDisplay Display { get; }
+        void MakeCurrent(IGlSurface surface);
+    }
+
+    public interface IGlSurface : IDisposable
+    {
+        IGlDisplay Display { get; }
+        void SwapBuffers();
+    }
+}

+ 22 - 0
src/Avalonia.OpenGL/IGlPlatformSurface.cs

@@ -0,0 +1,22 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+    public interface IGlPlatformSurface
+    {
+        IGlPlatformSurfaceRenderTarget CreateGlRenderTarget();
+    }
+
+    public interface IGlPlatformSurfaceRenderTarget : IDisposable
+    {
+        IGlPlatformSurfaceRenderingSession BeginDraw();
+    }
+
+    public interface IGlPlatformSurfaceRenderingSession : IDisposable
+    {
+        IGlDisplay Display { get; }
+        int PixelWidth { get; }
+        int PixelHeight { get; }
+        Vector Dpi { get; }
+    }
+}

+ 7 - 0
src/Avalonia.OpenGL/IWindowingPlatformGlFeature.cs

@@ -0,0 +1,7 @@
+namespace Avalonia.OpenGL
+{
+    public interface IWindowingPlatformGlFeature
+    {
+        IGlContext ImmediateContext { get; }
+    }
+}

+ 12 - 0
src/Avalonia.OpenGL/OpenGlException.cs

@@ -0,0 +1,12 @@
+using System;
+
+namespace Avalonia.OpenGL
+{
+    public class OpenGlException : Exception
+    {
+        public OpenGlException(string message) : base(message)
+        {
+
+        }
+    }
+}

+ 1 - 0
src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj

@@ -9,6 +9,7 @@
     <ProjectReference Include="..\..\Avalonia.Controls\Avalonia.Controls.csproj" />
     <ProjectReference Include="..\..\Avalonia.Input\Avalonia.Input.csproj" />
     <ProjectReference Include="..\..\Avalonia.Interactivity\Avalonia.Interactivity.csproj" />
+    <ProjectReference Include="..\..\Avalonia.OpenGL\Avalonia.OpenGL.csproj" />
     <ProjectReference Include="..\..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
   </ItemGroup>
 </Project>

+ 2 - 1
src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs

@@ -7,6 +7,7 @@ using Avalonia.Gtk3;
 using Avalonia.Gtk3.Interop;
 using Avalonia.Input;
 using Avalonia.Input.Platform;
+using Avalonia.OpenGL;
 using Avalonia.Platform;
 using Avalonia.Platform.Interop;
 using Avalonia.Rendering;
@@ -56,7 +57,7 @@ namespace Avalonia.Gtk3
                 .Bind<IRenderLoop>().ToConstant(new RenderLoop())
                 .Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
                 .Bind<IPlatformIconLoader>().ToConstant(new PlatformIconLoader());
-
+            EglGlPlatformFeature.TryInitialize();
         }
 
         public IWindowImpl CreateWindow() => new WindowImpl();

+ 23 - 6
src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

@@ -7,6 +7,7 @@ using Avalonia.Controls;
 using Avalonia.Gtk3.Interop;
 using Avalonia.Input;
 using Avalonia.Input.Raw;
+using Avalonia.OpenGL;
 using Avalonia.Platform;
 using Avalonia.Platform.Interop;
 using Avalonia.Rendering;
@@ -14,12 +15,13 @@ using Avalonia.Threading;
 
 namespace Avalonia.Gtk3
 {
-    abstract class WindowBaseImpl : IWindowBaseImpl, IPlatformHandle
+    abstract class WindowBaseImpl : IWindowBaseImpl, IPlatformHandle, IEglWindowGlPlatformSurfaceInfo
     {
         public readonly GtkWindow GtkWidget;
         private IInputRoot _inputRoot;
         private readonly GtkImContext _imContext;
         private readonly FramebufferManager _framebuffer;
+        private readonly EglGlPlatformSurface _egl;
         protected readonly List<IDisposable> Disposables = new List<IDisposable>();
         private Size _lastSize;
         private Point _lastPosition;
@@ -37,7 +39,13 @@ namespace Avalonia.Gtk3
         {
             
             GtkWidget = gtkWidget;
-            _framebuffer = new FramebufferManager(this);
+            
+            var glf = AvaloniaLocator.Current.GetService<IWindowingPlatformGlFeature>() 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);
@@ -58,12 +66,15 @@ namespace Avalonia.Gtk3
             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);
             }
         }
 
@@ -489,7 +500,7 @@ namespace Avalonia.Gtk3
         }
 
         IntPtr IPlatformHandle.Handle => Native.GetNativeGdkWindowHandle(Native.GtkWidgetGetWindow(GtkWidget));
-        public IEnumerable<object> Surfaces => new object[] {Handle, _framebuffer};
+        public IEnumerable<object> Surfaces => new object[] {Handle, _egl, _framebuffer};
 
         public IRenderer CreateRenderer(IRenderRoot root)
         {
@@ -498,5 +509,11 @@ namespace Avalonia.Gtk3
                 ? (IRenderer) new DeferredRenderer(root, loop)
                 : new ImmediateRenderer(root);
         }
+
+
+        int IEglWindowGlPlatformSurfaceInfo.PixelWidth => (int)Math.Max(1, LastKnownScaleFactor * ClientSize.Width);
+        int IEglWindowGlPlatformSurfaceInfo.PixelHeight => (int)Math.Max(1, LastKnownScaleFactor * ClientSize.Height);
+        Vector IEglWindowGlPlatformSurfaceInfo.Dpi => new Vector(96*LastKnownScaleFactor, 96 * LastKnownScaleFactor);
+        IntPtr IEglWindowGlPlatformSurfaceInfo.Handle => Handle.Handle;
     }
 }

+ 1 - 0
src/Skia/Avalonia.Skia/Avalonia.Skia.csproj

@@ -12,6 +12,7 @@
     <ProjectReference Include="..\..\Avalonia.Input\Avalonia.Input.csproj" />
     <ProjectReference Include="..\..\Avalonia.Interactivity\Avalonia.Interactivity.csproj" />
     <ProjectReference Include="..\..\Avalonia.Layout\Avalonia.Layout.csproj" />
+    <ProjectReference Include="..\..\Avalonia.OpenGL\Avalonia.OpenGL.csproj" />
     <ProjectReference Include="..\..\Avalonia.Styling\Avalonia.Styling.csproj" />
     <ProjectReference Include="..\..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
   </ItemGroup>

+ 10 - 2
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@@ -29,6 +29,7 @@ namespace Avalonia.Skia
         private double _currentOpacity = 1.0f;
         private readonly bool _canTextUseLcdRendering;
         private Matrix _currentTransform;
+        private GRContext _grContext;
 
         /// <summary>
         /// Context create info.
@@ -54,6 +55,11 @@ namespace Avalonia.Skia
             /// Render text without Lcd rendering.
             /// </summary>
             public bool DisableTextLcdRendering;
+
+            /// <summary>
+            /// GPU-accelerated context (optional)
+            /// </summary>
+            public GRContext GrContext;
         }
 
         /// <summary>
@@ -67,7 +73,8 @@ namespace Avalonia.Skia
             _visualBrushRenderer = createInfo.VisualBrushRenderer;
             _disposables = disposables;
             _canTextUseLcdRendering = !createInfo.DisableTextLcdRendering;
-
+            _grContext = createInfo.GrContext;
+            
             Canvas = createInfo.Canvas;
 
             if (Canvas == null)
@@ -615,7 +622,8 @@ namespace Avalonia.Skia
                 Height = height,
                 Dpi = dpi,
                 Format = format,
-                DisableTextLcdRendering = !_canTextUseLcdRendering
+                DisableTextLcdRendering = !_canTextUseLcdRendering,
+                GrContext = _grContext
             };
 
             return new SurfaceRenderTarget(createInfo);

+ 62 - 0
src/Skia/Avalonia.Skia/GlRenderTarget.cs

@@ -0,0 +1,62 @@
+using System;
+using System.Reactive.Disposables;
+using Avalonia.OpenGL;
+using Avalonia.Platform;
+using Avalonia.Rendering;
+using SkiaSharp;
+using static Avalonia.OpenGL.GlConsts;
+namespace Avalonia.Skia
+{
+    public class GlRenderTarget : IRenderTarget
+    {
+        private readonly GRContext _grContext;
+        private IGlPlatformSurfaceRenderTarget _surface;
+
+        public GlRenderTarget(GRContext grContext, IGlPlatformSurface glSurface)
+        {
+            _grContext = grContext;
+            _surface = glSurface.CreateGlRenderTarget();
+        }
+
+        public void Dispose() => _surface.Dispose();
+
+        public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
+        {
+            var session = _surface.BeginDraw();
+            var disp = session.Display;
+            var gl = disp.GlInterface;
+            gl.GetIntegerv(GL_FRAMEBUFFER_BINDING, out var fb);
+            GRBackendRenderTargetDesc desc = new GRBackendRenderTargetDesc
+            {
+                Width = session.PixelWidth,
+                Height = session.PixelHeight,
+                SampleCount = disp.SampleCount,
+                StencilBits = disp.StencilSize,
+                Config = GRPixelConfig.Rgba8888,
+                Origin=GRSurfaceOrigin.BottomLeft,
+                RenderTargetHandle = new IntPtr(fb)
+            };
+            gl.Viewport(0, 0, desc.Width, desc.Height);
+            gl.ClearStencil(0);
+            gl.ClearColor(0, 0, 0, 0);
+            gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+            var surface = SKSurface.Create(_grContext, desc);
+
+            var nfo = new DrawingContextImpl.CreateInfo
+            {
+                GrContext = _grContext,
+                Canvas = surface.Canvas,
+                Dpi = session.Dpi,
+                VisualBrushRenderer = visualBrushRenderer,
+                DisableTextLcdRendering = true
+            };
+            return new DrawingContextImpl(nfo, Disposable.Create(() =>
+            {
+                surface.Canvas.Flush();
+                surface.Dispose();
+                session.Dispose();
+            }));
+
+        }
+    }
+}

+ 25 - 2
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@@ -6,7 +6,9 @@ using System.Collections.Generic;
 using System.IO;
 using Avalonia.Controls.Platform.Surfaces;
 using Avalonia.Media;
+using Avalonia.OpenGL;
 using Avalonia.Platform;
+using SkiaSharp;
 
 namespace Avalonia.Skia
 {
@@ -15,6 +17,22 @@ namespace Avalonia.Skia
     /// </summary>
     public class PlatformRenderInterface : IPlatformRenderInterface
     {
+        private GRContext GrContext { get; }
+
+        public PlatformRenderInterface()
+        {
+            var gl = AvaloniaLocator.Current.GetService<IWindowingPlatformGlFeature>();
+            if (gl != null)
+            {
+                var display = gl.ImmediateContext.Display;
+                var iface = display.Type == GlDisplayType.OpenGL2
+                    ? GRGlInterface.AssembleGlInterface((_, proc) => display.GlInterface.GetProcAddress(proc))
+                    : GRGlInterface.AssembleGlesInterface((_, proc) => display.GlInterface.GetProcAddress(proc));
+                gl.ImmediateContext.MakeCurrent(null);
+                GrContext = GRContext.Create(GRBackend.OpenGL, iface);
+            }
+        }
+        
         /// <inheritdoc />
         public IFormattedTextImpl CreateFormattedText(
             string text,
@@ -78,7 +96,8 @@ namespace Avalonia.Skia
                 Width = width,
                 Height = height,
                 Dpi = dpi,
-                DisableTextLcdRendering = false
+                DisableTextLcdRendering = false,
+                GrContext = GrContext
             };
             
             return new SurfaceRenderTarget(createInfo);
@@ -89,6 +108,10 @@ namespace Avalonia.Skia
         {
             foreach (var surface in surfaces)
             {
+                if (surface is IGlPlatformSurface glSurface)
+                {
+                    return new GlRenderTarget(GrContext, glSurface);
+                }
                 if (surface is IFramebufferPlatformSurface framebufferSurface)
                 {
                     return new FramebufferRenderTarget(framebufferSurface);
@@ -105,4 +128,4 @@ namespace Avalonia.Skia
             return new WriteableBitmapImpl(width, height, format);
         }
     }
-}
+}

+ 14 - 6
src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs

@@ -19,6 +19,7 @@ namespace Avalonia.Skia
         private readonly SKSurface _surface;
         private readonly SKCanvas _canvas;
         private readonly bool _disableLcdRendering;
+        private readonly GRContext _grContext;
         
         /// <summary>
         /// Create new surface render target.
@@ -30,8 +31,8 @@ namespace Avalonia.Skia
             PixelHeight = createInfo.Height;
             _dpi = createInfo.Dpi;
             _disableLcdRendering = createInfo.DisableTextLcdRendering;
-
-            _surface = CreateSurface(PixelWidth, PixelHeight, createInfo.Format);
+            _grContext = createInfo.GrContext;
+            _surface = CreateSurface(createInfo.GrContext, PixelWidth, PixelHeight, createInfo.Format);
 
             _canvas = _surface?.Canvas;
 
@@ -48,10 +49,11 @@ namespace Avalonia.Skia
         /// <param name="height">Height.</param>
         /// <param name="format">Format.</param>
         /// <returns></returns>
-        private static SKSurface CreateSurface(int width, int height, PixelFormat? format)
+        private static SKSurface CreateSurface(GRContext gpu, int width, int height, PixelFormat? format)
         {
             var imageInfo = MakeImageInfo(width, height, format);
-
+            if (gpu != null)
+                return SKSurface.Create(gpu, false, imageInfo);
             return SKSurface.Create(imageInfo);
         }
 
@@ -73,7 +75,8 @@ namespace Avalonia.Skia
                 Canvas = _canvas,
                 Dpi = _dpi,
                 VisualBrushRenderer = visualBrushRenderer,
-                DisableTextLcdRendering = _disableLcdRendering
+                DisableTextLcdRendering = _disableLcdRendering,
+                GrContext = _grContext
             };
 
             return new DrawingContextImpl(createInfo);
@@ -164,6 +167,11 @@ namespace Avalonia.Skia
             /// Render text without Lcd rendering.
             /// </summary>
             public bool DisableTextLcdRendering;
+
+            /// <summary>
+            /// GPU-accelerated context (optional)
+            /// </summary>
+            public GRContext GrContext;
         }
     }
-}
+}