summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2014-08-28 01:38:57 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-28 01:38:58 +0000
commit4c5a27b5f667ebc7cb2b188655820ad3fddedb52 (patch)
treea8374af7dbedfc25d0e972876869fc7b445b708b /core/jni
parent040a7f0526532995a072a0473483e69b6575ac72 (diff)
parent119907cd2575c56b1ebf66348b52e67aaf6a88d8 (diff)
downloadframeworks_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.cpp7
-rw-r--r--core/jni/android_view_RenderNodeAnimator.cpp53
-rw-r--r--core/jni/android_view_ThreadedRenderer.cpp87
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 },