Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f276acd9 authored by Doris Liu's avatar Doris Liu
Browse files

VectorDrawable native rendering - Step 4 of MANY

This CL runs VectorDrawable animation on RenderThread. The changes in this CL
include:
- Convert all the animators in AnimatorSet for AVD into a set of RenderNodeAnimators.
- Hook up the new animators with RenderThread
- Add drawOp in RecordingCanvas for drawing VD so that during the animation
  on RenderThread, all the property changes on VD can be reflected on the screen.

TODO:
- Implement reverse and reset for AVD.

Change-Id: I2df1d754f2db0ad098d9c15dde4bb2bdfafc2315
parent 650e3b70
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1030,6 +1030,20 @@ public final class AnimatorSet extends Animator {
        }
    }

    /**
     * @hide
     * TODO: For animatorSet defined in XML, we can use a flag to indicate what the play order
     * if defined (i.e. sequential or together), then we can use the flag instead of calculate
     * dynamically.
     * @return whether all the animators in the set are supposed to play together
     */
    public boolean shouldPlayTogether() {
        updateAnimatorsDuration();
        createDependencyGraph();
        // All the child nodes are set out to play right after the delay animation
        return mRootNode.mChildNodes.size() == mNodes.size() - 1;
    }

    @Override
    public long getTotalDuration() {
        updateAnimatorsDuration();
+2 −2
Original line number Diff line number Diff line
@@ -231,7 +231,7 @@ class PathKeyframes implements Keyframes {
        }
    }

    private abstract static class IntKeyframesBase extends SimpleKeyframes implements IntKeyframes {
    abstract static class IntKeyframesBase extends SimpleKeyframes implements IntKeyframes {
        @Override
        public Class getType() {
            return Integer.class;
@@ -243,7 +243,7 @@ class PathKeyframes implements Keyframes {
        }
    }

    private abstract static class FloatKeyframesBase extends SimpleKeyframes
    abstract static class FloatKeyframesBase extends SimpleKeyframes
            implements FloatKeyframes {
        @Override
        public Class getType() {
+56 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.graphics.PointF;
import android.util.FloatProperty;
import android.util.IntProperty;
import android.util.Log;
import android.util.PathParser;
import android.util.Property;

import java.lang.reflect.InvocationTargetException;
@@ -1046,6 +1047,43 @@ public class PropertyValuesHolder implements Cloneable {
        return mAnimatedValue;
    }

    /**
     * PropertyValuesHolder is Animators use to hold internal animation related data.
     * Therefore, in order to replicate the animation behavior, we need to get data out of
     * PropertyValuesHolder.
     * @hide
     */
    public void getPropertyValues(PropertyValues values) {
        init();
        values.propertyName = mPropertyName;
        values.type = mValueType;
        values.startValue = mKeyframes.getValue(0);
        if (values.startValue instanceof PathParser.PathData) {
            // PathData evaluator returns the same mutable PathData object when query fraction,
            // so we have to make a copy here.
            values.startValue = new PathParser.PathData((PathParser.PathData) values.startValue);
        }
        values.endValue = mKeyframes.getValue(1);
        if (values.endValue instanceof PathParser.PathData) {
            // PathData evaluator returns the same mutable PathData object when query fraction,
            // so we have to make a copy here.
            values.endValue = new PathParser.PathData((PathParser.PathData) values.endValue);
        }
        // TODO: We need a better way to get data out of keyframes.
        if (mKeyframes instanceof PathKeyframes.FloatKeyframesBase
                || mKeyframes instanceof PathKeyframes.IntKeyframesBase) {
            // property values will animate based on external data source (e.g. Path)
            values.dataSource = new PropertyValues.DataSource() {
                @Override
                public Object getValueAtFraction(float fraction) {
                    return mKeyframes.getValue(fraction);
                }
            };
        } else {
            values.dataSource = null;
        }
    }

    @Override
    public String toString() {
        return mPropertyName + ": " + mKeyframes.toString();
@@ -1601,6 +1639,24 @@ public class PropertyValuesHolder implements Cloneable {
        }
    };

    /**
     * @hide
     */
    public static class PropertyValues {
        public String propertyName;
        public Class type;
        public Object startValue;
        public Object endValue;
        public DataSource dataSource = null;
        public interface DataSource {
            Object getValueAtFraction(float fraction);
        }
        public String toString() {
            return ("property name: " + propertyName + ", type: " + type + ", startValue: "
                    + startValue.toString() + ", endValue: " + endValue.toString());
        }
    }

    native static private long nGetIntMethod(Class targetClass, String methodName);
    native static private long nGetFloatMethod(Class targetClass, String methodName);
    native static private long nGetMultipleIntMethod(Class targetClass, String methodName,
+1 −0
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ public class PathParser {
            }
            super.finalize();
        }

    }

    /**
+9 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.AnimatedVectorDrawable;

/**
 * <p>A display list records a series of graphics related operations and can replay
@@ -771,6 +772,14 @@ public class RenderNode {
        mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
    }

    public void addAnimator(AnimatedVectorDrawable.VectorDrawableAnimator 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);
    }

    public void endAllAnimators() {
        nEndAllAnimators(mNativeRenderNode);
    }
Loading