protected virtual void Dispose(bool disposing)
 {
     if (!disposed)
     {
         if (disposing)
         {
             DestroyContext();
             window   = null;
             disposed = true;
         }
     }
 }
Exemple #2
0
        private void Init()
        {
            // default
            ContextRenderingApi        = GLVersion.ES1;
            mHolder                    = Holder;
            RenderThreadRestartRetries = 3;

            // Add callback to get the SurfaceCreated etc events
            mHolder.AddCallback(this);
            // Force the SurfaceType to be Gpu to API_11 and earlier
            // it is ignored in later API's
            mHolder.SetType(SurfaceType.Gpu);
            windowInfo = new AndroidWindow(mHolder);

            pauseSignal = new ManualResetEvent(true);
        }
        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()));
            }
        }
		protected virtual void Dispose(bool disposing)
		{
			if (!disposed)
			{
				if (disposing) {
					DestroyContext ();
					window = null;
					disposed = true;
				}
			}
		}
		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!");
			}
		}
Exemple #6
0
        public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
        {
            AndroidWindow android_win = (AndroidWindow)window;

            return(new Android.AndroidGraphicsContext(handle, android_win.CreateEglWindowInfo(), shareContext, major, minor, flags));
        }
        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!");
                }
            }
        }
		// 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 ();
		}