GLRootView.java revision edada7ca2b7c70c5459cbe488c1a16cc186f2bf0
1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.ui; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.Context; 20bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Changimport android.graphics.Matrix; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.PixelFormat; 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.opengl.GLSurfaceView; 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.os.Process; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.os.SystemClock; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.util.AttributeSet; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.view.MotionEvent; 2779cf902f4cc602774e90bc2040f0029978becb61Owen Linimport android.view.SurfaceHolder; 28edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Changimport android.view.View; 29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 30edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Changimport com.android.gallery3d.R; 312b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.anim.CanvasAnimation; 322b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.common.Utils; 332b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.GalleryUtils; 342b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.Profile; 352b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 36d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Linimport java.util.ArrayDeque; 37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.ArrayList; 381ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Changimport java.util.concurrent.locks.Condition; 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.concurrent.locks.ReentrantLock; 402b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.egl.EGLConfig; 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL10; 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL11; 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// The root component of all <code>GLView</code>s. The rendering is done in GL 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// thread while the event handling is done in the main thread. To synchronize 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// the two threads, the entry points of this package need to synchronize on the 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// <code>GLRootView</code> instance unless it can be proved that the rendering 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// thread won't access the same thing as the method. The entry points include: 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// (1) The public methods of HeadUpDisplay 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// (2) The public methods of CameraHeadUpDisplay 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// (3) The overridden methods in GLRootView. 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class GLRootView extends GLSurfaceView 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin implements GLSurfaceView.Renderer, GLRoot { 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "GLRootView"; 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final boolean DEBUG_FPS = false; 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mFrameCount = 0; 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private long mFrameCountingStart = 0; 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final boolean DEBUG_INVALIDATE = false; 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mInvalidateColor = 0; 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final boolean DEBUG_DRAWING_STAT = false; 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 663d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static final boolean DEBUG_PROFILE = false; 677d19f7f4281f232b9dceee4a5df390c03e2bd16bChih-Chung Chang private static final boolean DEBUG_PROFILE_SLOW_ONLY = false; 683d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int FLAG_INITIALIZED = 1; 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int FLAG_NEED_LAYOUT = 2; 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private GL11 mGL; 737b83fb8e3a8978b33a6b9bfc56d85fe2c1a9cf06Chih-Chung Chang private GLCanvas mCanvas; 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private GLView mContentView; 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 762ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang private OrientationSource mOrientationSource; 77bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // mCompensation is the difference between the UI orientation on GLCanvas 78bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // and the framework orientation. See OrientationManager for details. 79bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private int mCompensation; 80bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // mCompensationMatrix maps the coordinates of touch events. It is kept sync 81bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // with mCompensation. 82bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private Matrix mCompensationMatrix = new Matrix(); 832ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang private int mDisplayRotation; 842ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang 85bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // The value which will become mCompensation in next layout. 86bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private int mPendingCompensation; 87bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mFlags = FLAG_NEED_LAYOUT; 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private volatile boolean mRenderRequested = false; 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final GalleryEGLConfigChooser mEglConfigChooser = 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new GalleryEGLConfigChooser(); 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final ArrayList<CanvasAnimation> mAnimations = 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new ArrayList<CanvasAnimation>(); 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 97d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin private final ArrayDeque<OnGLIdleListener> mIdleListeners = 98d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin new ArrayDeque<OnGLIdleListener>(); 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final IdleRunner mIdleRunner = new IdleRunner(); 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final ReentrantLock mRenderLock = new ReentrantLock(); 1031ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang private final Condition mFreezeCondition = 1041ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang mRenderLock.newCondition(); 1051ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang private boolean mFreeze; 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private long mLastDrawFinishTime; 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mInDownState = false; 109edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang private boolean mFirstDraw = true; 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public GLRootView(Context context) { 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin this(context, null); 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public GLRootView(Context context, AttributeSet attrs) { 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super(context, attrs); 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFlags |= FLAG_INITIALIZED; 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setBackgroundDrawable(null); 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setEGLConfigChooser(mEglConfigChooser); 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setRenderer(this); 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin getHolder().setFormat(PixelFormat.RGB_565); 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Uncomment this to enable gl error check. 12449affdc4e274098a34e4eb2dbe4a89a750f1ba7fOwen Lin // setDebugFlags(DEBUG_CHECK_GL_ERROR); 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void registerLaunchedAnimation(CanvasAnimation animation) { 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Register the newly launched animation so that we can set the start 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // time more precisely. (Usually, it takes much longer for first 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // rendering, so we set the animation start time as the time we 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // complete rendering) 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAnimations.add(animation); 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void addOnGLIdleListener(OnGLIdleListener listener) { 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mIdleListeners) { 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIdleListeners.addLast(listener); 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIdleRunner.enable(); 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setContentPane(GLView content) { 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mContentView == content) return; 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mContentView != null) { 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mInDownState) { 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin long now = SystemClock.uptimeMillis(); 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MotionEvent cancelEvent = MotionEvent.obtain( 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0); 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentView.dispatchTouchEvent(cancelEvent); 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cancelEvent.recycle(); 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mInDownState = false; 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentView.detachFromRoot(); 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin BasicTexture.yieldAllTextures(); 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentView = content; 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (content != null) { 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin content.attachToRoot(this); 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestLayoutContentPane(); 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void requestRender() { 168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (DEBUG_INVALIDATE) { 169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin StackTraceElement e = Thread.currentThread().getStackTrace()[4]; 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String caller = e.getFileName() + ":" + e.getLineNumber() + " "; 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.d(TAG, "invalidate: " + caller); 172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mRenderRequested) return; 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderRequested = true; 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super.requestRender(); 176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void requestLayoutContentPane() { 180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mContentView == null || (mFlags & FLAG_NEED_LAYOUT) != 0) return; 183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // "View" system will invoke onLayout() for initialization(bug ?), we 185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // have to ignore it since the GLThread is not ready yet. 186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if ((mFlags & FLAG_INITIALIZED) == 0) return; 187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFlags |= FLAG_NEED_LAYOUT; 189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestRender(); 190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void layoutContentPane() { 196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFlags &= ~FLAG_NEED_LAYOUT; 197bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 198bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int w = getWidth(); 199bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int h = getHeight(); 2002ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang int displayRotation = 0; 2012ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang int compensation = 0; 2022ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang 2032ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang // Get the new orientation values 2042ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang if (mOrientationSource != null) { 2052ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang displayRotation = mOrientationSource.getDisplayRotation(); 2062ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang compensation = mOrientationSource.getCompensation(); 2072ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang } else { 2082ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang displayRotation = 0; 2092ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang compensation = 0; 2102ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang } 211bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 2122ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang if (mCompensation != compensation) { 2132ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang mCompensation = compensation; 214bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mCompensation % 180 != 0) { 215bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCompensationMatrix.setRotate(mCompensation); 216bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // move center to origin before rotation 217bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCompensationMatrix.preTranslate(-w / 2, -h / 2); 218bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // align with the new origin after rotation 219bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCompensationMatrix.postTranslate(h / 2, w / 2); 220bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } else { 221bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCompensationMatrix.setRotate(mCompensation, w / 2, h / 2); 222bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 223bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 2242ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang mDisplayRotation = displayRotation; 225bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 226bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Do the actual layout. 227bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mCompensation % 180 != 0) { 228bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int tmp = w; 229bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang w = h; 230bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang h = tmp; 231bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 232bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang Log.i(TAG, "layout content pane " + w + "x" + h 233bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang + " (compensation " + mCompensation + ")"); 234bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mContentView != null && w != 0 && h != 0) { 235bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mContentView.layout(0, 0, w, h); 236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Uncomment this to dump the view hierarchy. 238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin //mContentView.dumpTree(""); 239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected void onLayout( 243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean changed, int left, int top, int right, int bottom) { 244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (changed) requestLayoutContentPane(); 245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin /** 248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Called when the context is created, possibly after automatic destruction. 249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // This is a GLSurfaceView.Renderer callback 251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onSurfaceCreated(GL10 gl1, EGLConfig config) { 253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = (GL11) gl1; 254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mGL != null) { 255f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // The GL Object has changed 256f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.i(TAG, "GLObject has changed from " + mGL + " to " + gl); 257f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 25837c605949219b8bf54c165c34d6405f5f2989f50Owen Lin mRenderLock.lock(); 25937c605949219b8bf54c165c34d6405f5f2989f50Owen Lin try { 26037c605949219b8bf54c165c34d6405f5f2989f50Owen Lin mGL = gl; 26137c605949219b8bf54c165c34d6405f5f2989f50Owen Lin mCanvas = new GLCanvasImpl(gl); 26237c605949219b8bf54c165c34d6405f5f2989f50Owen Lin BasicTexture.invalidateAllTextures(); 26337c605949219b8bf54c165c34d6405f5f2989f50Owen Lin } finally { 26437c605949219b8bf54c165c34d6405f5f2989f50Owen Lin mRenderLock.unlock(); 26537c605949219b8bf54c165c34d6405f5f2989f50Owen Lin } 26637c605949219b8bf54c165c34d6405f5f2989f50Owen Lin 2673d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (DEBUG_FPS || DEBUG_PROFILE) { 268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); 2693d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } else { 2703d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin /** 275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Called when the OpenGL surface is recreated without destroying the 276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * context. 277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // This is a GLSurfaceView.Renderer callback 279f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 280f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onSurfaceChanged(GL10 gl1, int width, int height) { 281f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.i(TAG, "onSurfaceChanged: " + width + "x" + height 282f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin + ", gl10: " + gl1.toString()); 283f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY); 284f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GalleryUtils.setRenderThread(); 2853d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (DEBUG_PROFILE) { 2863d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Log.d(TAG, "Start profiling"); 2873d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.enable(20); // take a sample every 20ms 2883d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 289f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = (GL11) gl1; 290f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.assertTrue(mGL == gl); 291f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 292f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCanvas.setSize(width, height); 293f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 294f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 295f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void outputFps() { 296f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin long now = System.nanoTime(); 297f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mFrameCountingStart == 0) { 298f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFrameCountingStart = now; 299f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if ((now - mFrameCountingStart) > 1000000000) { 300f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.d(TAG, "fps: " + (double) mFrameCount 301f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 1000000000 / (now - mFrameCountingStart)); 302f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFrameCountingStart = now; 303f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFrameCount = 0; 304f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 305f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ++mFrameCount; 306f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 307f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 308f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 309f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onDrawFrame(GL10 gl) { 310cb05834cedb8223fc59456afcd62fa7448f2b3b8Chih-Chung Chang AnimationTime.update(); 3113d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long t0; 3127d19f7f4281f232b9dceee4a5df390c03e2bd16bChih-Chung Chang if (DEBUG_PROFILE_SLOW_ONLY) { 3133d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.hold(); 3143d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang t0 = System.nanoTime(); 3153d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 316f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 3171ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang 3181ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang while (mFreeze) { 3191ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang mFreezeCondition.awaitUninterruptibly(); 3201ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang } 3211ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang 322f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 323f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin onDrawFrameLocked(gl); 324f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 325f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 326f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 327d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin 328edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang // We put a black cover View in front of the SurfaceView and hide it 329edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang // after the first draw. This prevents the SurfaceView being transparent 330edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang // before the first draw. 331edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang if (mFirstDraw) { 332edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang mFirstDraw = false; 333edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang post(new Runnable() { 334edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang public void run() { 335edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang View root = getRootView(); 336edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang View cover = root.findViewById(R.id.gl_root_cover); 337edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang cover.setVisibility(GONE); 338edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang } 339edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang }); 340edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang } 341edada7ca2b7c70c5459cbe488c1a16cc186f2bf0Chih-Chung Chang 3427d19f7f4281f232b9dceee4a5df390c03e2bd16bChih-Chung Chang if (DEBUG_PROFILE_SLOW_ONLY) { 3433d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long t = System.nanoTime(); 3443d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long durationInMs = (t - mLastDrawFinishTime) / 1000000; 3453d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long durationDrawInMs = (t - t0) / 1000000; 3463d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mLastDrawFinishTime = t; 3473d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 3483d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (durationInMs > 34) { // 34ms -> we skipped at least 2 frames 3493d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Log.v(TAG, "----- SLOW (" + durationDrawInMs + "/" + 3503d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang durationInMs + ") -----"); 3513d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.commit(); 3523d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } else { 3533d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.drop(); 354f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 355f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 356f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 357f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 358f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void onDrawFrameLocked(GL10 gl) { 359f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (DEBUG_FPS) outputFps(); 360f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 361f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // release the unbound textures and deleted buffers. 362f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCanvas.deleteRecycledResources(); 363f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 364f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // reset texture upload limit 365f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin UploadedTexture.resetUploadLimit(); 366f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 367f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderRequested = false; 368f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 369f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if ((mFlags & FLAG_NEED_LAYOUT) != 0) layoutContentPane(); 370f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 371bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.save(GLCanvas.SAVE_FLAG_ALL); 372bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang rotateCanvas(-mCompensation); 373f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mContentView != null) { 374f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentView.render(mCanvas); 375f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 376bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.restore(); 377f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 378f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!mAnimations.isEmpty()) { 3797d19f7f4281f232b9dceee4a5df390c03e2bd16bChih-Chung Chang long now = AnimationTime.get(); 380f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0, n = mAnimations.size(); i < n; i++) { 381f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAnimations.get(i).setStartTime(now); 382f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 383f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAnimations.clear(); 384f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 385f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 386f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (UploadedTexture.uploadLimitReached()) { 387f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestRender(); 388f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 389f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 390f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mIdleListeners) { 391d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin if (!mIdleListeners.isEmpty()) mIdleRunner.enable(); 392f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 393f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 394f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (DEBUG_INVALIDATE) { 395f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCanvas.fillRect(10, 10, 5, 5, mInvalidateColor); 396f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mInvalidateColor = ~mInvalidateColor; 397f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 398f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 399f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (DEBUG_DRAWING_STAT) { 400f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCanvas.dumpStatisticsAndClear(); 401f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 402f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 403f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 404bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private void rotateCanvas(int degrees) { 405bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (degrees == 0) return; 406bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int w = getWidth(); 407bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int h = getHeight(); 408bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int cx = w / 2; 409bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int cy = h / 2; 410bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.translate(cx, cy); 411bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.rotate(degrees, 0, 0, 1); 412bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (degrees % 180 != 0) { 413bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.translate(-cy, -cx); 414bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } else { 415bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.translate(-cx, -cy); 416bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 417bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 418bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 419f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 420f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean dispatchTouchEvent(MotionEvent event) { 421bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (!isEnabled()) return false; 422bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 423f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int action = event.getAction(); 424f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (action == MotionEvent.ACTION_CANCEL 425f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin || action == MotionEvent.ACTION_UP) { 426f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mInDownState = false; 427f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (!mInDownState && action != MotionEvent.ACTION_DOWN) { 428f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return false; 429f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 430bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 431bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mCompensation != 0) { 432bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang event.transform(mCompensationMatrix); 433bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 434bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 435f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 436f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 437f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // If this has been detached from root, we don't need to handle event 438f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean handled = mContentView != null 439f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin && mContentView.dispatchTouchEvent(event); 440f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (action == MotionEvent.ACTION_DOWN && handled) { 441f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mInDownState = true; 442f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 443f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return handled; 444f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 445f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 446f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 447f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 448f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 449f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private class IdleRunner implements Runnable { 450f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // true if the idle runner is in the queue 451f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mActive = false; 452f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 453f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 454f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void run() { 455f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin OnGLIdleListener listener; 456f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mIdleListeners) { 457f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActive = false; 458f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mIdleListeners.isEmpty()) return; 459f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin listener = mIdleListeners.removeFirst(); 460f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 461f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 462f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 463d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin if (!listener.onGLIdle(mCanvas, mRenderRequested)) return; 464f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 465f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 466f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 467f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mIdleListeners) { 468f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIdleListeners.addLast(listener); 469d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin if (!mRenderRequested) enable(); 470f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 471f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 472f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 473f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void enable() { 474f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Who gets the flag can add it to the queue 475f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mActive) return; 476f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActive = true; 477f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin queueEvent(this); 478f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 479f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 480f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 481f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 482f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void lockRenderThread() { 483f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 484f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 485f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 486f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 487f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void unlockRenderThread() { 488f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 489f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 4903d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 4913d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang @Override 4923d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public void onPause() { 49379cf902f4cc602774e90bc2040f0029978becb61Owen Lin unfreeze(); 4943d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang super.onPause(); 4953d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (DEBUG_PROFILE) { 4963d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Log.d(TAG, "Stop profiling"); 4973d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.disableAll(); 4983d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.dumpToFile("/sdcard/gallery.prof"); 4993d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.reset(); 5003d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 5013d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 502bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 503bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang @Override 5042ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang public void setOrientationSource(OrientationSource source) { 5052ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang mOrientationSource = source; 5062ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang } 5072ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang 5082ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang @Override 5092ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang public int getDisplayRotation() { 5102ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang return mDisplayRotation; 5112ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang } 5122ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang 5132ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang @Override 5142ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang public int getCompensation() { 5152ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang return mCompensation; 5162ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang } 5172ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang 5182ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang @Override 5192ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang public Matrix getCompensationMatrix() { 5202ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang return mCompensationMatrix; 521bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 5221ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang 5231ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang @Override 5241ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang public void freeze() { 5251ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang mRenderLock.lock(); 5261ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang mFreeze = true; 5271ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang mRenderLock.unlock(); 5281ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang } 5291ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang 5301ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang @Override 5311ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang public void unfreeze() { 5321ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang mRenderLock.lock(); 5331ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang mFreeze = false; 5341ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang mFreezeCondition.signalAll(); 5351ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang mRenderLock.unlock(); 5361ade1266d8e13830e3b07c1ebd8c95f4e859e129Chih-Chung Chang } 53779cf902f4cc602774e90bc2040f0029978becb61Owen Lin 5380b2486cff0c1b951c54325596256b986307f7f3aChih-Chung Chang @Override 5390b2486cff0c1b951c54325596256b986307f7f3aChih-Chung Chang public void setLightsOutMode(boolean enabled) { 540e919bcff63e898d53869725a979cdfd01ef92b08Chih-Chung Chang int flags = enabled 541e919bcff63e898d53869725a979cdfd01ef92b08Chih-Chung Chang ? SYSTEM_UI_FLAG_LOW_PROFILE 542e919bcff63e898d53869725a979cdfd01ef92b08Chih-Chung Chang | SYSTEM_UI_FLAG_FULLSCREEN 543e919bcff63e898d53869725a979cdfd01ef92b08Chih-Chung Chang | SYSTEM_UI_FLAG_LAYOUT_STABLE 544e919bcff63e898d53869725a979cdfd01ef92b08Chih-Chung Chang : 0; 5450b2486cff0c1b951c54325596256b986307f7f3aChih-Chung Chang setSystemUiVisibility(flags); 5460b2486cff0c1b951c54325596256b986307f7f3aChih-Chung Chang } 5470b2486cff0c1b951c54325596256b986307f7f3aChih-Chung Chang 54879cf902f4cc602774e90bc2040f0029978becb61Owen Lin // We need to unfreeze in the following methods and in onPause(). 54979cf902f4cc602774e90bc2040f0029978becb61Owen Lin // These methods will wait on GLThread. If we have freezed the GLRootView, 55079cf902f4cc602774e90bc2040f0029978becb61Owen Lin // the GLThread will wait on main thread to call unfreeze and cause dead 55179cf902f4cc602774e90bc2040f0029978becb61Owen Lin // lock. 55279cf902f4cc602774e90bc2040f0029978becb61Owen Lin @Override 55379cf902f4cc602774e90bc2040f0029978becb61Owen Lin public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 55479cf902f4cc602774e90bc2040f0029978becb61Owen Lin unfreeze(); 55579cf902f4cc602774e90bc2040f0029978becb61Owen Lin super.surfaceChanged(holder, format, w, h); 55679cf902f4cc602774e90bc2040f0029978becb61Owen Lin } 55779cf902f4cc602774e90bc2040f0029978becb61Owen Lin 55879cf902f4cc602774e90bc2040f0029978becb61Owen Lin @Override 55979cf902f4cc602774e90bc2040f0029978becb61Owen Lin public void surfaceCreated(SurfaceHolder holder) { 56079cf902f4cc602774e90bc2040f0029978becb61Owen Lin unfreeze(); 56179cf902f4cc602774e90bc2040f0029978becb61Owen Lin super.surfaceCreated(holder); 56279cf902f4cc602774e90bc2040f0029978becb61Owen Lin } 56379cf902f4cc602774e90bc2040f0029978becb61Owen Lin 56479cf902f4cc602774e90bc2040f0029978becb61Owen Lin @Override 56579cf902f4cc602774e90bc2040f0029978becb61Owen Lin public void surfaceDestroyed(SurfaceHolder holder) { 56679cf902f4cc602774e90bc2040f0029978becb61Owen Lin unfreeze(); 56779cf902f4cc602774e90bc2040f0029978becb61Owen Lin super.surfaceDestroyed(holder); 56879cf902f4cc602774e90bc2040f0029978becb61Owen Lin } 56979cf902f4cc602774e90bc2040f0029978becb61Owen Lin 57079cf902f4cc602774e90bc2040f0029978becb61Owen Lin @Override 57179cf902f4cc602774e90bc2040f0029978becb61Owen Lin protected void onDetachedFromWindow() { 57279cf902f4cc602774e90bc2040f0029978becb61Owen Lin unfreeze(); 57379cf902f4cc602774e90bc2040f0029978becb61Owen Lin super.onDetachedFromWindow(); 57479cf902f4cc602774e90bc2040f0029978becb61Owen Lin } 57579cf902f4cc602774e90bc2040f0029978becb61Owen Lin 57679cf902f4cc602774e90bc2040f0029978becb61Owen Lin @Override 57779cf902f4cc602774e90bc2040f0029978becb61Owen Lin protected void finalize() throws Throwable { 57879cf902f4cc602774e90bc2040f0029978becb61Owen Lin try { 57979cf902f4cc602774e90bc2040f0029978becb61Owen Lin unfreeze(); 58079cf902f4cc602774e90bc2040f0029978becb61Owen Lin } finally { 58179cf902f4cc602774e90bc2040f0029978becb61Owen Lin super.finalize(); 58279cf902f4cc602774e90bc2040f0029978becb61Owen Lin } 58379cf902f4cc602774e90bc2040f0029978becb61Owen Lin } 584f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 585