blob: ade718b9e6b80603892339bb6c5502c2b9abf656 [file] [log] [blame]
Doris Liu766431a2016-02-04 22:17:11 +00001/*
2 * Copyright (C) 2016 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#define LOG_TAG "OpenGLRenderer"
17
18#include "jni.h"
19#include "GraphicsJNI.h"
20#include "core_jni_helpers.h"
21#include "log/log.h"
22
23#include "Animator.h"
24#include "Interpolator.h"
25#include "PropertyValuesAnimatorSet.h"
26#include "PropertyValuesHolder.h"
27#include "VectorDrawable.h"
28
29namespace android {
30using namespace uirenderer;
31using namespace VectorDrawable;
32
33static struct {
34 jclass clazz;
35 jmethodID callOnFinished;
36} gVectorDrawableAnimatorClassInfo;
37
38static JNIEnv* getEnv(JavaVM* vm) {
39 JNIEnv* env;
40 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
41 return 0;
42 }
43 return env;
44}
45
Doris Liuc4bb1852016-02-19 21:39:21 +000046static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishListener, jint id) {
Doris Liu766431a2016-02-04 22:17:11 +000047 class AnimationListenerBridge : public AnimationListener {
48 public:
Doris Liuc4bb1852016-02-19 21:39:21 +000049 AnimationListenerBridge(JNIEnv* env, jobject finishListener, jint id) {
Doris Liu766431a2016-02-04 22:17:11 +000050 mFinishListener = env->NewGlobalRef(finishListener);
51 env->GetJavaVM(&mJvm);
Doris Liuc4bb1852016-02-19 21:39:21 +000052 mId = id;
Doris Liu766431a2016-02-04 22:17:11 +000053 }
54
55 virtual ~AnimationListenerBridge() {
56 if (mFinishListener) {
57 onAnimationFinished(NULL);
58 }
59 }
60
61 virtual void onAnimationFinished(BaseRenderNodeAnimator*) {
62 LOG_ALWAYS_FATAL_IF(!mFinishListener, "Finished listener twice?");
63 JNIEnv* env = getEnv(mJvm);
64 env->CallStaticVoidMethod(
65 gVectorDrawableAnimatorClassInfo.clazz,
66 gVectorDrawableAnimatorClassInfo.callOnFinished,
Doris Liuc4bb1852016-02-19 21:39:21 +000067 mFinishListener, mId);
Doris Liu766431a2016-02-04 22:17:11 +000068 releaseJavaObject();
69 }
70
71 private:
72 void releaseJavaObject() {
73 JNIEnv* env = getEnv(mJvm);
74 env->DeleteGlobalRef(mFinishListener);
75 mFinishListener = NULL;
76 }
77
78 JavaVM* mJvm;
79 jobject mFinishListener;
Doris Liuc4bb1852016-02-19 21:39:21 +000080 jint mId;
Doris Liu766431a2016-02-04 22:17:11 +000081 };
Doris Liuc4bb1852016-02-19 21:39:21 +000082 return new AnimationListenerBridge(env, finishListener, id);
Doris Liu766431a2016-02-04 22:17:11 +000083}
84
85static void addAnimator(JNIEnv*, jobject, jlong animatorSetPtr, jlong propertyHolderPtr,
Doris Liuf7167e82016-08-03 17:54:28 -070086 jlong interpolatorPtr, jlong startDelay, jlong duration, jint repeatCount,
87 jint repeatMode) {
Doris Liu766431a2016-02-04 22:17:11 +000088 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
89 PropertyValuesHolder* holder = reinterpret_cast<PropertyValuesHolder*>(propertyHolderPtr);
90 Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr);
Doris Liuf7167e82016-08-03 17:54:28 -070091 RepeatMode mode = static_cast<RepeatMode>(repeatMode);
92 set->addPropertyAnimator(holder, interpolator, startDelay, duration, repeatCount, mode);
Doris Liu766431a2016-02-04 22:17:11 +000093}
94
95static jlong createAnimatorSet(JNIEnv*, jobject) {
96 PropertyValuesAnimatorSet* animatorSet = new PropertyValuesAnimatorSet();
97 return reinterpret_cast<jlong>(animatorSet);
98}
99
Doris Liu718cd3e2016-05-17 16:50:31 -0700100static void setVectorDrawableTarget(JNIEnv*, jobject,jlong animatorPtr, jlong vectorDrawablePtr) {
101 VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(vectorDrawablePtr);
102 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorPtr);
103 set->setVectorDrawable(tree);
104}
105
Doris Liu766431a2016-02-04 22:17:11 +0000106static jlong createGroupPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jint propertyId,
107 jfloat startValue, jfloat endValue) {
108 VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(nativePtr);
109 GroupPropertyValuesHolder* newHolder = new GroupPropertyValuesHolder(group, propertyId,
110 startValue, endValue);
111 return reinterpret_cast<jlong>(newHolder);
112}
113
114static jlong createPathDataPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jlong startValuePtr,
115 jlong endValuePtr) {
116 VectorDrawable::Path* path = reinterpret_cast<VectorDrawable::Path*>(nativePtr);
117 PathData* startData = reinterpret_cast<PathData*>(startValuePtr);
118 PathData* endData = reinterpret_cast<PathData*>(endValuePtr);
119 PathDataPropertyValuesHolder* newHolder = new PathDataPropertyValuesHolder(path,
120 startData, endData);
121 return reinterpret_cast<jlong>(newHolder);
122}
123
124static jlong createPathColorPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jint propertyId,
125 int startValue, jint endValue) {
126 VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(nativePtr);
127 FullPathColorPropertyValuesHolder* newHolder = new FullPathColorPropertyValuesHolder(fullPath,
128 propertyId, startValue, endValue);
129 return reinterpret_cast<jlong>(newHolder);
130}
131
132static jlong createPathPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jint propertyId,
133 float startValue, jfloat endValue) {
134 VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(nativePtr);
135 FullPathPropertyValuesHolder* newHolder = new FullPathPropertyValuesHolder(fullPath,
136 propertyId, startValue, endValue);
137 return reinterpret_cast<jlong>(newHolder);
138}
139
140static jlong createRootAlphaPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jfloat startValue,
141 float endValue) {
142 VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(nativePtr);
143 RootAlphaPropertyValuesHolder* newHolder = new RootAlphaPropertyValuesHolder(tree,
144 startValue, endValue);
145 return reinterpret_cast<jlong>(newHolder);
146}
Doris Liuc9493872016-06-02 16:20:18 -0700147static void setFloatPropertyHolderData(JNIEnv* env, jobject, jlong propertyHolderPtr,
Doris Liu766431a2016-02-04 22:17:11 +0000148 jfloatArray srcData, jint length) {
Doris Liu766431a2016-02-04 22:17:11 +0000149 jfloat* propertyData = env->GetFloatArrayElements(srcData, nullptr);
Doris Liuc9493872016-06-02 16:20:18 -0700150 PropertyValuesHolderImpl<float>* holder =
151 reinterpret_cast<PropertyValuesHolderImpl<float>*>(propertyHolderPtr);
Doris Liu766431a2016-02-04 22:17:11 +0000152 holder->setPropertyDataSource(propertyData, length);
153 env->ReleaseFloatArrayElements(srcData, propertyData, JNI_ABORT);
154}
Doris Liuc9493872016-06-02 16:20:18 -0700155
156static void setIntPropertyHolderData(JNIEnv* env, jobject, jlong propertyHolderPtr,
157 jintArray srcData, jint length) {
158 jint* propertyData = env->GetIntArrayElements(srcData, nullptr);
159 PropertyValuesHolderImpl<int>* holder =
160 reinterpret_cast<PropertyValuesHolderImpl<int>*>(propertyHolderPtr);
161 holder->setPropertyDataSource(propertyData, length);
162 env->ReleaseIntArrayElements(srcData, propertyData, JNI_ABORT);
163}
164
Doris Liuc4bb1852016-02-19 21:39:21 +0000165static void start(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
Doris Liu766431a2016-02-04 22:17:11 +0000166 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
Doris Liuc4bb1852016-02-19 21:39:21 +0000167 AnimationListener* listener = createAnimationListener(env, finishListener, id);
Doris Liu766431a2016-02-04 22:17:11 +0000168 set->start(listener);
169}
170
Doris Liuc4bb1852016-02-19 21:39:21 +0000171static void reverse(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
172 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
173 AnimationListener* listener = createAnimationListener(env, finishListener, id);
174 set->reverse(listener);
Doris Liu766431a2016-02-04 22:17:11 +0000175}
176
177static void end(JNIEnv*, jobject, jlong animatorSetPtr) {
178 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
179 set->end();
180}
181
182static void reset(JNIEnv*, jobject, jlong animatorSetPtr) {
183 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
184 set->reset();
185}
186
187static const JNINativeMethod gMethods[] = {
188 {"nCreateAnimatorSet", "()J", (void*)createAnimatorSet},
Doris Liu718cd3e2016-05-17 16:50:31 -0700189 {"nSetVectorDrawableTarget", "(JJ)V", (void*)setVectorDrawableTarget},
Doris Liuf7167e82016-08-03 17:54:28 -0700190 {"nAddAnimator", "(JJJJJII)V", (void*)addAnimator},
Doris Liu766431a2016-02-04 22:17:11 +0000191 {"nCreateGroupPropertyHolder", "!(JIFF)J", (void*)createGroupPropertyHolder},
192 {"nCreatePathDataPropertyHolder", "!(JJJ)J", (void*)createPathDataPropertyHolder},
193 {"nCreatePathColorPropertyHolder", "!(JIII)J", (void*)createPathColorPropertyHolder},
194 {"nCreatePathPropertyHolder", "!(JIFF)J", (void*)createPathPropertyHolder},
195 {"nCreateRootAlphaPropertyHolder", "!(JFF)J", (void*)createRootAlphaPropertyHolder},
Doris Liuc9493872016-06-02 16:20:18 -0700196 {"nSetPropertyHolderData", "(J[FI)V", (void*)setFloatPropertyHolderData},
197 {"nSetPropertyHolderData", "(J[II)V", (void*)setIntPropertyHolderData},
Doris Liu28cfd202016-02-22 16:51:40 -0800198 {"nStart", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)start},
199 {"nReverse", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)reverse},
Doris Liu766431a2016-02-04 22:17:11 +0000200 {"nEnd", "!(J)V", (void*)end},
201 {"nReset", "!(J)V", (void*)reset},
202};
203
Doris Liu28cfd202016-02-22 16:51:40 -0800204const char* const kClassPathName = "android/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT";
Doris Liu766431a2016-02-04 22:17:11 +0000205int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env) {
206 gVectorDrawableAnimatorClassInfo.clazz = FindClassOrDie(env, kClassPathName);
207 gVectorDrawableAnimatorClassInfo.clazz = MakeGlobalRefOrDie(env,
208 gVectorDrawableAnimatorClassInfo.clazz);
209
210 gVectorDrawableAnimatorClassInfo.callOnFinished = GetStaticMethodIDOrDie(
211 env, gVectorDrawableAnimatorClassInfo.clazz, "callOnFinished",
Doris Liu28cfd202016-02-22 16:51:40 -0800212 "(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V");
Doris Liu766431a2016-02-04 22:17:11 +0000213 return RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedVectorDrawable",
214 gMethods, NELEM(gMethods));
215}
216
217}; // namespace android