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

Commit e45b1fd0 authored by John Reck's avatar John Reck
Browse files

RenderThread animator support

Change-Id: Icf29098edfdaf7ed550bbe9d49e9eaefb4167084
parent 627aad9c
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ import android.annotation.NonNull;
import android.graphics.Matrix;
import android.graphics.Outline;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>A display list records a series of graphics related operations and can replay
 * them later. Display lists are usually built by recording operations on a
@@ -176,10 +179,23 @@ public class RenderNode {
    private boolean mValid;
    private final long mNativeRenderNode;

    // We need to keep a strong reference to all running animators to ensure that
    // they can call removeAnimator when they have finished, as the native-side
    // object can only hold a WeakReference<> to avoid leaking memory due to
    // cyclic references.
    private List<RenderNodeAnimator> mActiveAnimators;

    private RenderNode(String name) {
        mNativeRenderNode = nCreate(name);
    }

    /**
     * @see RenderNode#adopt(long)
     */
    private RenderNode(long nativePtr) {
        mNativeRenderNode = nativePtr;
    }

    /**
     * Creates a new display list that can be used to record batches of
     * drawing operations.
@@ -194,6 +210,17 @@ public class RenderNode {
        return new RenderNode(name);
    }

    /**
     * Adopts an existing native render node.
     *
     * Note: This will *NOT* incRef() on the native object, however it will
     * decRef() when it is destroyed. The caller should have already incRef'd it
     */
    public static RenderNode adopt(long nativePtr) {
        return new RenderNode(nativePtr);
    }


    /**
     * Starts recording a display list for the render node. All
     * operations performed on the returned canvas are recorded and
@@ -821,6 +848,23 @@ public class RenderNode {
        nOutput(mNativeRenderNode);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Animations
    ///////////////////////////////////////////////////////////////////////////

    public void addAnimator(RenderNodeAnimator animator) {
        if (mActiveAnimators == null) {
            mActiveAnimators = new ArrayList<RenderNodeAnimator>();
        }
        mActiveAnimators.add(animator);
        nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
    }

    public void removeAnimator(RenderNodeAnimator animator) {
        nRemoveAnimator(mNativeRenderNode, animator.getNativeAnimator());
        mActiveAnimators.remove(animator);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Native methods
    ///////////////////////////////////////////////////////////////////////////
@@ -895,6 +939,13 @@ public class RenderNode {
    private static native float nGetPivotY(long renderNode);
    private static native void nOutput(long renderNode);

    ///////////////////////////////////////////////////////////////////////////
    // Animations
    ///////////////////////////////////////////////////////////////////////////

    private static native void nAddAnimator(long renderNode, long animatorPtr);
    private static native void nRemoveAnimator(long renderNode, long animatorPtr);

    ///////////////////////////////////////////////////////////////////////////
    // Finalization
    ///////////////////////////////////////////////////////////////////////////
+122 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 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 android.view;

import android.util.SparseIntArray;

import java.lang.ref.WeakReference;

/**
 * @hide
 */
public final class RenderNodeAnimator {

    // Keep in sync with enum RenderProperty in Animator.h
    private static final int TRANSLATION_X = 0;
    private static final int TRANSLATION_Y = 1;
    private static final int TRANSLATION_Z = 2;
    private static final int SCALE_X = 3;
    private static final int SCALE_Y = 4;
    private static final int ROTATION = 5;
    private static final int ROTATION_X = 6;
    private static final int ROTATION_Y = 7;
    private static final int X = 8;
    private static final int Y = 9;
    private static final int Z = 10;
    private static final int ALPHA = 11;

    // ViewPropertyAnimator uses a mask for its values, we need to remap them
    // to the enum values here. RenderPropertyAnimator can't use the mask values
    // directly as internally it uses a lookup table so it needs the values to
    // be sequential starting from 0
    private static final SparseIntArray sViewPropertyAnimatorMap = new SparseIntArray(15) {{
        put(ViewPropertyAnimator.TRANSLATION_X, TRANSLATION_X);
        put(ViewPropertyAnimator.TRANSLATION_Y, TRANSLATION_Y);
        put(ViewPropertyAnimator.TRANSLATION_Z, TRANSLATION_Z);
        put(ViewPropertyAnimator.SCALE_X, SCALE_X);
        put(ViewPropertyAnimator.SCALE_Y, SCALE_Y);
        put(ViewPropertyAnimator.ROTATION, ROTATION);
        put(ViewPropertyAnimator.ROTATION_X, ROTATION_X);
        put(ViewPropertyAnimator.ROTATION_Y, ROTATION_Y);
        put(ViewPropertyAnimator.X, X);
        put(ViewPropertyAnimator.Y, Y);
        put(ViewPropertyAnimator.Z, Z);
        put(ViewPropertyAnimator.ALPHA, ALPHA);
    }};

    // Keep in sync DeltaValueType in Animator.h
    private static final int DELTA_TYPE_ABSOLUTE = 0;
    private static final int DELTA_TYPE_DELTA = 1;

    private RenderNode mTarget;
    private long mNativePtr;

    public int mapViewPropertyToRenderProperty(int viewProperty) {
        return sViewPropertyAnimatorMap.get(viewProperty);
    }

    public RenderNodeAnimator(int property, int deltaType, float deltaValue) {
        mNativePtr = nCreateAnimator(new WeakReference<RenderNodeAnimator>(this),
                property, deltaType, deltaValue);
    }

    public void start(View target) {
        mTarget = target.mRenderNode;
        mTarget.addAnimator(this);
        // Kick off a frame to start the process
        target.invalidateViewProperty(true, false);
    }

    public void cancel() {
        mTarget.removeAnimator(this);
    }

    public void setDuration(int duration) {
        nSetDuration(mNativePtr, duration);
    }

    long getNativeAnimator() {
        return mNativePtr;
    }

    private void onFinished() {
        mTarget.removeAnimator(this);
    }

    // Called by native
    private static void callOnFinished(WeakReference<RenderNodeAnimator> weakThis) {
        RenderNodeAnimator animator = weakThis.get();
        if (animator != null) {
            animator.onFinished();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            nUnref(mNativePtr);
            mNativePtr = 0;
        } finally {
            super.finalize();
        }
    }

    private static native long nCreateAnimator(WeakReference<RenderNodeAnimator> weakThis,
            int property, int deltaValueType, float deltaValue);
    private static native void nSetDuration(long nativePtr, int duration);
    private static native void nUnref(long nativePtr);
}
+8 −7
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ import java.io.PrintWriter;
public class ThreadedRenderer extends HardwareRenderer {
    private static final String LOGTAG = "ThreadedRenderer";

    private static final Rect NULL_RECT = new Rect(-1, -1, -1, -1);
    private static final Rect NULL_RECT = new Rect();

    private int mWidth, mHeight;
    private long mNativeProxy;
@@ -58,9 +58,10 @@ public class ThreadedRenderer extends HardwareRenderer {
    private RenderNode mRootNode;

    ThreadedRenderer(boolean translucent) {
        mNativeProxy = nCreateProxy(translucent);
        mRootNode = RenderNode.create("RootNode");
        long rootNodePtr = nCreateRootRenderNode();
        mRootNode = RenderNode.adopt(rootNodePtr);
        mRootNode.setClipToBounds(false);
        mNativeProxy = nCreateProxy(translucent, rootNodePtr);
    }

    @Override
@@ -202,8 +203,7 @@ public class ThreadedRenderer extends HardwareRenderer {
        if (dirty == null) {
            dirty = NULL_RECT;
        }
        nDrawDisplayList(mNativeProxy, mRootNode.getNativeDisplayList(),
                dirty.left, dirty.top, dirty.right, dirty.bottom);
        nSyncAndDrawFrame(mNativeProxy, dirty.left, dirty.top, dirty.right, dirty.bottom);
    }

    @Override
@@ -293,7 +293,8 @@ public class ThreadedRenderer extends HardwareRenderer {
    /** @hide */
    public static native void postToRenderThread(Runnable runnable);

    private static native long nCreateProxy(boolean translucent);
    private static native long nCreateRootRenderNode();
    private static native long nCreateProxy(boolean translucent, long rootRenderNode);
    private static native void nDeleteProxy(long nativeProxy);

    private static native boolean nInitialize(long nativeProxy, Surface window);
@@ -302,7 +303,7 @@ public class ThreadedRenderer extends HardwareRenderer {
    private static native void nSetup(long nativeProxy, int width, int height);
    private static native void nSetDisplayListData(long nativeProxy, long displayList,
            long newData);
    private static native void nDrawDisplayList(long nativeProxy, long displayList,
    private static native void nSyncAndDrawFrame(long nativeProxy,
            int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
    private static native void nRunWithGlContext(long nativeProxy, Runnable runnable);
    private static native void nDestroyCanvasAndSurface(long nativeProxy);
+13 −13
Original line number Diff line number Diff line
@@ -133,19 +133,19 @@ public class ViewPropertyAnimator {
     * Constants used to associate a property being requested and the mechanism used to set
     * the property (this class calls directly into View to set the properties in question).
     */
    private static final int NONE           = 0x0000;
    private static final int TRANSLATION_X  = 0x0001;
    private static final int TRANSLATION_Y  = 0x0002;
    private static final int TRANSLATION_Z  = 0x0004;
    private static final int SCALE_X        = 0x0008;
    private static final int SCALE_Y        = 0x0010;
    private static final int ROTATION       = 0x0020;
    private static final int ROTATION_X     = 0x0040;
    private static final int ROTATION_Y     = 0x0080;
    private static final int X              = 0x0100;
    private static final int Y              = 0x0200;
    private static final int Z              = 0x0400;
    private static final int ALPHA          = 0x0800;
    static final int NONE           = 0x0000;
    static final int TRANSLATION_X  = 0x0001;
    static final int TRANSLATION_Y  = 0x0002;
    static final int TRANSLATION_Z  = 0x0004;
    static final int SCALE_X        = 0x0008;
    static final int SCALE_Y        = 0x0010;
    static final int ROTATION       = 0x0020;
    static final int ROTATION_X     = 0x0040;
    static final int ROTATION_Y     = 0x0080;
    static final int X              = 0x0100;
    static final int Y              = 0x0200;
    static final int Z              = 0x0400;
    static final int ALPHA          = 0x0800;

    private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | TRANSLATION_Z |
            SCALE_X | SCALE_Y | ROTATION | ROTATION_X | ROTATION_Y | X | Y | Z;
+1 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ LOCAL_SRC_FILES:= \
	android_view_MotionEvent.cpp \
	android_view_PointerIcon.cpp \
	android_view_RenderNode.cpp \
	android_view_RenderNodeAnimator.cpp \
	android_view_VelocityTracker.cpp \
	android_text_AndroidCharacter.cpp \
	android_text_AndroidBidi.cpp \
Loading