Code example for ConditionVariable

Methods: block, close

0
    private int mHeight; // height of the view in UI 
 
    private boolean mIsLandscape = true; 
    private final float[] mTransformMatrix = new float[16]; 
 
    private ConditionVariable mEglThreadBlockVar = new ConditionVariable(); 
    private HandlerThread mEglThread; 
    private EGLHandler mEglHandler; 
 
    private EGLConfig mEglConfig; 
    private EGLDisplay mEglDisplay; 
    private EGLContext mEglContext; 
    private EGLSurface mEglSurface; 
    private SurfaceTexture mMosaicOutputSurfaceTexture; 
    private SurfaceTexture mInputSurfaceTexture; 
    private EGL10 mEgl; 
    private GL10 mGl; 
 
    private class EGLHandler extends Handler { 
        public static final int MSG_INIT_EGL_SYNC = 0; 
        public static final int MSG_SHOW_PREVIEW_FRAME_SYNC = 1; 
        public static final int MSG_SHOW_PREVIEW_FRAME = 2; 
        public static final int MSG_ALIGN_FRAME_SYNC = 3; 
        public static final int MSG_RELEASE = 4; 
 
        public EGLHandler(Looper looper) { 
            super(looper); 
        } 
 
        @Override 
        public void handleMessage(Message msg) { 
            switch (msg.what) { 
                case MSG_INIT_EGL_SYNC: 
                    doInitGL(); 
                    mEglThreadBlockVar.open(); 
                    break; 
                case MSG_SHOW_PREVIEW_FRAME_SYNC: 
                    doShowPreviewFrame(); 
                    mEglThreadBlockVar.open(); 
                    break; 
                case MSG_SHOW_PREVIEW_FRAME: 
                    doShowPreviewFrame(); 
                    break; 
                case MSG_ALIGN_FRAME_SYNC: 
                    doAlignFrame(); 
                    mEglThreadBlockVar.open(); 
                    break; 
                case MSG_RELEASE: 
                    doRelease(); 
                    mEglThreadBlockVar.open(); 
                    break; 
            } 
        } 
 
        private void doAlignFrame() { 
            mInputSurfaceTexture.updateTexImage(); 
            mInputSurfaceTexture.getTransformMatrix(mTransformMatrix); 
 
            MosaicRenderer.setWarping(true); 
            // Call preprocess to render it to low-res and high-res RGB textures. 
            MosaicRenderer.preprocess(mTransformMatrix); 
            // Now, transfer the textures from GPU to CPU memory for processing 
            MosaicRenderer.transferGPUtoCPU(); 
            MosaicRenderer.updateMatrix(); 
            draw(); 
            mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); 
        } 
 
        private void doShowPreviewFrame() { 
            mInputSurfaceTexture.updateTexImage(); 
            mInputSurfaceTexture.getTransformMatrix(mTransformMatrix); 
 
            MosaicRenderer.setWarping(false); 
            // Call preprocess to render it to low-res and high-res RGB textures. 
            MosaicRenderer.preprocess(mTransformMatrix); 
            MosaicRenderer.updateMatrix(); 
            draw(); 
            mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); 
        } 
 
        private void doInitGL() { 
            // These are copied from GLSurfaceView 
            mEgl = (EGL10) EGLContext.getEGL(); 
            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 
            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) { 
                throw new RuntimeException("eglGetDisplay failed"); 
            } 
            int[] version = new int[2]; 
            if (!mEgl.eglInitialize(mEglDisplay, version)) { 
                throw new RuntimeException("eglInitialize failed"); 
            } else { 
                Log.v(TAG, "EGL version: " + version[0] + '.' + version[1]); 
            } 
            int[] attribList = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; 
            mEglConfig = chooseConfig(mEgl, mEglDisplay); 
            mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT, 
                                                attribList); 
 
            if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) { 
                throw new RuntimeException("failed to createContext"); 
            } 
            mEglSurface = mEgl.eglCreateWindowSurface( 
                    mEglDisplay, mEglConfig, mMosaicOutputSurfaceTexture, null); 
            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) { 
                throw new RuntimeException("failed to createWindowSurface"); 
            } 
 
            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 
                throw new RuntimeException("failed to eglMakeCurrent"); 
            } 
 
            mGl = (GL10) mEglContext.getGL(); 
 
            mInputSurfaceTexture = new SurfaceTexture(MosaicRenderer.init()); 
            MosaicRenderer.reset(mWidth, mHeight, mIsLandscape); 
        } 
 
        private void doRelease() { 
            mEgl.eglDestroySurface(mEglDisplay, mEglSurface); 
            mEgl.eglDestroyContext(mEglDisplay, mEglContext); 
            mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, 
                    EGL10.EGL_NO_CONTEXT); 
            mEgl.eglTerminate(mEglDisplay); 
            mEglSurface = null; 
            mEglContext = null; 
            mEglDisplay = null; 
            releaseSurfaceTexture(mInputSurfaceTexture); 
            mEglThread.quit(); 
        } 
 
        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH) 
        private void releaseSurfaceTexture(SurfaceTexture st) { 
            if (ApiHelper.HAS_RELEASE_SURFACE_TEXTURE) { 
                st.release(); 
            } 
        } 
 
        // Should be called from other thread. 
        public void sendMessageSync(int msg) { 
            mEglThreadBlockVar.close(); 
            sendEmptyMessage(msg); 
            mEglThreadBlockVar.block(); 
        } 
 
    }