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/graphics/CanvasProperty.cpp68
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp12
-rw-r--r--core/jni/android_view_RenderNodeAnimator.cpp103
-rw-r--r--core/jni/android_view_RenderNodeAnimator.h40
-rw-r--r--core/jni/android_view_ThreadedRenderer.cpp42
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,