OSDN Git Service

More efficient drawing during animation
authorDoris Liu <tianliu@google.com>
Sat, 22 Mar 2014 01:33:57 +0000 (18:33 -0700)
committerDoris Liu <tianliu@google.com>
Mon, 24 Mar 2014 18:20:41 +0000 (11:20 -0700)
- Improved mode options animation and video capture animation

- Changed the drawPath() calls to drawCircle() as drawing oval is
generally optimized and therefore more efficient. The efficiency
gained depends on the hardware/software specific implementation,
depending on where it's rendered. But drawCircle() should always
no more costly than drawPath().

- Move the video capture button animation to after MediaRecorder
initialization/release to avoid animation being blocked by time
consuming operations.

Bug: 13589320
Change-Id: I9c01374e46d439e33a066cfba07d95749a3caebf

src/com/android/camera/VideoModule.java
src/com/android/camera/ui/BottomBar.java
src/com/android/camera/widget/ModeOptions.java

index 92f426c..285a6fc 100644 (file)
@@ -1224,11 +1224,6 @@ public class VideoModule extends CameraModule
         mUI.showFocusUI(false);
         mUI.showVideoRecordingHints(false);
 
-        // A special case of mode options closing: during capture it should
-        // not be possible to change mode state.
-        mAppController.getCameraAppUI().hideModeOptions();
-        mAppController.getCameraAppUI().animateBottomBarToVideoStop(R.drawable.ic_stop);
-
         mActivity.updateStorageSpaceAndHint();
         if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
             Log.v(TAG, "Storage issue, ignore the start request");
@@ -1275,6 +1270,11 @@ public class VideoModule extends CameraModule
         mMediaRecorderRecording = true;
         mActivity.lockOrientation();
         mRecordingStartTime = SystemClock.uptimeMillis();
+
+        // A special case of mode options closing: during capture it should
+        // not be possible to change mode state.
+        mAppController.getCameraAppUI().hideModeOptions();
+        mAppController.getCameraAppUI().animateBottomBarToVideoStop(R.drawable.ic_stop);
         mUI.showRecordingUI(true);
 
         setFocusParameters();
@@ -1322,9 +1322,6 @@ public class VideoModule extends CameraModule
         mUI.showFocusUI(true);
         mUI.showVideoRecordingHints(true);
 
-        mAppController.getCameraAppUI().showModeOptions();
-        mAppController.getCameraAppUI().animateBottomBarToFullSize(mShutterIconId);
-
         boolean fail = false;
         if (mMediaRecorderRecording) {
             boolean shouldAddToMediaStoreNow = false;
@@ -1379,6 +1376,9 @@ public class VideoModule extends CameraModule
         }
         // release media recorder
         releaseMediaRecorder();
+
+        mAppController.getCameraAppUI().showModeOptions();
+        mAppController.getCameraAppUI().animateBottomBarToFullSize(mShutterIconId);
         if (!mPaused) {
             setFocusParameters();
             mCameraDevice.lock();
index 77a22e4..ebbf743 100644 (file)
@@ -22,7 +22,6 @@ import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.graphics.Path;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.TransitionDrawable;
@@ -107,11 +106,13 @@ public class BottomBar extends FrameLayout
     private int mBackgroundPressedColor;
     private int mBackgroundAlpha = 0xff;
 
-    private final Paint mCirclePaint = new Paint();
-    private final Path mCirclePath = new Path();
     private boolean mDrawCircle;
     private final float mCircleRadius;
-    private final Path mRectPath = new Path();
+    private float mCurrentCircleRadius;
+    private int mCircleColor;
+    private final Paint mCirclePaint= new Paint();
+    private float mCenterX;
+    private float mCenterY;
 
     private final RectF mRect = new RectF();
 
@@ -129,15 +130,14 @@ public class BottomBar extends FrameLayout
         mOptimalHeight = getResources().getDimensionPixelSize(R.dimen.bottom_bar_height_optimal);
         mCircleRadius = getResources()
             .getDimensionPixelSize(R.dimen.video_capture_circle_diameter) / 2;
-        mCirclePaint.setAntiAlias(true);
         mBackgroundAlphaOverlay = getResources().getInteger(R.integer.bottom_bar_background_alpha_overlay);
         mBackgroundAlphaDefault = getResources().getInteger(R.integer
                 .bottom_bar_background_alpha);
     }
 
     private void setPaintColor(int alpha, int color, boolean isCaptureChange) {
-        int computedColor = (alpha << 24) | (color & 0x00ffffff);
-        mCirclePaint.setColor(computedColor);
+        mCircleColor = (alpha << 24) | (color & 0x00ffffff);
+        mCirclePaint.setColor(mCircleColor);
         invalidate();
     }
 
@@ -356,28 +356,9 @@ public class BottomBar extends FrameLayout
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
-
         notifyAreaAdjust();
-
-        final int width = getWidth();
-        final int height = getHeight();
-
-        if (changed) {
-            mCirclePath.reset();
-            mCirclePath.addCircle(
-                width/2,
-                height/2,
-                (int)(diagonalLength(width, height)/2),
-                Path.Direction.CW);
-
-            mRect.set(
-                0.0f,
-                0.0f,
-                width,
-                height);
-            mRectPath.reset();
-            mRectPath.addRect(mRect, Path.Direction.CW);
-        }
+        mCenterX = (right - left) / 2;
+        mCenterY = (bottom - top) / 2;
     }
 
     @Override
@@ -413,9 +394,9 @@ public class BottomBar extends FrameLayout
         switch (mMode) {
             case MODE_CAPTURE:
                 if (mDrawCircle) {
-                    canvas.drawPath(mCirclePath, mCirclePaint);
+                    canvas.drawCircle(mCenterX, mCenterY, mCurrentCircleRadius, mCirclePaint);
                 } else {
-                    canvas.drawPath(mRectPath, mCirclePaint);
+                    canvas.drawColor(mCircleColor);
                 }
                 break;
             case MODE_INTENT:
@@ -493,12 +474,7 @@ public class BottomBar extends FrameLayout
             radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
-                    mCirclePath.reset();
-                    mCirclePath.addCircle(
-                            getWidth()/2,
-                            getHeight()/2,
-                            (Float) animation.getAnimatedValue(),
-                            Path.Direction.CW);
+                    mCurrentCircleRadius = (Float) animation.getAnimatedValue();
                     invalidate();
                 }
             });
@@ -518,19 +494,15 @@ public class BottomBar extends FrameLayout
      */
     public void animateToFullSize(int resId) {
         if (mDrawCircle) {
+            final float endRadius = (float) diagonalLength()/2;
             final ValueAnimator radiusAnimator =
-                ValueAnimator.ofFloat(mCircleRadius, (float) diagonalLength()/2);
+                ValueAnimator.ofFloat(mCircleRadius, endRadius);
             radiusAnimator.setDuration(CIRCLE_ANIM_DURATION_MS);
             radiusAnimator.setInterpolator(Gusterpolator.INSTANCE);
             radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
-                    mCirclePath.reset();
-                    mCirclePath.addCircle(
-                            getWidth()/2,
-                            getHeight()/2,
-                            (Float) animation.getAnimatedValue(),
-                            Path.Direction.CW);
+                    mCurrentCircleRadius = (Float) animation.getAnimatedValue();
                     invalidate();
                 }
             });
@@ -538,7 +510,8 @@ public class BottomBar extends FrameLayout
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     mDrawCircle = false;
-                }
+                    mCurrentCircleRadius = endRadius;
+               }
             });
             radiusAnimator.start();
         }
index eb2a200..575834c 100644 (file)
@@ -42,7 +42,6 @@ import java.util.ArrayList;
 public class ModeOptions extends FrameLayout {
     private int mBackgroundColor;
     private final Paint mPaint = new Paint();
-    private final Path mPath = new Path();
     private boolean mIsHiddenOrHiding;
     private RectF mAnimateFrom = new RectF();
     private View mViewToShowHide;
@@ -59,6 +58,7 @@ public class ModeOptions extends FrameLayout {
 
     private int mParentSize;
     private boolean mIsPortrait;
+    private float mRadius = 0f;
 
     public ModeOptions(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -131,7 +131,7 @@ public class ModeOptions extends FrameLayout {
     @Override
     public void onDraw(Canvas canvas) {
         if (mDrawCircle) {
-            canvas.drawPath(mPath, mPaint);
+            canvas.drawCircle(mAnimateFrom.centerX(), mAnimateFrom.centerY(), mRadius, mPaint);
         } else if (mFill) {
             canvas.drawPaint(mPaint);
         }
@@ -157,11 +157,7 @@ public class ModeOptions extends FrameLayout {
             radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
-                    mPath.reset();
-                    mPath.addCircle(mAnimateFrom.centerX(),
-                        mAnimateFrom.centerY(),
-                        (Float) animation.getAnimatedValue(),
-                        Path.Direction.CW);
+                    mRadius = (Float) animation.getAnimatedValue();
                     mDrawCircle = true;
                     mFill = false;
                 }
@@ -169,7 +165,6 @@ public class ModeOptions extends FrameLayout {
             radiusAnimator.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
-                    mPath.reset();
                     mDrawCircle = false;
                     mFill = true;
                 }
@@ -238,11 +233,7 @@ public class ModeOptions extends FrameLayout {
             radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
-                    mPath.reset();
-                    mPath.addCircle(mAnimateFrom.centerX(),
-                        mAnimateFrom.centerY(),
-                        (Float) animation.getAnimatedValue(),
-                        Path.Direction.CW);
+                    mRadius = (Float) animation.getAnimatedValue();
                     mDrawCircle = true;
                     mFill = false;
                     invalidate();
@@ -252,7 +243,6 @@ public class ModeOptions extends FrameLayout {
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     if (mViewToShowHide != null) {
-                        mPath.reset();
                         mViewToShowHide.setVisibility(View.VISIBLE);
                         mDrawCircle = false;
                         mFill = false;