blob: 7c0c6ef5aeb070eb5ef899c42af0b53551a7464e [file] [log] [blame]
John Recke45b1fd2014-04-15 09:50:16 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "OpenGLRenderer"
18
John Recke45b1fd2014-04-15 09:50:16 -070019#include "jni.h"
20#include "GraphicsJNI.h"
21#include <nativehelper/JNIHelp.h>
22#include <android_runtime/AndroidRuntime.h>
23
24#include <Animator.h>
25#include <Interpolator.h>
26#include <RenderProperties.h>
27
28namespace android {
29
30using namespace uirenderer;
31
32static struct {
33 jclass clazz;
34
35 jmethodID callOnFinished;
36} gRenderNodeAnimatorClassInfo;
37
John Reck496b8772014-04-30 16:59:40 -070038#ifdef USE_OPENGL_RENDERER
39
John Recke45b1fd2014-04-15 09:50:16 -070040static JNIEnv* getEnv(JavaVM* vm) {
41 JNIEnv* env;
42 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
43 return 0;
44 }
45 return env;
46}
47
John Reck52244ff2014-05-01 21:27:37 -070048class AnimationListenerBridge : public AnimationListener {
49public:
50 // This holds a strong reference to a Java WeakReference<T> object. This avoids
51 // cyclic-references-of-doom. If you think "I know, just use NewWeakGlobalRef!"
52 // then you end up with basically a PhantomReference, which is totally not
53 // what we want.
54 AnimationListenerBridge(JNIEnv* env, jobject weakThis) {
55 mWeakThis = env->NewGlobalRef(weakThis);
56 env->GetJavaVM(&mJvm);
57 }
John Recke45b1fd2014-04-15 09:50:16 -070058
John Reck52244ff2014-05-01 21:27:37 -070059 virtual ~AnimationListenerBridge() {
60 JNIEnv* env = getEnv(mJvm);
61 env->DeleteGlobalRef(mWeakThis);
62 mWeakThis = NULL;
63 }
John Recke45b1fd2014-04-15 09:50:16 -070064
John Reckff941dc2014-05-14 16:34:14 -070065 virtual void onAnimationFinished(BaseRenderNodeAnimator*) {
John Reck52244ff2014-05-01 21:27:37 -070066 JNIEnv* env = getEnv(mJvm);
67 env->CallStaticVoidMethod(
68 gRenderNodeAnimatorClassInfo.clazz,
69 gRenderNodeAnimatorClassInfo.callOnFinished,
70 mWeakThis);
71 }
John Recke45b1fd2014-04-15 09:50:16 -070072
John Reck52244ff2014-05-01 21:27:37 -070073private:
74 JavaVM* mJvm;
75 jobject mWeakThis;
76};
77
78static inline RenderPropertyAnimator::RenderProperty toRenderProperty(jint property) {
79 LOG_ALWAYS_FATAL_IF(property < 0 || property > RenderPropertyAnimator::ALPHA,
John Recke45b1fd2014-04-15 09:50:16 -070080 "Invalid property %d", property);
John Reck52244ff2014-05-01 21:27:37 -070081 return static_cast<RenderPropertyAnimator::RenderProperty>(property);
82}
83
John Reck52244ff2014-05-01 21:27:37 -070084static inline CanvasPropertyPaintAnimator::PaintField toPaintField(jint field) {
85 LOG_ALWAYS_FATAL_IF(field < 0
86 || field > CanvasPropertyPaintAnimator::ALPHA,
87 "Invalid paint field %d", field);
88 return static_cast<CanvasPropertyPaintAnimator::PaintField>(field);
89}
90
91static jlong createAnimator(JNIEnv* env, jobject clazz, jobject weakThis,
John Reckff941dc2014-05-14 16:34:14 -070092 jint propertyRaw, jfloat finalValue) {
John Reck52244ff2014-05-01 21:27:37 -070093 RenderPropertyAnimator::RenderProperty property = toRenderProperty(propertyRaw);
John Reck52244ff2014-05-01 21:27:37 -070094
John Reckff941dc2014-05-14 16:34:14 -070095 BaseRenderNodeAnimator* animator = new RenderPropertyAnimator(property, finalValue);
John Reck52244ff2014-05-01 21:27:37 -070096 animator->setListener(new AnimationListenerBridge(env, weakThis));
97 return reinterpret_cast<jlong>( animator );
98}
99
100static jlong createCanvasPropertyFloatAnimator(JNIEnv* env, jobject clazz,
John Reckff941dc2014-05-14 16:34:14 -0700101 jobject weakThis, jlong canvasPropertyPtr, jfloat finalValue) {
John Reck52244ff2014-05-01 21:27:37 -0700102 CanvasPropertyPrimitive* canvasProperty = reinterpret_cast<CanvasPropertyPrimitive*>(canvasPropertyPtr);
John Reckff941dc2014-05-14 16:34:14 -0700103 BaseRenderNodeAnimator* animator = new CanvasPropertyPrimitiveAnimator(canvasProperty, finalValue);
John Reck52244ff2014-05-01 21:27:37 -0700104 animator->setListener(new AnimationListenerBridge(env, weakThis));
105 return reinterpret_cast<jlong>( animator );
106}
107
108static jlong createCanvasPropertyPaintAnimator(JNIEnv* env, jobject clazz,
109 jobject weakThis, jlong canvasPropertyPtr, jint paintFieldRaw,
John Reckff941dc2014-05-14 16:34:14 -0700110 jfloat finalValue) {
John Reck52244ff2014-05-01 21:27:37 -0700111 CanvasPropertyPaint* canvasProperty = reinterpret_cast<CanvasPropertyPaint*>(canvasPropertyPtr);
112 CanvasPropertyPaintAnimator::PaintField paintField = toPaintField(paintFieldRaw);
John Reckff941dc2014-05-14 16:34:14 -0700113 BaseRenderNodeAnimator* animator = new CanvasPropertyPaintAnimator(
114 canvasProperty, paintField, finalValue);
John Reck52244ff2014-05-01 21:27:37 -0700115 animator->setListener(new AnimationListenerBridge(env, weakThis));
John Recke45b1fd2014-04-15 09:50:16 -0700116 return reinterpret_cast<jlong>( animator );
117}
118
John Reckd3de42c2014-07-15 14:29:33 -0700119static jlong createRevealAnimator(JNIEnv* env, jobject clazz, jobject weakThis,
120 jint centerX, jint centerY, jboolean inverseClip, jfloat startRadius, jfloat endRadius) {
121 BaseRenderNodeAnimator* animator = new RevealAnimator(centerX, centerY, inverseClip,
122 startRadius, endRadius);
123 animator->setListener(new AnimationListenerBridge(env, weakThis));
124 return reinterpret_cast<jlong>( animator );
125}
126
John Reckc6b32642014-06-02 11:00:09 -0700127static void setStartValue(JNIEnv* env, jobject clazz, jlong animatorPtr, jfloat startValue) {
128 BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
129 animator->setStartValue(startValue);
130}
131
Alan Viverettead2f8e32014-05-16 13:28:33 -0700132static void setDuration(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong duration) {
John Recke45b1fd2014-04-15 09:50:16 -0700133 LOG_ALWAYS_FATAL_IF(duration < 0, "Duration cannot be negative");
John Reckff941dc2014-05-14 16:34:14 -0700134 BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
John Recke45b1fd2014-04-15 09:50:16 -0700135 animator->setDuration(duration);
136}
137
Alan Viverettead2f8e32014-05-16 13:28:33 -0700138static jlong getDuration(JNIEnv* env, jobject clazz, jlong animatorPtr) {
John Reckff941dc2014-05-14 16:34:14 -0700139 BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
Alan Viverettead2f8e32014-05-16 13:28:33 -0700140 return static_cast<jlong>(animator->duration());
141}
142
143static void setStartDelay(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong startDelay) {
144 LOG_ALWAYS_FATAL_IF(startDelay < 0, "Start delay cannot be negative");
145 BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
146 animator->setStartDelay(startDelay);
147}
148
149static jlong getStartDelay(JNIEnv* env, jobject clazz, jlong animatorPtr) {
150 BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
151 return static_cast<jlong>(animator->startDelay());
John Reck315c3292014-05-09 19:21:04 -0700152}
153
154static void setInterpolator(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong interpolatorPtr) {
John Reckff941dc2014-05-14 16:34:14 -0700155 BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
John Reck315c3292014-05-09 19:21:04 -0700156 Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr);
157 animator->setInterpolator(interpolator);
158}
159
John Reck8d8af3c2014-07-01 15:23:45 -0700160static void start(JNIEnv* env, jobject clazz, jlong animatorPtr) {
161 BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
162 animator->start();
163}
164
John Reckd3de42c2014-07-15 14:29:33 -0700165static void end(JNIEnv* env, jobject clazz, jlong animatorPtr) {
John Reck68bfe0a2014-06-24 15:34:58 -0700166 BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
John Reckd3de42c2014-07-15 14:29:33 -0700167 animator->end();
John Reck68bfe0a2014-06-24 15:34:58 -0700168}
169
John Reck496b8772014-04-30 16:59:40 -0700170#endif
171
John Recke45b1fd2014-04-15 09:50:16 -0700172// ----------------------------------------------------------------------------
173// JNI Glue
174// ----------------------------------------------------------------------------
175
176const char* const kClassPathName = "android/view/RenderNodeAnimator";
177
178static JNINativeMethod gMethods[] = {
John Reck496b8772014-04-30 16:59:40 -0700179#ifdef USE_OPENGL_RENDERER
John Reckff941dc2014-05-14 16:34:14 -0700180 { "nCreateAnimator", "(Ljava/lang/ref/WeakReference;IF)J", (void*) createAnimator },
181 { "nCreateCanvasPropertyFloatAnimator", "(Ljava/lang/ref/WeakReference;JF)J", (void*) createCanvasPropertyFloatAnimator },
182 { "nCreateCanvasPropertyPaintAnimator", "(Ljava/lang/ref/WeakReference;JIF)J", (void*) createCanvasPropertyPaintAnimator },
John Reckd3de42c2014-07-15 14:29:33 -0700183 { "nCreateRevealAnimator", "(Ljava/lang/ref/WeakReference;IIZFF)J", (void*) createRevealAnimator },
John Reckc6b32642014-06-02 11:00:09 -0700184 { "nSetStartValue", "(JF)V", (void*) setStartValue },
Alan Viverettead2f8e32014-05-16 13:28:33 -0700185 { "nSetDuration", "(JJ)V", (void*) setDuration },
186 { "nGetDuration", "(J)J", (void*) getDuration },
187 { "nSetStartDelay", "(JJ)V", (void*) setStartDelay },
188 { "nGetStartDelay", "(J)J", (void*) getStartDelay },
John Reck315c3292014-05-09 19:21:04 -0700189 { "nSetInterpolator", "(JJ)V", (void*) setInterpolator },
John Reck8d8af3c2014-07-01 15:23:45 -0700190 { "nStart", "(J)V", (void*) start },
John Reckd3de42c2014-07-15 14:29:33 -0700191 { "nEnd", "(J)V", (void*) end },
John Reck496b8772014-04-30 16:59:40 -0700192#endif
John Recke45b1fd2014-04-15 09:50:16 -0700193};
194
195#define FIND_CLASS(var, className) \
196 var = env->FindClass(className); \
197 LOG_FATAL_IF(! var, "Unable to find class " className);
198
199#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
200 var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
201 LOG_FATAL_IF(! var, "Unable to find method " methodName);
202
203int register_android_view_RenderNodeAnimator(JNIEnv* env) {
204 FIND_CLASS(gRenderNodeAnimatorClassInfo.clazz, kClassPathName);
205 gRenderNodeAnimatorClassInfo.clazz = jclass(env->NewGlobalRef(gRenderNodeAnimatorClassInfo.clazz));
206
207 GET_STATIC_METHOD_ID(gRenderNodeAnimatorClassInfo.callOnFinished, gRenderNodeAnimatorClassInfo.clazz,
208 "callOnFinished", "(Ljava/lang/ref/WeakReference;)V");
209
210 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
211}
212
213
214} // namespace android