int GetAttrib (IEGL10 egl, EGLDisplay display, EGLConfig config, int attrib)
		{
			int[] ret = new int [1];
			try {
				egl.EglGetConfigAttrib (display, config, attrib, ret);
			} catch (Exception e) {
				Log.Warn ("AndroidGraphicsMode", "EglGetConfigAttrib {0} threw exception {1}", attrib, e);
			}
			return ret[0];
		}
        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()));
            }
        }
		void Init (GraphicsMode mode, IWindowInfo win, IGraphicsContext sharedContext,
										int major, int minor, GraphicsContextFlags flags)
		{
			window = win as AndroidWindow;
			if (window == null)
				throw new ArgumentException ("win");

			AndroidGraphicsContext shared = sharedContext as AndroidGraphicsContext;

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

			window.InitializeDisplay ();

			if (mode == null)
				mode = new GraphicsMode ();

			if (mode is AndroidGraphicsMode) {
				GraphicsMode = mode;
			} else {
				GraphicsMode = new AndroidGraphicsMode (window.Display, major, mode);
			}

			if (shared != null && !PBufferSupported)
				throw new EglException ("Multiple Context's are not supported by this device");

			if (Mode.Config == null)
				Mode.Initialize (window.Display, major);

			/*
			 * Create an OpenGL ES context. We want to do this as rarely as possible, an
			 * OpenGL context is a somewhat heavy object.
			 */
			int EglContextClientVersion = 0x3098;
			int EglContextMinorVersion = 0x30fb;
			int[] attribList = null;
			if (major >= 2) {
				string extensions = egl.EglQueryString (window.Display, Egl.Egl.EXTENSIONS);
				if (minor > 0 && !string.IsNullOrEmpty (extensions) && extensions.Contains ("EGL_KHR_create_context")) {
					attribList = new int [] { EglContextClientVersion, major,
						EglContextMinorVersion, minor,
						EGL10.EglNone
					};
				} else {
					attribList = new int [] { EglContextClientVersion, major,
						EGL10.EglNone
					};
				}
			}

			EGLContext = egl.EglCreateContext (window.Display,
						EGLConfig,
						shared != null && shared.EGLContext != null ? shared.EGLContext : EGL10.EglNoContext,
						attribList);

			if (EGLContext == EGL10.EglNoContext)
				throw EglException.GenerateException ("EglCreateContext == EGL10.EglNoContext", egl, null);

			if (shared != null && shared.EGLContext != null) {
				egl.EglMakeCurrent (window.Display, EGL10.EglNoSurface, EGL10.EglNoSurface, EGL10.EglNoContext);
				int[] pbufferAttribList = new int [] { EGL10.EglWidth, 64, EGL10.EglHeight, 64, EGL10.EglNone };
				surface = window.CreatePBufferSurface (EGLConfig, pbufferAttribList);
				if (surface == EGL10.EglNoSurface)
					throw new EglException ("Could not create PBuffer for shared context!");
			}
		}
		public static EglException GenerateException (string msg, IEGL10 egl, int? error)
		{
			if (egl == null)
				return new EglException (msg);
			error = error ?? egl.EglGetError ();
			if (error == EGL10.EglSuccess)
				return new EglException (msg);
			return new EglException (String.Format ("{0} failed with error {1} (0x{1:x})", msg, error.Value));
		}
        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");
        }
Example #6
0
        // This method is called everytime the context needs
        // to be recreated. Use it to set any egl-specific settings
        // prior to context creation
        protected override void CreateFrameBuffer()
        {
            IEGL10 egl = EGLContext.EGL.JavaCast <IEGL10> ();
            var    win = new AndroidWindow(Holder);

            win.InitializeDisplay();

            int[] num_configs = new int[1];
            if (!egl.EglGetConfigs(win.Display, null, 0, num_configs))
            {
                throw EglException.GenerateException("Failed to retrieve GraphicsMode configurations", egl);
            }

            EGLConfig[] configs = new EGLConfig[num_configs[0]];
            if (!egl.EglGetConfigs(win.Display, configs, num_configs[0], num_configs))
            {
                throw EglException.GenerateException("Failed to retrieve GraphicsMode configurations", egl);
            }

            Log.Verbose("GLDiag", "Testing {0} graphics configurations", num_configs[0]);

            Dictionary <IntPtr, AndroidGraphicsMode> validModes = new Dictionary <IntPtr, AndroidGraphicsMode> ();

            int count = 0;

            foreach (var c in configs)
            {
                var r       = GetAttrib(egl, win.Display, c, EGL11.EglRedSize);
                var g       = GetAttrib(egl, win.Display, c, EGL11.EglGreenSize);
                var b       = GetAttrib(egl, win.Display, c, EGL11.EglBlueSize);
                var a       = GetAttrib(egl, win.Display, c, EGL11.EglAlphaSize);
                var depth   = GetAttrib(egl, win.Display, c, EGL11.EglDepthSize);
                var stencil = GetAttrib(egl, win.Display, c, EGL11.EglStencilSize);
                var s       = GetAttrib(egl, win.Display, c, EGL11.EglSampleBuffers);
                var samples = GetAttrib(egl, win.Display, c, EGL11.EglSamples);

                Log.Verbose("AndroidGraphicsMode", "Testing graphics mode: {8} red {0} green {1} blue {2} alpha {3} ({4}) depth {5} stencil {6} samples {7}",
                            r, g, b,
                            a, r + g + b + a, depth,
                            stencil, samples, count++);

                try {
                    win.CreateSurface(c);
                    win.DestroySurface();
                    validModes.Add(c.Handle, new AndroidGraphicsMode(r + g + b + a, depth, stencil, s > 0 ? samples : 0, 2, true));
                    Log.Verbose("AndroidGraphicsMode", "Graphics mode {0} valid", count - 1);
                } catch {
                    Log.Verbose("AndroidGraphicsMode", "Graphics mode {0} invalid", count - 1);
                }
            }

            win.TerminateDisplay();

            if (validModes.Count == 0)
            {
                throw new EglException("There is no valid graphics mode, aborting");
            }

            IntPtr key = IntPtr.Zero;

            foreach (var k in validModes)
            {
                if (key == IntPtr.Zero)
                {
                    key = k.Key;
                }
                var a = k.Value;
                Log.Verbose("AndroidGraphicsMode", "Valid graphics mode: {9} red {0} green {1} blue {2} alpha {3} ({4}) depth {5} stencil {6} samples {7} buffers {8}",
                            a.ColorFormat.Red, a.ColorFormat.Green, a.ColorFormat.Blue,
                            a.ColorFormat.Alpha, a.ColorFormat.BitsPerPixel, a.Depth,
                            a.Stencil, a.Samples, a.Buffers, (int)k.Key);
            }

            GraphicsMode = validModes[key];

            // if you don't call this, the context won't be created
            base.CreateFrameBuffer();
        }
Example #7
0
 static int GetAttribute(EGLConfig config, IEGL10 egl, EGLDisplay eglDisplay, int attribute)
 {
     int[] data = new int[1];
     egl.EglGetConfigAttrib(eglDisplay, config, EGL11.EglRedSize, data);
     return(data[0]);
 }
 public void destroyContext(IEGL10 egl, EGLDisplay display, EGLContext context)
 {
     egl.EglDestroyContext(display, context);
 }
        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()));
            }
        }