summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/ui/GLRootView.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/ui/GLRootView.java')
-rw-r--r--src/com/android/gallery3d/ui/GLRootView.java630
1 files changed, 0 insertions, 630 deletions
diff --git a/src/com/android/gallery3d/ui/GLRootView.java b/src/com/android/gallery3d/ui/GLRootView.java
deleted file mode 100644
index dc898d83d..000000000
--- a/src/com/android/gallery3d/ui/GLRootView.java
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gallery3d.ui;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.Matrix;
-import android.graphics.PixelFormat;
-import android.opengl.GLSurfaceView;
-import android.os.Build;
-import android.os.Process;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-import android.view.View;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.anim.CanvasAnimation;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.glrenderer.BasicTexture;
-import com.android.gallery3d.glrenderer.GLCanvas;
-import com.android.gallery3d.glrenderer.GLES11Canvas;
-import com.android.gallery3d.glrenderer.GLES20Canvas;
-import com.android.gallery3d.glrenderer.UploadedTexture;
-import com.android.gallery3d.util.GalleryUtils;
-import com.android.gallery3d.util.MotionEventHelper;
-import com.android.gallery3d.util.Profile;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-import javax.microedition.khronos.opengles.GL11;
-
-// The root component of all <code>GLView</code>s. The rendering is done in GL
-// thread while the event handling is done in the main thread. To synchronize
-// the two threads, the entry points of this package need to synchronize on the
-// <code>GLRootView</code> instance unless it can be proved that the rendering
-// thread won't access the same thing as the method. The entry points include:
-// (1) The public methods of HeadUpDisplay
-// (2) The public methods of CameraHeadUpDisplay
-// (3) The overridden methods in GLRootView.
-public class GLRootView extends GLSurfaceView
- implements GLSurfaceView.Renderer, GLRoot {
- private static final String TAG = "GLRootView";
-
- private static final boolean DEBUG_FPS = false;
- private int mFrameCount = 0;
- private long mFrameCountingStart = 0;
-
- private static final boolean DEBUG_INVALIDATE = false;
- private int mInvalidateColor = 0;
-
- private static final boolean DEBUG_DRAWING_STAT = false;
-
- private static final boolean DEBUG_PROFILE = false;
- private static final boolean DEBUG_PROFILE_SLOW_ONLY = false;
-
- private static final int FLAG_INITIALIZED = 1;
- private static final int FLAG_NEED_LAYOUT = 2;
-
- private GL11 mGL;
- private GLCanvas mCanvas;
- private GLView mContentView;
-
- private OrientationSource mOrientationSource;
- // mCompensation is the difference between the UI orientation on GLCanvas
- // and the framework orientation. See OrientationManager for details.
- private int mCompensation;
- // mCompensationMatrix maps the coordinates of touch events. It is kept sync
- // with mCompensation.
- private Matrix mCompensationMatrix = new Matrix();
- private int mDisplayRotation;
-
- private int mFlags = FLAG_NEED_LAYOUT;
- private volatile boolean mRenderRequested = false;
-
- private final ArrayList<CanvasAnimation> mAnimations =
- new ArrayList<CanvasAnimation>();
-
- private final ArrayDeque<OnGLIdleListener> mIdleListeners =
- new ArrayDeque<OnGLIdleListener>();
-
- private final IdleRunner mIdleRunner = new IdleRunner();
-
- private final ReentrantLock mRenderLock = new ReentrantLock();
- private final Condition mFreezeCondition =
- mRenderLock.newCondition();
- private boolean mFreeze;
-
- private long mLastDrawFinishTime;
- private boolean mInDownState = false;
- private boolean mFirstDraw = true;
-
- public GLRootView(Context context) {
- this(context, null);
- }
-
- public GLRootView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mFlags |= FLAG_INITIALIZED;
- setBackgroundDrawable(null);
- setEGLContextClientVersion(ApiHelper.HAS_GLES20_REQUIRED ? 2 : 1);
- if (ApiHelper.USE_888_PIXEL_FORMAT) {
- setEGLConfigChooser(8, 8, 8, 0, 0, 0);
- } else {
- setEGLConfigChooser(5, 6, 5, 0, 0, 0);
- }
- setRenderer(this);
- if (ApiHelper.USE_888_PIXEL_FORMAT) {
- getHolder().setFormat(PixelFormat.RGB_888);
- } else {
- getHolder().setFormat(PixelFormat.RGB_565);
- }
-
- // Uncomment this to enable gl error check.
- // setDebugFlags(DEBUG_CHECK_GL_ERROR);
- }
-
- @Override
- public void registerLaunchedAnimation(CanvasAnimation animation) {
- // Register the newly launched animation so that we can set the start
- // time more precisely. (Usually, it takes much longer for first
- // rendering, so we set the animation start time as the time we
- // complete rendering)
- mAnimations.add(animation);
- }
-
- @Override
- public void addOnGLIdleListener(OnGLIdleListener listener) {
- synchronized (mIdleListeners) {
- mIdleListeners.addLast(listener);
- mIdleRunner.enable();
- }
- }
-
- @Override
- public void setContentPane(GLView content) {
- if (mContentView == content) return;
- if (mContentView != null) {
- if (mInDownState) {
- long now = SystemClock.uptimeMillis();
- MotionEvent cancelEvent = MotionEvent.obtain(
- now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0);
- mContentView.dispatchTouchEvent(cancelEvent);
- cancelEvent.recycle();
- mInDownState = false;
- }
- mContentView.detachFromRoot();
- BasicTexture.yieldAllTextures();
- }
- mContentView = content;
- if (content != null) {
- content.attachToRoot(this);
- requestLayoutContentPane();
- }
- }
-
- @Override
- public void requestRenderForced() {
- superRequestRender();
- }
-
- @Override
- public void requestRender() {
- if (DEBUG_INVALIDATE) {
- StackTraceElement e = Thread.currentThread().getStackTrace()[4];
- String caller = e.getFileName() + ":" + e.getLineNumber() + " ";
- Log.d(TAG, "invalidate: " + caller);
- }
- if (mRenderRequested) return;
- mRenderRequested = true;
- if (ApiHelper.HAS_POST_ON_ANIMATION) {
- postOnAnimation(mRequestRenderOnAnimationFrame);
- } else {
- super.requestRender();
- }
- }
-
- private Runnable mRequestRenderOnAnimationFrame = new Runnable() {
- @Override
- public void run() {
- superRequestRender();
- }
- };
-
- private void superRequestRender() {
- super.requestRender();
- }
-
- @Override
- public void requestLayoutContentPane() {
- mRenderLock.lock();
- try {
- if (mContentView == null || (mFlags & FLAG_NEED_LAYOUT) != 0) return;
-
- // "View" system will invoke onLayout() for initialization(bug ?), we
- // have to ignore it since the GLThread is not ready yet.
- if ((mFlags & FLAG_INITIALIZED) == 0) return;
-
- mFlags |= FLAG_NEED_LAYOUT;
- requestRender();
- } finally {
- mRenderLock.unlock();
- }
- }
-
- private void layoutContentPane() {
- mFlags &= ~FLAG_NEED_LAYOUT;
-
- int w = getWidth();
- int h = getHeight();
- int displayRotation = 0;
- int compensation = 0;
-
- // Get the new orientation values
- if (mOrientationSource != null) {
- displayRotation = mOrientationSource.getDisplayRotation();
- compensation = mOrientationSource.getCompensation();
- } else {
- displayRotation = 0;
- compensation = 0;
- }
-
- if (mCompensation != compensation) {
- mCompensation = compensation;
- if (mCompensation % 180 != 0) {
- mCompensationMatrix.setRotate(mCompensation);
- // move center to origin before rotation
- mCompensationMatrix.preTranslate(-w / 2, -h / 2);
- // align with the new origin after rotation
- mCompensationMatrix.postTranslate(h / 2, w / 2);
- } else {
- mCompensationMatrix.setRotate(mCompensation, w / 2, h / 2);
- }
- }
- mDisplayRotation = displayRotation;
-
- // Do the actual layout.
- if (mCompensation % 180 != 0) {
- int tmp = w;
- w = h;
- h = tmp;
- }
- Log.i(TAG, "layout content pane " + w + "x" + h
- + " (compensation " + mCompensation + ")");
- if (mContentView != null && w != 0 && h != 0) {
- mContentView.layout(0, 0, w, h);
- }
- // Uncomment this to dump the view hierarchy.
- //mContentView.dumpTree("");
- }
-
- @Override
- protected void onLayout(
- boolean changed, int left, int top, int right, int bottom) {
- if (changed) requestLayoutContentPane();
- }
-
- /**
- * Called when the context is created, possibly after automatic destruction.
- */
- // This is a GLSurfaceView.Renderer callback
- @Override
- public void onSurfaceCreated(GL10 gl1, EGLConfig config) {
- GL11 gl = (GL11) gl1;
- if (mGL != null) {
- // The GL Object has changed
- Log.i(TAG, "GLObject has changed from " + mGL + " to " + gl);
- }
- mRenderLock.lock();
- try {
- mGL = gl;
- mCanvas = ApiHelper.HAS_GLES20_REQUIRED ? new GLES20Canvas() : new GLES11Canvas(gl);
- BasicTexture.invalidateAllTextures();
- } finally {
- mRenderLock.unlock();
- }
-
- if (DEBUG_FPS || DEBUG_PROFILE) {
- setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
- } else {
- setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
- }
- }
-
- /**
- * Called when the OpenGL surface is recreated without destroying the
- * context.
- */
- // This is a GLSurfaceView.Renderer callback
- @Override
- public void onSurfaceChanged(GL10 gl1, int width, int height) {
- Log.i(TAG, "onSurfaceChanged: " + width + "x" + height
- + ", gl10: " + gl1.toString());
- Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
- GalleryUtils.setRenderThread();
- if (DEBUG_PROFILE) {
- Log.d(TAG, "Start profiling");
- Profile.enable(20); // take a sample every 20ms
- }
- GL11 gl = (GL11) gl1;
- Utils.assertTrue(mGL == gl);
-
- mCanvas.setSize(width, height);
- }
-
- private void outputFps() {
- long now = System.nanoTime();
- if (mFrameCountingStart == 0) {
- mFrameCountingStart = now;
- } else if ((now - mFrameCountingStart) > 1000000000) {
- Log.d(TAG, "fps: " + (double) mFrameCount
- * 1000000000 / (now - mFrameCountingStart));
- mFrameCountingStart = now;
- mFrameCount = 0;
- }
- ++mFrameCount;
- }
-
- @Override
- public void onDrawFrame(GL10 gl) {
- AnimationTime.update();
- long t0;
- if (DEBUG_PROFILE_SLOW_ONLY) {
- Profile.hold();
- t0 = System.nanoTime();
- }
- mRenderLock.lock();
-
- while (mFreeze) {
- mFreezeCondition.awaitUninterruptibly();
- }
-
- try {
- onDrawFrameLocked(gl);
- } finally {
- mRenderLock.unlock();
- }
-
- // We put a black cover View in front of the SurfaceView and hide it
- // after the first draw. This prevents the SurfaceView being transparent
- // before the first draw.
- if (mFirstDraw) {
- mFirstDraw = false;
- post(new Runnable() {
- @Override
- public void run() {
- View root = getRootView();
- View cover = root.findViewById(R.id.gl_root_cover);
- cover.setVisibility(GONE);
- }
- });
- }
-
- if (DEBUG_PROFILE_SLOW_ONLY) {
- long t = System.nanoTime();
- long durationInMs = (t - mLastDrawFinishTime) / 1000000;
- long durationDrawInMs = (t - t0) / 1000000;
- mLastDrawFinishTime = t;
-
- if (durationInMs > 34) { // 34ms -> we skipped at least 2 frames
- Log.v(TAG, "----- SLOW (" + durationDrawInMs + "/" +
- durationInMs + ") -----");
- Profile.commit();
- } else {
- Profile.drop();
- }
- }
- }
-
- private void onDrawFrameLocked(GL10 gl) {
- if (DEBUG_FPS) outputFps();
-
- // release the unbound textures and deleted buffers.
- mCanvas.deleteRecycledResources();
-
- // reset texture upload limit
- UploadedTexture.resetUploadLimit();
-
- mRenderRequested = false;
-
- if ((mOrientationSource != null
- && mDisplayRotation != mOrientationSource.getDisplayRotation())
- || (mFlags & FLAG_NEED_LAYOUT) != 0) {
- layoutContentPane();
- }
-
- mCanvas.save(GLCanvas.SAVE_FLAG_ALL);
- rotateCanvas(-mCompensation);
- if (mContentView != null) {
- mContentView.render(mCanvas);
- } else {
- // Make sure we always draw something to prevent displaying garbage
- mCanvas.clearBuffer();
- }
- mCanvas.restore();
-
- if (!mAnimations.isEmpty()) {
- long now = AnimationTime.get();
- for (int i = 0, n = mAnimations.size(); i < n; i++) {
- mAnimations.get(i).setStartTime(now);
- }
- mAnimations.clear();
- }
-
- if (UploadedTexture.uploadLimitReached()) {
- requestRender();
- }
-
- synchronized (mIdleListeners) {
- if (!mIdleListeners.isEmpty()) mIdleRunner.enable();
- }
-
- if (DEBUG_INVALIDATE) {
- mCanvas.fillRect(10, 10, 5, 5, mInvalidateColor);
- mInvalidateColor = ~mInvalidateColor;
- }
-
- if (DEBUG_DRAWING_STAT) {
- mCanvas.dumpStatisticsAndClear();
- }
- }
-
- private void rotateCanvas(int degrees) {
- if (degrees == 0) return;
- int w = getWidth();
- int h = getHeight();
- int cx = w / 2;
- int cy = h / 2;
- mCanvas.translate(cx, cy);
- mCanvas.rotate(degrees, 0, 0, 1);
- if (degrees % 180 != 0) {
- mCanvas.translate(-cy, -cx);
- } else {
- mCanvas.translate(-cx, -cy);
- }
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- if (!isEnabled()) return false;
-
- int action = event.getAction();
- if (action == MotionEvent.ACTION_CANCEL
- || action == MotionEvent.ACTION_UP) {
- mInDownState = false;
- } else if (!mInDownState && action != MotionEvent.ACTION_DOWN) {
- return false;
- }
-
- if (mCompensation != 0) {
- event = MotionEventHelper.transformEvent(event, mCompensationMatrix);
- }
-
- mRenderLock.lock();
- try {
- // If this has been detached from root, we don't need to handle event
- boolean handled = mContentView != null
- && mContentView.dispatchTouchEvent(event);
- if (action == MotionEvent.ACTION_DOWN && handled) {
- mInDownState = true;
- }
- return handled;
- } finally {
- mRenderLock.unlock();
- }
- }
-
- private class IdleRunner implements Runnable {
- // true if the idle runner is in the queue
- private boolean mActive = false;
-
- @Override
- public void run() {
- OnGLIdleListener listener;
- synchronized (mIdleListeners) {
- mActive = false;
- if (mIdleListeners.isEmpty()) return;
- listener = mIdleListeners.removeFirst();
- }
- mRenderLock.lock();
- boolean keepInQueue;
- try {
- keepInQueue = listener.onGLIdle(mCanvas, mRenderRequested);
- } finally {
- mRenderLock.unlock();
- }
- synchronized (mIdleListeners) {
- if (keepInQueue) mIdleListeners.addLast(listener);
- if (!mRenderRequested && !mIdleListeners.isEmpty()) enable();
- }
- }
-
- public void enable() {
- // Who gets the flag can add it to the queue
- if (mActive) return;
- mActive = true;
- queueEvent(this);
- }
- }
-
- @Override
- public void lockRenderThread() {
- mRenderLock.lock();
- }
-
- @Override
- public void unlockRenderThread() {
- mRenderLock.unlock();
- }
-
- @Override
- public void onPause() {
- unfreeze();
- super.onPause();
- if (DEBUG_PROFILE) {
- Log.d(TAG, "Stop profiling");
- Profile.disableAll();
- Profile.dumpToFile("/sdcard/gallery.prof");
- Profile.reset();
- }
- }
-
- @Override
- public void setOrientationSource(OrientationSource source) {
- mOrientationSource = source;
- }
-
- @Override
- public int getDisplayRotation() {
- return mDisplayRotation;
- }
-
- @Override
- public int getCompensation() {
- return mCompensation;
- }
-
- @Override
- public Matrix getCompensationMatrix() {
- return mCompensationMatrix;
- }
-
- @Override
- public void freeze() {
- mRenderLock.lock();
- mFreeze = true;
- mRenderLock.unlock();
- }
-
- @Override
- public void unfreeze() {
- mRenderLock.lock();
- mFreeze = false;
- mFreezeCondition.signalAll();
- mRenderLock.unlock();
- }
-
- @Override
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- public void setLightsOutMode(boolean enabled) {
- if (!ApiHelper.HAS_SET_SYSTEM_UI_VISIBILITY) return;
-
- int flags = 0;
- if (enabled) {
- flags = STATUS_BAR_HIDDEN;
- if (ApiHelper.HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE) {
- flags |= (SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_STABLE);
- }
- }
- setSystemUiVisibility(flags);
- }
-
- // We need to unfreeze in the following methods and in onPause().
- // These methods will wait on GLThread. If we have freezed the GLRootView,
- // the GLThread will wait on main thread to call unfreeze and cause dead
- // lock.
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
- unfreeze();
- super.surfaceChanged(holder, format, w, h);
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- unfreeze();
- super.surfaceCreated(holder);
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- unfreeze();
- super.surfaceDestroyed(holder);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- unfreeze();
- super.onDetachedFromWindow();
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- unfreeze();
- } finally {
- super.finalize();
- }
- }
-}