summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/view/HardwareRenderer.java2
-rw-r--r--core/java/android/view/RenderNode.java21
-rw-r--r--core/java/android/view/RenderNodeAnimator.java44
-rw-r--r--core/java/android/view/ThreadedRenderer.java20
-rw-r--r--core/java/android/view/View.java9
-rw-r--r--core/java/android/view/ViewRootImpl.java21
-rw-r--r--core/java/android/widget/Editor.java2
7 files changed, 84 insertions, 35 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index de90899..edb3798 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -485,4 +485,6 @@ public abstract class HardwareRenderer {
* Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
*/
abstract void notifyFramePending();
+
+ abstract void registerAnimatingRenderNode(RenderNode animator);
}
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 099f153..9dc9766 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -167,10 +167,13 @@ public class RenderNode {
public static final int STATUS_DREW = 0x4;
private boolean mValid;
- private final long mNativeRenderNode;
+ // Do not access directly unless you are ThreadedRenderer
+ final long mNativeRenderNode;
+ private final View mOwningView;
- private RenderNode(String name) {
+ private RenderNode(String name, View owningView) {
mNativeRenderNode = nCreate(name);
+ mOwningView = owningView;
}
/**
@@ -178,6 +181,7 @@ public class RenderNode {
*/
private RenderNode(long nativePtr) {
mNativeRenderNode = nativePtr;
+ mOwningView = null;
}
/**
@@ -188,8 +192,8 @@ public class RenderNode {
*
* @return A new RenderNode.
*/
- public static RenderNode create(String name) {
- return new RenderNode(name);
+ public static RenderNode create(String name, @Nullable View owningView) {
+ return new RenderNode(name, owningView);
}
/**
@@ -805,7 +809,15 @@ public class RenderNode {
///////////////////////////////////////////////////////////////////////////
public void addAnimator(RenderNodeAnimator animator) {
+ if (mOwningView == null || mOwningView.mAttachInfo == null) {
+ throw new IllegalStateException("Cannot start this animator on a detached view!");
+ }
nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
+ mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
+ }
+
+ public void endAllAnimators() {
+ nEndAllAnimators(mNativeRenderNode);
}
///////////////////////////////////////////////////////////////////////////
@@ -891,6 +903,7 @@ public class RenderNode {
///////////////////////////////////////////////////////////////////////////
private static native void nAddAnimator(long renderNode, long animatorPtr);
+ private static native void nEndAllAnimators(long renderNode);
///////////////////////////////////////////////////////////////////////////
// Finalization
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index 9433237..413ea04 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -19,7 +19,6 @@ package android.view;
import android.animation.Animator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
-import android.animation.Animator.AnimatorListener;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
import android.graphics.Paint;
@@ -30,7 +29,6 @@ import com.android.internal.view.animation.FallbackLUTInterpolator;
import com.android.internal.view.animation.HasNativeInterpolator;
import com.android.internal.view.animation.NativeInterpolatorFactory;
-import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
@@ -111,13 +109,11 @@ public class RenderNodeAnimator extends Animator {
mRenderProperty = property;
mFinalValue = finalValue;
mUiThreadHandlesDelay = true;
- init(nCreateAnimator(new WeakReference<RenderNodeAnimator>(this),
- property, finalValue));
+ init(nCreateAnimator(property, finalValue));
}
public RenderNodeAnimator(CanvasProperty<Float> property, float finalValue) {
init(nCreateCanvasPropertyFloatAnimator(
- new WeakReference<RenderNodeAnimator>(this),
property.getNativeContainer(), finalValue));
mUiThreadHandlesDelay = false;
}
@@ -132,14 +128,12 @@ public class RenderNodeAnimator extends Animator {
*/
public RenderNodeAnimator(CanvasProperty<Paint> property, int paintField, float finalValue) {
init(nCreateCanvasPropertyPaintAnimator(
- new WeakReference<RenderNodeAnimator>(this),
property.getNativeContainer(), paintField, finalValue));
mUiThreadHandlesDelay = false;
}
public RenderNodeAnimator(int x, int y, float startRadius, float endRadius) {
- init(nCreateRevealAnimator(new WeakReference<RenderNodeAnimator>(this),
- x, y, startRadius, endRadius));
+ init(nCreateRevealAnimator(x, y, startRadius, endRadius));
mUiThreadHandlesDelay = true;
}
@@ -192,7 +186,7 @@ public class RenderNodeAnimator extends Animator {
}
private void doStart() {
- nStart(mNativePtr.get());
+ nStart(mNativePtr.get(), this);
// Alpha is a special snowflake that has the canonical value stored
// in mTransformationInfo instead of in RenderNode, so we need to update
@@ -248,24 +242,21 @@ public class RenderNodeAnimator extends Animator {
public void setTarget(View view) {
mViewTarget = view;
- mTarget = view.mRenderNode;
- mTarget.addAnimator(this);
+ setTarget(mViewTarget.mRenderNode);
}
public void setTarget(Canvas canvas) {
if (!(canvas instanceof GLES20RecordingCanvas)) {
throw new IllegalArgumentException("Not a GLES20RecordingCanvas");
}
-
final GLES20RecordingCanvas recordingCanvas = (GLES20RecordingCanvas) canvas;
setTarget(recordingCanvas.mNode);
}
- public void setTarget(RenderNode node) {
+ private void setTarget(RenderNode node) {
if (mTarget != null) {
throw new IllegalStateException("Target already set!");
}
- mViewTarget = null;
mTarget = node;
mTarget.addAnimator(this);
}
@@ -335,6 +326,12 @@ public class RenderNodeAnimator extends Animator {
for (int i = 0; i < numListeners; i++) {
listeners.get(i).onAnimationEnd(this);
}
+
+ // Release the native object, as it has a global reference to us. This
+ // breaks the cyclic reference chain, and allows this object to be
+ // GC'd
+ mNativePtr.release();
+ mNativePtr = null;
}
@SuppressWarnings("unchecked")
@@ -427,11 +424,8 @@ public class RenderNodeAnimator extends Animator {
}
// Called by native
- private static void callOnFinished(WeakReference<RenderNodeAnimator> weakThis) {
- RenderNodeAnimator animator = weakThis.get();
- if (animator != null) {
- animator.onFinished();
- }
+ private static void callOnFinished(RenderNodeAnimator animator) {
+ animator.onFinished();
}
@Override
@@ -439,22 +433,20 @@ public class RenderNodeAnimator extends Animator {
throw new IllegalStateException("Cannot clone this animator");
}
- private static native long nCreateAnimator(WeakReference<RenderNodeAnimator> weakThis,
- int property, float finalValue);
- private static native long nCreateCanvasPropertyFloatAnimator(WeakReference<RenderNodeAnimator> weakThis,
+ private static native long nCreateAnimator(int property, float finalValue);
+ private static native long nCreateCanvasPropertyFloatAnimator(
long canvasProperty, float finalValue);
- private static native long nCreateCanvasPropertyPaintAnimator(WeakReference<RenderNodeAnimator> weakThis,
+ private static native long nCreateCanvasPropertyPaintAnimator(
long canvasProperty, int paintField, float finalValue);
- private static native long nCreateRevealAnimator(WeakReference<RenderNodeAnimator> weakThis,
+ private static native long nCreateRevealAnimator(
int x, int y, float startRadius, float endRadius);
private static native void nSetStartValue(long nativePtr, float startValue);
private static native void nSetDuration(long nativePtr, long duration);
private static native long nGetDuration(long nativePtr);
private static native void nSetStartDelay(long nativePtr, long startDelay);
- private static native long nGetStartDelay(long nativePtr);
private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
- private static native void nStart(long animPtr);
+ private static native void nStart(long animPtr, RenderNodeAnimator finishListener);
private static native void nEnd(long animPtr);
}
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 50341fc..faade96 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -314,6 +314,20 @@ public class ThreadedRenderer extends HardwareRenderer {
attachInfo.mIgnoreDirtyState = false;
+ // register animating rendernodes which started animating prior to renderer
+ // creation, which is typical for animators started prior to first draw
+ if (attachInfo.mPendingAnimatingRenderNodes != null) {
+ final int count = attachInfo.mPendingAnimatingRenderNodes.size();
+ for (int i = 0; i < count; i++) {
+ registerAnimatingRenderNode(
+ attachInfo.mPendingAnimatingRenderNodes.get(i));
+ }
+ attachInfo.mPendingAnimatingRenderNodes.clear();
+ // We don't need this anymore as subsequent calls to
+ // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
+ attachInfo.mPendingAnimatingRenderNodes = null;
+ }
+
int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos,
recordDuration, view.getResources().getDisplayMetrics().density);
if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
@@ -372,6 +386,11 @@ public class ThreadedRenderer extends HardwareRenderer {
}
@Override
+ void registerAnimatingRenderNode(RenderNode animator) {
+ nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
+ }
+
+ @Override
protected void finalize() throws Throwable {
try {
nDeleteProxy(mNativeProxy);
@@ -468,6 +487,7 @@ public class ThreadedRenderer extends HardwareRenderer {
private static native int nSyncAndDrawFrame(long nativeProxy,
long frameTimeNanos, long recordDuration, float density);
private static native void nDestroyCanvasAndSurface(long nativeProxy);
+ private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6f58582..9e1dbe0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3565,7 +3565,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
mUserPaddingStart = UNDEFINED_PADDING;
mUserPaddingEnd = UNDEFINED_PADDING;
- mRenderNode = RenderNode.create(getClass().getName());
+ mRenderNode = RenderNode.create(getClass().getName(), this);
if (!sCompatibilityDone && context != null) {
final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
@@ -4161,7 +4161,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
View() {
mResources = null;
- mRenderNode = RenderNode.create(getClass().getName());
+ mRenderNode = RenderNode.create(getClass().getName(), this);
}
private static SparseArray<String> getAttributeMap() {
@@ -15180,9 +15180,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param renderNode Existing RenderNode, or {@code null}
* @return A valid display list for the specified drawable
*/
- private static RenderNode getDrawableRenderNode(Drawable drawable, RenderNode renderNode) {
+ private RenderNode getDrawableRenderNode(Drawable drawable, RenderNode renderNode) {
if (renderNode == null) {
- renderNode = RenderNode.create(drawable.getClass().getName());
+ renderNode = RenderNode.create(drawable.getClass().getName(), this);
}
final Rect bounds = drawable.getBounds();
@@ -19908,6 +19908,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
boolean mHardwareAccelerated;
boolean mHardwareAccelerationRequested;
HardwareRenderer mHardwareRenderer;
+ List<RenderNode> mPendingAnimatingRenderNodes;
/**
* The state of the display to which the window is attached, as reported
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bb469a3..80dbbf5 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -671,6 +671,17 @@ public final class ViewRootImpl implements ViewParent,
ThreadedRenderer.invokeFunctor(functor, waitForCompletion);
}
+ public void registerAnimatingRenderNode(RenderNode animator) {
+ if (mAttachInfo.mHardwareRenderer != null) {
+ mAttachInfo.mHardwareRenderer.registerAnimatingRenderNode(animator);
+ } else {
+ if (mAttachInfo.mPendingAnimatingRenderNodes == null) {
+ mAttachInfo.mPendingAnimatingRenderNodes = new ArrayList<RenderNode>();
+ }
+ mAttachInfo.mPendingAnimatingRenderNodes.add(animator);
+ }
+ }
+
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
mAttachInfo.mHardwareAccelerated = false;
mAttachInfo.mHardwareAccelerationRequested = false;
@@ -2329,6 +2340,16 @@ public final class ViewRootImpl implements ViewParent,
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
+ // For whatever reason we didn't create a HardwareRenderer, end any
+ // hardware animations that are now dangling
+ if (mAttachInfo.mPendingAnimatingRenderNodes != null) {
+ final int count = mAttachInfo.mPendingAnimatingRenderNodes.size();
+ for (int i = 0; i < count; i++) {
+ mAttachInfo.mPendingAnimatingRenderNodes.get(i).endAllAnimators();
+ }
+ mAttachInfo.mPendingAnimatingRenderNodes.clear();
+ }
+
if (mReportNextDraw) {
mReportNextDraw = false;
if (mAttachInfo.mHardwareRenderer != null) {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 29c8298..46b225d 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -147,7 +147,7 @@ public class Editor {
boolean isDirty;
public TextDisplayList(String name) {
isDirty = true;
- displayList = RenderNode.create(name);
+ displayList = RenderNode.create(name, null);
}
boolean needsRecord() { return isDirty || !displayList.isValid(); }
}