diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/view/HardwareRenderer.java | 2 | ||||
-rw-r--r-- | core/java/android/view/RenderNode.java | 21 | ||||
-rw-r--r-- | core/java/android/view/RenderNodeAnimator.java | 44 | ||||
-rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 20 | ||||
-rw-r--r-- | core/java/android/view/View.java | 9 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 21 | ||||
-rw-r--r-- | core/java/android/widget/Editor.java | 2 |
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(); } } |