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/graphics/CanvasProperty.cpp | 68 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 12 | ||||
-rw-r--r-- | core/jni/android_view_RenderNodeAnimator.cpp | 103 | ||||
-rw-r--r-- | core/jni/android_view_RenderNodeAnimator.h | 40 | ||||
-rw-r--r-- | core/jni/android_view_ThreadedRenderer.cpp | 42 |
7 files changed, 183 insertions, 85 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk index ee59c8a..667bf6c 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -92,6 +92,7 @@ LOCAL_SRC_FILES:= \ android/graphics/BitmapFactory.cpp \ android/graphics/Camera.cpp \ android/graphics/Canvas.cpp \ + android/graphics/CanvasProperty.cpp \ android/graphics/ColorFilter.cpp \ android/graphics/DrawFilter.cpp \ android/graphics/CreateJavaOutputStreamAdaptor.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index f964cd2..66fbb8e 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -105,6 +105,7 @@ extern int register_android_content_StringBlock(JNIEnv* env); extern int register_android_content_XmlBlock(JNIEnv* env); extern int register_android_emoji_EmojiFactory(JNIEnv* env); extern int register_android_graphics_Canvas(JNIEnv* env); +extern int register_android_graphics_CanvasProperty(JNIEnv* env); extern int register_android_graphics_ColorFilter(JNIEnv* env); extern int register_android_graphics_DrawFilter(JNIEnv* env); extern int register_android_graphics_Matrix(JNIEnv* env); @@ -1221,6 +1222,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_graphics_Camera), REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor), REG_JNI(register_android_graphics_Canvas), + REG_JNI(register_android_graphics_CanvasProperty), REG_JNI(register_android_graphics_ColorFilter), REG_JNI(register_android_graphics_DrawFilter), REG_JNI(register_android_graphics_Interpolator), diff --git a/core/jni/android/graphics/CanvasProperty.cpp b/core/jni/android/graphics/CanvasProperty.cpp new file mode 100644 index 0000000..70e2db5 --- /dev/null +++ b/core/jni/android/graphics/CanvasProperty.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 20014 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 "GraphicsJNI.h" +#include <android_runtime/AndroidRuntime.h> + +#include <utils/VirtualLightRefBase.h> +#include <CanvasProperty.h> + +namespace android { + +using namespace uirenderer; + +#ifdef USE_OPENGL_RENDERER + +static jlong incRef(VirtualLightRefBase* ptr) { + ptr->incStrong(0); + return reinterpret_cast<jlong>(ptr); +} + +static jlong createFloat(JNIEnv* env, jobject clazz, jfloat initialValue) { + return incRef(new CanvasPropertyPrimitive(initialValue)); +} + +static jlong createPaint(JNIEnv* env, jobject clazz, jlong paintPtr) { + const SkPaint* paint = reinterpret_cast<const SkPaint*>(paintPtr); + return incRef(new CanvasPropertyPaint(*paint)); +} + +static void unref(JNIEnv* env, jobject clazz, jlong containerPtr) { + reinterpret_cast<VirtualLightRefBase*>(containerPtr)->decStrong(0); +} + +#endif + +// ---------------------------------------------------------------------------- +// JNI Glue +// ---------------------------------------------------------------------------- + +const char* const kClassPathName = "android/graphics/CanvasProperty"; + +static JNINativeMethod gMethods[] = { +#ifdef USE_OPENGL_RENDERER + { "nCreateFloat", "(F)J", (void*) createFloat }, + { "nCreatePaint", "(J)J", (void*) createPaint }, + { "nUnref", "(J)V", (void*) unref }, +#endif +}; + +int register_android_graphics_CanvasProperty(JNIEnv* env) { + return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); +} + +}; // namespace android diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index ef5ebd0..3aa179d 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -49,6 +49,7 @@ #include <Stencil.h> #include <Rect.h> #include <RenderNode.h> +#include <CanvasProperty.h> #include <TextLayout.h> #include <TextLayoutCache.h> @@ -544,6 +545,16 @@ static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz, renderer->drawCircle(x, y, radius, paint); } +static void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz, + jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) { + OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); + CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr); + CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr); + CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr); + CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr); + renderer->drawCircle(xProp, yProp, radiusProp, paintProp); +} + static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz, jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, jlong paintPtr) { @@ -1041,6 +1052,7 @@ static JNINativeMethod gMethods[] = { { "nDrawRects", "(J[FIJ)V", (void*) android_view_GLES20Canvas_drawRects }, { "nDrawRoundRect", "(JFFFFFFJ)V", (void*) android_view_GLES20Canvas_drawRoundRect }, { "nDrawCircle", "(JFFFJ)V", (void*) android_view_GLES20Canvas_drawCircle }, + { "nDrawCircle", "(JJJJJ)V", (void*) android_view_GLES20Canvas_drawCircleProps }, { "nDrawOval", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawOval }, { "nDrawArc", "(JFFFFFFZJ)V", (void*) android_view_GLES20Canvas_drawArc }, { "nDrawPoints", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawPoints }, diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp index b92c992..3be013b 100644 --- a/core/jni/android_view_RenderNodeAnimator.cpp +++ b/core/jni/android_view_RenderNodeAnimator.cpp @@ -16,8 +16,6 @@ #define LOG_TAG "OpenGLRenderer" -#include "android_view_RenderNodeAnimator.h" - #include "jni.h" #include "GraphicsJNI.h" #include <nativehelper/JNIHelp.h> @@ -47,46 +45,93 @@ static JNIEnv* getEnv(JavaVM* vm) { 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); -} +class AnimationListenerBridge : public AnimationListener { +public: + // This holds a strong reference to a Java WeakReference<T> object. This avoids + // 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); + env->GetJavaVM(&mJvm); + } -RenderNodeAnimator::~RenderNodeAnimator() { - JNIEnv* env = getEnv(mJvm); - env->DeleteGlobalRef(mWeakThis); - mWeakThis = NULL; -} + virtual ~AnimationListenerBridge() { + JNIEnv* env = getEnv(mJvm); + env->DeleteGlobalRef(mWeakThis); + mWeakThis = NULL; + } -void RenderNodeAnimator::callOnFinished() { - JNIEnv* env = getEnv(mJvm); - env->CallStaticVoidMethod( - gRenderNodeAnimatorClassInfo.clazz, - gRenderNodeAnimatorClassInfo.callOnFinished, - mWeakThis); -} + virtual void onAnimationFinished(BaseAnimator*) { + 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, +private: + JavaVM* mJvm; + jobject mWeakThis; +}; + +static inline RenderPropertyAnimator::RenderProperty toRenderProperty(jint property) { + LOG_ALWAYS_FATAL_IF(property < 0 || property > RenderPropertyAnimator::ALPHA, "Invalid property %d", property); + return static_cast<RenderPropertyAnimator::RenderProperty>(property); +} + +static inline RenderPropertyAnimator::DeltaValueType toDeltaType(jint deltaType) { LOG_ALWAYS_FATAL_IF(deltaType != RenderPropertyAnimator::DELTA && deltaType != RenderPropertyAnimator::ABSOLUTE, "Invalid delta type %d", deltaType); + return static_cast<RenderPropertyAnimator::DeltaValueType>(deltaType); +} + +static inline CanvasPropertyPaintAnimator::PaintField toPaintField(jint field) { + LOG_ALWAYS_FATAL_IF(field < 0 + || field > CanvasPropertyPaintAnimator::ALPHA, + "Invalid paint field %d", field); + return static_cast<CanvasPropertyPaintAnimator::PaintField>(field); +} + +static jlong createAnimator(JNIEnv* env, jobject clazz, jobject weakThis, + jint propertyRaw, jint deltaTypeRaw, jfloat deltaValue) { + RenderPropertyAnimator::RenderProperty property = toRenderProperty(propertyRaw); + RenderPropertyAnimator::DeltaValueType deltaType = toDeltaType(deltaTypeRaw); + + BaseAnimator* animator = new RenderPropertyAnimator(property, deltaType, deltaValue); + animator->incStrong(0); + animator->setListener(new AnimationListenerBridge(env, weakThis)); + return reinterpret_cast<jlong>( animator ); +} + +static jlong createCanvasPropertyFloatAnimator(JNIEnv* env, jobject clazz, + jobject weakThis, jlong canvasPropertyPtr, jint deltaTypeRaw, jfloat deltaValue) { + RenderPropertyAnimator::DeltaValueType deltaType = toDeltaType(deltaTypeRaw); + CanvasPropertyPrimitive* canvasProperty = reinterpret_cast<CanvasPropertyPrimitive*>(canvasPropertyPtr); + BaseAnimator* animator = new CanvasPropertyPrimitiveAnimator(canvasProperty, deltaType, deltaValue); + animator->incStrong(0); + animator->setListener(new AnimationListenerBridge(env, weakThis)); + return reinterpret_cast<jlong>( animator ); +} - RenderNodeAnimator* animator = new RenderNodeAnimator(env, weakThis, - static_cast<RenderPropertyAnimator::RenderProperty>(property), - static_cast<RenderPropertyAnimator::DeltaValueType>(deltaType), - deltaValue); +static jlong createCanvasPropertyPaintAnimator(JNIEnv* env, jobject clazz, + jobject weakThis, jlong canvasPropertyPtr, jint paintFieldRaw, + jint deltaTypeRaw, jfloat deltaValue) { + RenderPropertyAnimator::DeltaValueType deltaType = toDeltaType(deltaTypeRaw); + CanvasPropertyPaint* canvasProperty = reinterpret_cast<CanvasPropertyPaint*>(canvasPropertyPtr); + CanvasPropertyPaintAnimator::PaintField paintField = toPaintField(paintFieldRaw); + BaseAnimator* animator = new CanvasPropertyPaintAnimator( + canvasProperty, paintField, deltaType, deltaValue); animator->incStrong(0); + animator->setListener(new AnimationListenerBridge(env, weakThis)); 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); + BaseAnimator* animator = reinterpret_cast<BaseAnimator*>(animatorPtr); animator->setDuration(duration); } @@ -106,6 +151,8 @@ const char* const kClassPathName = "android/view/RenderNodeAnimator"; static JNINativeMethod gMethods[] = { #ifdef USE_OPENGL_RENDERER { "nCreateAnimator", "(Ljava/lang/ref/WeakReference;IIF)J", (void*) createAnimator }, + { "nCreateCanvasPropertyFloatAnimator", "(Ljava/lang/ref/WeakReference;JIF)J", (void*) createCanvasPropertyFloatAnimator }, + { "nCreateCanvasPropertyPaintAnimator", "(Ljava/lang/ref/WeakReference;JIIF)J", (void*) createCanvasPropertyPaintAnimator }, { "nSetDuration", "(JI)V", (void*) setDuration }, { "nUnref", "(J)V", (void*) unref }, #endif diff --git a/core/jni/android_view_RenderNodeAnimator.h b/core/jni/android_view_RenderNodeAnimator.h deleted file mode 100644 index 760ca91..0000000 --- a/core/jni/android_view_RenderNodeAnimator.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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" - -#ifdef USE_OPENGL_RENDERER - -#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; -}; - -} - -#endif diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 58fc1e1..564c9a6 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -26,7 +26,7 @@ #include <android_runtime/android_view_Surface.h> #include <system/window.h> -#include "android_view_RenderNodeAnimator.h" +#include <Animator.h> #include <RenderNode.h> #include <renderthread/RenderProxy.h> #include <renderthread/RenderTask.h> @@ -67,26 +67,34 @@ private: jobject mRunnable; }; +class OnFinishedEvent { +public: + OnFinishedEvent(BaseAnimator* animator, AnimationListener* listener) + : animator(animator), listener(listener) {} + sp<BaseAnimator> animator; + sp<AnimationListener> listener; +}; + class InvokeAnimationListeners : public MessageHandler { public: - InvokeAnimationListeners(std::vector< sp<RenderNodeAnimator> >& animators) { - mAnimators.swap(animators); + InvokeAnimationListeners(std::vector<OnFinishedEvent>& events) { + mOnFinishedEvents.swap(events); } - static void callOnFinished(const sp<RenderNodeAnimator>& animator) { - animator->callOnFinished(); + static void callOnFinished(OnFinishedEvent& event) { + event.listener->onAnimationFinished(event.animator.get()); } virtual void handleMessage(const Message& message) { - std::for_each(mAnimators.begin(), mAnimators.end(), callOnFinished); - mAnimators.clear(); + std::for_each(mOnFinishedEvents.begin(), mOnFinishedEvents.end(), callOnFinished); + mOnFinishedEvents.clear(); } private: - std::vector< sp<RenderNodeAnimator> > mAnimators; + std::vector<OnFinishedEvent> mOnFinishedEvents; }; -class RootRenderNode : public RenderNode, public AnimationListener { +class RootRenderNode : public RenderNode, public AnimationHook { public: RootRenderNode() : RenderNode() { mLooper = Looper::getForThread(); @@ -96,27 +104,27 @@ public: virtual ~RootRenderNode() {} - void onAnimationFinished(const sp<RenderPropertyAnimator>& animator) { - mFinishedAnimators.push_back( - reinterpret_cast<RenderNodeAnimator*>(animator.get())); + virtual void callOnFinished(BaseAnimator* animator, AnimationListener* listener) { + OnFinishedEvent event(animator, listener); + mOnFinishedEvents.push_back(event); } virtual void prepareTree(TreeInfo& info) { - info.animationListener = this; + info.animationHook = this; RenderNode::prepareTree(info); - info.animationListener = NULL; + info.animationHook = NULL; // post all the finished stuff - if (mFinishedAnimators.size()) { + if (mOnFinishedEvents.size()) { sp<InvokeAnimationListeners> message - = new InvokeAnimationListeners(mFinishedAnimators); + = new InvokeAnimationListeners(mOnFinishedEvents); mLooper->sendMessage(message, 0); } } private: sp<Looper> mLooper; - std::vector< sp<RenderNodeAnimator> > mFinishedAnimators; + std::vector<OnFinishedEvent> mOnFinishedEvents; }; static void android_view_ThreadedRenderer_postToRenderThread(JNIEnv* env, jobject clazz, |