blob: b6b53666e26e829feb671f991d07cbaca1beedf5 [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
Mark Salyzyn96bf5982016-09-28 16:15:30 -070018#include "android/log.h"
19
Doris Liu766431a2016-02-04 22:17:11 +000020#include "jni.h"
21#include "GraphicsJNI.h"
22#include "core_jni_helpers.h"
Doris Liu766431a2016-02-04 22:17:11 +000023
24#include "Animator.h"
25#include "Interpolator.h"
26#include "PropertyValuesAnimatorSet.h"
27#include "PropertyValuesHolder.h"
28#include "VectorDrawable.h"
29
30namespace android {
31using namespace uirenderer;
32using namespace VectorDrawable;
33
34static struct {
35 jclass clazz;
36 jmethodID callOnFinished;
37} gVectorDrawableAnimatorClassInfo;
38
39static JNIEnv* getEnv(JavaVM* vm) {
40 JNIEnv* env;
41 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
42 return 0;
43 }
44 return env;
45}
46
Doris Liuc4bb1852016-02-19 21:39:21 +000047static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishListener, jint id) {
Doris Liu766431a2016-02-04 22:17:11 +000048 class AnimationListenerBridge : public AnimationListener {
49 public:
Doris Liuc4bb1852016-02-19 21:39:21 +000050 AnimationListenerBridge(JNIEnv* env, jobject finishListener, jint id) {
Doris Liu766431a2016-02-04 22:17:11 +000051 mFinishListener = env->NewGlobalRef(finishListener);
52 env->GetJavaVM(&mJvm);
Doris Liuc4bb1852016-02-19 21:39:21 +000053 mId = id;
Doris Liu766431a2016-02-04 22:17:11 +000054 }
55
56 virtual ~AnimationListenerBridge() {
57 if (mFinishListener) {
58 onAnimationFinished(NULL);
59 }
60 }
61
62 virtual void onAnimationFinished(BaseRenderNodeAnimator*) {
63 LOG_ALWAYS_FATAL_IF(!mFinishListener, "Finished listener twice?");
64 JNIEnv* env = getEnv(mJvm);
65 env->CallStaticVoidMethod(
66 gVectorDrawableAnimatorClassInfo.clazz,
67 gVectorDrawableAnimatorClassInfo.callOnFinished,
Doris Liuc4bb1852016-02-19 21:39:21 +000068 mFinishListener, mId);
Doris Liu766431a2016-02-04 22:17:11 +000069 releaseJavaObject();
70 }
71
72 private:
73 void releaseJavaObject() {
74 JNIEnv* env = getEnv(mJvm);
75 env->DeleteGlobalRef(mFinishListener);
76 mFinishListener = NULL;
77 }
78
79 JavaVM* mJvm;
80 jobject mFinishListener;
Doris Liuc4bb1852016-02-19 21:39:21 +000081 jint mId;
Doris Liu766431a2016-02-04 22:17:11 +000082 };
Doris Liuc4bb1852016-02-19 21:39:21 +000083 return new AnimationListenerBridge(env, finishListener, id);
Doris Liu766431a2016-02-04 22:17:11 +000084}
85
86static void addAnimator(JNIEnv*, jobject, jlong animatorSetPtr, jlong propertyHolderPtr,
Doris Liuf7167e82016-08-03 17:54:28 -070087 jlong interpolatorPtr, jlong startDelay, jlong duration, jint repeatCount,
88 jint repeatMode) {
Doris Liu766431a2016-02-04 22:17:11 +000089 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
90 PropertyValuesHolder* holder = reinterpret_cast<PropertyValuesHolder*>(propertyHolderPtr);
91 Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr);
Doris Liuf7167e82016-08-03 17:54:28 -070092 RepeatMode mode = static_cast<RepeatMode>(repeatMode);
93 set->addPropertyAnimator(holder, interpolator, startDelay, duration, repeatCount, mode);
Doris Liu766431a2016-02-04 22:17:11 +000094}
95
96static jlong createAnimatorSet(JNIEnv*, jobject) {
97 PropertyValuesAnimatorSet* animatorSet = new PropertyValuesAnimatorSet();
98 return reinterpret_cast<jlong>(animatorSet);
99}
100
Doris Liu718cd3e2016-05-17 16:50:31 -0700101static void setVectorDrawableTarget(JNIEnv*, jobject,jlong animatorPtr, jlong vectorDrawablePtr) {
102 VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(vectorDrawablePtr);
103 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorPtr);
104 set->setVectorDrawable(tree);
105}
106
Doris Liu766431a2016-02-04 22:17:11 +0000107static jlong createGroupPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jint propertyId,
108 jfloat startValue, jfloat endValue) {
109 VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(nativePtr);
110 GroupPropertyValuesHolder* newHolder = new GroupPropertyValuesHolder(group, propertyId,
111 startValue, endValue);
112 return reinterpret_cast<jlong>(newHolder);
113}
114
115static jlong createPathDataPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jlong startValuePtr,
116 jlong endValuePtr) {
117 VectorDrawable::Path* path = reinterpret_cast<VectorDrawable::Path*>(nativePtr);
118 PathData* startData = reinterpret_cast<PathData*>(startValuePtr);
119 PathData* endData = reinterpret_cast<PathData*>(endValuePtr);
120 PathDataPropertyValuesHolder* newHolder = new PathDataPropertyValuesHolder(path,
121 startData, endData);
122 return reinterpret_cast<jlong>(newHolder);
123}
124
125static jlong createPathColorPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jint propertyId,
126 int startValue, jint endValue) {
127 VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(nativePtr);
128 FullPathColorPropertyValuesHolder* newHolder = new FullPathColorPropertyValuesHolder(fullPath,
129 propertyId, startValue, endValue);
130 return reinterpret_cast<jlong>(newHolder);
131}
132
133static jlong createPathPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jint propertyId,
134 float startValue, jfloat endValue) {
135 VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(nativePtr);
136 FullPathPropertyValuesHolder* newHolder = new FullPathPropertyValuesHolder(fullPath,
137 propertyId, startValue, endValue);
138 return reinterpret_cast<jlong>(newHolder);
139}
140
141static jlong createRootAlphaPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jfloat startValue,
142 float endValue) {
143 VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(nativePtr);
144 RootAlphaPropertyValuesHolder* newHolder = new RootAlphaPropertyValuesHolder(tree,
145 startValue, endValue);
146 return reinterpret_cast<jlong>(newHolder);
147}
Doris Liuc9493872016-06-02 16:20:18 -0700148static void setFloatPropertyHolderData(JNIEnv* env, jobject, jlong propertyHolderPtr,
Doris Liu766431a2016-02-04 22:17:11 +0000149 jfloatArray srcData, jint length) {
Doris Liu766431a2016-02-04 22:17:11 +0000150 jfloat* propertyData = env->GetFloatArrayElements(srcData, nullptr);
Doris Liuc9493872016-06-02 16:20:18 -0700151 PropertyValuesHolderImpl<float>* holder =
152 reinterpret_cast<PropertyValuesHolderImpl<float>*>(propertyHolderPtr);
Doris Liu766431a2016-02-04 22:17:11 +0000153 holder->setPropertyDataSource(propertyData, length);
154 env->ReleaseFloatArrayElements(srcData, propertyData, JNI_ABORT);
155}
Doris Liuc9493872016-06-02 16:20:18 -0700156
157static void setIntPropertyHolderData(JNIEnv* env, jobject, jlong propertyHolderPtr,
158 jintArray srcData, jint length) {
159 jint* propertyData = env->GetIntArrayElements(srcData, nullptr);
160 PropertyValuesHolderImpl<int>* holder =
161 reinterpret_cast<PropertyValuesHolderImpl<int>*>(propertyHolderPtr);
162 holder->setPropertyDataSource(propertyData, length);
163 env->ReleaseIntArrayElements(srcData, propertyData, JNI_ABORT);
164}
165
Doris Liuc4bb1852016-02-19 21:39:21 +0000166static void start(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
Doris Liu766431a2016-02-04 22:17:11 +0000167 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
Doris Liuc4bb1852016-02-19 21:39:21 +0000168 AnimationListener* listener = createAnimationListener(env, finishListener, id);
Doris Liu766431a2016-02-04 22:17:11 +0000169 set->start(listener);
170}
171
Doris Liuc4bb1852016-02-19 21:39:21 +0000172static void reverse(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
173 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
174 AnimationListener* listener = createAnimationListener(env, finishListener, id);
175 set->reverse(listener);
Doris Liu766431a2016-02-04 22:17:11 +0000176}
177
178static void end(JNIEnv*, jobject, jlong animatorSetPtr) {
179 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
180 set->end();
181}
182
183static void reset(JNIEnv*, jobject, jlong animatorSetPtr) {
184 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
185 set->reset();
186}
187
188static const JNINativeMethod gMethods[] = {
189 {"nCreateAnimatorSet", "()J", (void*)createAnimatorSet},
Doris Liu718cd3e2016-05-17 16:50:31 -0700190 {"nSetVectorDrawableTarget", "(JJ)V", (void*)setVectorDrawableTarget},
Doris Liuf7167e82016-08-03 17:54:28 -0700191 {"nAddAnimator", "(JJJJJII)V", (void*)addAnimator},
Doris Liuc9493872016-06-02 16:20:18 -0700192 {"nSetPropertyHolderData", "(J[FI)V", (void*)setFloatPropertyHolderData},
193 {"nSetPropertyHolderData", "(J[II)V", (void*)setIntPropertyHolderData},
Doris Liu28cfd202016-02-22 16:51:40 -0800194 {"nStart", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)start},
195 {"nReverse", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)reverse},
John Reck299659d2016-10-07 10:33:44 -0700196
197 // ------------- @FastNative -------------------
198
199 {"nCreateGroupPropertyHolder", "(JIFF)J", (void*)createGroupPropertyHolder},
200 {"nCreatePathDataPropertyHolder", "(JJJ)J", (void*)createPathDataPropertyHolder},
201 {"nCreatePathColorPropertyHolder", "(JIII)J", (void*)createPathColorPropertyHolder},
202 {"nCreatePathPropertyHolder", "(JIFF)J", (void*)createPathPropertyHolder},
203 {"nCreateRootAlphaPropertyHolder", "(JFF)J", (void*)createRootAlphaPropertyHolder},
204 {"nEnd", "(J)V", (void*)end},
205 {"nReset", "(J)V", (void*)reset},
Doris Liu766431a2016-02-04 22:17:11 +0000206};
207
Doris Liu28cfd202016-02-22 16:51:40 -0800208const char* const kClassPathName = "android/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT";
Doris Liu766431a2016-02-04 22:17:11 +0000209int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env) {
210 gVectorDrawableAnimatorClassInfo.clazz = FindClassOrDie(env, kClassPathName);
211 gVectorDrawableAnimatorClassInfo.clazz = MakeGlobalRefOrDie(env,
212 gVectorDrawableAnimatorClassInfo.clazz);
213
214 gVectorDrawableAnimatorClassInfo.callOnFinished = GetStaticMethodIDOrDie(
215 env, gVectorDrawableAnimatorClassInfo.clazz, "callOnFinished",
Doris Liu28cfd202016-02-22 16:51:40 -0800216 "(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V");
Doris Liu766431a2016-02-04 22:17:11 +0000217 return RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedVectorDrawable",
218 gMethods, NELEM(gMethods));
219}
220
221}; // namespace android