2 * Copyright (C) 2016 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #define LOG_TAG "OpenGLRenderer"
19 #include "GraphicsJNI.h"
20 #include "core_jni_helpers.h"
24 #include "Interpolator.h"
25 #include "PropertyValuesAnimatorSet.h"
26 #include "PropertyValuesHolder.h"
27 #include "VectorDrawable.h"
30 using namespace uirenderer;
31 using namespace VectorDrawable;
35 jmethodID callOnFinished;
36 } gVectorDrawableAnimatorClassInfo;
38 static JNIEnv* getEnv(JavaVM* vm) {
40 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
46 static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishListener, jint id) {
47 class AnimationListenerBridge : public AnimationListener {
49 AnimationListenerBridge(JNIEnv* env, jobject finishListener, jint id) {
50 mFinishListener = env->NewGlobalRef(finishListener);
51 env->GetJavaVM(&mJvm);
55 virtual ~AnimationListenerBridge() {
56 if (mFinishListener) {
57 onAnimationFinished(NULL);
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,
67 mFinishListener, mId);
72 void releaseJavaObject() {
73 JNIEnv* env = getEnv(mJvm);
74 env->DeleteGlobalRef(mFinishListener);
75 mFinishListener = NULL;
79 jobject mFinishListener;
82 return new AnimationListenerBridge(env, finishListener, id);
85 static void addAnimator(JNIEnv*, jobject, jlong animatorSetPtr, jlong propertyHolderPtr,
86 jlong interpolatorPtr, jlong startDelay, jlong duration, jint repeatCount) {
87 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
88 PropertyValuesHolder* holder = reinterpret_cast<PropertyValuesHolder*>(propertyHolderPtr);
89 Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr);
90 set->addPropertyAnimator(holder, interpolator, startDelay, duration, repeatCount);
93 static jlong createAnimatorSet(JNIEnv*, jobject) {
94 PropertyValuesAnimatorSet* animatorSet = new PropertyValuesAnimatorSet();
95 return reinterpret_cast<jlong>(animatorSet);
98 static jlong createGroupPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jint propertyId,
99 jfloat startValue, jfloat endValue) {
100 VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(nativePtr);
101 GroupPropertyValuesHolder* newHolder = new GroupPropertyValuesHolder(group, propertyId,
102 startValue, endValue);
103 return reinterpret_cast<jlong>(newHolder);
106 static jlong createPathDataPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jlong startValuePtr,
108 VectorDrawable::Path* path = reinterpret_cast<VectorDrawable::Path*>(nativePtr);
109 PathData* startData = reinterpret_cast<PathData*>(startValuePtr);
110 PathData* endData = reinterpret_cast<PathData*>(endValuePtr);
111 PathDataPropertyValuesHolder* newHolder = new PathDataPropertyValuesHolder(path,
113 return reinterpret_cast<jlong>(newHolder);
116 static jlong createPathColorPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jint propertyId,
117 int startValue, jint endValue) {
118 VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(nativePtr);
119 FullPathColorPropertyValuesHolder* newHolder = new FullPathColorPropertyValuesHolder(fullPath,
120 propertyId, startValue, endValue);
121 return reinterpret_cast<jlong>(newHolder);
124 static jlong createPathPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jint propertyId,
125 float startValue, jfloat endValue) {
126 VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(nativePtr);
127 FullPathPropertyValuesHolder* newHolder = new FullPathPropertyValuesHolder(fullPath,
128 propertyId, startValue, endValue);
129 return reinterpret_cast<jlong>(newHolder);
132 static jlong createRootAlphaPropertyHolder(JNIEnv*, jobject, jlong nativePtr, jfloat startValue,
134 VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(nativePtr);
135 RootAlphaPropertyValuesHolder* newHolder = new RootAlphaPropertyValuesHolder(tree,
136 startValue, endValue);
137 return reinterpret_cast<jlong>(newHolder);
139 static void setPropertyHolderData(JNIEnv* env, jobject, jlong propertyHolderPtr,
140 jfloatArray srcData, jint length) {
142 jfloat* propertyData = env->GetFloatArrayElements(srcData, nullptr);
143 PropertyValuesHolder* holder = reinterpret_cast<PropertyValuesHolder*>(propertyHolderPtr);
144 holder->setPropertyDataSource(propertyData, length);
145 env->ReleaseFloatArrayElements(srcData, propertyData, JNI_ABORT);
147 static void start(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
148 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
149 AnimationListener* listener = createAnimationListener(env, finishListener, id);
150 set->start(listener);
153 static void reverse(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
154 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
155 AnimationListener* listener = createAnimationListener(env, finishListener, id);
156 set->reverse(listener);
159 static void end(JNIEnv*, jobject, jlong animatorSetPtr) {
160 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
164 static void reset(JNIEnv*, jobject, jlong animatorSetPtr) {
165 PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
169 static const JNINativeMethod gMethods[] = {
170 {"nCreateAnimatorSet", "()J", (void*)createAnimatorSet},
171 {"nAddAnimator", "(JJJJJI)V", (void*)addAnimator},
172 {"nCreateGroupPropertyHolder", "!(JIFF)J", (void*)createGroupPropertyHolder},
173 {"nCreatePathDataPropertyHolder", "!(JJJ)J", (void*)createPathDataPropertyHolder},
174 {"nCreatePathColorPropertyHolder", "!(JIII)J", (void*)createPathColorPropertyHolder},
175 {"nCreatePathPropertyHolder", "!(JIFF)J", (void*)createPathPropertyHolder},
176 {"nCreateRootAlphaPropertyHolder", "!(JFF)J", (void*)createRootAlphaPropertyHolder},
177 {"nSetPropertyHolderData", "(J[FI)V", (void*)setPropertyHolderData},
178 {"nStart", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)start},
179 {"nReverse", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)reverse},
180 {"nEnd", "!(J)V", (void*)end},
181 {"nReset", "!(J)V", (void*)reset},
184 const char* const kClassPathName = "android/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT";
185 int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env) {
186 gVectorDrawableAnimatorClassInfo.clazz = FindClassOrDie(env, kClassPathName);
187 gVectorDrawableAnimatorClassInfo.clazz = MakeGlobalRefOrDie(env,
188 gVectorDrawableAnimatorClassInfo.clazz);
190 gVectorDrawableAnimatorClassInfo.callOnFinished = GetStaticMethodIDOrDie(
191 env, gVectorDrawableAnimatorClassInfo.clazz, "callOnFinished",
192 "(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V");
193 return RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedVectorDrawable",
194 gMethods, NELEM(gMethods));
197 }; // namespace android