diff options
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/view/RenderNode.java | 51 | ||||
-rw-r--r-- | core/java/android/view/RenderNodeAnimator.java | 122 | ||||
-rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 15 | ||||
-rw-r--r-- | core/java/android/view/ViewPropertyAnimator.java | 26 |
4 files changed, 194 insertions, 20 deletions
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java index 3dc09c4..8b80c3e0 100644 --- a/core/java/android/view/RenderNode.java +++ b/core/java/android/view/RenderNode.java @@ -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,11 +179,24 @@ 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. * @@ -195,6 +211,17 @@ public class RenderNode { } /** + * 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 * stored in this display list. @@ -822,6 +849,23 @@ public class RenderNode { } /////////////////////////////////////////////////////////////////////////// + // 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 /////////////////////////////////////////////////////////////////////////// @@ -896,6 +940,13 @@ public class 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 /////////////////////////////////////////////////////////////////////////// diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java new file mode 100644 index 0000000..b70ae3d --- /dev/null +++ b/core/java/android/view/RenderNodeAnimator.java @@ -0,0 +1,122 @@ +/* + * 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); +} diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index c7a6d41..eaec8ab 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -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); diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index b1aa7b2..11d2622 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -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; |