/** * Prepares EGL. We want a GLES 2.0 context and a surface that supports recording. */ private void EglSetup() { _EGLDisplay = EGL14.EglGetDisplay(EGL14.EglDefaultDisplay); if (_EGLDisplay == EGL14.EglNoDisplay) { throw new RuntimeException("unable to get EGL14 display"); } int[] version = new int[2]; if (!EGL14.EglInitialize(_EGLDisplay, version, 0, version, 1)) { _EGLDisplay = null; throw new RuntimeException("unable to initialize EGL14"); } // Configure EGL for pbuffer and OpenGL ES 2.0. We want enough RGB bits // to be able to tell if the frame is reasonable. int[] attribList = { EGL14.EglRedSize, 8, EGL14.EglGreenSize, 8, EGL14.EglBlueSize, 8, EGL14.EglRenderableType, EGL_OPENGL_ES2_BIT, EGL_RECORDABLE_ANDROID, 1, EGL14.EglNone }; var configs = new EGLConfig[1]; var numConfigs = new int[1]; if (!EGL14.EglChooseConfig(_EGLDisplay, attribList, 0, configs, 0, configs.Length, numConfigs, 0)) { throw new RuntimeException("unable to find RGB888+recordable ES2 EGL config"); } // Configure context for OpenGL ES 2.0. int[] attrib_list = { EGL14.EglContextClientVersion, 2, EGL14.EglNone }; _EGLContext = EGL14.EglCreateContext(_EGLDisplay, configs[0], EGL14.EglNoContext, attrib_list, 0); CheckEglError("eglCreateContext"); if (_EGLContext == null) { throw new RuntimeException("null context"); } // Create a window surface, and attach it to the Surface we received. int[] surfaceAttribs = { EGL14.EglNone }; _EGLSurface = EGL14.EglCreateWindowSurface(_EGLDisplay, configs[0], _surface, surfaceAttribs, 0); CheckEglError("eglCreateWindowSurface"); if (_EGLSurface == null) { throw new RuntimeException("surface was null"); } }
/** * Prepares EGL. We want a GLES 2.0 context and a surface that supports recording. */ private void eglSetup() { mEGLDisplay = EGL14.EglGetDisplay(EGL14.EglDefaultDisplay); if (mEGLDisplay == EGL14.EglNoDisplay) { throw new Java.Lang.RuntimeException("unable to get EGL14 display"); } int[] version = new int[2]; if (!EGL14.EglInitialize(mEGLDisplay, version, 0, version, 1)) { throw new RuntimeException("unable to initialize EGL14"); } // Configure EGL for recording and OpenGL ES 2.0. int[] attribList; if (mEGLSharedContext == null) { attribList = new int[] { EGL14.EglRedSize, 8, EGL14.EglGreenSize, 8, EGL14.EglBlueSize, 8, EGL14.EglRenderableType, EGL14.EglOpenglEs2Bit, EGL14.EglNone }; } else { attribList = new int[] { EGL14.EglRedSize, 8, EGL14.EglGreenSize, 8, EGL14.EglBlueSize, 8, EGL14.EglRenderableType, EGL14.EglOpenglEs2Bit, EGL_RECORDABLE_ANDROID, 1, EGL14.EglNone }; } EGLConfig[] configs = new EGLConfig[1]; int[] numConfigs = new int[1]; EGL14.EglChooseConfig(mEGLDisplay, attribList, 0, configs, 0, configs.Length, numConfigs, 0); checkEglError("eglCreateContext RGB888+recordable ES2"); // Configure context for OpenGL ES 2.0. int[] attrib_list = { EGL14.EglContextClientVersion, 2, EGL14.EglNone }; if (mEGLSharedContext == null) { mEGLContext = EGL14.EglCreateContext(mEGLDisplay, configs[0], EGL14.EglNoContext, attrib_list, 0); } else { mEGLContext = EGL14.EglCreateContext(mEGLDisplay, configs[0], mEGLSharedContext, attrib_list, 0); } checkEglError("eglCreateContext"); // Create a window surface, and attach it to the Surface we received. int[] surfaceAttribs = { EGL14.EglNone }; mEGLSurface = EGL14.EglCreateWindowSurface(mEGLDisplay, configs[0], mSurface, surfaceAttribs, 0); checkEglError("eglCreateWindowSurface"); GLES20.GlDisable(GLES20.GlDepthTest); GLES20.GlDisable(GLES20.GlCullFaceMode); }
public override void Run() { if (mSurfaceView.mHasGLContext.Get()) { return; } mEGLDisplay = EGL14.EglGetDisplay(EGL14.EglDefaultDisplay); int[] version = new int[2]; EGL14.EglInitialize(mEGLDisplay, version, 0, version, 1); EGLConfig eglConfig = chooseEglConfig(mEGLDisplay); mEGLContext = EGL14 .EglCreateContext(mEGLDisplay, eglConfig, EGL14.EglNoContext, new int[] { EGL14.EglContextClientVersion, 2, EGL14.EglNone }, 0); int[] surfaceAttribs = { EGL14.EglNone }; mEGLSurface = EGL14 .EglCreateWindowSurface(mEGLDisplay, eglConfig, mSurfaceView, surfaceAttribs, 0); EGL14.EglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext); // guarantee to only report surface as created once GL context // associated with the surface has been created, and call on the GL thread // NOT the main thread but BEFORE the codec surface is attached to the GL context RendererCallbacks result; if (mSurfaceView.mRendererCallbacksWeakReference != null && mSurfaceView.mRendererCallbacksWeakReference.TryGetTarget(out result)) { result.onSurfaceCreated(); } mSurfaceView.mMediaSurfaceCreated.Set(false); GLES20.GlClearColor(0.1f, 0.1f, 0.1f, 1.0f); mSurfaceView.mHasGLContext.Set(true); if (mSurfaceView.mRendererCallbacksWeakReference != null && mSurfaceView.mRendererCallbacksWeakReference.TryGetTarget(out result)) { result.onContextCreated(); } mLoop.Set(true); while (mLoop.Get()) { if (!mSurfaceView.mPaused) { bool shouldRender = false; //we're just rendering when requested, so check that no one //has requested and if not, just continue if (mSurfaceView.mRenderMode.Get() == (int)Rendermode.WhenDirty) { if (mSurfaceView.mRenderRequested.Get()) { mSurfaceView.mRenderRequested.Set(false); shouldRender = true; } } else { shouldRender = true; } if (mSurfaceView.mSizeChange.Get()) { GLES20.GlViewport(0, 0, mSurfaceView.mWidth, mSurfaceView.mHeight); if (mSurfaceView.mRendererCallbacksWeakReference != null && mSurfaceView.mRendererCallbacksWeakReference.TryGetTarget(out result)) { result.onSurfaceChanged(mSurfaceView.mWidth, mSurfaceView.mHeight); } mSurfaceView.mSizeChange.Set(false); } if (shouldRender) { if (mSurfaceView.mRendererCallbacksWeakReference != null && mSurfaceView.mRendererCallbacksWeakReference.TryGetTarget(out result)) { result.onPreDrawFrame(); } if (mSurfaceView.mRendererCallbacksWeakReference != null && mSurfaceView.mRendererCallbacksWeakReference.TryGetTarget(out result)) { result.onDrawScreen(); } EGL14.EglSwapBuffers(mEGLDisplay, mEGLSurface); if (mSurfaceView.mIsRecording.Get()) { if (!mSurfaceView.mMediaSurfaceCreated.Get()) { mEGLSurfaceMedia = EGL14 .EglCreateWindowSurface(mEGLDisplay, eglConfig, mSurfaceView.mSurface, surfaceAttribs, 0); mSurfaceView.mMediaSurfaceCreated.Set(true); } EGL14.EglMakeCurrent(mEGLDisplay, mEGLSurfaceMedia, mEGLSurfaceMedia, mEGLContext); if (mSurfaceView.mRendererCallbacksWeakReference != null && mSurfaceView.mRendererCallbacksWeakReference.TryGetTarget(out result)) { GLES20.GlViewport(0, 0, mSurfaceView.mOutWidth, mSurfaceView.mOutHeight); //EGLExt.EglPresentationTimeANDROID(mEGLDisplay, mEGLSurfaceMedia, (JavaSystem.CurrentTimeMillis() - RecordableSurfaceView.mStartTimeMillisecs) * 1000L *1000L); result.onDrawRecording(); GLES20.GlViewport(0, 0, mSurfaceView.mWidth, mSurfaceView.mHeight); } EGL14.EglSwapBuffers(mEGLDisplay, mEGLSurfaceMedia); EGL14.EglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext); } } while (mRunnableQueue.Count > 0) { Runnable ev = mRunnableQueue.First.Value; mRunnableQueue.RemoveFirst(); ev.Run(); } } /* try { Thread.Sleep((long)(1f / 120.0f * 1000f)); } catch (InterruptedException intex) // THIS IS KEY TO BLACKOUT BUG, THIS CATCH NEVER HAPPENS AND SO THE OLD SURFACE IS NEVER NUKED / REMADE mHasGLContext NEVER SET TO FALSE { if (mSurfaceView.mRendererCallbacksWeakReference != null && mSurfaceView.mRendererCallbacksWeakReference.TryGetTarget(out result)) { result.onSurfaceDestroyed(); } if (mEGLDisplay != null) { EGL14.EglMakeCurrent(mEGLDisplay, EGL14.EglNoSurface, EGL14.EglNoSurface, EGL14.EglNoContext); if (mEGLSurface != null) { EGL14.EglDestroySurface(mEGLDisplay, mEGLSurface); } if (mEGLSurfaceMedia != null) { EGL14.EglDestroySurface(mEGLDisplay, mEGLSurfaceMedia); } EGL14.EglDestroyContext(mEGLDisplay, mEGLContext); mSurfaceView.mHasGLContext.Set(false); EGL14.EglReleaseThread(); EGL14.EglTerminate(mEGLDisplay); mSurfaceView.mSurface.Release(); } return; }*/ } }