summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wren <cwren@android.com>2013-04-12 06:29:51 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2013-04-12 06:29:51 -0700
commit64cc0094372b6687fc18a023e6abe44a026435b8 (patch)
tree804c6705025d4b1b08fe42a1bf5df9b5bc6e4b50
parent70cd23da385cb820554b16a48fa9e5b10ec65db6 (diff)
parentee47f2fe85688eeb7fa7a90f9c13340635302358 (diff)
downloadandroid_packages_screensavers_PhotoTable-64cc0094372b6687fc18a023e6abe44a026435b8.tar.gz
android_packages_screensavers_PhotoTable-64cc0094372b6687fc18a023e6abe44a026435b8.tar.bz2
android_packages_screensavers_PhotoTable-64cc0094372b6687fc18a023e6abe44a026435b8.zip
am ee47f2fe: am f362b8f1: graphics optimization to get back inside 60Hz.
* commit 'ee47f2fe85688eeb7fa7a90f9c13340635302358': graphics optimization to get back inside 60Hz.
-rw-r--r--res/layout-sw800dp/table.xml17
-rw-r--r--res/layout/table.xml27
-rw-r--r--res/values-land-notouch/config.xml10
-rw-r--r--res/values-sw800dp/config.xml5
-rw-r--r--res/values/config.xml4
-rw-r--r--src/com/android/dreams/phototable/PhotoTable.java173
6 files changed, 162 insertions, 74 deletions
diff --git a/res/layout-sw800dp/table.xml b/res/layout-sw800dp/table.xml
index 0b67524..e063cd5 100644
--- a/res/layout-sw800dp/table.xml
+++ b/res/layout-sw800dp/table.xml
@@ -21,7 +21,22 @@
android:background="@+drawable/table"
android:id="@+id/table"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent" >
+
+ <FrameLayout
+ android:id="@+id/stageleft"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
+ <FrameLayout
+ android:id="@+id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layerType="hardware"
+ />
+
+ </com.android.dreams.phototable.PhotoTable>
<!-- View
android:background="@+drawable/vignette_br"
android:layout_gravity="bottom|right"
diff --git a/res/layout/table.xml b/res/layout/table.xml
index b1575b7..7cdb51a 100644
--- a/res/layout/table.xml
+++ b/res/layout/table.xml
@@ -18,13 +18,28 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
>
+
<com.android.dreams.phototable.PhotoTable
- android:background="@+drawable/table"
- android:id="@+id/table"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:focusable="true"
- />
+ android:id="@+id/table"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@+drawable/table"
+ android:focusable="true" >
+
+ <FrameLayout
+ android:id="@+id/stageleft"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
+ <FrameLayout
+ android:id="@+id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layerType="hardware"
+ />
+
+ </com.android.dreams.phototable.PhotoTable>
<!-- View
android:background="@+drawable/vignette_br"
android:layout_gravity="bottom|right"
diff --git a/res/values-land-notouch/config.xml b/res/values-land-notouch/config.xml
index c9d537f..d125dd1 100644
--- a/res/values-land-notouch/config.xml
+++ b/res/values-land-notouch/config.xml
@@ -16,9 +16,15 @@
<resources>
<!-- Maximum number of photos to leave on the table. -->
- <integer name="table_capacity">8</integer>
+ <integer name="table_capacity">6</integer>
<!-- Number of images to discard at a time. -->
- <integer name="redeal_count">4</integer>
+ <integer name="redeal_count">2</integer>
+
+ <!-- Parts per million ratio between image size on the table and screen size. -->
+ <integer name="table_ratio">333333</integer>
+
+ <!-- Duration in milliseconds for the pickup animation. -->
+ <integer name="photo_pickup_duration">1500</integer>
</resources> \ No newline at end of file
diff --git a/res/values-sw800dp/config.xml b/res/values-sw800dp/config.xml
index 699e15a..ec6a85f 100644
--- a/res/values-sw800dp/config.xml
+++ b/res/values-sw800dp/config.xml
@@ -20,7 +20,8 @@
<!-- Milliseconds to wait before the next fast drop.-->
<integer name="fast_drop">5000</integer>
- <!-- Parts per million ratio between image size and screen size. -->
- <integer name="image_ratio">500000</integer>
+ <!-- Duration in milliseconds for the pickup animation. -->
+ <integer name="photo_pickup_duration">1500</integer>
+
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 84299b1..c3a6e65 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -100,8 +100,8 @@
<!-- Enable story mode. -->
<bool name="enable_story_mode">true</bool>
- <!-- Duration ion milliseconds for the pickup animation. -->
- <integer name="photo_pickup_duration">2000</integer>
+ <!-- Duration in milliseconds for the pickup animation. -->
+ <integer name="photo_pickup_duration">1000</integer>
<!-- Milliseconds that the selection will remain without user interaction. -->
<integer name="max_selection_time">30000</integer>
diff --git a/src/com/android/dreams/phototable/PhotoTable.java b/src/com/android/dreams/phototable/PhotoTable.java
index 7f4f61a..7e7f92e 100644
--- a/src/com/android/dreams/phototable/PhotoTable.java
+++ b/src/com/android/dreams/phototable/PhotoTable.java
@@ -15,9 +15,6 @@
*/
package com.android.dreams.phototable;
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -36,17 +33,20 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
-import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import java.util.ArrayList;
import java.util.Formatter;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
+import java.util.Set;
/**
* A surface where photos sit.
@@ -97,7 +97,7 @@ public class PhotoTable extends FrameLayout {
private final int mTableCapacity;
private final int mRedealCount;
private final int mInset;
- private final PhotoSourcePlexor mPhotoSource;
+ private final PhotoSource mPhotoSource;
private final Resources mResources;
private final Interpolator mThrowInterpolator;
private final Interpolator mDropInterpolator;
@@ -108,6 +108,7 @@ public class PhotoTable extends FrameLayout {
private final long mPickUpDuration;
private final int mMaxSelectionTime;
private final int mMaxFocusTime;
+ private final List<View> mAnimating;
private DreamService mDream;
private PhotoLaunchTask mPhotoLaunchTask;
@@ -122,6 +123,8 @@ public class PhotoTable extends FrameLayout {
private View mOnDeck[];
private View mFocus;
private int mHighlightColor;
+ private ViewGroup mBackground;
+ private ViewGroup mStageLeft;
public PhotoTable(Context context, AttributeSet as) {
super(context, as);
@@ -151,6 +154,7 @@ public class PhotoTable extends FrameLayout {
mOnTable = new LinkedList<View>();
mPhotoSource = new PhotoSourcePlexor(getContext(),
getContext().getSharedPreferences(PhotoTableDreamSettings.PREFS_NAME, 0));
+ mAnimating = new ArrayList<View>();
mLauncher = new Launcher();
mFocusReaper = new FocusReaper();
mSelectionReaper = new SelectionReaper();
@@ -162,6 +166,11 @@ public class PhotoTable extends FrameLayout {
mStarted = false;
}
+ @Override
+ public void onFinishInflate() {
+ mBackground = (ViewGroup) findViewById(R.id.background);
+ mStageLeft = (ViewGroup) findViewById(R.id.stageleft);
+ }
public void setDream(DreamService dream) {
mDream = dream;
@@ -180,7 +189,7 @@ public class PhotoTable extends FrameLayout {
dropOnTable(mSelection);
mPhotoSource.donePaging(getBitmap(mSelection));
if (mStoryModeEnabled) {
- fadeInExcept(mSelection);
+ fadeInBackground(mSelection);
}
mSelection = null;
}
@@ -203,7 +212,7 @@ public class PhotoTable extends FrameLayout {
mSelection = selected;
promoteSelection();
if (mStoryModeEnabled) {
- fadeOutExcept(mSelection);
+ fadeOutBackground(mSelection);
}
}
}
@@ -443,7 +452,7 @@ public class PhotoTable extends FrameLayout {
/** Put a nice border on the bitmap. */
private static View applyFrame(final PhotoTable table, final BitmapFactory.Options options,
- final Bitmap decodedPhoto) {
+ Bitmap decodedPhoto) {
LayoutInflater inflater = (LayoutInflater) table.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View photo = inflater.inflate(R.layout.photo, null);
@@ -593,47 +602,38 @@ public class PhotoTable extends FrameLayout {
}
/** De-emphasize the other photos on the table. */
- public void fadeOutExcept(final View photo) {
- List<Animator> animations = new LinkedList<Animator>();
- for (View background: mOnTable) {
- if (background != photo) {
- // fade out to transparent.
- background.animate().cancel();
- animations.add(ObjectAnimator.ofFloat(background, "alpha", 0f));
- }
- }
- if (animations.size() > 0) {
- AnimatorSet set = new AnimatorSet();
- set.playTogether(animations);
- set.setDuration(mPickUpDuration);
- set.start();
- }
+ public void fadeOutBackground(final View photo) {
+ mBackground.animate()
+ .withLayer()
+ .setDuration(mPickUpDuration)
+ .alpha(0f);
}
/** Return the other photos to foreground status. */
- public void fadeInExcept(final View photo) {
- List<Animator> animations = new LinkedList<Animator>();
- for (View background: mOnTable) {
- if (background != photo) {
- // fade back to full opacity.
- background.animate().cancel();
- animations.add(ObjectAnimator.ofFloat(background, "alpha", 1f));
+ public void fadeInBackground(final View photo) {
+ mAnimating.add(photo);
+ mBackground.animate()
+ .withLayer()
+ .setDuration(mPickUpDuration)
+ .alpha(1f)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mAnimating.remove(photo);
+ if (!mAnimating.contains(photo)) {
+ moveToBackground(photo);
+ }
}
- }
- if (animations.size() > 0) {
- AnimatorSet set = new AnimatorSet();
- set.playTogether(animations);
- set.setDuration(mPickUpDuration);
- set.start();
- }
+ });
}
-
/** Dispose of the photo gracefully, in case we can see some of it. */
public void fadeAway(final View photo, final boolean replace) {
// fade out of view
mOnTable.remove(photo);
+ exitStageLeft(photo);
+ photo.setOnTouchListener(null);
photo.animate().cancel();
photo.animate()
.withLayer()
@@ -645,6 +645,7 @@ public class PhotoTable extends FrameLayout {
if (photo == getFocus()) {
clearFocus();
}
+ mStageLeft.removeView(photo);
recycle(photo);
if (replace) {
scheduleNext(mNowDropDelay);
@@ -656,7 +657,11 @@ public class PhotoTable extends FrameLayout {
/** Visually on top, and also freshest, for the purposes of timeouts. */
public void moveToTopOfPile(View photo) {
// make this photo the last to be removed.
- bringChildToFront(photo);
+ if (isInBackground(photo)) {
+ mBackground.bringChildToFront(photo);
+ } else {
+ bringChildToFront(photo);
+ }
invalidate();
mOnTable.remove(photo);
mOnTable.offer(photo);
@@ -680,6 +685,7 @@ public class PhotoTable extends FrameLayout {
x += (slot == NEXT? 1f : -1f) * offset;
photo.animate()
+ .withLayer()
.rotation(0f)
.rotationY(0f)
.scaleX(scale)
@@ -752,7 +758,9 @@ public class PhotoTable extends FrameLayout {
moveFocus(photo, 180f);
}
}
+ moveToForeground(photo);
ViewPropertyAnimator animator = photo.animate()
+ .withLayer()
.xBy(dx)
.yBy(dy)
.setDuration(duration)
@@ -816,14 +824,55 @@ public class PhotoTable extends FrameLayout {
log("animate it");
// toss onto table
+ mAnimating.add(photo);
photo.animate()
- .scaleX(mTableRatio / mImageRatio)
- .scaleY(mTableRatio / mImageRatio)
- .rotation(angle)
- .x(x)
- .y(y)
- .setDuration(duration)
- .setInterpolator(interpolator);
+ .withLayer()
+ .scaleX(mTableRatio / mImageRatio)
+ .scaleY(mTableRatio / mImageRatio)
+ .rotation(angle)
+ .x(x)
+ .y(y)
+ .setDuration(duration)
+ .setInterpolator(interpolator)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mAnimating.remove(photo);
+ if (!mAnimating.contains(photo)) {
+ moveToBackground(photo);
+ }
+ }
+ });
+ }
+
+ private void moveToBackground(View photo) {
+ if (!isInBackground(photo)) {
+ removeView(photo);
+ mBackground.addView(photo, new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT));
+ }
+ }
+
+ private void exitStageLeft(View photo) {
+ if (isInBackground(photo)) {
+ mBackground.removeView(photo);
+ } else {
+ removeView(photo);
+ }
+ mStageLeft.addView(photo, new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT));
+ }
+
+ private void moveToForeground(View photo) {
+ if (isInBackground(photo)) {
+ mBackground.removeView(photo);
+ addView(photo, new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT));
+ }
+ }
+
+ private boolean isInBackground(View photo) {
+ return mBackground.indexOfChild(photo) != -1;
}
/** wrap all orientations to the interval [-180, 180). */
@@ -850,22 +899,24 @@ public class PhotoTable extends FrameLayout {
log("animate it");
// lift up to the glass for a good look
+ moveToForeground(photo);
photo.animate()
- .rotation(0f)
- .rotationY(0f)
- .alpha(1f)
- .scaleX(scale)
- .scaleY(scale)
- .x(x)
- .y(y)
- .setDuration(mPickUpDuration)
- .setInterpolator(new DecelerateInterpolator(2f))
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- log("endtimes: %f", photo.getX());
- }
- });
+ .withLayer()
+ .rotation(0f)
+ .rotationY(0f)
+ .alpha(1f)
+ .scaleX(scale)
+ .scaleY(scale)
+ .x(x)
+ .y(y)
+ .setDuration(mPickUpDuration)
+ .setInterpolator(new DecelerateInterpolator(2f))
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ log("endtimes: %f", photo.getX());
+ }
+ });
}
private Bitmap getBitmap(View photo) {