• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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