diff options
Diffstat (limited to 'core/jni')
-rw-r--r-- | core/jni/Android.mk | 1 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_view_RenderNode.cpp | 23 | ||||
-rw-r--r-- | core/jni/android_view_RenderNodeAnimator.cpp | 127 | ||||
-rw-r--r-- | core/jni/android_view_RenderNodeAnimator.h | 36 | ||||
-rw-r--r-- | core/jni/android_view_ThreadedRenderer.cpp | 80 |
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 }, |