private EGLConfig getMatchingConfig(IEGL10 egl, EGLDisplay display, int[] configAttribs)
            {
                // Get the number of minimally matching EGL configurations
                int[] num_config = new int[1];
                egl.EglChooseConfig(display, configAttribs, null, 0, num_config);
                int numConfigs = num_config[0];

                if (numConfigs <= 0)
                {
                    throw new Exception("No matching EGL configs");
                }
                // Allocate then read the array of minimally matching EGL configs
                EGLConfig[] configs = new EGLConfig[numConfigs];
                egl.EglChooseConfig(display, configAttribs, configs, numConfigs, num_config);
                // Now return the "best" one
                return(chooseConfig(egl, display, configs));
            }
        internal AndroidAsyncGraphicsContext(AndroidGraphicsContext graphicsContext, AndroidWindow androidWindow, int versionMajor)
        {
            egl = EGLContext.EGL.JavaCast<IEGL10>();

            var pbufferAttribList = new[] 
                {
                    EGL10.EglWidth, 1,
                    EGL10.EglHeight, 1,
                    EGL10.EglNone
                };

            EGLDisplay = androidWindow.Display;
            var androidGraphicsContext = graphicsContext;
            var config = androidGraphicsContext.EGLConfig;

            var attribList = new[] 
                { 
                    EGL10.EglSurfaceType, EGL10.EglPbufferBit,
                    EGL10.EglRenderableType, 4, // (opengl es 2.0)
            
                    EGL10.EglRedSize, graphicsContext.GraphicsMode.ColorFormat.Red,
                    EGL10.EglGreenSize, graphicsContext.GraphicsMode.ColorFormat.Green,
                    EGL10.EglBlueSize, graphicsContext.GraphicsMode.ColorFormat.Blue,
                    EGL10.EglAlphaSize, graphicsContext.GraphicsMode.ColorFormat.Alpha,
            
                    EGL10.EglDepthSize, graphicsContext.GraphicsMode.Depth,
                    EGL10.EglStencilSize, graphicsContext.GraphicsMode.Stencil,
            
                    //Egl.SAMPLE_BUFFERS, samples > 0 ? 1 : 0,
                    EGL10.EglSamples, 0,
            
                    EGL10.EglNone,
                };

            // first ask the number of config available
            var numConfig = new int[1];
            if (!egl.EglChooseConfig(EGLDisplay, attribList, null, 0, numConfig))
            {
                throw new InvalidOperationException(string.Format("EglChooseConfig {0:x}", egl.EglGetError()));
            }

            // retrieve the available configs
            var configs = new EGLConfig[numConfig[0]];
            if (!egl.EglChooseConfig(EGLDisplay, attribList, configs, configs.Length, numConfig))
            {
                throw new InvalidOperationException(string.Format("EglChooseConfig {0:x}", egl.EglGetError()));
            }

            // choose the best config
            EGLConfig = ChooseConfigEGL(configs);

            // create the surface
            EGLSurface = egl.EglCreatePbufferSurface(EGLDisplay, EGLConfig, pbufferAttribList);
            if (EGLSurface == EGL10.EglNoSurface)
            {
                throw new InvalidOperationException(string.Format("EglCreatePBufferSurface {0:x}", egl.EglGetError()));
            }

            // 0x3098 is EGL_CONTEXT_CLIENT_VERSION
            var attribList3 = new[] { 0x3098, versionMajor, EGL10.EglNone };
            EGLContext = egl.EglCreateContext(EGLDisplay, config, androidGraphicsContext.EGLContext, attribList3);
            if (EGLContext == EGL10.EglNoContext)
            {
                throw new InvalidOperationException(string.Format("EglCreateContext {0:x}", egl.EglGetError()));
            }
        }
        private void CreateEGLContext()
        {
            ExEnLog.WriteLine("ExEnAndroidSurfaceView.CreateEGLContext Begin");

            // Assumes lockObject is locked

            lostEglContext = false;

            egl = EGLContext.EGL.JavaCast<IEGL10>();

            eglDisplay = egl.EglGetDisplay(EGL10Consts.EglDefaultDisplay);
            if(eglDisplay == EGL10Consts.EglNoDisplay)
                throw new ExEnSurfaceException("Could not get EGL display");

            int[] version = new int[2];
            if(!egl.EglInitialize(eglDisplay, version))
                throw new ExEnSurfaceException(AddEGLError("Could not initialize EGL display"));

            ExEnLog.WriteLine("EGL Version: " + version[0] + "." + version[1]);

            // TODO: allow GraphicsDeviceManager to specify a frame buffer configuration
            // TODO: test this configuration works on many devices:
            int[] configAttribs = new int[] {
                    //EGL10Consts.EglRedSize, 5,
                    //EGL10Consts.EglGreenSize, 6,
                    //EGL10Consts.EglBlueSize, 5,
                    //EGL10Consts.EglAlphaSize, 0,
                    //EGL10Consts.EglDepthSize, 4,
                    //EGL10Consts.EglStencilSize, 0,
                    EGL10Consts.EglNone };
            EGLConfig[] configs = new EGLConfig[1];
            int[] numConfigs = new int[1];
            if(!egl.EglChooseConfig(eglDisplay, configAttribs, configs, 1, numConfigs))
                throw new ExEnSurfaceException(AddEGLError("Could not get EGL config"));
            if(numConfigs[0] == 0)
                throw new ExEnSurfaceException("No valid EGL configs found");
            eglConfig = configs[0];

            const int EglContextClientVersion = 0x3098;
            int[] contextAttribs = new int[] { EglContextClientVersion, 1, EGL10Consts.EglNone };
            eglContext = egl.EglCreateContext(eglDisplay, eglConfig, EGL10Consts.EglNoContext, contextAttribs);
            if(eglContext == null || eglContext == EGL10Consts.EglNoContext)
            {
                eglContext = null;
                throw new ExEnSurfaceException(AddEGLError("Could not create EGL context"));
            }

            eglContextAvailable = true;

            ExEnLog.WriteLine("ExEnAndroidSurfaceView.CreateEGLContext End");
        }
        internal AndroidAsyncGraphicsContext(AndroidGraphicsContext graphicsContext, AndroidWindow androidWindow, int versionMajor)
        {
            egl = EGLContext.EGL.JavaCast <IEGL10>();

            var pbufferAttribList = new[]
            {
                EGL10.EglWidth, 1,
                EGL10.EglHeight, 1,
                EGL10.EglNone
            };

            EGLDisplay = androidWindow.Display;
            var androidGraphicsContext = graphicsContext;
            var config = androidGraphicsContext.EGLConfig;

            var attribList = new[]
            {
                EGL10.EglSurfaceType, EGL10.EglPbufferBit,
                EGL10.EglRenderableType, 4,     // (opengl es 2.0)

                EGL10.EglRedSize, graphicsContext.GraphicsMode.ColorFormat.Red,
                EGL10.EglGreenSize, graphicsContext.GraphicsMode.ColorFormat.Green,
                EGL10.EglBlueSize, graphicsContext.GraphicsMode.ColorFormat.Blue,
                EGL10.EglAlphaSize, graphicsContext.GraphicsMode.ColorFormat.Alpha,

                EGL10.EglDepthSize, graphicsContext.GraphicsMode.Depth,
                EGL10.EglStencilSize, graphicsContext.GraphicsMode.Stencil,

                //Egl.SAMPLE_BUFFERS, samples > 0 ? 1 : 0,
                EGL10.EglSamples, 0,

                EGL10.EglNone,
            };

            // first ask the number of config available
            var numConfig = new int[1];

            if (!egl.EglChooseConfig(EGLDisplay, attribList, null, 0, numConfig))
            {
                throw new InvalidOperationException(string.Format("EglChooseConfig {0:x}", egl.EglGetError()));
            }

            // retrieve the available configs
            var configs = new EGLConfig[numConfig[0]];

            if (!egl.EglChooseConfig(EGLDisplay, attribList, configs, configs.Length, numConfig))
            {
                throw new InvalidOperationException(string.Format("EglChooseConfig {0:x}", egl.EglGetError()));
            }

            // choose the best config
            EGLConfig = ChooseConfigEGL(configs);

            // create the surface
            EGLSurface = egl.EglCreatePbufferSurface(EGLDisplay, EGLConfig, pbufferAttribList);
            if (EGLSurface == EGL10.EglNoSurface)
            {
                throw new InvalidOperationException(string.Format("EglCreatePBufferSurface {0:x}", egl.EglGetError()));
            }

            // 0x3098 is EGL_CONTEXT_CLIENT_VERSION
            var attribList3 = new[] { 0x3098, versionMajor, EGL10.EglNone };

            EGLContext = egl.EglCreateContext(EGLDisplay, config, androidGraphicsContext.EGLContext, attribList3);
            if (EGLContext == EGL10.EglNoContext)
            {
                throw new InvalidOperationException(string.Format("EglCreateContext {0:x}", egl.EglGetError()));
            }
        }