Handle hidden RT VectorDrawable animators

This CL changes the target of VD specific animators to VectorDrawable,
instead of RenderNode. The benefit of doing so is that animators can
now detect whether the animation is meaningful by checking whether
their VD target is in the display list. If not, that means the VD is
not drawing for the current frame, in which case we can be smarter
and more power efficient by removing the animator from the list and
posting a delayed onFinished listener callback.

By setting VD as the animation target, when an ImageView decides to
update its drawable from one AVD to something else, we'll be able
to detect that the previous AVD is no longer in the display list,
and stop providing animation pulse to the stale AVD, which is
something we couldn't do previously.  This change also
handles the case where one AVD instance could be drawn in two
different views.

Bug: 27441375
Change-Id: Id4b3b37f28274c917cb9beb9dcd3d1e6991b5c5d
This commit is contained in:
Doris Liu
2016-05-17 16:50:31 -07:00
parent 2a86e67c41
commit 67ce99b66e
19 changed files with 262 additions and 52 deletions

View File

@@ -793,12 +793,12 @@ public class RenderNode {
return mOwningView != null && mOwningView.mAttachInfo != null;
}
public void addAnimator(AnimatedVectorDrawable.VectorDrawableAnimatorRT animatorSet) {
public void registerVectorDrawableAnimator(
AnimatedVectorDrawable.VectorDrawableAnimatorRT animatorSet) {
if (mOwningView == null || mOwningView.mAttachInfo == null) {
throw new IllegalStateException("Cannot start this animator on a detached view!");
}
nAddAnimator(mNativeRenderNode, animatorSet.getAnimatorNativePtr());
mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
mOwningView.mAttachInfo.mViewRootImpl.registerVectorDrawableAnimator(animatorSet);
}
public void endAllAnimators() {

View File

@@ -23,6 +23,7 @@ import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -881,6 +882,12 @@ public final class ThreadedRenderer {
nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
}
void registerVectorDrawableAnimator(
AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
animator.getAnimatorNativePtr());
}
public void serializeDisplayListTree() {
nSerializeDisplayListTree(mNativeProxy);
}
@@ -992,6 +999,7 @@ public final class ThreadedRenderer {
private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
private static native void nDestroy(long nativeProxy, long rootRenderNode);
private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
private static native void nInvokeFunctor(long functor, boolean waitForCompletion);

View File

@@ -42,6 +42,7 @@ import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
@@ -825,6 +826,13 @@ public final class ViewRootImpl implements ViewParent,
}
}
public void registerVectorDrawableAnimator(
AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.registerVectorDrawableAnimator(animator);
}
}
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
mAttachInfo.mHardwareAccelerated = false;
mAttachInfo.mHardwareAccelerationRequested = false;