1feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/* 2feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Copyright (C) 2014 The Android Open Source Project 3feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 4feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * you may not use this file except in compliance with the License. 6feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * You may obtain a copy of the License at 7feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 8feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 10feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Unless required by applicable law or agreed to in writing, software 11feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * See the License for the specific language governing permissions and 14feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * limitations under the License. 15feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 16feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 17feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpackage android.hardware.camera2.legacy; 18feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 19feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.graphics.SurfaceTexture; 204aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunkimport android.hardware.camera2.impl.CameraDeviceImpl; 21feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.ConditionVariable; 22feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.Handler; 23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.Message; 24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.Log; 25f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkimport android.util.Pair; 26f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkimport android.util.Size; 27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.view.Surface; 28feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 29feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.Collection; 30feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 3191838ded36131525312739c0929913b215519c2aRuben Brunkimport static com.android.internal.util.Preconditions.*; 3291838ded36131525312739c0929913b215519c2aRuben Brunk 33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 34feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * GLThreadManager handles the thread used for rendering into the configured output surfaces. 35feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 36feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpublic class GLThreadManager { 37feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final String TAG; 38a78791f22af6c6985d186494737468bb19b69540Eino-Ville Talvala private static final boolean DEBUG = false; 39feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 40feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final int MSG_NEW_CONFIGURATION = 1; 41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final int MSG_NEW_FRAME = 2; 42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final int MSG_CLEANUP = 3; 43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final int MSG_DROP_FRAMES = 4; 44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final int MSG_ALLOW_FRAMES = 5; 45feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 4691838ded36131525312739c0929913b215519c2aRuben Brunk private CaptureCollector mCaptureCollector; 4791838ded36131525312739c0929913b215519c2aRuben Brunk 484aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk private final CameraDeviceState mDeviceState; 494aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk 50feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final SurfaceTextureRenderer mTextureRenderer; 51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final RequestHandlerThread mGLHandlerThread; 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final RequestThreadManager.FpsCounter mPrevCounter = 55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk new RequestThreadManager.FpsCounter("GL Preview Producer"); 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Container object for Configure messages. 59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 60feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static class ConfigureHolder { 61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public final ConditionVariable condition; 62f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk public final Collection<Pair<Surface, Size>> surfaces; 6391838ded36131525312739c0929913b215519c2aRuben Brunk public final CaptureCollector collector; 64feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 65f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk public ConfigureHolder(ConditionVariable condition, Collection<Pair<Surface, 66f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk Size>> surfaces, CaptureCollector collector) { 67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk this.condition = condition; 68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk this.surfaces = surfaces; 6991838ded36131525312739c0929913b215519c2aRuben Brunk this.collector = collector; 70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 71feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 72feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final Handler.Callback mGLHandlerCb = new Handler.Callback() { 74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private boolean mCleanup = false; 75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private boolean mConfigured = false; 76feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private boolean mDroppingFrames = false; 77feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 78feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @SuppressWarnings("unchecked") 79feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 80feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public boolean handleMessage(Message msg) { 81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mCleanup) { 82feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return true; 83feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 844aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk try { 854aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk switch (msg.what) { 864aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk case MSG_NEW_CONFIGURATION: 874aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk ConfigureHolder configure = (ConfigureHolder) msg.obj; 884aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mTextureRenderer.cleanupEGLContext(); 894aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mTextureRenderer.configureSurfaces(configure.surfaces); 904aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mCaptureCollector = checkNotNull(configure.collector); 914aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk configure.condition.open(); 924aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mConfigured = true; 934aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk break; 944aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk case MSG_NEW_FRAME: 954aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk if (mDroppingFrames) { 964aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk Log.w(TAG, "Ignoring frame."); 974aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk break; 984aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk } 994aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk if (DEBUG) { 1004aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mPrevCounter.countAndLog(); 1014aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk } 1024aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk if (!mConfigured) { 1034aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk Log.e(TAG, "Dropping frame, EGL context not configured!"); 1044aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk } 1054aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mTextureRenderer.drawIntoSurfaces(mCaptureCollector); 1064aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk break; 1074aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk case MSG_CLEANUP: 1084aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mTextureRenderer.cleanupEGLContext(); 1094aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mCleanup = true; 1104aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mConfigured = false; 1114aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk break; 1124aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk case MSG_DROP_FRAMES: 1134aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mDroppingFrames = true; 1144aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk break; 1154aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk case MSG_ALLOW_FRAMES: 1164aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mDroppingFrames = false; 1174aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk break; 11851dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin case RequestHandlerThread.MSG_POKE_IDLE_HANDLER: 11951dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin // OK: Ignore message. 12051dcfd65a6742884e07182dd7d13b916fd4e0305Igor Murashkin break; 1214aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk default: 1224aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk Log.e(TAG, "Unhandled message " + msg.what + " on GLThread."); 123feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk break; 1244aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk } 1254aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk } catch (Exception e) { 1264aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk Log.e(TAG, "Received exception on GL render thread: ", e); 1274aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mDeviceState.setError(CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); 128feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 129feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return true; 130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk }; 132feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 133feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 134feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Create a new GL thread and renderer. 135feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param cameraId the camera id for this thread. 137b68dd5c8b92d376540ac4ae6ed59671db641685eRuben Brunk * @param facing direction the camera is facing. 1384aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk * @param state {@link CameraDeviceState} to use for error handling. 139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 1404aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk public GLThreadManager(int cameraId, int facing, CameraDeviceState state) { 141b68dd5c8b92d376540ac4ae6ed59671db641685eRuben Brunk mTextureRenderer = new SurfaceTextureRenderer(facing); 142feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk TAG = String.format("CameraDeviceGLThread-%d", cameraId); 143feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mGLHandlerThread = new RequestHandlerThread(TAG, mGLHandlerCb); 1444aed87a9ed31a1ea7fd1ac8fd9ae538d9ecbef7eRuben Brunk mDeviceState = state; 145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 147feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Start the thread. 149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 151feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * This must be called before queueing new frames. 152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 153feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void start() { 155feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mGLHandlerThread.start(); 156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 157feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 158feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 159feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Wait until the thread has started. 160feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 161feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void waitUntilStarted() { 162feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mGLHandlerThread.waitUntilStarted(); 163feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 164feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 165feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 166feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Quit the thread. 167feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 168feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 169feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * No further methods can be called after this. 170feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 171feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 172feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void quit() { 173feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Handler handler = mGLHandlerThread.getHandler(); 174feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk handler.sendMessageAtFrontOfQueue(handler.obtainMessage(MSG_CLEANUP)); 175feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mGLHandlerThread.quitSafely(); 176d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk try { 177d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mGLHandlerThread.join(); 178d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } catch (InterruptedException e) { 179d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.", 180d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk mGLHandlerThread.getName(), mGLHandlerThread.getId())); 181d85e1a6ced452c9bd0d805f6ce19f50c9ea9b0a6Ruben Brunk } 182feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 183feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 184feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 18591838ded36131525312739c0929913b215519c2aRuben Brunk * Queue a new call to draw into the surfaces specified in the next available preview 18691838ded36131525312739c0929913b215519c2aRuben Brunk * request from the {@link CaptureCollector} passed to 18791838ded36131525312739c0929913b215519c2aRuben Brunk * {@link #setConfigurationAndWait(java.util.Collection, CaptureCollector)}; 188feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 18991838ded36131525312739c0929913b215519c2aRuben Brunk public void queueNewFrame() { 190feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Handler handler = mGLHandlerThread.getHandler(); 191feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 192feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 193feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Avoid queuing more than one new frame. If we are not consuming faster than frames 194feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * are produced, drop frames rather than allowing the queue to back up. 195feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 196feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!handler.hasMessages(MSG_NEW_FRAME)) { 19791838ded36131525312739c0929913b215519c2aRuben Brunk handler.sendMessage(handler.obtainMessage(MSG_NEW_FRAME)); 198feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 199feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "GLThread dropping frame. Not consuming frames quickly enough!"); 200feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 201feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 202feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 203feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 204feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Configure the GL renderer for the given set of output surfaces, and block until 205feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * this configuration has been applied. 206feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 207f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk * @param surfaces a collection of pairs of {@link android.view.Surface}s and their 208f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk * corresponding sizes to configure. 20991838ded36131525312739c0929913b215519c2aRuben Brunk * @param collector a {@link CaptureCollector} to retrieve requests from. 210feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 211f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk public void setConfigurationAndWait(Collection<Pair<Surface, Size>> surfaces, 212f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk CaptureCollector collector) { 21391838ded36131525312739c0929913b215519c2aRuben Brunk checkNotNull(collector, "collector must not be null"); 214feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Handler handler = mGLHandlerThread.getHandler(); 215feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 216feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk final ConditionVariable condition = new ConditionVariable(/*closed*/false); 21791838ded36131525312739c0929913b215519c2aRuben Brunk ConfigureHolder configure = new ConfigureHolder(condition, surfaces, collector); 218feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 219feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Message m = handler.obtainMessage(MSG_NEW_CONFIGURATION, /*arg1*/0, /*arg2*/0, configure); 220feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk handler.sendMessage(m); 221feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 222feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Block until configuration applied. 223feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk condition.block(); 224feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 225feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 226feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 227feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Get the underlying surface to produce frames from. 228feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 229feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 230feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * This returns the surface that is drawn into the set of surfaces passed in for each frame. 231feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * This method should only be called after a call to 232feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link #setConfigurationAndWait(java.util.Collection)}. Calling this before the first call 233feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * to {@link #setConfigurationAndWait(java.util.Collection)}, after {@link #quit()}, or 234feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * concurrently to one of these calls may result in an invalid 235feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link android.graphics.SurfaceTexture} being returned. 236feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 237feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 238feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @return an {@link android.graphics.SurfaceTexture} to draw to. 239feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 240feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public SurfaceTexture getCurrentSurfaceTexture() { 241feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return mTextureRenderer.getSurfaceTexture(); 242feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 243feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 244feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 245feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Ignore any subsequent calls to {@link #queueNewFrame(java.util.Collection)}. 246feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 247feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void ignoreNewFrames() { 248feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mGLHandlerThread.getHandler().sendEmptyMessage(MSG_DROP_FRAMES); 249feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 250feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 251feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 252feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Wait until no messages are queued. 253feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 254feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void waitUntilIdle() { 255feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mGLHandlerThread.waitUntilIdle(); 256feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 257feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 258feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 259feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Re-enable drawing new frames after a call to {@link #ignoreNewFrames()}. 260feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 261feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void allowNewFrames() { 262feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mGLHandlerThread.getHandler().sendEmptyMessage(MSG_ALLOW_FRAMES); 263feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 264feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 265