diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index e2aafa93eaa10..33631b774d9b6 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -16,6 +16,8 @@
package android.view;
+import android.graphics.Matrix;
+
/**
* A display lists records a series of graphics related operation and can replay
* them later. Display lists are usually built by recording operations on a
@@ -117,12 +119,26 @@ public abstract class DisplayList {
public abstract void setClipChildren(boolean clipChildren);
/**
- * Set the application scale on the DisplayList. This scale is incurred by applications that
- * are auto-scaled for compatibility reasons. By default, the value is 1 (unscaled).
+ * Set the static matrix on the DisplayList. This matrix exists if a custom ViewGroup
+ * overrides
+ * {@link ViewGroup#getChildStaticTransformation(View, android.view.animation.Transformation)}
+ * and also has {@link ViewGroup#setStaticTransformationsEnabled(boolean)} set to true.
+ * This matrix will be concatenated with any other matrices in the DisplayList to position
+ * the view appropriately.
*
- * @param scale The scaling factor
+ * @param matrix The matrix
*/
- public abstract void setApplicationScale(float scale);
+ public abstract void setStaticMatrix(Matrix matrix);
+
+ /**
+ * Set the Animation matrix on the DisplayList. This matrix exists if an Animation is
+ * currently playing on a View, and is set on the DisplayList during at draw() time. When
+ * the Animation finishes, the matrix should be cleared by sending null
+ * for the matrix parameter.
+ *
+ * @param matrix The matrix, null indicates that the matrix should be cleared.
+ */
+ public abstract void setAnimationMatrix(Matrix matrix);
/**
* Sets the alpha value for the DisplayList
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index 9b4cf216fdea8..bc3bce0cfdafd 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -17,6 +17,7 @@
package android.view;
import android.graphics.Bitmap;
+import android.graphics.Matrix;
import java.util.ArrayList;
@@ -119,9 +120,18 @@ class GLES20DisplayList extends DisplayList {
}
@Override
- public void setApplicationScale(float scale) {
+ public void setStaticMatrix(Matrix matrix) {
try {
- nSetApplicationScale(getNativeDisplayList(), scale);
+ nSetStaticMatrix(getNativeDisplayList(), matrix.native_instance);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setAnimationMatrix(Matrix matrix) {
+ try {
+ nSetAnimationMatrix(getNativeDisplayList(), matrix.native_instance);
} catch (IllegalStateException e) {
// invalid DisplayList okay: we'll set current values the next time we render to it
}
@@ -335,6 +345,8 @@ class GLES20DisplayList extends DisplayList {
private static native void nSetTransformationInfo(int displayList, float alpha,
float translationX, float translationY, float rotation, float rotationX,
float rotationY, float scaleX, float scaleY);
+ private static native void nSetStaticMatrix(int displayList, int nativeMatrix);
+ private static native void nSetAnimationMatrix(int displayList, int animationMatrix);
///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 99743e4c84995..d72253b098b60 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -11529,12 +11529,34 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
displayList.setClipChildren(
(((ViewGroup)mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
}
- if (mAttachInfo != null && mAttachInfo.mScalingRequired &&
- mAttachInfo.mApplicationScale != 1.0f) {
- displayList.setApplicationScale(1f / mAttachInfo.mApplicationScale);
+ float alpha = 1;
+ if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
+ ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
+ ViewGroup parentVG = (ViewGroup) mParent;
+ final boolean hasTransform =
+ parentVG.getChildStaticTransformation(this, parentVG.mChildTransformation);
+ if (hasTransform) {
+ Transformation transform = parentVG.mChildTransformation;
+ final int transformType = parentVG.mChildTransformation.getTransformationType();
+ if (transformType != Transformation.TYPE_IDENTITY) {
+ if ((transformType & Transformation.TYPE_ALPHA) != 0) {
+ alpha = transform.getAlpha();
+ }
+ if ((transformType & Transformation.TYPE_MATRIX) != 0) {
+ displayList.setStaticMatrix(transform.getMatrix());
+ }
+ }
+ }
}
if (mTransformationInfo != null) {
- displayList.setTransformationInfo(mTransformationInfo.mAlpha,
+ alpha *= mTransformationInfo.mAlpha;
+ if (alpha < 1) {
+ final int multipliedAlpha = (int) (255 * alpha);
+ if (onSetAlpha(multipliedAlpha)) {
+ alpha = 1;
+ }
+ }
+ displayList.setTransformationInfo(alpha,
mTransformationInfo.mTranslationX, mTransformationInfo.mTranslationY,
mTransformationInfo.mRotation, mTransformationInfo.mRotationX,
mTransformationInfo.mRotationY, mTransformationInfo.mScaleX,
@@ -11548,6 +11570,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
displayList.setPivotX(getPivotX());
displayList.setPivotY(getPivotY());
}
+ } else if (alpha < 1) {
+ displayList.setAlpha(alpha);
}
}
}
@@ -11580,6 +11604,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if ((flags & ViewGroup.FLAG_CHILDREN_DRAWN_WITH_CACHE) != 0 ||
(flags & ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE) != 0) {
caching = true;
+ // Auto-scaled apps are not hw-accelerated, no need to set scaling flag on DisplayList
if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
} else {
caching = (layerType != LAYER_TYPE_NONE) || hardwareAccelerated;
@@ -11590,7 +11615,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
more = drawAnimation(parent, drawingTime, a, scalingRequired);
concatMatrix = a.willChangeTransformationMatrix();
transformToApply = parent.mChildTransformation;
- } else if ((flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
+ } else if (!useDisplayListProperties &&
+ (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
final boolean hasTransform =
parent.getChildStaticTransformation(this, parent.mChildTransformation);
if (hasTransform) {
@@ -11658,6 +11684,17 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
}
useDisplayListProperties &= hasDisplayList;
+ if (useDisplayListProperties) {
+ displayList = getDisplayList();
+ if (!displayList.isValid()) {
+ // Uncommon, but possible. If a view is removed from the hierarchy during the call
+ // to getDisplayList(), the display list will be marked invalid and we should not
+ // try to use it again.
+ displayList = null;
+ hasDisplayList = false;
+ useDisplayListProperties = false;
+ }
+ }
final boolean hasNoCache = cache == null || hasDisplayList;
final boolean offsetForScroll = cache == null && !hasDisplayList &&
@@ -11675,6 +11712,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
if (scalingRequired) {
if (useDisplayListProperties) {
+ // TODO: Might not need this if we put everything inside the DL
restoreTo = canvas.save();
}
// mAttachInfo cannot be null, otherwise scalingRequired == false
@@ -11684,7 +11722,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
float alpha = useDisplayListProperties ? 1 : getAlpha();
- if (transformToApply != null || alpha < 1.0f || !hasIdentityMatrix()) {
+ if (transformToApply != null || alpha < 1 || !hasIdentityMatrix()) {
if (transformToApply != null || !childHasIdentityMatrix) {
int transX = 0;
int transY = 0;
@@ -11696,16 +11734,20 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (transformToApply != null) {
if (concatMatrix) {
- // Undo the scroll translation, apply the transformation matrix,
- // then redo the scroll translate to get the correct result.
- canvas.translate(-transX, -transY);
- canvas.concat(transformToApply.getMatrix());
- canvas.translate(transX, transY);
+ if (useDisplayListProperties) {
+ displayList.setAnimationMatrix(transformToApply.getMatrix());
+ } else {
+ // Undo the scroll translation, apply the transformation matrix,
+ // then redo the scroll translate to get the correct result.
+ canvas.translate(-transX, -transY);
+ canvas.concat(transformToApply.getMatrix());
+ canvas.translate(transX, transY);
+ }
parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
}
float transformAlpha = transformToApply.getAlpha();
- if (transformAlpha < 1.0f) {
+ if (transformAlpha < 1) {
alpha *= transformToApply.getAlpha();
parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
}
@@ -11718,7 +11760,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
}
- if (alpha < 1.0f) {
+ if (alpha < 1) {
parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
if (hasNoCache) {
final int multipliedAlpha = (int) (255 * alpha);
@@ -11728,7 +11770,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
layerType != LAYER_TYPE_NONE) {
layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
}
- if (layerType == LAYER_TYPE_NONE) {
+ if (useDisplayListProperties) {
+ displayList.setAlpha(alpha * getAlpha());
+ } else if (layerType == LAYER_TYPE_NONE) {
final int scrollX = hasDisplayList ? 0 : sx;
final int scrollY = hasDisplayList ? 0 : sy;
canvas.saveLayerAlpha(scrollX, scrollY, scrollX + mRight - mLeft,
@@ -11758,7 +11802,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
}
- if (hasDisplayList) {
+ if (!useDisplayListProperties && hasDisplayList) {
displayList = getDisplayList();
if (!displayList.isValid()) {
// Uncommon, but possible. If a view is removed from the hierarchy during the call
@@ -11815,7 +11859,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
cachePaint.setDither(false);
parent.mCachePaint = cachePaint;
}
- if (alpha < 1.0f) {
+ if (alpha < 1) {
cachePaint.setAlpha((int) (alpha * 255));
parent.mGroupFlags |= ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE;
} else if ((flags & ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE) != 0) {
diff --git a/core/jni/android_view_GLES20DisplayList.cpp b/core/jni/android_view_GLES20DisplayList.cpp
index 407c1967e4da1..60fb6d45d5fab 100644
--- a/core/jni/android_view_GLES20DisplayList.cpp
+++ b/core/jni/android_view_GLES20DisplayList.cpp
@@ -45,9 +45,14 @@ static void android_view_GLES20DisplayList_setCaching(JNIEnv* env,
displayList->setCaching(caching);
}
-static void android_view_GLES20DisplayList_setApplicationScale(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float scale) {
- displayList->setApplicationScale(scale);
+static void android_view_GLES20DisplayList_setStaticMatrix(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
+ displayList->setStaticMatrix(matrix);
+}
+
+static void android_view_GLES20DisplayList_setAnimationMatrix(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
+ displayList->setAnimationMatrix(matrix);
}
static void android_view_GLES20DisplayList_setClipChildren(JNIEnv* env,
@@ -175,33 +180,32 @@ const char* const kClassPathName = "android/view/GLES20DisplayList";
static JNINativeMethod gMethods[] = {
#ifdef USE_OPENGL_RENDERER
- { "nSetCaching", "(IZ)V", (void*) android_view_GLES20DisplayList_setCaching },
- { "nSetApplicationScale", "(IF)V",
- (void*) android_view_GLES20DisplayList_setApplicationScale },
- { "nSetClipChildren", "(IZ)V", (void*) android_view_GLES20DisplayList_setClipChildren },
- { "nSetAlpha", "(IF)V", (void*) android_view_GLES20DisplayList_setAlpha },
- { "nSetTranslationX", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationX },
- { "nSetTranslationY", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationY },
- { "nSetRotation", "(IF)V", (void*) android_view_GLES20DisplayList_setRotation },
- { "nSetRotationX", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationX },
- { "nSetRotationY", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationY },
- { "nSetScaleX", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleX },
- { "nSetScaleY", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleY },
- { "nSetTransformationInfo", "(IFFFFFFFF)V",
+ { "nSetCaching", "(IZ)V", (void*) android_view_GLES20DisplayList_setCaching },
+ { "nSetStaticMatrix", "(II)V", (void*) android_view_GLES20DisplayList_setStaticMatrix },
+ { "nSetAnimationMatrix", "(II)V", (void*) android_view_GLES20DisplayList_setAnimationMatrix },
+ { "nSetClipChildren", "(IZ)V", (void*) android_view_GLES20DisplayList_setClipChildren },
+ { "nSetAlpha", "(IF)V", (void*) android_view_GLES20DisplayList_setAlpha },
+ { "nSetTranslationX", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationX },
+ { "nSetTranslationY", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationY },
+ { "nSetRotation", "(IF)V", (void*) android_view_GLES20DisplayList_setRotation },
+ { "nSetRotationX", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationX },
+ { "nSetRotationY", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationY },
+ { "nSetScaleX", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleX },
+ { "nSetScaleY", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleY },
+ { "nSetTransformationInfo","(IFFFFFFFF)V",
(void*) android_view_GLES20DisplayList_setTransformationInfo },
- { "nSetPivotX", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotX },
- { "nSetPivotY", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotY },
- { "nSetCameraDistance", "(IF)V",
- (void*) android_view_GLES20DisplayList_setCameraDistance },
- { "nSetLeft", "(II)V", (void*) android_view_GLES20DisplayList_setLeft },
- { "nSetTop", "(II)V", (void*) android_view_GLES20DisplayList_setTop },
- { "nSetRight", "(II)V", (void*) android_view_GLES20DisplayList_setRight },
- { "nSetBottom", "(II)V", (void*) android_view_GLES20DisplayList_setBottom },
- { "nSetLeftTop", "(III)V", (void*) android_view_GLES20DisplayList_setLeftTop },
- { "nSetLeftTopRightBottom", "(IIIII)V",
+ { "nSetPivotX", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotX },
+ { "nSetPivotY", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotY },
+ { "nSetCameraDistance", "(IF)V", (void*) android_view_GLES20DisplayList_setCameraDistance },
+ { "nSetLeft", "(II)V", (void*) android_view_GLES20DisplayList_setLeft },
+ { "nSetTop", "(II)V", (void*) android_view_GLES20DisplayList_setTop },
+ { "nSetRight", "(II)V", (void*) android_view_GLES20DisplayList_setRight },
+ { "nSetBottom", "(II)V", (void*) android_view_GLES20DisplayList_setBottom },
+ { "nSetLeftTop", "(III)V", (void*) android_view_GLES20DisplayList_setLeftTop },
+ { "nSetLeftTopRightBottom","(IIIII)V",
(void*) android_view_GLES20DisplayList_setLeftTopRightBottom },
- { "nOffsetLeftRight", "(II)V", (void*) android_view_GLES20DisplayList_offsetLeftRight },
- { "nOffsetTopBottom", "(II)V", (void*) android_view_GLES20DisplayList_offsetTopBottom },
+ { "nOffsetLeftRight", "(II)V", (void*) android_view_GLES20DisplayList_offsetLeftRight },
+ { "nOffsetTopBottom", "(II)V", (void*) android_view_GLES20DisplayList_offsetTopBottom },
#endif
};
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 3a3f8a586c67f..f37bfd2f9c12b 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -94,7 +94,8 @@ void DisplayList::outputLogBuffer(int fd) {
}
DisplayList::DisplayList(const DisplayListRenderer& recorder) :
- mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL) {
+ mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
+ mStaticMatrix(NULL), mAnimationMatrix(NULL) {
initFromDisplayListRenderer(recorder);
}
@@ -108,7 +109,6 @@ void DisplayList::initProperties() {
mTop = 0;
mRight = 0;
mBottom = 0;
- mApplicationScale = -1;
mClipChildren = true;
mAlpha = 1;
mMultipliedAlpha = 255;
@@ -143,18 +143,16 @@ void DisplayList::clearResources() {
sk_free((void*) mReader.base());
if (USE_DISPLAY_LIST_PROPERTIES) {
- if (mTransformMatrix) {
- delete mTransformMatrix;
- mTransformMatrix = NULL;
- }
- if (mTransformCamera) {
- delete mTransformCamera;
- mTransformCamera = NULL;
- }
- if (mTransformMatrix3D) {
- delete mTransformMatrix3D;
- mTransformMatrix3D = NULL;
- }
+ delete mTransformMatrix;
+ delete mTransformCamera;
+ delete mTransformMatrix3D;
+ delete mStaticMatrix;
+ delete mAnimationMatrix;
+ mTransformMatrix = NULL;
+ mTransformCamera = NULL;
+ mTransformMatrix3D = NULL;
+ mStaticMatrix = NULL;
+ mAnimationMatrix = NULL;
}
Caches& caches = Caches::getInstance();
@@ -667,12 +665,26 @@ void DisplayList::updateMatrix() {
void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
if (USE_DISPLAY_LIST_PROPERTIES) {
updateMatrix();
- if (mApplicationScale >= 0) {
- ALOGD("%s%s %.2f, %.2f", (char*) indent, "Scale",
- mApplicationScale, mApplicationScale);
- }
if (mLeft != 0 || mTop != 0) {
- ALOGD("%s%s %d, %d", indent, "Translate", mLeft, mTop);
+ ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
+ }
+ if (mStaticMatrix) {
+ ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix (static)", mStaticMatrix,
+ mStaticMatrix->get(0), mStaticMatrix->get(1),
+ mStaticMatrix->get(2), mStaticMatrix->get(3),
+ mStaticMatrix->get(4), mStaticMatrix->get(5),
+ mStaticMatrix->get(6), mStaticMatrix->get(7),
+ mStaticMatrix->get(8));
+ }
+ if (mAnimationMatrix) {
+ ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix (animation)", mAnimationMatrix,
+ mAnimationMatrix->get(0), mAnimationMatrix->get(1),
+ mAnimationMatrix->get(2), mAnimationMatrix->get(3),
+ mAnimationMatrix->get(4), mAnimationMatrix->get(5),
+ mAnimationMatrix->get(6), mAnimationMatrix->get(7),
+ mAnimationMatrix->get(8));
}
if (mMatrixFlags != 0) {
if (mMatrixFlags == TRANSLATION) {
@@ -719,13 +731,29 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t width, ui
#endif
updateMatrix();
if (mLeft != 0 || mTop != 0) {
- DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate", mLeft, mTop);
+ DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
renderer.translate(mLeft, mTop);
}
- if (mApplicationScale >= 0) {
- DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, "Scale",
- mApplicationScale, mApplicationScale);
- renderer.scale(mApplicationScale, mApplicationScale);
+ if (mStaticMatrix) {
+ DISPLAY_LIST_LOGD(
+ "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix (static)", mStaticMatrix,
+ mStaticMatrix->get(0), mStaticMatrix->get(1),
+ mStaticMatrix->get(2), mStaticMatrix->get(3),
+ mStaticMatrix->get(4), mStaticMatrix->get(5),
+ mStaticMatrix->get(6), mStaticMatrix->get(7),
+ mStaticMatrix->get(8));
+ renderer.concatMatrix(mStaticMatrix);
+ } else if (mAnimationMatrix) {
+ DISPLAY_LIST_LOGD(
+ "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix (animation)", mAnimationMatrix,
+ mAnimationMatrix->get(0), mAnimationMatrix->get(1),
+ mAnimationMatrix->get(2), mAnimationMatrix->get(3),
+ mAnimationMatrix->get(4), mAnimationMatrix->get(5),
+ mAnimationMatrix->get(6), mAnimationMatrix->get(7),
+ mAnimationMatrix->get(8));
+ renderer.concatMatrix(mAnimationMatrix);
}
if (mMatrixFlags != 0) {
if (mMatrixFlags == TRANSLATION) {
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index fff1d7c64bbd7..a6108e1ecc55b 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -156,14 +156,24 @@ public:
}
}
- void setApplicationScale(float scale) {
- mApplicationScale = scale;
- }
-
void setClipChildren(bool clipChildren) {
mClipChildren = clipChildren;
}
+ void setStaticMatrix(SkMatrix* matrix) {
+ delete mStaticMatrix;
+ mStaticMatrix = new SkMatrix(*matrix);
+ }
+
+ void setAnimationMatrix(SkMatrix* matrix) {
+ delete mAnimationMatrix;
+ if (matrix) {
+ mAnimationMatrix = new SkMatrix(*matrix);
+ } else {
+ mAnimationMatrix = NULL;
+ }
+ }
+
void setAlpha(float alpha) {
if (alpha != mAlpha) {
mAlpha = alpha;
@@ -483,7 +493,6 @@ private:
String8 mName;
// View properties
- float mApplicationScale;
bool mClipChildren;
float mAlpha;
int mMultipliedAlpha;
@@ -502,6 +511,8 @@ private:
SkMatrix* mTransformMatrix;
Sk3DView* mTransformCamera;
SkMatrix* mTransformMatrix3D;
+ SkMatrix* mStaticMatrix;
+ SkMatrix* mAnimationMatrix;
bool mCaching;
};
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index b310d93d97dee..f4c0841d694a6 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -638,7 +638,6 @@
-
+
+
+
+
+
+
+
diff --git a/tests/HwAccelerationTest/res/layout/transforms_and_animations.xml b/tests/HwAccelerationTest/res/layout/transforms_and_animations.xml
new file mode 100644
index 0000000000000..1595502f6db9a
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/transforms_and_animations.xml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java
new file mode 100644
index 0000000000000..684d17944549d
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2012 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.test.hwui;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+import android.view.animation.TranslateAnimation;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.LinearLayout;
+
+public class TransformsAndAnimationsActivity extends Activity {
+ Button button1;
+ Button button2;
+ Button button3;
+ Button button1a;
+ Button button2a;
+ Button button3a;
+ Button button1b;
+ Button button2b;
+ Button button3b;
+ Button button4;
+ Button button5;
+ Button button6;
+ Button button7;
+ Button button8;
+ CheckBox layersNoneCB;
+ CheckBox layersHardwareCB;
+ CheckBox layersSoftwareCB;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.transforms_and_animations);
+
+ button1 = (Button) findViewById(R.id.button1);
+ button2 = (Button) findViewById(R.id.button2);
+ button3 = (Button) findViewById(R.id.button3);
+ button1a = (Button) findViewById(R.id.button1a);
+ button2a = (Button) findViewById(R.id.button2a);
+ button3a = (Button) findViewById(R.id.button3a);
+ button1b = (Button) findViewById(R.id.button1b);
+ button2b = (Button) findViewById(R.id.button2b);
+ button3b = (Button) findViewById(R.id.button3b);
+ button4 = (Button) findViewById(R.id.button4);
+ button5 = (Button) findViewById(R.id.button5);
+ button6 = (Button) findViewById(R.id.button6);
+ button7 = (Button) findViewById(R.id.button7);
+ button8 = (Button) findViewById(R.id.button8);
+ layersNoneCB = (CheckBox) findViewById(R.id.layersNoneCB);
+ layersHardwareCB = (CheckBox) findViewById(R.id.layersHwCB);
+ layersSoftwareCB = (CheckBox) findViewById(R.id.layersSwCB);
+
+ layersNoneCB.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ setLayerType(View.LAYER_TYPE_NONE);
+ layersHardwareCB.setChecked(false);
+ layersSoftwareCB.setChecked(false);
+ }
+ }
+ });
+
+ layersSoftwareCB.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ setLayerType(View.LAYER_TYPE_SOFTWARE);
+ layersHardwareCB.setChecked(false);
+ layersNoneCB.setChecked(false);
+ }
+ }
+ });
+
+ layersHardwareCB.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ setLayerType(View.LAYER_TYPE_HARDWARE);
+ layersNoneCB.setChecked(false);
+ layersSoftwareCB.setChecked(false);
+ }
+ }
+ });
+
+ button1a.setAlpha(.5f);
+ button2a.setAlpha(.5f);
+ button3a.setAlpha(.5f);
+ button3.setTranslationX(50);
+ button7.setTranslationX(50);
+ button8.setTranslationX(50);
+
+ final AlphaAnimation alphaAnim = new AlphaAnimation(1, 0);
+ alphaAnim.setDuration(1000);
+ alphaAnim.setRepeatCount(Animation.INFINITE);
+ alphaAnim.setRepeatMode(Animation.REVERSE);
+
+ final TranslateAnimation transAnim = new TranslateAnimation(0, -50, 0, 0);
+ transAnim.setDuration(1000);
+ transAnim.setRepeatCount(Animation.INFINITE);
+ transAnim.setRepeatMode(Animation.REVERSE);
+
+ getWindow().getDecorView().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ button1.startAnimation(alphaAnim);
+ button2.startAnimation(alphaAnim);
+ button3.startAnimation(alphaAnim);
+
+ button1a.startAnimation(alphaAnim);
+ button2a.startAnimation(alphaAnim);
+ button3a.startAnimation(alphaAnim);
+
+ button1b.startAnimation(alphaAnim);
+ button2b.startAnimation(alphaAnim);
+ button3b.startAnimation(alphaAnim);
+ startAnimator(button1b);
+ startAnimator(button2b);
+ startAnimator(button3b);
+
+ button7.startAnimation(transAnim);
+ button8.startAnimation(transAnim);
+ }
+ }, 2000);
+ }
+
+ private void setLayerType(int layerType) {
+ button1.setLayerType(layerType, null);
+ button2.setLayerType(layerType, null);
+ button3.setLayerType(layerType, null);
+ button1a.setLayerType(layerType, null);
+ button2a.setLayerType(layerType, null);
+ button3a.setLayerType(layerType, null);
+ button1b.setLayerType(layerType, null);
+ button2b.setLayerType(layerType, null);
+ button3b.setLayerType(layerType, null);
+ button4.setLayerType(layerType, null);
+ button5.setLayerType(layerType, null);
+ button6.setLayerType(layerType, null);
+ button7.setLayerType(layerType, null);
+ button8.setLayerType(layerType, null);
+ }
+
+ private void startAnimator(View target) {
+ ObjectAnimator anim1b = ObjectAnimator.ofFloat(target, View.ALPHA, 0);
+ anim1b.setRepeatCount(ValueAnimator.INFINITE);
+ anim1b.setRepeatMode(ValueAnimator.REVERSE);
+ anim1b.setDuration(1000);
+ anim1b.start();
+ }
+
+ public static class MyLayout extends LinearLayout {
+
+ public MyLayout(Context context) {
+ super(context);
+ setStaticTransformationsEnabled(true);
+ }
+
+ public MyLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setStaticTransformationsEnabled(true);
+ }
+
+ public MyLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setStaticTransformationsEnabled(true);
+ }
+
+ @Override
+ protected boolean getChildStaticTransformation(View child, Transformation t) {
+ t.clear();
+ t.setAlpha(.35f);
+
+ return true;
+ }
+ }
+}
+