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