summaryrefslogtreecommitdiffstats
path: root/core/jni/android_view_ThreadedRenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/jni/android_view_ThreadedRenderer.cpp')
-rw-r--r--core/jni/android_view_ThreadedRenderer.cpp87
1 files changed, 74 insertions, 13 deletions
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 },