/** * Discard all resources held by this class, notably the EGL context. Also releases the * Surface that was passed to our constructor. */ public void release() { if (EGL14.eglGetCurrentContext().equals(mEGLContext)) { // Clear the current context and surface to ensure they are discarded immediately. EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT); } EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface); EGL14.eglDestroyContext(mEGLDisplay, mEGLContext); //EGL14.eglTerminate(mEGLDisplay); mSurface.release(); // null everything out so future attempts to use this object will cause an NPE mEGLDisplay = null; mEGLContext = null; mEGLSurface = null; mSurface = null; }
public EGLSurface createGLESWithPBuffer(EGLConfigAttrs attrs,EGLContextAttrs ctxAttrs,int width,int height){ EGLConfig config=getConfig(attrs.surfaceType(EGL14.EGL_PBUFFER_BIT)); if(config==null){ log("getConfig failed : "+EGL14.eglGetError()); return null; } EGLContext eglContext=createContext(config,EGL14.EGL_NO_CONTEXT,ctxAttrs); if(eglContext==EGL14.EGL_NO_CONTEXT){ log("createContext failed : "+EGL14.eglGetError()); return null; } EGLSurface eglSurface=createPBufferSurface(config,width,height); if(eglSurface==EGL14.EGL_NO_SURFACE){ log("createWindowSurface failed : "+EGL14.eglGetError()); return null; } if(!EGL14.eglMakeCurrent(mEGLDisplay,eglSurface,eglSurface,eglContext)){ log("eglMakeCurrent failed : "+EGL14.eglGetError()); return null; } return eglSurface; }
private int[] filterConfigSpec(int[] configSpec) { if (mEGLContextClientVersion != 2 && mEGLContextClientVersion != 3) { return configSpec; } /* We know none of the subclasses define EGL_RENDERABLE_TYPE. * And we know the configSpec is well formed. */ int len = configSpec.length; int[] newConfigSpec = new int[len + 2]; System.arraycopy(configSpec, 0, newConfigSpec, 0, len - 1); newConfigSpec[len - 1] = EGL10.EGL_RENDERABLE_TYPE; if (mEGLContextClientVersion == 2) { newConfigSpec[len] = EGL14.EGL_OPENGL_ES2_BIT; /* EGL_OPENGL_ES2_BIT */ } else { newConfigSpec[len] = EGLExt.EGL_OPENGL_ES3_BIT_KHR; /* EGL_OPENGL_ES3_BIT_KHR */ } newConfigSpec[len + 1] = EGL10.EGL_NONE; return newConfigSpec; }
/** * Creates an EGL surface associated with a Surface. * <p> * If this is destined for MediaCodec, the EGLConfig should have the "recordable" attribute. */ public EGLSurface createWindowSurface(Object surface) { if (!(surface instanceof Surface) && !(surface instanceof SurfaceTexture)) { throw new RuntimeException("invalid surface: " + surface); } // Create a window surface, and attach it to the Surface we received. int[] surfaceAttribs = { EGL14.EGL_NONE }; EGLSurface eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surface, surfaceAttribs, 0); checkEglError("eglCreateWindowSurface"); if (eglSurface == null) { throw new RuntimeException("surface was null"); } return eglSurface; }
/** * Discard all resources held by this class, notably the EGL context. */ public void release() { if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) { EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface); EGL14.eglDestroyContext(mEGLDisplay, mEGLContext); EGL14.eglReleaseThread(); EGL14.eglTerminate(mEGLDisplay); } mSurface.release(); // this causes a bunch of warnings that appear harmless but might confuse someone: // W BufferQueue: [unnamed-3997-2] cancelBuffer: BufferQueue has been abandoned! //mSurfaceTexture.release(); mEGLDisplay = EGL14.EGL_NO_DISPLAY; mEGLContext = EGL14.EGL_NO_CONTEXT; mEGLSurface = EGL14.EGL_NO_SURFACE; mTextureRender = null; mSurface = null; mSurfaceTexture = null; }
private static EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] configAttributes) { EGLConfig[] configs = new EGLConfig[1]; int[] numConfigs = new int[1]; if (!EGL14.eglChooseConfig( eglDisplay, configAttributes, 0, configs, 0, configs.length, numConfigs, 0)) { throw new RuntimeException( "eglChooseConfig failed: 0x" + Integer.toHexString(EGL14.eglGetError())); } if (numConfigs[0] <= 0) { throw new RuntimeException("Unable to find any matching EGL config"); } final EGLConfig eglConfig = configs[0]; if (eglConfig == null) { throw new RuntimeException("eglChooseConfig returned null"); } return eglConfig; }
private static EGLContext createEglContext( EglBase14.Context sharedContext, EGLDisplay eglDisplay, EGLConfig eglConfig) { if (sharedContext != null && sharedContext.egl14Context == EGL14.EGL_NO_CONTEXT) { throw new RuntimeException("Invalid sharedContext"); } int[] contextAttributes = {EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE}; EGLContext rootContext = sharedContext == null ? EGL14.EGL_NO_CONTEXT : sharedContext.egl14Context; final EGLContext eglContext; synchronized (EglBase.lock) { eglContext = EGL14.eglCreateContext(eglDisplay, eglConfig, rootContext, contextAttributes, 0); } if (eglContext == EGL14.EGL_NO_CONTEXT) { throw new RuntimeException( "Failed to create EGL context: 0x" + Integer.toHexString(EGL14.eglGetError())); } return eglContext; }
@Override public void onCameraSurfaceCreate(SurfaceTexture surfaceTexture) { Log.d(TAG, "onCameraSurfaceCreate"); mCamera = Camera.open(); Camera.Parameters parameters = mCamera.getParameters(); parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); mVideoRecorder.createInputSurfaceWindow(EGL14.eglGetCurrentContext()); try { parameters.setPreviewSize(PREVIEW_WIDTH, PREVIEW_HEIGHT); mCameraView.setPreviewSize(PREVIEW_HEIGHT, PREVIEW_WIDTH); mVideoRecorder.setPreviewSize(PREVIEW_HEIGHT, PREVIEW_WIDTH); mCamera.setParameters(parameters); mCamera.setPreviewTexture(surfaceTexture); mCamera.setDisplayOrientation(Profile.ORIENTATION_90); mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); } isSurfaceReady = true; }
/** * Discards all resources held by this class, notably the EGL context. This must be * called from the thread where the context was created. * <p> * On completion, no context will be current. */ public void release() { if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) { // Android is unusual in that it uses a reference-counted EGLDisplay. So for // every eglInitialize() we need an eglTerminate(). EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT); EGL14.eglDestroyContext(mEGLDisplay, mEGLContext); EGL14.eglReleaseThread(); EGL14.eglTerminate(mEGLDisplay); } mEGLDisplay = EGL14.EGL_NO_DISPLAY; mEGLContext = EGL14.EGL_NO_CONTEXT; mEGLConfig = null; }
public OffscreenImage(Bitmap bitmap) { mWidth = bitmap.getWidth(); mHeight = bitmap.getHeight(); // 初始化EGL环境 mEgl = new EGLEnvironment(EGL14.eglGetCurrentContext(), false); // 创建离屏缓冲 mInputSurface = mEgl.createOffscreen(mWidth, mHeight); // 设置渲染环境可用 mInputSurface.makeCurrent(); BitmapInput bitmapInput = new BitmapInput(bitmap); mPipeline = new RenderPipeline(); mPipeline.onSurfaceCreated(null, null); mPipeline.setStartPointRender(bitmapInput); }
/** @return from a new EGL display connection */ @NonNull public static EGLDisplay newDisplay() { final EGLDisplay result = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); if (result == EGL14.EGL_NO_DISPLAY) { logError(); throw new RuntimeException("Unable to get EGL14 display"); } else { final int[] v = new int[2]; if (!EGL14.eglInitialize(result, v, 0, v, 1)) { try { logError(); throw new RuntimeException("Unable to initialize EGL14 display"); } finally { closeDisplay(result); } } else { logDebug(getDisplayString(result) + " created (EGL" + v[0] + "" + v[1] + ")"); return result; } } }
@Override public void onDraw(int textureId, FloatBuffer cubeBuffer, FloatBuffer textureBuffer) { // Draw on screen surface super.onDraw(textureId, cubeBuffer, textureBuffer); if (mIsRecording) { // create encoder surface if (mCodecInput == null) { mEGLCore = new EglCore(EGL14.eglGetCurrentContext(), EglCore.FLAG_RECORDABLE); mCodecInput = new WindowSurface(mEGLCore, mVideoEncoder.getSurface(), false); } // Draw on encoder surface mCodecInput.makeCurrent(); super.onDraw(textureId, cubeBuffer, textureBuffer); if (mIsRecording) {//super.onDraw maybe executed stopRecording mCodecInput.swapBuffers(); mVideoEncoder.frameAvailableSoon(); } } // Make screen surface be current surface mEGL.eglMakeCurrent(mEGLDisplay, mEGLScreenSurface, mEGLScreenSurface, mEGLContext); }
public EGLSurface createEGLSurface(Object surface) { if (!(surface instanceof Surface) && !(surface instanceof SurfaceTexture)) { throw new RuntimeException("invalid surface: " + surface); } // Create a window surface, and attach it to the Surface we received. int[] surfaceAttributes = { EGL14.EGL_NONE }; EGLSurface eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surface, surfaceAttributes, 0); if (eglSurface == null) { throw new RuntimeException("surface was null"); } return eglSurface; }
/** * Makes our EGL context current, using the supplied "draw" and "read" surfaces. */ public void makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) { if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) { // called makeCurrent() before create? Log.d(TAG, "NOTE: makeCurrent w/o display"); } if (!EGL14.eglMakeCurrent(mEGLDisplay, drawSurface, readSurface, mEGLContext)) { throw new RuntimeException("eglMakeCurrent(draw,read) failed"); } }
public void changeDisplay(int key){ mEGLDisplay=EGL14.eglGetDisplay(key); //获取版本号,[0]为版本号,[1]为子版本号 int[] versions=new int[2]; EGL14.eglInitialize(mEGLDisplay,versions,0,versions,1); log(EGL14.eglQueryString(mEGLDisplay, EGL14.EGL_VENDOR)); log(EGL14.eglQueryString(mEGLDisplay, EGL14.EGL_VERSION)); log(EGL14.eglQueryString(mEGLDisplay, EGL14.EGL_EXTENSIONS)); }
public EGLConfig getConfig(EGLConfigAttrs attrs){ EGLConfig[] configs = new EGLConfig[1]; int[] configNum = new int[1]; EGL14.eglChooseConfig(mEGLDisplay,attrs.build(),0,configs,0,1,configNum,0); //选择的过程可能出现多个,也可能一个都没有,这里只用一个 if(configNum[0]>0){ if(attrs.isDefault()){ mEGLConfig=configs[0]; } return configs[0]; } return null; }
/** * Makes our EGL context current, using the supplied surface for both "draw" and "read". */ public void makeCurrent(EGLSurface eglSurface) { if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) { // called makeCurrent() before create? Log.d(TAG, "NOTE: makeCurrent w/o display"); } if (!EGL14.eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext)) { int error = EGL14.eglGetError(); throw new RuntimeException("eglMakeCurrent failed with error = " + error); } }
@SuppressWarnings("unused") private EGLConfig getConfig(final boolean with_depth_buffer, final boolean isRecordable) { final int[] attribList = { EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL14.EGL_RED_SIZE, 8, EGL14.EGL_GREEN_SIZE, 8, EGL14.EGL_BLUE_SIZE, 8, EGL14.EGL_ALPHA_SIZE, 8, EGL14.EGL_NONE, EGL14.EGL_NONE, //EGL14.EGL_STENCIL_SIZE, 8, EGL14.EGL_NONE, EGL14.EGL_NONE, //EGL_RECORDABLE_ANDROID, 1, // this flag need to recording of MediaCodec EGL14.EGL_NONE, EGL14.EGL_NONE, // with_depth_buffer ? EGL14.EGL_DEPTH_SIZE : EGL14.EGL_NONE, // with_depth_buffer ? 16 : 0, EGL14.EGL_NONE }; int offset = 10; if (false) { // ステンシルバッファ(常時未使用) attribList[offset++] = EGL14.EGL_STENCIL_SIZE; attribList[offset++] = 8; } if (with_depth_buffer) { // デプスバッファ attribList[offset++] = EGL14.EGL_DEPTH_SIZE; attribList[offset++] = 16; } if (isRecordable && (Build.VERSION.SDK_INT >= 18)) {// MediaCodecの入力用Surfaceの場合 attribList[offset++] = EGL_RECORDABLE_ANDROID; attribList[offset++] = 1; } for (int i = attribList.length - 1; i >= offset; i--) { attribList[i] = EGL14.EGL_NONE; } final EGLConfig[] configs = new EGLConfig[1]; final int[] numConfigs = new int[1]; if (!EGL14.eglChooseConfig(mEglDisplay, attribList, 0, configs, 0, configs.length, numConfigs, 0)) { // XXX it will be better to fallback to RGB565 Log.w(TAG, "unable to find RGBA8888 / " + " EGLConfig"); return null; } return configs[0]; }
public boolean destroyGLES(EGLSurface surface,EGLContext context){ EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT); if(surface!=null){ EGL14.eglDestroySurface(mEGLDisplay,surface); } if(context!=null){ EGL14.eglDestroyContext(mEGLDisplay,context); } EGL14.eglTerminate(mEGLDisplay); log("gl destroy gles"); return true; }
public void release() { if (mEglDisplay != EGL14.EGL_NO_DISPLAY) { destroyContext(); EGL14.eglTerminate(mEglDisplay); EGL14.eglReleaseThread(); } mEglDisplay = EGL14.EGL_NO_DISPLAY; mEglContext = EGL14.EGL_NO_CONTEXT; }
public void makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) { if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) { // called makeCurrent() before create? Log.d(TAG, "NOTE: makeCurrent w/o display"); } if (!EGL14.eglMakeCurrent(mEGLDisplay, drawSurface, readSurface, mEGLContext)) { throw new RuntimeException("eglMakeCurrent(draw,read) failed"); } }
private void release() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { mEGLContext = EGL14.EGL_NO_CONTEXT; } mState.set(STATE_RELEASED); synchronized (mRenderListenerLock) { Iterator<GLRender.GLRenderListener> it = mGLRenderListenerList.iterator(); while (it.hasNext()) { GLRenderListener listener = it.next(); listener.onReleased(); } } }
private void destroyWindowSurface(EGLSurface surface) { if (DEBUG) Log.v(TAG, "destroySurface:"); if (surface != EGL14.EGL_NO_SURFACE) { EGL14.eglMakeCurrent(mEglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT); EGL14.eglDestroySurface(mEglDisplay, surface); } surface = EGL14.EGL_NO_SURFACE; if (DEBUG) Log.v(TAG, "destroySurface:finished"); }
/** * Creates an off-screen surface. */ public void createOffscreenSurface(int width, int height) { if (mEGLSurface != EGL14.EGL_NO_SURFACE) { throw new IllegalStateException("surface already created"); } mEGLSurface = mEglCore.createOffscreenSurface(width, height); mWidth = width; mHeight = height; }
private void checkEglError(String msg) { boolean failed = false; while (EGL14.eglGetError() != EGL14.EGL_SUCCESS) { failed = true; } if (failed) { throw new RuntimeException("EGL error encountered (see log)"); } }
/** * Finds a suitable EGLConfig. * * @param flags Bit flags from constructor. * @param version Must be 2 or 3. */ private EGLConfig getConfig(int flags, int version) { int renderableType = EGL14.EGL_OPENGL_ES2_BIT; if (version >= 3) { renderableType |= EGLExt.EGL_OPENGL_ES3_BIT_KHR; } // The actual surface is generally RGBA or RGBX, so situationally omitting alpha // doesn't really help. It can also lead to a huge performance hit on glReadPixels() // when reading into a GL_RGBA buffer. int[] attribList = { EGL14.EGL_RED_SIZE, 8, EGL14.EGL_GREEN_SIZE, 8, EGL14.EGL_BLUE_SIZE, 8, EGL14.EGL_ALPHA_SIZE, 8, //EGL14.EGL_DEPTH_SIZE, 16, //EGL14.EGL_STENCIL_SIZE, 8, EGL14.EGL_RENDERABLE_TYPE, renderableType, EGL14.EGL_NONE, 0, // placeholder for recordable [@-3] EGL14.EGL_NONE }; if ((flags & FLAG_RECORDABLE) != 0) { attribList[attribList.length - 3] = EGL_RECORDABLE_ANDROID; attribList[attribList.length - 2] = 1; } EGLConfig[] configs = new EGLConfig[1]; int[] numConfigs = new int[1]; if (!EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, configs, 0, configs.length, numConfigs, 0)) { Log.w(TAG, "unable to find RGB8888 / " + version + " EGLConfig"); return null; } return configs[0]; }
/** * Discard all resources held by this class, notably the EGL context. Also releases the * Surface that was passed to our constructor. */ public void release() { if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) { EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface); EGL14.eglDestroyContext(mEGLDisplay, mEGLContext); EGL14.eglReleaseThread(); EGL14.eglTerminate(mEGLDisplay); } mSurface.release(); mEGLDisplay = EGL14.EGL_NO_DISPLAY; mEGLContext = EGL14.EGL_NO_CONTEXT; mEGLSurface = EGL14.EGL_NO_SURFACE; mSurface = null; }
public void release() { if (DEBUG) Log.v(TAG, "release:"); if (mEglDisplay != EGL14.EGL_NO_DISPLAY) { destroyContext(); EGL14.eglTerminate(mEglDisplay); EGL14.eglReleaseThread(); } mEglDisplay = EGL14.EGL_NO_DISPLAY; mEglContext = EGL14.EGL_NO_CONTEXT; }
private EGLContext createContext(final EGLContext sharedContext) { final int[] attributes = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE }; final EGLContext context = EGL14.eglCreateContext(mEglDisplay, mEglConfig, sharedContext, attributes, 0); checkEglError("eglCreateContext"); return context; }
/** * Checks for EGL errors. */ private void checkEglError(String msg) { int error; if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) { throw new RuntimeException(msg + ": EGL error: 0x" + Integer.toHexString(error)); } }
@Override public void makeCurrent() { checkIsNotReleased(); if (eglSurface == EGL14.EGL_NO_SURFACE) { throw new RuntimeException("No EGLSurface - can't make current"); } synchronized (EglBase.lock) { if (!EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) { throw new RuntimeException( "eglMakeCurrent failed: 0x" + Integer.toHexString(EGL14.eglGetError())); } } }
/** * Returns the surface's height, in pixels. */ public int getHeight() { if (mHeight < 0) { return mEglCore.querySurface(mEGLSurface, EGL14.EGL_HEIGHT); } else { return mHeight; } }
/** * Checks for EGL errors. Throws an exception if an error has been raised. */ private void checkEglError(String msg) { int error; if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) { throw new RuntimeException(msg + ": EGL error: 0x" + Integer.toHexString(error)); } }
/** * @param surface 来自MediaCodec.createInputSurface() */ public InputSurface(Surface surface) { if (surface == null) { throw new NullPointerException(); } mSurface = surface; // 初始化EGL环境 mEgl = new EGLEnvironment(EGL14.eglGetCurrentContext(), false); // 创建离屏缓冲 mInputSurface = mEgl.createFromSurface(surface); // 设置渲染环境可用 mInputSurface.makeCurrent(); }