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(); 
                    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, true);
        } 
 
        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();
        } 
 
        private void releaseSurfaceTexture(SurfaceTexture st) {
            st.release();
        } 
 
        // Should be called from other thread. 
        public void sendMessageSync(int msg) {
            mEglThreadBlockVar.close();
            sendEmptyMessage(msg);
            mEglThreadBlockVar.block();
        } 
 
    } 
 
    public MosaicPreviewRenderer(SurfaceTexture tex, int w, int h, boolean isLandscape) {