Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 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 | |
Mark Salyzyn | 96bf598 | 2016-09-28 16:15:30 -0700 | [diff] [blame] | 18 | #include "android/log.h" |
| 19 | |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 20 | #include "jni.h" |
| 21 | #include "GraphicsJNI.h" |
| 22 | #include "core_jni_helpers.h" |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 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 | |
| 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 | |
Doris Liu | c4bb185 | 2016-02-19 21:39:21 +0000 | [diff] [blame] | 47 | static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishListener, jint id) { |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 48 | class AnimationListenerBridge : public AnimationListener { |
| 49 | public: |
Doris Liu | c4bb185 | 2016-02-19 21:39:21 +0000 | [diff] [blame] | 50 | AnimationListenerBridge(JNIEnv* env, jobject finishListener, jint id) { |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 51 | mFinishListener = env->NewGlobalRef(finishListener); |
| 52 | env->GetJavaVM(&mJvm); |
Doris Liu | c4bb185 | 2016-02-19 21:39:21 +0000 | [diff] [blame] | 53 | mId = id; |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 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, |
Doris Liu | c4bb185 | 2016-02-19 21:39:21 +0000 | [diff] [blame] | 68 | mFinishListener, mId); |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 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; |
Doris Liu | c4bb185 | 2016-02-19 21:39:21 +0000 | [diff] [blame] | 81 | jint mId; |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 82 | }; |
Doris Liu | c4bb185 | 2016-02-19 21:39:21 +0000 | [diff] [blame] | 83 | return new AnimationListenerBridge(env, finishListener, id); |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 84 | } |
| 85 | |
| 86 | static void addAnimator(JNIEnv*, jobject, jlong animatorSetPtr, jlong propertyHolderPtr, |
Doris Liu | f7167e8 | 2016-08-03 17:54:28 -0700 | [diff] [blame] | 87 | jlong interpolatorPtr, jlong startDelay, jlong duration, jint repeatCount, |
| 88 | jint repeatMode) { |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 89 | PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr); |
| 90 | PropertyValuesHolder* holder = reinterpret_cast<PropertyValuesHolder*>(propertyHolderPtr); |
| 91 | Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr); |
Doris Liu | f7167e8 | 2016-08-03 17:54:28 -0700 | [diff] [blame] | 92 | RepeatMode mode = static_cast<RepeatMode>(repeatMode); |
| 93 | set->addPropertyAnimator(holder, interpolator, startDelay, duration, repeatCount, mode); |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | static jlong createAnimatorSet(JNIEnv*, jobject) { |
| 97 | PropertyValuesAnimatorSet* animatorSet = new PropertyValuesAnimatorSet(); |
| 98 | return reinterpret_cast<jlong>(animatorSet); |
| 99 | } |
| 100 | |
Doris Liu | 718cd3e | 2016-05-17 16:50:31 -0700 | [diff] [blame] | 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 | |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | } |
Doris Liu | c949387 | 2016-06-02 16:20:18 -0700 | [diff] [blame] | 148 | static void setFloatPropertyHolderData(JNIEnv* env, jobject, jlong propertyHolderPtr, |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 149 | jfloatArray srcData, jint length) { |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 150 | jfloat* propertyData = env->GetFloatArrayElements(srcData, nullptr); |
Doris Liu | c949387 | 2016-06-02 16:20:18 -0700 | [diff] [blame] | 151 | PropertyValuesHolderImpl<float>* holder = |
| 152 | reinterpret_cast<PropertyValuesHolderImpl<float>*>(propertyHolderPtr); |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 153 | holder->setPropertyDataSource(propertyData, length); |
| 154 | env->ReleaseFloatArrayElements(srcData, propertyData, JNI_ABORT); |
| 155 | } |
Doris Liu | c949387 | 2016-06-02 16:20:18 -0700 | [diff] [blame] | 156 | |
| 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 | |
Doris Liu | c4bb185 | 2016-02-19 21:39:21 +0000 | [diff] [blame] | 166 | static void start(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) { |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 167 | PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr); |
Doris Liu | c4bb185 | 2016-02-19 21:39:21 +0000 | [diff] [blame] | 168 | AnimationListener* listener = createAnimationListener(env, finishListener, id); |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 169 | set->start(listener); |
| 170 | } |
| 171 | |
Doris Liu | c4bb185 | 2016-02-19 21:39:21 +0000 | [diff] [blame] | 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); |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 176 | } |
| 177 | |
| 178 | static void end(JNIEnv*, jobject, jlong animatorSetPtr) { |
| 179 | PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr); |
| 180 | set->end(); |
| 181 | } |
| 182 | |
| 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}, |
Doris Liu | 718cd3e | 2016-05-17 16:50:31 -0700 | [diff] [blame] | 190 | {"nSetVectorDrawableTarget", "(JJ)V", (void*)setVectorDrawableTarget}, |
Doris Liu | f7167e8 | 2016-08-03 17:54:28 -0700 | [diff] [blame] | 191 | {"nAddAnimator", "(JJJJJII)V", (void*)addAnimator}, |
Doris Liu | c949387 | 2016-06-02 16:20:18 -0700 | [diff] [blame] | 192 | {"nSetPropertyHolderData", "(J[FI)V", (void*)setFloatPropertyHolderData}, |
| 193 | {"nSetPropertyHolderData", "(J[II)V", (void*)setIntPropertyHolderData}, |
Doris Liu | 28cfd20 | 2016-02-22 16:51:40 -0800 | [diff] [blame] | 194 | {"nStart", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)start}, |
| 195 | {"nReverse", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V", (void*)reverse}, |
John Reck | 299659d | 2016-10-07 10:33:44 -0700 | [diff] [blame] | 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}, |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 206 | }; |
| 207 | |
Doris Liu | 28cfd20 | 2016-02-22 16:51:40 -0800 | [diff] [blame] | 208 | const char* const kClassPathName = "android/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT"; |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 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", |
Doris Liu | 28cfd20 | 2016-02-22 16:51:40 -0800 | [diff] [blame] | 216 | "(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V"); |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 217 | return RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedVectorDrawable", |
| 218 | gMethods, NELEM(gMethods)); |
| 219 | } |
| 220 | |
| 221 | }; // namespace android |