GLRootView.java revision bd141b5a51c96f6fcaddfa547f0928ce69cf0755
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.graphics.Rect; 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.opengl.GLSurfaceView; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.os.Process; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.os.SystemClock; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.util.AttributeSet; 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.view.MotionEvent; 28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 292b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.anim.CanvasAnimation; 302b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.common.Utils; 312b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.GalleryUtils; 322b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.Profile; 332b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 34d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Linimport java.util.ArrayDeque; 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.ArrayList; 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.concurrent.locks.ReentrantLock; 372b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.egl.EGLConfig; 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL10; 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL11; 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// The root component of all <code>GLView</code>s. The rendering is done in GL 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// thread while the event handling is done in the main thread. To synchronize 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// the two threads, the entry points of this package need to synchronize on the 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// <code>GLRootView</code> instance unless it can be proved that the rendering 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// thread won't access the same thing as the method. The entry points include: 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// (1) The public methods of HeadUpDisplay 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// (2) The public methods of CameraHeadUpDisplay 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// (3) The overridden methods in GLRootView. 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class GLRootView extends GLSurfaceView 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin implements GLSurfaceView.Renderer, GLRoot { 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "GLRootView"; 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final boolean DEBUG_FPS = false; 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mFrameCount = 0; 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private long mFrameCountingStart = 0; 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final boolean DEBUG_INVALIDATE = false; 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mInvalidateColor = 0; 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final boolean DEBUG_DRAWING_STAT = false; 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 633d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang private static final boolean DEBUG_PROFILE = false; 647d19f7f4281f232b9dceee4a5df390c03e2bd16bChih-Chung Chang private static final boolean DEBUG_PROFILE_SLOW_ONLY = false; 653d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int FLAG_INITIALIZED = 1; 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int FLAG_NEED_LAYOUT = 2; 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private GL11 mGL; 707b83fb8e3a8978b33a6b9bfc56d85fe2c1a9cf06Chih-Chung Chang private GLCanvas mCanvas; 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private GLView mContentView; 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 73bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // mCompensation is the difference between the UI orientation on GLCanvas 74bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // and the framework orientation. See OrientationManager for details. 75bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private int mCompensation; 76bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // mCompensationMatrix maps the coordinates of touch events. It is kept sync 77bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // with mCompensation. 78bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private Matrix mCompensationMatrix = new Matrix(); 79bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // The value which will become mCompensation in next layout. 80bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private int mPendingCompensation; 81bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mFlags = FLAG_NEED_LAYOUT; 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private volatile boolean mRenderRequested = false; 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final GalleryEGLConfigChooser mEglConfigChooser = 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new GalleryEGLConfigChooser(); 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final ArrayList<CanvasAnimation> mAnimations = 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new ArrayList<CanvasAnimation>(); 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 91d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin private final ArrayDeque<OnGLIdleListener> mIdleListeners = 92d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin new ArrayDeque<OnGLIdleListener>(); 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final IdleRunner mIdleRunner = new IdleRunner(); 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final ReentrantLock mRenderLock = new ReentrantLock(); 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private long mLastDrawFinishTime; 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mInDownState = false; 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public GLRootView(Context context) { 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin this(context, null); 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public GLRootView(Context context, AttributeSet attrs) { 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super(context, attrs); 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFlags |= FLAG_INITIALIZED; 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setBackgroundDrawable(null); 109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setEGLConfigChooser(mEglConfigChooser); 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setRenderer(this); 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin getHolder().setFormat(PixelFormat.RGB_565); 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Uncomment this to enable gl error check. 114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin //setDebugFlags(DEBUG_CHECK_GL_ERROR); 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void registerLaunchedAnimation(CanvasAnimation animation) { 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Register the newly launched animation so that we can set the start 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // time more precisely. (Usually, it takes much longer for first 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // rendering, so we set the animation start time as the time we 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // complete rendering) 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAnimations.add(animation); 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void addOnGLIdleListener(OnGLIdleListener listener) { 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mIdleListeners) { 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIdleListeners.addLast(listener); 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIdleRunner.enable(); 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setContentPane(GLView content) { 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mContentView == content) return; 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mContentView != null) { 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mInDownState) { 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin long now = SystemClock.uptimeMillis(); 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MotionEvent cancelEvent = MotionEvent.obtain( 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0); 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentView.dispatchTouchEvent(cancelEvent); 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cancelEvent.recycle(); 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mInDownState = false; 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentView.detachFromRoot(); 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin BasicTexture.yieldAllTextures(); 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentView = content; 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (content != null) { 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin content.attachToRoot(this); 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestLayoutContentPane(); 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void requestRender() { 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (DEBUG_INVALIDATE) { 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin StackTraceElement e = Thread.currentThread().getStackTrace()[4]; 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String caller = e.getFileName() + ":" + e.getLineNumber() + " "; 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.d(TAG, "invalidate: " + caller); 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mRenderRequested) return; 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderRequested = true; 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super.requestRender(); 166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void requestLayoutContentPane() { 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mContentView == null || (mFlags & FLAG_NEED_LAYOUT) != 0) return; 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // "View" system will invoke onLayout() for initialization(bug ?), we 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // have to ignore it since the GLThread is not ready yet. 176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if ((mFlags & FLAG_INITIALIZED) == 0) return; 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFlags |= FLAG_NEED_LAYOUT; 179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestRender(); 180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void layoutContentPane() { 186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFlags &= ~FLAG_NEED_LAYOUT; 187bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 188bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int w = getWidth(); 189bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int h = getHeight(); 190bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 191bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Before doing layout, if there is a compensation change pending, update 192bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // mCompensation and mCompensationMatrix. 193bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mCompensation != mPendingCompensation) { 194bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCompensation = mPendingCompensation; 195bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mCompensation % 180 != 0) { 196bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCompensationMatrix.setRotate(mCompensation); 197bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // move center to origin before rotation 198bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCompensationMatrix.preTranslate(-w / 2, -h / 2); 199bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // align with the new origin after rotation 200bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCompensationMatrix.postTranslate(h / 2, w / 2); 201bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } else { 202bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCompensationMatrix.setRotate(mCompensation, w / 2, h / 2); 203bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 204bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 205bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 206bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Tell the views about current display rotation and compensation value. 207bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mContentView != null) { 208bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // This is a hack: note the 0 should be the display rotation, but we 209bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // don't know the display rotation here. The PhotoPage will inject 210bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // the correct value in its mRootPane.orient() method. 211bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mContentView.orient(0, mCompensation); 212bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 213bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 214bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Do the actual layout. 215bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mCompensation % 180 != 0) { 216bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int tmp = w; 217bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang w = h; 218bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang h = tmp; 219bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 220bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang Log.i(TAG, "layout content pane " + w + "x" + h 221bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang + " (compensation " + mCompensation + ")"); 222bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mContentView != null && w != 0 && h != 0) { 223bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mContentView.layout(0, 0, w, h); 224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Uncomment this to dump the view hierarchy. 226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin //mContentView.dumpTree(""); 227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected void onLayout( 231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean changed, int left, int top, int right, int bottom) { 232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (changed) requestLayoutContentPane(); 233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin /** 236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Called when the context is created, possibly after automatic destruction. 237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // This is a GLSurfaceView.Renderer callback 239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onSurfaceCreated(GL10 gl1, EGLConfig config) { 241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = (GL11) gl1; 242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mGL != null) { 243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // The GL Object has changed 244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.i(TAG, "GLObject has changed from " + mGL + " to " + gl); 245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL = gl; 247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCanvas = new GLCanvasImpl(gl); 2483d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (DEBUG_FPS || DEBUG_PROFILE) { 249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); 2503d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } else { 2513d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 255f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin /** 256f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Called when the OpenGL surface is recreated without destroying the 257f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * context. 258f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // This is a GLSurfaceView.Renderer callback 260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onSurfaceChanged(GL10 gl1, int width, int height) { 262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.i(TAG, "onSurfaceChanged: " + width + "x" + height 263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin + ", gl10: " + gl1.toString()); 264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY); 265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GalleryUtils.setRenderThread(); 2663950038a697470bb8b7cd6798716aecd8285eb00Chih-Chung Chang BasicTexture.invalidateAllTextures(); 2673d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (DEBUG_PROFILE) { 2683d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Log.d(TAG, "Start profiling"); 2693d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.enable(20); // take a sample every 20ms 2703d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = (GL11) gl1; 272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.assertTrue(mGL == gl); 273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCanvas.setSize(width, height); 275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void outputFps() { 278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin long now = System.nanoTime(); 279f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mFrameCountingStart == 0) { 280f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFrameCountingStart = now; 281f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if ((now - mFrameCountingStart) > 1000000000) { 282f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.d(TAG, "fps: " + (double) mFrameCount 283f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 1000000000 / (now - mFrameCountingStart)); 284f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFrameCountingStart = now; 285f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFrameCount = 0; 286f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 287f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ++mFrameCount; 288f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 289f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 290f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 291f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onDrawFrame(GL10 gl) { 292cb05834cedb8223fc59456afcd62fa7448f2b3b8Chih-Chung Chang AnimationTime.update(); 2933d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long t0; 2947d19f7f4281f232b9dceee4a5df390c03e2bd16bChih-Chung Chang if (DEBUG_PROFILE_SLOW_ONLY) { 2953d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.hold(); 2963d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang t0 = System.nanoTime(); 2973d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 298f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 299f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 300f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin onDrawFrameLocked(gl); 301f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 302f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 303f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 304d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin 3057d19f7f4281f232b9dceee4a5df390c03e2bd16bChih-Chung Chang if (DEBUG_PROFILE_SLOW_ONLY) { 3063d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long t = System.nanoTime(); 3073d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long durationInMs = (t - mLastDrawFinishTime) / 1000000; 3083d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang long durationDrawInMs = (t - t0) / 1000000; 3093d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang mLastDrawFinishTime = t; 3103d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 3113d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (durationInMs > 34) { // 34ms -> we skipped at least 2 frames 3123d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Log.v(TAG, "----- SLOW (" + durationDrawInMs + "/" + 3133d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang durationInMs + ") -----"); 3143d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.commit(); 3153d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } else { 3163d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.drop(); 317f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 318f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 319f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 320f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 321f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void onDrawFrameLocked(GL10 gl) { 322f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (DEBUG_FPS) outputFps(); 323f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 324f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // release the unbound textures and deleted buffers. 325f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCanvas.deleteRecycledResources(); 326f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 327f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // reset texture upload limit 328f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin UploadedTexture.resetUploadLimit(); 329f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 330f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderRequested = false; 331f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 332f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if ((mFlags & FLAG_NEED_LAYOUT) != 0) layoutContentPane(); 333f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 334bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.save(GLCanvas.SAVE_FLAG_ALL); 335bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang rotateCanvas(-mCompensation); 336f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mContentView != null) { 337f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentView.render(mCanvas); 338f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 339bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.restore(); 340f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 341f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!mAnimations.isEmpty()) { 3427d19f7f4281f232b9dceee4a5df390c03e2bd16bChih-Chung Chang long now = AnimationTime.get(); 343f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0, n = mAnimations.size(); i < n; i++) { 344f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAnimations.get(i).setStartTime(now); 345f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 346f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAnimations.clear(); 347f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 348f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 349f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (UploadedTexture.uploadLimitReached()) { 350f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestRender(); 351f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 352f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 353f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mIdleListeners) { 354d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin if (!mIdleListeners.isEmpty()) mIdleRunner.enable(); 355f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 356f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 357f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (DEBUG_INVALIDATE) { 358f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCanvas.fillRect(10, 10, 5, 5, mInvalidateColor); 359f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mInvalidateColor = ~mInvalidateColor; 360f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 361f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 362f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (DEBUG_DRAWING_STAT) { 363f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCanvas.dumpStatisticsAndClear(); 364f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 365f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 366f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 367bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private void rotateCanvas(int degrees) { 368bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (degrees == 0) return; 369bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int w = getWidth(); 370bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int h = getHeight(); 371bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int cx = w / 2; 372bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int cy = h / 2; 373bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.translate(cx, cy); 374bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.rotate(degrees, 0, 0, 1); 375bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (degrees % 180 != 0) { 376bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.translate(-cy, -cx); 377bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } else { 378bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mCanvas.translate(-cx, -cy); 379bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 380bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 381bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 382f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 383f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean dispatchTouchEvent(MotionEvent event) { 384bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (!isEnabled()) return false; 385bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 386f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int action = event.getAction(); 387f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (action == MotionEvent.ACTION_CANCEL 388f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin || action == MotionEvent.ACTION_UP) { 389f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mInDownState = false; 390f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (!mInDownState && action != MotionEvent.ACTION_DOWN) { 391f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return false; 392f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 393bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 394bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mCompensation != 0) { 395bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang event.transform(mCompensationMatrix); 396bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 397bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 398f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 399f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 400f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // If this has been detached from root, we don't need to handle event 401f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean handled = mContentView != null 402f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin && mContentView.dispatchTouchEvent(event); 403f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (action == MotionEvent.ACTION_DOWN && handled) { 404f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mInDownState = true; 405f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 406f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return handled; 407f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 408f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 409f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 410f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 411f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 412f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private class IdleRunner implements Runnable { 413f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // true if the idle runner is in the queue 414f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mActive = false; 415f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 416f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 417f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void run() { 418f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin OnGLIdleListener listener; 419f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mIdleListeners) { 420f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActive = false; 421f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mIdleListeners.isEmpty()) return; 422f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin listener = mIdleListeners.removeFirst(); 423f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 424f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 425f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 426d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin if (!listener.onGLIdle(mCanvas, mRenderRequested)) return; 427f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 428f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 429f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 430f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mIdleListeners) { 431f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIdleListeners.addLast(listener); 432d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin if (!mRenderRequested) enable(); 433f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 434f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 435f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 436f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void enable() { 437f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Who gets the flag can add it to the queue 438f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mActive) return; 439f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActive = true; 440f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin queueEvent(this); 441f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 442f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 443f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 444f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 445f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void lockRenderThread() { 446f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.lock(); 447f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 448f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 449f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 450f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void unlockRenderThread() { 451f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRenderLock.unlock(); 452f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 4533d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang 4543d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang @Override 4553d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang public void onPause() { 4563d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang super.onPause(); 4573d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang if (DEBUG_PROFILE) { 4583d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Log.d(TAG, "Stop profiling"); 4593d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.disableAll(); 4603d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.dumpToFile("/sdcard/gallery.prof"); 4613d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang Profile.reset(); 4623d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 4633d238a7a19b1010578709c63f86e12b2bce0e4fcChih-Chung Chang } 464bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 465bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang @Override 466bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public void setOrientationCompensation(int degrees) { 467bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mPendingCompensation == degrees) return; 468bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mPendingCompensation = degrees; 469bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang requestLayoutContentPane(); 470bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 471f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 472