1eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal/*
2eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal * Copyright (C) 2011 The Android Open Source Project
3eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal *
4eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal * Licensed under the Apache License, Version 2.0 (the "License");
5eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal * you may not use this file except in compliance with the License.
6eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal * You may obtain a copy of the License at
7eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal *
8eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal *      http://www.apache.org/licenses/LICENSE-2.0
9eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal *
10eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal * Unless required by applicable law or agreed to in writing, software
11eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal * distributed under the License is distributed on an "AS IS" BASIS,
12eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal * See the License for the specific language governing permissions and
14eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal * limitations under the License.
15eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal */
16eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
17eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalpackage com.android.camera.panorama;
18eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
19d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chenimport android.app.Activity;
20eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalimport android.content.Context;
21d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chenimport android.content.pm.ActivityInfo;
22eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalimport android.graphics.PixelFormat;
23eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalimport android.opengl.GLSurfaceView;
2441a2e9735136f372de95652d0828600282c8e967mbansalimport android.os.ConditionVariable;
25eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalimport android.util.AttributeSet;
26eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalimport android.util.Log;
27eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
2836839102e03107e3fb121197036365a58ec2686eAngus Kongimport javax.microedition.khronos.egl.EGL10;
2936839102e03107e3fb121197036365a58ec2686eAngus Kongimport javax.microedition.khronos.egl.EGLConfig;
3036839102e03107e3fb121197036365a58ec2686eAngus Kongimport javax.microedition.khronos.egl.EGLContext;
3136839102e03107e3fb121197036365a58ec2686eAngus Kongimport javax.microedition.khronos.egl.EGLDisplay;
3236839102e03107e3fb121197036365a58ec2686eAngus Kong
33eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalpublic class MosaicRendererSurfaceView extends GLSurfaceView {
3436839102e03107e3fb121197036365a58ec2686eAngus Kong    private static final String TAG = "MosaicRendererSurfaceView";
35eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    private static final boolean DEBUG = false;
36eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    private MosaicRendererSurfaceViewRenderer mRenderer;
3741a2e9735136f372de95652d0828600282c8e967mbansal    private ConditionVariable mPreviewFrameReadyForProcessing;
38d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen    private boolean mIsLandscapeOrientation = true;
39eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
40eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    public MosaicRendererSurfaceView(Context context) {
41eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        super(context);
42d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen        initialize(context, false, 0, 0);
43eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
44eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
45eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    public MosaicRendererSurfaceView(Context context, AttributeSet attrs) {
46eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        super(context, attrs);
47d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen        initialize(context, false, 0, 0);
48eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
49eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
50d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen    public MosaicRendererSurfaceView(Context context, boolean translucent,
51d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen            int depth, int stencil) {
52eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        super(context);
53d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen        initialize(context, translucent, depth, stencil);
54d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen    }
55d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen
56d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen    private void initialize(Context context, boolean translucent, int depth, int stencil) {
57d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen        getDisplayOrientation(context);
58eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        init(translucent, depth, stencil);
59eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        setZOrderMediaOverlay(true);
60eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
61eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
62d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen    private void getDisplayOrientation(Context context) {
63d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen        Activity activity = (PanoramaActivity) context;
64d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen        mIsLandscapeOrientation = (activity.getRequestedOrientation()
65d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen                == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE );
66d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen    }
67d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen
68eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    private void init(boolean translucent, int depth, int stencil) {
69eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
70eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        /* By default, GLSurfaceView() creates a RGB_565 opaque surface.
71eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         * If we want a translucent one, we should change the surface's
72eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         * format here, using PixelFormat.TRANSLUCENT for GL Surfaces
73eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         * is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
74eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         */
75eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        if (translucent) {
76eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
77eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
78eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
79eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        /* Setup the context factory for 2.0 rendering.
80eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         * See ContextFactory class definition below
81eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         */
82eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        setEGLContextFactory(new ContextFactory());
83eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
84eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        /* We need to choose an EGLConfig that matches the format of
85eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         * our surface exactly. This is going to be done in our
86eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         * custom config chooser. See ConfigChooser class definition
87eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         * below.
88eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         */
8936839102e03107e3fb121197036365a58ec2686eAngus Kong        setEGLConfigChooser(
9036839102e03107e3fb121197036365a58ec2686eAngus Kong            translucent ? new ConfigChooser(8, 8, 8, 8, depth, stencil) :
9136839102e03107e3fb121197036365a58ec2686eAngus Kong            new ConfigChooser(5, 6, 5, 0, depth, stencil));
92eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
93eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        /* Set the renderer responsible for frame rendering */
94d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen        mRenderer = new MosaicRendererSurfaceViewRenderer(mIsLandscapeOrientation);
95eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        setRenderer(mRenderer);
96eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        setRenderMode(RENDERMODE_WHEN_DIRTY);
9741a2e9735136f372de95652d0828600282c8e967mbansal        mPreviewFrameReadyForProcessing = new ConditionVariable();
98eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
99eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
100eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
101eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
102eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
103eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            Log.w(TAG, "creating OpenGL ES 2.0 context");
104eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            checkEglError("Before eglCreateContext", egl);
10536839102e03107e3fb121197036365a58ec2686eAngus Kong            int[] attribList = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
10636839102e03107e3fb121197036365a58ec2686eAngus Kong            EGLContext context = egl.eglCreateContext(
10736839102e03107e3fb121197036365a58ec2686eAngus Kong                display, eglConfig, EGL10.EGL_NO_CONTEXT, attribList);
108eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            checkEglError("After eglCreateContext", egl);
109eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            return context;
110eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
111eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
112eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
113eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            egl.eglDestroyContext(display, context);
114eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
115eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
116eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
117eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    private static void checkEglError(String prompt, EGL10 egl) {
118eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        int error;
119eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
120eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
121eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
122eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
123eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
124eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
125eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
126eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
127eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            mRedSize = r;
128eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            mGreenSize = g;
129eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            mBlueSize = b;
130eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            mAlphaSize = a;
131eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            mDepthSize = depth;
132eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            mStencilSize = stencil;
133eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
134eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
135eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        /* This EGL config specification is used to specify 2.0 rendering.
136eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         * We use a minimum size of 4 bits for red/green/blue, but will
137eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         * perform actual matching in chooseConfig() below.
138eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal         */
139eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        private static final int EGL_OPENGL_ES2_BIT = 4;
140eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        private static final int[] CONFIG_ATTRIBUTES =
141eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        {
142eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            EGL10.EGL_RED_SIZE, 4,
143eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            EGL10.EGL_GREEN_SIZE, 4,
144eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            EGL10.EGL_BLUE_SIZE, 4,
145eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
146eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            EGL10.EGL_NONE
147eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        };
148eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
149eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
150eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
151eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            /* Get the number of minimally matching EGL configurations
152eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal             */
15336839102e03107e3fb121197036365a58ec2686eAngus Kong            int[] numConfig = new int[1];
15436839102e03107e3fb121197036365a58ec2686eAngus Kong            egl.eglChooseConfig(display, CONFIG_ATTRIBUTES, null, 0, numConfig);
155eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
15636839102e03107e3fb121197036365a58ec2686eAngus Kong            int numConfigs = numConfig[0];
157eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
158eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            if (numConfigs <= 0) {
159eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                throw new IllegalArgumentException("No configs match configSpec");
160eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            }
161eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
162eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            /* Allocate then read the array of minimally matching EGL configs
163eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal             */
164eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            EGLConfig[] configs = new EGLConfig[numConfigs];
16536839102e03107e3fb121197036365a58ec2686eAngus Kong            egl.eglChooseConfig(display, CONFIG_ATTRIBUTES, configs, numConfigs, numConfig);
166eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
167eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            if (DEBUG) {
168eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                 printConfigs(egl, display, configs);
169eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            }
170eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            /* Now return the "best" one
171eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal             */
172eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            return chooseConfig(egl, display, configs);
173eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
174eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
175eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
176eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                EGLConfig[] configs) {
17736839102e03107e3fb121197036365a58ec2686eAngus Kong            for (EGLConfig config : configs) {
178eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                int d = findConfigAttrib(egl, display, config,
179eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                        EGL10.EGL_DEPTH_SIZE, 0);
180eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                int s = findConfigAttrib(egl, display, config,
181eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                        EGL10.EGL_STENCIL_SIZE, 0);
182eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
183eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                // We need at least mDepthSize and mStencilSize bits
184eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                if (d < mDepthSize || s < mStencilSize)
185eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    continue;
186eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
187eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                // We want an *exact* match for red/green/blue/alpha
188eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                int r = findConfigAttrib(egl, display, config,
189eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                        EGL10.EGL_RED_SIZE, 0);
190eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                int g = findConfigAttrib(egl, display, config,
191eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                            EGL10.EGL_GREEN_SIZE, 0);
192eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                int b = findConfigAttrib(egl, display, config,
193eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                            EGL10.EGL_BLUE_SIZE, 0);
194eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                int a = findConfigAttrib(egl, display, config,
195eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                        EGL10.EGL_ALPHA_SIZE, 0);
196eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
197eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)
198eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    return config;
199eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            }
200eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            return null;
201eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
202eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
203eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        private int findConfigAttrib(EGL10 egl, EGLDisplay display,
204eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                EGLConfig config, int attribute, int defaultValue) {
205eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
206eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
207eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                return mValue[0];
208eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            }
209eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            return defaultValue;
210eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
211eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
212eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        private void printConfigs(EGL10 egl, EGLDisplay display,
213eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            EGLConfig[] configs) {
214eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            int numConfigs = configs.length;
215eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            Log.w(TAG, String.format("%d configurations", numConfigs));
216eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            for (int i = 0; i < numConfigs; i++) {
217eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                Log.w(TAG, String.format("Configuration %d:\n", i));
218eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                printConfig(egl, display, configs[i]);
219eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            }
220eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
221eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
222eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        private void printConfig(EGL10 egl, EGLDisplay display,
223eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                EGLConfig config) {
224eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            int[] attributes = {
225eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_BUFFER_SIZE,
226eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_ALPHA_SIZE,
227eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_BLUE_SIZE,
228eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_GREEN_SIZE,
229eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_RED_SIZE,
230eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_DEPTH_SIZE,
231eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_STENCIL_SIZE,
232eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_CONFIG_CAVEAT,
233eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_CONFIG_ID,
234eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_LEVEL,
235eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_MAX_PBUFFER_HEIGHT,
236eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_MAX_PBUFFER_PIXELS,
237eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_MAX_PBUFFER_WIDTH,
238eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_NATIVE_RENDERABLE,
239eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_NATIVE_VISUAL_ID,
240eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_NATIVE_VISUAL_TYPE,
241eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
242eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_SAMPLES,
243eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_SAMPLE_BUFFERS,
244eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_SURFACE_TYPE,
245eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_TRANSPARENT_TYPE,
246eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_TRANSPARENT_RED_VALUE,
247eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_TRANSPARENT_GREEN_VALUE,
248eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_TRANSPARENT_BLUE_VALUE,
249eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
250eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
251eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
252eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
253eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_LUMINANCE_SIZE,
254eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_ALPHA_MASK_SIZE,
255eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_COLOR_BUFFER_TYPE,
256eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    EGL10.EGL_RENDERABLE_TYPE,
257eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    0x3042 // EGL10.EGL_CONFORMANT
258eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            };
259eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            String[] names = {
260eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_BUFFER_SIZE",
261eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_ALPHA_SIZE",
262eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_BLUE_SIZE",
263eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_GREEN_SIZE",
264eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_RED_SIZE",
265eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_DEPTH_SIZE",
266eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_STENCIL_SIZE",
267eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_CONFIG_CAVEAT",
268eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_CONFIG_ID",
269eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_LEVEL",
270eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_MAX_PBUFFER_HEIGHT",
271eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_MAX_PBUFFER_PIXELS",
272eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_MAX_PBUFFER_WIDTH",
273eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_NATIVE_RENDERABLE",
274eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_NATIVE_VISUAL_ID",
275eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_NATIVE_VISUAL_TYPE",
276eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_PRESERVED_RESOURCES",
277eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_SAMPLES",
278eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_SAMPLE_BUFFERS",
279eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_SURFACE_TYPE",
280eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_TRANSPARENT_TYPE",
281eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_TRANSPARENT_RED_VALUE",
282eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_TRANSPARENT_GREEN_VALUE",
283eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_TRANSPARENT_BLUE_VALUE",
284eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_BIND_TO_TEXTURE_RGB",
285eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_BIND_TO_TEXTURE_RGBA",
286eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_MIN_SWAP_INTERVAL",
287eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_MAX_SWAP_INTERVAL",
288eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_LUMINANCE_SIZE",
289eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_ALPHA_MASK_SIZE",
290eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_COLOR_BUFFER_TYPE",
291eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_RENDERABLE_TYPE",
292eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    "EGL_CONFORMANT"
293eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            };
294eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            int[] value = new int[1];
295eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            for (int i = 0; i < attributes.length; i++) {
296eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                int attribute = attributes[i];
297eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                String name = names[i];
29836839102e03107e3fb121197036365a58ec2686eAngus Kong                if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
299eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    Log.w(TAG, String.format("  %s: %d\n", name, value[0]));
300eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                } else {
301eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    // Log.w(TAG, String.format("  %s: failed\n", name));
302eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                    while (egl.eglGetError() != EGL10.EGL_SUCCESS);
303eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                }
304eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            }
305eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
306eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
307eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        // Subclasses can adjust these values:
308eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        protected int mRedSize;
309eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        protected int mGreenSize;
310eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        protected int mBlueSize;
311eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        protected int mAlphaSize;
312eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        protected int mDepthSize;
313eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        protected int mStencilSize;
314eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        private int[] mValue = new int[1];
315eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
316eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
31736839102e03107e3fb121197036365a58ec2686eAngus Kong    public void lockPreviewReadyFlag() {
31841a2e9735136f372de95652d0828600282c8e967mbansal        mPreviewFrameReadyForProcessing.close();
31941a2e9735136f372de95652d0828600282c8e967mbansal    }
32041a2e9735136f372de95652d0828600282c8e967mbansal
32136839102e03107e3fb121197036365a58ec2686eAngus Kong    private void unlockPreviewReadyFlag() {
32241a2e9735136f372de95652d0828600282c8e967mbansal        mPreviewFrameReadyForProcessing.open();
32341a2e9735136f372de95652d0828600282c8e967mbansal    }
32441a2e9735136f372de95652d0828600282c8e967mbansal
32536839102e03107e3fb121197036365a58ec2686eAngus Kong    public void waitUntilPreviewReady() {
32641a2e9735136f372de95652d0828600282c8e967mbansal        mPreviewFrameReadyForProcessing.block();
32741a2e9735136f372de95652d0828600282c8e967mbansal    }
32841a2e9735136f372de95652d0828600282c8e967mbansal
32936839102e03107e3fb121197036365a58ec2686eAngus Kong    public void setReady() {
330eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        queueEvent(new Runnable() {
331eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
332eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            @Override
333eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            public void run() {
334eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                mRenderer.setReady();
335eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            }
336eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        });
337eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
338eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
3392faf16a90a6a6d18e40faf45ced217b913b214b6Angus Kong    public void preprocess(final float[] transformMatrix) {
34041a2e9735136f372de95652d0828600282c8e967mbansal        queueEvent(new Runnable() {
34141a2e9735136f372de95652d0828600282c8e967mbansal
34241a2e9735136f372de95652d0828600282c8e967mbansal            @Override
34341a2e9735136f372de95652d0828600282c8e967mbansal            public void run() {
3442faf16a90a6a6d18e40faf45ced217b913b214b6Angus Kong                mRenderer.preprocess(transformMatrix);
34541a2e9735136f372de95652d0828600282c8e967mbansal            }
34641a2e9735136f372de95652d0828600282c8e967mbansal        });
34741a2e9735136f372de95652d0828600282c8e967mbansal    }
34841a2e9735136f372de95652d0828600282c8e967mbansal
34936839102e03107e3fb121197036365a58ec2686eAngus Kong    public void transferGPUtoCPU() {
35041a2e9735136f372de95652d0828600282c8e967mbansal        queueEvent(new Runnable() {
35141a2e9735136f372de95652d0828600282c8e967mbansal
35241a2e9735136f372de95652d0828600282c8e967mbansal            @Override
35341a2e9735136f372de95652d0828600282c8e967mbansal            public void run() {
35441a2e9735136f372de95652d0828600282c8e967mbansal                mRenderer.transferGPUtoCPU();
35541a2e9735136f372de95652d0828600282c8e967mbansal                unlockPreviewReadyFlag();
35641a2e9735136f372de95652d0828600282c8e967mbansal            }
35741a2e9735136f372de95652d0828600282c8e967mbansal        });
35841a2e9735136f372de95652d0828600282c8e967mbansal    }
35941a2e9735136f372de95652d0828600282c8e967mbansal
36036839102e03107e3fb121197036365a58ec2686eAngus Kong    public void setWarping(final boolean flag) {
36141a2e9735136f372de95652d0828600282c8e967mbansal        queueEvent(new Runnable() {
36241a2e9735136f372de95652d0828600282c8e967mbansal
36341a2e9735136f372de95652d0828600282c8e967mbansal            @Override
36441a2e9735136f372de95652d0828600282c8e967mbansal            public void run() {
36541a2e9735136f372de95652d0828600282c8e967mbansal                mRenderer.setWarping(flag);
36641a2e9735136f372de95652d0828600282c8e967mbansal            }
36741a2e9735136f372de95652d0828600282c8e967mbansal        });
36841a2e9735136f372de95652d0828600282c8e967mbansal    }
36941a2e9735136f372de95652d0828600282c8e967mbansal
37036839102e03107e3fb121197036365a58ec2686eAngus Kong    public MosaicRendererSurfaceViewRenderer getRenderer() {
37136839102e03107e3fb121197036365a58ec2686eAngus Kong        return mRenderer;
37236839102e03107e3fb121197036365a58ec2686eAngus Kong    }
37336839102e03107e3fb121197036365a58ec2686eAngus Kong
374eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
375