summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
Diffstat (limited to 'core/jni')
-rw-r--r--core/jni/Android.mk1
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/android_view_RenderNode.cpp23
-rw-r--r--core/jni/android_view_RenderNodeAnimator.cpp127
-rw-r--r--core/jni/android_view_RenderNodeAnimator.h36
-rw-r--r--core/jni/android_view_ThreadedRenderer.cpp80
6 files changed, 261 insertions, 8 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 711f28a..ee59c8a 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -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 \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index aa635c6..f964cd2 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -120,6 +120,7 @@ extern int register_android_graphics_Xfermode(JNIEnv* env);
extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
extern int register_android_view_RenderNode(JNIEnv* env);
+extern int register_android_view_RenderNodeAnimator(JNIEnv* env);
extern int register_android_view_GraphicBuffer(JNIEnv* env);
extern int register_android_view_GLES20Canvas(JNIEnv* env);
extern int register_android_view_GLRenderer(JNIEnv* env);
@@ -1193,6 +1194,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_graphics_Graphics),
REG_JNI(register_android_view_DisplayEventReceiver),
REG_JNI(register_android_view_RenderNode),
+ REG_JNI(register_android_view_RenderNodeAnimator),
REG_JNI(register_android_view_GraphicBuffer),
REG_JNI(register_android_view_GLES20Canvas),
REG_JNI(register_android_view_GLRenderer),
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 3ad2ae5..4715c26 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -23,6 +23,7 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
+#include <Animator.h>
#include <DisplayListRenderer.h>
#include <RenderNode.h>
@@ -438,6 +439,25 @@ static jfloat android_view_RenderNode_getPivotY(JNIEnv* env,
return renderNode->stagingProperties().getPivotY();
}
+// ----------------------------------------------------------------------------
+// RenderProperties - Animations
+// ----------------------------------------------------------------------------
+
+static void android_view_RenderNode_addAnimator(JNIEnv* env, jobject clazz,
+ jlong renderNodePtr, jlong animatorPtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ RenderPropertyAnimator* animator = reinterpret_cast<RenderPropertyAnimator*>(animatorPtr);
+ renderNode->addAnimator(animator);
+}
+
+static void android_view_RenderNode_removeAnimator(JNIEnv* env, jobject clazz,
+ jlong renderNodePtr, jlong animatorPtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ RenderPropertyAnimator* animator = reinterpret_cast<RenderPropertyAnimator*>(animatorPtr);
+ renderNode->removeAnimator(animator);
+}
+
+
#endif // USE_OPENGL_RENDERER
// ----------------------------------------------------------------------------
@@ -513,6 +533,9 @@ static JNINativeMethod gMethods[] = {
{ "nGetPivotX", "(J)F", (void*) android_view_RenderNode_getPivotX },
{ "nGetPivotY", "(J)F", (void*) android_view_RenderNode_getPivotY },
+
+ { "nAddAnimator", "(JJ)V", (void*) android_view_RenderNode_addAnimator },
+ { "nRemoveAnimator", "(JJ)V", (void*) android_view_RenderNode_removeAnimator },
#endif
};
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp
new file mode 100644
index 0000000..35cdf60
--- /dev/null
+++ b/core/jni/android_view_RenderNodeAnimator.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include "android_view_RenderNodeAnimator.h"
+
+#include "jni.h"
+#include "GraphicsJNI.h"
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include <Animator.h>
+#include <Interpolator.h>
+#include <RenderProperties.h>
+
+namespace android {
+
+using namespace uirenderer;
+
+static struct {
+ jclass clazz;
+
+ jmethodID callOnFinished;
+} gRenderNodeAnimatorClassInfo;
+
+static JNIEnv* getEnv(JavaVM* vm) {
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ return 0;
+ }
+ return env;
+}
+
+RenderNodeAnimator::RenderNodeAnimator(JNIEnv* env, jobject weakThis,
+ RenderProperty property, DeltaValueType deltaType, float delta)
+ : RenderPropertyAnimator(property, deltaType, delta) {
+ mWeakThis = env->NewGlobalRef(weakThis);
+ env->GetJavaVM(&mJvm);
+}
+
+RenderNodeAnimator::~RenderNodeAnimator() {
+ JNIEnv* env = getEnv(mJvm);
+ env->DeleteGlobalRef(mWeakThis);
+ mWeakThis = NULL;
+}
+
+void RenderNodeAnimator::callOnFinished() {
+ JNIEnv* env = getEnv(mJvm);
+ env->CallStaticVoidMethod(
+ gRenderNodeAnimatorClassInfo.clazz,
+ gRenderNodeAnimatorClassInfo.callOnFinished,
+ mWeakThis);
+}
+
+static jlong createAnimator(JNIEnv* env, jobject clazz, jobject weakThis,
+ jint property, jint deltaType, jfloat deltaValue) {
+ LOG_ALWAYS_FATAL_IF(property < 0 || property > RenderNodeAnimator::ALPHA,
+ "Invalid property %d", property);
+ LOG_ALWAYS_FATAL_IF(deltaType != RenderPropertyAnimator::DELTA
+ && deltaType != RenderPropertyAnimator::ABSOLUTE,
+ "Invalid delta type %d", deltaType);
+
+ RenderNodeAnimator* animator = new RenderNodeAnimator(env, weakThis,
+ static_cast<RenderPropertyAnimator::RenderProperty>(property),
+ static_cast<RenderPropertyAnimator::DeltaValueType>(deltaType),
+ deltaValue);
+ animator->incStrong(0);
+ return reinterpret_cast<jlong>( animator );
+}
+
+static void setDuration(JNIEnv* env, jobject clazz, jlong animatorPtr, jint duration) {
+ LOG_ALWAYS_FATAL_IF(duration < 0, "Duration cannot be negative");
+ RenderNodeAnimator* animator = reinterpret_cast<RenderNodeAnimator*>(animatorPtr);
+ animator->setDuration(duration);
+}
+
+static void unref(JNIEnv* env, jobject clazz, jlong objPtr) {
+ VirtualLightRefBase* obj = reinterpret_cast<VirtualLightRefBase*>(objPtr);
+ obj->decStrong(0);
+}
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/view/RenderNodeAnimator";
+
+static JNINativeMethod gMethods[] = {
+ { "nCreateAnimator", "(Ljava/lang/ref/WeakReference;IIF)J", (void*) createAnimator },
+ { "nSetDuration", "(JI)V", (void*) setDuration },
+ { "nUnref", "(J)V", (void*) unref },
+};
+
+#define FIND_CLASS(var, className) \
+ var = env->FindClass(className); \
+ LOG_FATAL_IF(! var, "Unable to find class " className);
+
+#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+ var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
+ LOG_FATAL_IF(! var, "Unable to find method " methodName);
+
+int register_android_view_RenderNodeAnimator(JNIEnv* env) {
+ FIND_CLASS(gRenderNodeAnimatorClassInfo.clazz, kClassPathName);
+ gRenderNodeAnimatorClassInfo.clazz = jclass(env->NewGlobalRef(gRenderNodeAnimatorClassInfo.clazz));
+
+ GET_STATIC_METHOD_ID(gRenderNodeAnimatorClassInfo.callOnFinished, gRenderNodeAnimatorClassInfo.clazz,
+ "callOnFinished", "(Ljava/lang/ref/WeakReference;)V");
+
+ return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+
+} // namespace android
diff --git a/core/jni/android_view_RenderNodeAnimator.h b/core/jni/android_view_RenderNodeAnimator.h
new file mode 100644
index 0000000..d84003f
--- /dev/null
+++ b/core/jni/android_view_RenderNodeAnimator.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include "jni.h"
+
+#include <Animator.h>
+
+namespace android {
+
+class RenderNodeAnimator : public uirenderer::RenderPropertyAnimator {
+public:
+ RenderNodeAnimator(JNIEnv* env, jobject callbackObject,
+ RenderProperty property, DeltaValueType deltaType, float delta);
+ virtual ~RenderNodeAnimator();
+
+ void callOnFinished();
+
+private:
+ JavaVM* mJvm;
+ jobject mWeakThis;
+};
+
+}
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index b5f489d..58fc1e1 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -16,6 +16,8 @@
#define LOG_TAG "ThreadedRenderer"
+#include <algorithm>
+
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
@@ -24,6 +26,8 @@
#include <android_runtime/android_view_Surface.h>
#include <system/window.h>
+#include "android_view_RenderNodeAnimator.h"
+#include <RenderNode.h>
#include <renderthread/RenderProxy.h>
#include <renderthread/RenderTask.h>
#include <renderthread/RenderThread.h>
@@ -63,15 +67,75 @@ private:
jobject mRunnable;
};
+class InvokeAnimationListeners : public MessageHandler {
+public:
+ InvokeAnimationListeners(std::vector< sp<RenderNodeAnimator> >& animators) {
+ mAnimators.swap(animators);
+ }
+
+ static void callOnFinished(const sp<RenderNodeAnimator>& animator) {
+ animator->callOnFinished();
+ }
+
+ virtual void handleMessage(const Message& message) {
+ std::for_each(mAnimators.begin(), mAnimators.end(), callOnFinished);
+ mAnimators.clear();
+ }
+
+private:
+ std::vector< sp<RenderNodeAnimator> > mAnimators;
+};
+
+class RootRenderNode : public RenderNode, public AnimationListener {
+public:
+ RootRenderNode() : RenderNode() {
+ mLooper = Looper::getForThread();
+ LOG_ALWAYS_FATAL_IF(!mLooper.get(),
+ "Must create RootRenderNode on a thread with a looper!");
+ }
+
+ virtual ~RootRenderNode() {}
+
+ void onAnimationFinished(const sp<RenderPropertyAnimator>& animator) {
+ mFinishedAnimators.push_back(
+ reinterpret_cast<RenderNodeAnimator*>(animator.get()));
+ }
+
+ virtual void prepareTree(TreeInfo& info) {
+ info.animationListener = this;
+ RenderNode::prepareTree(info);
+ info.animationListener = NULL;
+
+ // post all the finished stuff
+ if (mFinishedAnimators.size()) {
+ sp<InvokeAnimationListeners> message
+ = new InvokeAnimationListeners(mFinishedAnimators);
+ mLooper->sendMessage(message, 0);
+ }
+ }
+
+private:
+ sp<Looper> mLooper;
+ std::vector< sp<RenderNodeAnimator> > mFinishedAnimators;
+};
+
static void android_view_ThreadedRenderer_postToRenderThread(JNIEnv* env, jobject clazz,
jobject jrunnable) {
RenderTask* task = new JavaTask(env, jrunnable);
RenderThread::getInstance().queue(task);
}
+static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {
+ RootRenderNode* node = new RootRenderNode();
+ node->incStrong(0);
+ node->setName("RootRenderNode");
+ return reinterpret_cast<jlong>(node);
+}
+
static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
- jboolean translucent) {
- return (jlong) new RenderProxy(translucent);
+ jboolean translucent, jlong rootRenderNodePtr) {
+ RenderNode* rootRenderNode = reinterpret_cast<RenderNode*>(rootRenderNodePtr);
+ return (jlong) new RenderProxy(translucent, rootRenderNode);
}
static void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz,
@@ -113,12 +177,11 @@ static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz,
proxy->setup(width, height);
}
-static void android_view_ThreadedRenderer_drawDisplayList(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jlong displayListPtr, jint dirtyLeft, jint dirtyTop,
+static void android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jint dirtyLeft, jint dirtyTop,
jint dirtyRight, jint dirtyBottom) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- proxy->drawDisplayList(displayList, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
+ proxy->syncAndDrawFrame(dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
}
static void android_view_ThreadedRenderer_destroyCanvasAndSurface(JNIEnv* env, jobject clazz,
@@ -187,13 +250,14 @@ const char* const kClassPathName = "android/view/ThreadedRenderer";
static JNINativeMethod gMethods[] = {
#ifdef USE_OPENGL_RENDERER
{ "postToRenderThread", "(Ljava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_postToRenderThread },
- { "nCreateProxy", "(Z)J", (void*) android_view_ThreadedRenderer_createProxy },
+ { "nCreateRootRenderNode", "()J", (void*) android_view_ThreadedRenderer_createRootRenderNode },
+ { "nCreateProxy", "(ZJ)J", (void*) android_view_ThreadedRenderer_createProxy },
{ "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
{ "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize },
{ "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
{ "nPauseSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_pauseSurface },
{ "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup },
- { "nDrawDisplayList", "(JJIIII)V", (void*) android_view_ThreadedRenderer_drawDisplayList },
+ { "nSyncAndDrawFrame", "(JIIII)V", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
{ "nDestroyCanvasAndSurface", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvasAndSurface },
{ "nInvokeFunctor", "(JJZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
{ "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext },