diff options
author | John Reck <jreck@google.com> | 2014-08-28 01:38:57 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-08-28 01:38:58 +0000 |
commit | 4c5a27b5f667ebc7cb2b188655820ad3fddedb52 (patch) | |
tree | a8374af7dbedfc25d0e972876869fc7b445b708b /core/jni | |
parent | 040a7f0526532995a072a0473483e69b6575ac72 (diff) | |
parent | 119907cd2575c56b1ebf66348b52e67aaf6a88d8 (diff) | |
download | frameworks_base-4c5a27b5f667ebc7cb2b188655820ad3fddedb52.zip frameworks_base-4c5a27b5f667ebc7cb2b188655820ad3fddedb52.tar.gz frameworks_base-4c5a27b5f667ebc7cb2b188655820ad3fddedb52.tar.bz2 |
Merge "Animator stuff" into lmp-dev
Diffstat (limited to 'core/jni')
-rw-r--r-- | core/jni/android_view_RenderNode.cpp | 7 | ||||
-rw-r--r-- | core/jni/android_view_RenderNodeAnimator.cpp | 53 | ||||
-rw-r--r-- | core/jni/android_view_ThreadedRenderer.cpp | 87 |
3 files changed, 110 insertions, 37 deletions
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp index 1e9d722..1296831 100644 --- a/core/jni/android_view_RenderNode.cpp +++ b/core/jni/android_view_RenderNode.cpp @@ -455,6 +455,12 @@ static void android_view_RenderNode_addAnimator(JNIEnv* env, jobject clazz, renderNode->addAnimator(animator); } +static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz, + jlong renderNodePtr) { + RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); + renderNode->animators().endAllAnimators(); +} + #endif // USE_OPENGL_RENDERER // ---------------------------------------------------------------------------- @@ -534,6 +540,7 @@ static JNINativeMethod gMethods[] = { { "nGetPivotY", "(J)F", (void*) android_view_RenderNode_getPivotY }, { "nAddAnimator", "(JJ)V", (void*) android_view_RenderNode_addAnimator }, + { "nEndAllAnimators", "(J)V", (void*) android_view_RenderNode_endAllAnimators }, #endif }; diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp index 767534f..85c2a09 100644 --- a/core/jni/android_view_RenderNodeAnimator.cpp +++ b/core/jni/android_view_RenderNodeAnimator.cpp @@ -51,28 +51,36 @@ public: // cyclic-references-of-doom. If you think "I know, just use NewWeakGlobalRef!" // then you end up with basically a PhantomReference, which is totally not // what we want. - AnimationListenerBridge(JNIEnv* env, jobject weakThis) { - mWeakThis = env->NewGlobalRef(weakThis); + AnimationListenerBridge(JNIEnv* env, jobject finishListener) { + mFinishListener = env->NewGlobalRef(finishListener); env->GetJavaVM(&mJvm); } virtual ~AnimationListenerBridge() { - JNIEnv* env = getEnv(mJvm); - env->DeleteGlobalRef(mWeakThis); - mWeakThis = NULL; + if (mFinishListener) { + onAnimationFinished(NULL); + } } virtual void onAnimationFinished(BaseRenderNodeAnimator*) { + LOG_ALWAYS_FATAL_IF(!mFinishListener, "Finished listener twice?"); JNIEnv* env = getEnv(mJvm); env->CallStaticVoidMethod( gRenderNodeAnimatorClassInfo.clazz, gRenderNodeAnimatorClassInfo.callOnFinished, - mWeakThis); + mFinishListener); + releaseJavaObject(); } private: + void releaseJavaObject() { + JNIEnv* env = getEnv(mJvm); + env->DeleteGlobalRef(mFinishListener); + mFinishListener = NULL; + } + JavaVM* mJvm; - jobject mWeakThis; + jobject mFinishListener; }; static inline RenderPropertyAnimator::RenderProperty toRenderProperty(jint property) { @@ -88,38 +96,33 @@ static inline CanvasPropertyPaintAnimator::PaintField toPaintField(jint field) { return static_cast<CanvasPropertyPaintAnimator::PaintField>(field); } -static jlong createAnimator(JNIEnv* env, jobject clazz, jobject weakThis, +static jlong createAnimator(JNIEnv* env, jobject clazz, jint propertyRaw, jfloat finalValue) { RenderPropertyAnimator::RenderProperty property = toRenderProperty(propertyRaw); - BaseRenderNodeAnimator* animator = new RenderPropertyAnimator(property, finalValue); - animator->setListener(new AnimationListenerBridge(env, weakThis)); return reinterpret_cast<jlong>( animator ); } static jlong createCanvasPropertyFloatAnimator(JNIEnv* env, jobject clazz, - jobject weakThis, jlong canvasPropertyPtr, jfloat finalValue) { + jlong canvasPropertyPtr, jfloat finalValue) { CanvasPropertyPrimitive* canvasProperty = reinterpret_cast<CanvasPropertyPrimitive*>(canvasPropertyPtr); BaseRenderNodeAnimator* animator = new CanvasPropertyPrimitiveAnimator(canvasProperty, finalValue); - animator->setListener(new AnimationListenerBridge(env, weakThis)); return reinterpret_cast<jlong>( animator ); } static jlong createCanvasPropertyPaintAnimator(JNIEnv* env, jobject clazz, - jobject weakThis, jlong canvasPropertyPtr, jint paintFieldRaw, + jlong canvasPropertyPtr, jint paintFieldRaw, jfloat finalValue) { CanvasPropertyPaint* canvasProperty = reinterpret_cast<CanvasPropertyPaint*>(canvasPropertyPtr); CanvasPropertyPaintAnimator::PaintField paintField = toPaintField(paintFieldRaw); BaseRenderNodeAnimator* animator = new CanvasPropertyPaintAnimator( canvasProperty, paintField, finalValue); - animator->setListener(new AnimationListenerBridge(env, weakThis)); return reinterpret_cast<jlong>( animator ); } -static jlong createRevealAnimator(JNIEnv* env, jobject clazz, jobject weakThis, +static jlong createRevealAnimator(JNIEnv* env, jobject clazz, jint centerX, jint centerY, jfloat startRadius, jfloat endRadius) { BaseRenderNodeAnimator* animator = new RevealAnimator(centerX, centerY, startRadius, endRadius); - animator->setListener(new AnimationListenerBridge(env, weakThis)); return reinterpret_cast<jlong>( animator ); } @@ -156,8 +159,11 @@ static void setInterpolator(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong animator->setInterpolator(interpolator); } -static void start(JNIEnv* env, jobject clazz, jlong animatorPtr) { +static void start(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) { BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); + if (finishListener) { + animator->setListener(new AnimationListenerBridge(env, finishListener)); + } animator->start(); } @@ -176,17 +182,16 @@ const char* const kClassPathName = "android/view/RenderNodeAnimator"; static JNINativeMethod gMethods[] = { #ifdef USE_OPENGL_RENDERER - { "nCreateAnimator", "(Ljava/lang/ref/WeakReference;IF)J", (void*) createAnimator }, - { "nCreateCanvasPropertyFloatAnimator", "(Ljava/lang/ref/WeakReference;JF)J", (void*) createCanvasPropertyFloatAnimator }, - { "nCreateCanvasPropertyPaintAnimator", "(Ljava/lang/ref/WeakReference;JIF)J", (void*) createCanvasPropertyPaintAnimator }, - { "nCreateRevealAnimator", "(Ljava/lang/ref/WeakReference;IIFF)J", (void*) createRevealAnimator }, + { "nCreateAnimator", "(IF)J", (void*) createAnimator }, + { "nCreateCanvasPropertyFloatAnimator", "(JF)J", (void*) createCanvasPropertyFloatAnimator }, + { "nCreateCanvasPropertyPaintAnimator", "(JIF)J", (void*) createCanvasPropertyPaintAnimator }, + { "nCreateRevealAnimator", "(IIFF)J", (void*) createRevealAnimator }, { "nSetStartValue", "(JF)V", (void*) setStartValue }, { "nSetDuration", "(JJ)V", (void*) setDuration }, { "nGetDuration", "(J)J", (void*) getDuration }, { "nSetStartDelay", "(JJ)V", (void*) setStartDelay }, - { "nGetStartDelay", "(J)J", (void*) getStartDelay }, { "nSetInterpolator", "(JJ)V", (void*) setInterpolator }, - { "nStart", "(J)V", (void*) start }, + { "nStart", "(JLandroid/view/RenderNodeAnimator;)V", (void*) start }, { "nEnd", "(J)V", (void*) end }, #endif }; @@ -204,7 +209,7 @@ int register_android_view_RenderNodeAnimator(JNIEnv* env) { gRenderNodeAnimatorClassInfo.clazz = jclass(env->NewGlobalRef(gRenderNodeAnimatorClassInfo.clazz)); GET_STATIC_METHOD_ID(gRenderNodeAnimatorClassInfo.callOnFinished, gRenderNodeAnimatorClassInfo.clazz, - "callOnFinished", "(Ljava/lang/ref/WeakReference;)V"); + "callOnFinished", "(Landroid/view/RenderNodeAnimator;)V"); return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); } diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 4e3419a..99babac 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -33,6 +33,8 @@ #include "android_view_GraphicBuffer.h" #include <Animator.h> +#include <AnimationContext.h> +#include <IContextFactory.h> #include <RenderNode.h> #include <renderthread/CanvasContext.h> #include <renderthread/RenderProxy.h> @@ -103,7 +105,7 @@ private: std::string mMessage; }; -class RootRenderNode : public RenderNode, AnimationHook, ErrorHandler { +class RootRenderNode : public RenderNode, ErrorHandler { public: RootRenderNode(JNIEnv* env) : RenderNode() { mLooper = Looper::getForThread(); @@ -114,34 +116,84 @@ public: virtual ~RootRenderNode() {} - virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) { - OnFinishedEvent event(animator, listener); - mOnFinishedEvents.push_back(event); - } - virtual void onError(const std::string& message) { mLooper->sendMessage(new RenderingException(mVm, message), 0); } virtual void prepareTree(TreeInfo& info) { - info.animationHook = this; info.errorHandler = this; RenderNode::prepareTree(info); - info.animationHook = NULL; info.errorHandler = NULL; + } + + void sendMessage(const sp<MessageHandler>& handler) { + mLooper->sendMessage(handler, 0); + } + + void attachAnimatingNode(RenderNode* animatingNode) { + mPendingAnimatingRenderNodes.push_back(animatingNode); + } + + void doAttachAnimatingNodes(AnimationContext* context) { + for (size_t i = 0; i < mPendingAnimatingRenderNodes.size(); i++) { + RenderNode* node = mPendingAnimatingRenderNodes[i].get(); + context->addAnimatingRenderNode(*node); + } + mPendingAnimatingRenderNodes.clear(); + } + +private: + sp<Looper> mLooper; + JavaVM* mVm; + std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes; +}; + +class AnimationContextBridge : public AnimationContext { +public: + AnimationContextBridge(renderthread::TimeLord& clock, RootRenderNode* rootNode) + : AnimationContext(clock), mRootNode(rootNode) { + } + + virtual ~AnimationContextBridge() {} + // Marks the start of a frame, which will update the frame time and move all + // next frame animations into the current frame + virtual void startFrame() { + mRootNode->doAttachAnimatingNodes(this); + AnimationContext::startFrame(); + } + + // Runs any animations still left in mCurrentFrameAnimations + virtual void runRemainingAnimations(TreeInfo& info) { + AnimationContext::runRemainingAnimations(info); // post all the finished stuff if (mOnFinishedEvents.size()) { sp<InvokeAnimationListeners> message = new InvokeAnimationListeners(mOnFinishedEvents); - mLooper->sendMessage(message, 0); + mRootNode->sendMessage(message); } } + virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) { + OnFinishedEvent event(animator, listener); + mOnFinishedEvents.push_back(event); + } + private: - sp<Looper> mLooper; + sp<RootRenderNode> mRootNode; std::vector<OnFinishedEvent> mOnFinishedEvents; - JavaVM* mVm; +}; + +class ContextFactoryImpl : public IContextFactory { +public: + ContextFactoryImpl(RootRenderNode* rootNode) : mRootNode(rootNode) {} + + virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) { + return new AnimationContextBridge(clock, mRootNode); + } + +private: + RootRenderNode* mRootNode; }; static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz, @@ -168,8 +220,9 @@ static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, job static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz, jboolean translucent, jlong rootRenderNodePtr) { - RenderNode* rootRenderNode = reinterpret_cast<RenderNode*>(rootRenderNodePtr); - return (jlong) new RenderProxy(translucent, rootRenderNode); + RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr); + ContextFactoryImpl factory(rootRenderNode); + return (jlong) new RenderProxy(translucent, rootRenderNode, &factory); } static void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz, @@ -244,6 +297,13 @@ static void android_view_ThreadedRenderer_destroyCanvasAndSurface(JNIEnv* env, j proxy->destroyCanvasAndSurface(); } +static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz, + jlong rootNodePtr, jlong animatingNodePtr) { + RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr); + RenderNode* animatingNode = reinterpret_cast<RenderNode*>(animatingNodePtr); + rootRenderNode->attachAnimatingNode(animatingNode); +} + static void android_view_ThreadedRenderer_invokeFunctor(JNIEnv* env, jobject clazz, jlong functorPtr, jboolean waitForCompletion) { Functor* functor = reinterpret_cast<Functor*>(functorPtr); @@ -371,6 +431,7 @@ static JNINativeMethod gMethods[] = { { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque }, { "nSyncAndDrawFrame", "(JJJF)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame }, { "nDestroyCanvasAndSurface", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvasAndSurface }, + { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode }, { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor }, { "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer }, { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer }, |