1 /*
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 "android/log.h"
19
20 #include "jni.h"
21 #include "GraphicsJNI.h"
22 #include "core_jni_helpers.h"
23
24 #include "Animator.h"
25 #include "Interpolator.h"
26 #include "PropertyValuesAnimatorSet.h"
27 #include "PropertyValuesHolder.h"
28 #include "VectorDrawable.h"
29
30 namespace android {
31 using namespace uirenderer;
32 using namespace VectorDrawable;
33
34 static struct {
35 jclass clazz;
36 jmethodID callOnFinished;
37 } gVectorDrawableAnimatorClassInfo;
38
getEnv(JavaVM * vm)39 static 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
createAnimationListener(JNIEnv * env,jobject finishListener,jint id)47 static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishListener, jint id) {
48 class AnimationListenerBridge : public AnimationListener {
49 public:
50 AnimationListenerBridge(JNIEnv* env, jobject finishListener, jint id) {
51 mFinishListener = env->NewGlobalRef(finishListener);
52 env->GetJavaVM(&mJvm);
53 mId = id;
54 }
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,
68 mFinishListener, mId);
69 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;
81 jint mId;
82 };
83 return new AnimationListenerBridge(env, finishListener, id);
84 }
85
addAnimator(JNIEnv *,jobject,jlong animatorSetPtr,jlong propertyHolderPtr,jlong interpolatorPtr,jlong startDelay,jlong duration,jint repeatCount,jint repeatMode)86 static void addAnimator(JNIEnv*, jobject, jlong animatorSetPtr, jlong propertyHolderPtr,
87 jlong interpolatorPtr, jlong startDelay, jlong duration, jint repeatCount,
88 jint repeatMode) {
89 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
90 PropertyValuesHolder* holder = reinterpret_cast<PropertyValuesHolder*>(propertyHolderPtr);
91 Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr);
92 RepeatMode mode = static_cast<RepeatMode>(repeatMode);
93 set->addPropertyAnimator(holder, interpolator, startDelay, duration, repeatCount, mode);
94 }
95
createAnimatorSet(JNIEnv *,jobject)96 static jlong createAnimatorSet(JNIEnv*, jobject) {
97 PropertyValuesAnimatorSet* animatorSet = new PropertyValuesAnimatorSet();
98 return reinterpret_cast<jlong>(animatorSet);
99 }
100
setVectorDrawableTarget(JNIEnv *,jobject,jlong animatorPtr,jlong vectorDrawablePtr)101 static 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
createGroupPropertyHolder(JNIEnv *,jobject,jlong nativePtr,jint propertyId,jfloat startValue,jfloat endValue)107 static 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
createPathDataPropertyHolder(JNIEnv *,jobject,jlong nativePtr,jlong startValuePtr,jlong endValuePtr)115 static 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
createPathColorPropertyHolder(JNIEnv *,jobject,jlong nativePtr,jint propertyId,int startValue,jint endValue)125 static 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
createPathPropertyHolder(JNIEnv *,jobject,jlong nativePtr,jint propertyId,float startValue,jfloat endValue)133 static 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
createRootAlphaPropertyHolder(JNIEnv *,jobject,jlong nativePtr,jfloat startValue,float endValue)141 static 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 }
setFloatPropertyHolderData(JNIEnv * env,jobject,jlong propertyHolderPtr,jfloatArray srcData,jint length)148 static void setFloatPropertyHolderData(JNIEnv* env, jobject, jlong propertyHolderPtr,
149 jfloatArray srcData, jint length) {
150 jfloat* propertyData = env->GetFloatArrayElements(srcData, nullptr);
151 PropertyValuesHolderImpl<float>* holder =
152 reinterpret_cast<PropertyValuesHolderImpl<float>*>(propertyHolderPtr);
153 holder->setPropertyDataSource(propertyData, length);
154 env->ReleaseFloatArrayElements(srcData, propertyData, JNI_ABORT);
155 }
156
setIntPropertyHolderData(JNIEnv * env,jobject,jlong propertyHolderPtr,jintArray srcData,jint length)157 static 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
start(JNIEnv * env,jobject,jlong animatorSetPtr,jobject finishListener,jint id)166 static void start(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
167 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
168 AnimationListener* listener = createAnimationListener(env, finishListener, id);
169 set->start(listener);
170 }
171
reverse(JNIEnv * env,jobject,jlong animatorSetPtr,jobject finishListener,jint id)172 static 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);
176 }
177
end(JNIEnv *,jobject,jlong animatorSetPtr)178 static void end(JNIEnv*, jobject, jlong animatorSetPtr) {
179 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
180 set->end();
181 }
182
reset(JNIEnv *,jobject,jlong animatorSetPtr)183 static void reset(JNIEnv*, jobject, jlong animatorSetPtr) {
184 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
185 set->reset();
186 }
187
188 static const JNINativeMethod gMethods[] = {
189 {"nCreateAnimatorSet", "()J", (void*)createAnimatorSet},
190 {"nSetVectorDrawableTarget", "(JJ)V", (void*)setVectorDrawableTarget},
191 {"nAddAnimator", "(JJJJJII)V", (void*)addAnimator},
192 {"nSetPropertyHolderData", "(J[FI)V", (void*)setFloatPropertyHolderData},
193 {"nSetPropertyHolderData", "(J[II)V", (void*)setIntPropertyHolderData},
194 {"nStart", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)start},
195 {"nReverse", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)reverse},
196
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},
206 };
207
208 const char* const kClassPathName = "android/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT";
register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv * env)209 int 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",
216 "(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V");
217 return RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedVectorDrawable",
218 gMethods, NELEM(gMethods));
219 }
220
221 }; // namespace android
222