android_view_RenderNodeAnimator.cpp revision ad2f8e334f3ef22d3e412b0660a2e1f996f94116
1e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck/* 2e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Copyright (C) 2013 The Android Open Source Project 3e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * 4e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Licensed under the Apache License, Version 2.0 (the "License"); 5e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * you may not use this file except in compliance with the License. 6e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * You may obtain a copy of the License at 7e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * 8e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * http://www.apache.org/licenses/LICENSE-2.0 9e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * 10e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Unless required by applicable law or agreed to in writing, software 11e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * distributed under the License is distributed on an "AS IS" BASIS, 12e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * See the License for the specific language governing permissions and 14e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * limitations under the License. 15e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck */ 16e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 17e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#define LOG_TAG "OpenGLRenderer" 18e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 19e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "jni.h" 20e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "GraphicsJNI.h" 21e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <nativehelper/JNIHelp.h> 22e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <android_runtime/AndroidRuntime.h> 23e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 24e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <Animator.h> 25e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <Interpolator.h> 26e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <RenderProperties.h> 27e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 28e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Recknamespace android { 29e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 30e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckusing namespace uirenderer; 31e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 32e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic struct { 33e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck jclass clazz; 34e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 35e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck jmethodID callOnFinished; 36e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} gRenderNodeAnimatorClassInfo; 37e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 38496b8770c19c573299e4be525e877acc977a2dadJohn Reck#ifdef USE_OPENGL_RENDERER 39496b8770c19c573299e4be525e877acc977a2dadJohn Reck 40e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic JNIEnv* getEnv(JavaVM* vm) { 41e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck JNIEnv* env; 42e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { 43e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck return 0; 44e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 45e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck return env; 46e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 47e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 4852244fff29042926e21fa897ef5ab11148e35299John Reckclass AnimationListenerBridge : public AnimationListener { 4952244fff29042926e21fa897ef5ab11148e35299John Reckpublic: 5052244fff29042926e21fa897ef5ab11148e35299John Reck // This holds a strong reference to a Java WeakReference<T> object. This avoids 5152244fff29042926e21fa897ef5ab11148e35299John Reck // cyclic-references-of-doom. If you think "I know, just use NewWeakGlobalRef!" 5252244fff29042926e21fa897ef5ab11148e35299John Reck // then you end up with basically a PhantomReference, which is totally not 5352244fff29042926e21fa897ef5ab11148e35299John Reck // what we want. 5452244fff29042926e21fa897ef5ab11148e35299John Reck AnimationListenerBridge(JNIEnv* env, jobject weakThis) { 5552244fff29042926e21fa897ef5ab11148e35299John Reck mWeakThis = env->NewGlobalRef(weakThis); 5652244fff29042926e21fa897ef5ab11148e35299John Reck env->GetJavaVM(&mJvm); 5752244fff29042926e21fa897ef5ab11148e35299John Reck } 58e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 5952244fff29042926e21fa897ef5ab11148e35299John Reck virtual ~AnimationListenerBridge() { 6052244fff29042926e21fa897ef5ab11148e35299John Reck JNIEnv* env = getEnv(mJvm); 6152244fff29042926e21fa897ef5ab11148e35299John Reck env->DeleteGlobalRef(mWeakThis); 6252244fff29042926e21fa897ef5ab11148e35299John Reck mWeakThis = NULL; 6352244fff29042926e21fa897ef5ab11148e35299John Reck } 64e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 65ff941dcd815021bb20d6504eb486acb1e50592c3John Reck virtual void onAnimationFinished(BaseRenderNodeAnimator*) { 6652244fff29042926e21fa897ef5ab11148e35299John Reck JNIEnv* env = getEnv(mJvm); 6752244fff29042926e21fa897ef5ab11148e35299John Reck env->CallStaticVoidMethod( 6852244fff29042926e21fa897ef5ab11148e35299John Reck gRenderNodeAnimatorClassInfo.clazz, 6952244fff29042926e21fa897ef5ab11148e35299John Reck gRenderNodeAnimatorClassInfo.callOnFinished, 7052244fff29042926e21fa897ef5ab11148e35299John Reck mWeakThis); 7152244fff29042926e21fa897ef5ab11148e35299John Reck } 72e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 7352244fff29042926e21fa897ef5ab11148e35299John Reckprivate: 7452244fff29042926e21fa897ef5ab11148e35299John Reck JavaVM* mJvm; 7552244fff29042926e21fa897ef5ab11148e35299John Reck jobject mWeakThis; 7652244fff29042926e21fa897ef5ab11148e35299John Reck}; 7752244fff29042926e21fa897ef5ab11148e35299John Reck 7852244fff29042926e21fa897ef5ab11148e35299John Reckstatic inline RenderPropertyAnimator::RenderProperty toRenderProperty(jint property) { 7952244fff29042926e21fa897ef5ab11148e35299John Reck LOG_ALWAYS_FATAL_IF(property < 0 || property > RenderPropertyAnimator::ALPHA, 80e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck "Invalid property %d", property); 8152244fff29042926e21fa897ef5ab11148e35299John Reck return static_cast<RenderPropertyAnimator::RenderProperty>(property); 8252244fff29042926e21fa897ef5ab11148e35299John Reck} 8352244fff29042926e21fa897ef5ab11148e35299John Reck 8452244fff29042926e21fa897ef5ab11148e35299John Reckstatic inline CanvasPropertyPaintAnimator::PaintField toPaintField(jint field) { 8552244fff29042926e21fa897ef5ab11148e35299John Reck LOG_ALWAYS_FATAL_IF(field < 0 8652244fff29042926e21fa897ef5ab11148e35299John Reck || field > CanvasPropertyPaintAnimator::ALPHA, 8752244fff29042926e21fa897ef5ab11148e35299John Reck "Invalid paint field %d", field); 8852244fff29042926e21fa897ef5ab11148e35299John Reck return static_cast<CanvasPropertyPaintAnimator::PaintField>(field); 8952244fff29042926e21fa897ef5ab11148e35299John Reck} 9052244fff29042926e21fa897ef5ab11148e35299John Reck 9152244fff29042926e21fa897ef5ab11148e35299John Reckstatic jlong createAnimator(JNIEnv* env, jobject clazz, jobject weakThis, 92ff941dcd815021bb20d6504eb486acb1e50592c3John Reck jint propertyRaw, jfloat finalValue) { 9352244fff29042926e21fa897ef5ab11148e35299John Reck RenderPropertyAnimator::RenderProperty property = toRenderProperty(propertyRaw); 9452244fff29042926e21fa897ef5ab11148e35299John Reck 95ff941dcd815021bb20d6504eb486acb1e50592c3John Reck BaseRenderNodeAnimator* animator = new RenderPropertyAnimator(property, finalValue); 9652244fff29042926e21fa897ef5ab11148e35299John Reck animator->setListener(new AnimationListenerBridge(env, weakThis)); 9752244fff29042926e21fa897ef5ab11148e35299John Reck return reinterpret_cast<jlong>( animator ); 9852244fff29042926e21fa897ef5ab11148e35299John Reck} 9952244fff29042926e21fa897ef5ab11148e35299John Reck 10052244fff29042926e21fa897ef5ab11148e35299John Reckstatic jlong createCanvasPropertyFloatAnimator(JNIEnv* env, jobject clazz, 101ff941dcd815021bb20d6504eb486acb1e50592c3John Reck jobject weakThis, jlong canvasPropertyPtr, jfloat finalValue) { 10252244fff29042926e21fa897ef5ab11148e35299John Reck CanvasPropertyPrimitive* canvasProperty = reinterpret_cast<CanvasPropertyPrimitive*>(canvasPropertyPtr); 103ff941dcd815021bb20d6504eb486acb1e50592c3John Reck BaseRenderNodeAnimator* animator = new CanvasPropertyPrimitiveAnimator(canvasProperty, finalValue); 10452244fff29042926e21fa897ef5ab11148e35299John Reck animator->setListener(new AnimationListenerBridge(env, weakThis)); 10552244fff29042926e21fa897ef5ab11148e35299John Reck return reinterpret_cast<jlong>( animator ); 10652244fff29042926e21fa897ef5ab11148e35299John Reck} 107e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 10852244fff29042926e21fa897ef5ab11148e35299John Reckstatic jlong createCanvasPropertyPaintAnimator(JNIEnv* env, jobject clazz, 10952244fff29042926e21fa897ef5ab11148e35299John Reck jobject weakThis, jlong canvasPropertyPtr, jint paintFieldRaw, 110ff941dcd815021bb20d6504eb486acb1e50592c3John Reck jfloat finalValue) { 11152244fff29042926e21fa897ef5ab11148e35299John Reck CanvasPropertyPaint* canvasProperty = reinterpret_cast<CanvasPropertyPaint*>(canvasPropertyPtr); 11252244fff29042926e21fa897ef5ab11148e35299John Reck CanvasPropertyPaintAnimator::PaintField paintField = toPaintField(paintFieldRaw); 113ff941dcd815021bb20d6504eb486acb1e50592c3John Reck BaseRenderNodeAnimator* animator = new CanvasPropertyPaintAnimator( 114ff941dcd815021bb20d6504eb486acb1e50592c3John Reck canvasProperty, paintField, finalValue); 11552244fff29042926e21fa897ef5ab11148e35299John Reck animator->setListener(new AnimationListenerBridge(env, weakThis)); 116e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck return reinterpret_cast<jlong>( animator ); 117e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 118e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 119ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverettestatic void setDuration(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong duration) { 120e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck LOG_ALWAYS_FATAL_IF(duration < 0, "Duration cannot be negative"); 121ff941dcd815021bb20d6504eb486acb1e50592c3John Reck BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); 122e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck animator->setDuration(duration); 123e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 124e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 125ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverettestatic jlong getDuration(JNIEnv* env, jobject clazz, jlong animatorPtr) { 126ff941dcd815021bb20d6504eb486acb1e50592c3John Reck BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); 127ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette return static_cast<jlong>(animator->duration()); 128ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette} 129ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 130ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverettestatic void setStartDelay(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong startDelay) { 131ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette LOG_ALWAYS_FATAL_IF(startDelay < 0, "Start delay cannot be negative"); 132ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); 133ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette animator->setStartDelay(startDelay); 134ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette} 135ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 136ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverettestatic jlong getStartDelay(JNIEnv* env, jobject clazz, jlong animatorPtr) { 137ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); 138ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette return static_cast<jlong>(animator->startDelay()); 139315c329544d7c593d1072b071cbb92d9afe74021John Reck} 140315c329544d7c593d1072b071cbb92d9afe74021John Reck 141315c329544d7c593d1072b071cbb92d9afe74021John Reckstatic void setInterpolator(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong interpolatorPtr) { 142ff941dcd815021bb20d6504eb486acb1e50592c3John Reck BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); 143315c329544d7c593d1072b071cbb92d9afe74021John Reck Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr); 144315c329544d7c593d1072b071cbb92d9afe74021John Reck animator->setInterpolator(interpolator); 145315c329544d7c593d1072b071cbb92d9afe74021John Reck} 146315c329544d7c593d1072b071cbb92d9afe74021John Reck 147496b8770c19c573299e4be525e877acc977a2dadJohn Reck#endif 148496b8770c19c573299e4be525e877acc977a2dadJohn Reck 149e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// ---------------------------------------------------------------------------- 150e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// JNI Glue 151e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// ---------------------------------------------------------------------------- 152e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 153e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckconst char* const kClassPathName = "android/view/RenderNodeAnimator"; 154e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 155e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic JNINativeMethod gMethods[] = { 156496b8770c19c573299e4be525e877acc977a2dadJohn Reck#ifdef USE_OPENGL_RENDERER 157ff941dcd815021bb20d6504eb486acb1e50592c3John Reck { "nCreateAnimator", "(Ljava/lang/ref/WeakReference;IF)J", (void*) createAnimator }, 158ff941dcd815021bb20d6504eb486acb1e50592c3John Reck { "nCreateCanvasPropertyFloatAnimator", "(Ljava/lang/ref/WeakReference;JF)J", (void*) createCanvasPropertyFloatAnimator }, 159ff941dcd815021bb20d6504eb486acb1e50592c3John Reck { "nCreateCanvasPropertyPaintAnimator", "(Ljava/lang/ref/WeakReference;JIF)J", (void*) createCanvasPropertyPaintAnimator }, 160ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette { "nSetDuration", "(JJ)V", (void*) setDuration }, 161ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette { "nGetDuration", "(J)J", (void*) getDuration }, 162ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette { "nSetStartDelay", "(JJ)V", (void*) setStartDelay }, 163ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette { "nGetStartDelay", "(J)J", (void*) getStartDelay }, 164315c329544d7c593d1072b071cbb92d9afe74021John Reck { "nSetInterpolator", "(JJ)V", (void*) setInterpolator }, 165496b8770c19c573299e4be525e877acc977a2dadJohn Reck#endif 166e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck}; 167e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 168e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#define FIND_CLASS(var, className) \ 169e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck var = env->FindClass(className); \ 170e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck LOG_FATAL_IF(! var, "Unable to find class " className); 171e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 172e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 173e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \ 174e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck LOG_FATAL_IF(! var, "Unable to find method " methodName); 175e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 176e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckint register_android_view_RenderNodeAnimator(JNIEnv* env) { 177e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck FIND_CLASS(gRenderNodeAnimatorClassInfo.clazz, kClassPathName); 178e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck gRenderNodeAnimatorClassInfo.clazz = jclass(env->NewGlobalRef(gRenderNodeAnimatorClassInfo.clazz)); 179e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 180e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck GET_STATIC_METHOD_ID(gRenderNodeAnimatorClassInfo.callOnFinished, gRenderNodeAnimatorClassInfo.clazz, 181e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck "callOnFinished", "(Ljava/lang/ref/WeakReference;)V"); 182e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 183e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 184e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 185e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 186e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 187e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} // namespace android 188