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"); }
// 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(); }
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())); } }