Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2012 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 
     17 #define LOG_TAG "OpenGLRenderer"
     18 
     19 #include <EGL/egl.h>
     20 
     21 #include "jni.h"
     22 #include "GraphicsJNI.h"
     23 #include <nativehelper/JNIHelp.h>
     24 #include <android_runtime/AndroidRuntime.h>
     25 
     26 #include <Animator.h>
     27 #include <RenderNode.h>
     28 #include <Paint.h>
     29 
     30 #include "core_jni_helpers.h"
     31 
     32 namespace android {
     33 
     34 using namespace uirenderer;
     35 
     36 #define SET_AND_DIRTY(prop, val, dirtyFlag) \
     37     (reinterpret_cast<RenderNode*>(renderNodePtr)->mutateStagingProperties().prop(val) \
     38         ? (reinterpret_cast<RenderNode*>(renderNodePtr)->setPropertyFieldsDirty(dirtyFlag), true) \
     39         : false)
     40 
     41 // ----------------------------------------------------------------------------
     42 // DisplayList view properties
     43 // ----------------------------------------------------------------------------
     44 
     45 static void android_view_RenderNode_output(JNIEnv* env,
     46         jobject clazz, jlong renderNodePtr) {
     47     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     48     renderNode->output();
     49 }
     50 
     51 static jint android_view_RenderNode_getDebugSize(JNIEnv* env,
     52         jobject clazz, jlong renderNodePtr) {
     53     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     54     return renderNode->getDebugSize();
     55 }
     56 
     57 static jlong android_view_RenderNode_create(JNIEnv* env, jobject clazz, jstring name) {
     58     RenderNode* renderNode = new RenderNode();
     59     renderNode->incStrong(0);
     60     if (name != NULL) {
     61         const char* textArray = env->GetStringUTFChars(name, NULL);
     62         renderNode->setName(textArray);
     63         env->ReleaseStringUTFChars(name, textArray);
     64     }
     65     return reinterpret_cast<jlong>(renderNode);
     66 }
     67 
     68 static void android_view_RenderNode_destroyRenderNode(JNIEnv* env,
     69         jobject clazz, jlong renderNodePtr) {
     70     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     71     renderNode->decStrong(0);
     72 }
     73 
     74 static void android_view_RenderNode_setDisplayListData(JNIEnv* env,
     75         jobject clazz, jlong renderNodePtr, jlong newDataPtr) {
     76     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     77     DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
     78     renderNode->setStagingDisplayList(newData);
     79 }
     80 
     81 // ----------------------------------------------------------------------------
     82 // RenderProperties - setters
     83 // ----------------------------------------------------------------------------
     84 
     85 static jboolean android_view_RenderNode_setLayerType(JNIEnv* env,
     86         jobject clazz, jlong renderNodePtr, jint jlayerType) {
     87     LayerType layerType = static_cast<LayerType>(jlayerType);
     88     return SET_AND_DIRTY(mutateLayerProperties().setType, layerType, RenderNode::GENERIC);
     89 }
     90 
     91 static jboolean android_view_RenderNode_setLayerPaint(JNIEnv* env,
     92         jobject clazz, jlong renderNodePtr, jlong paintPtr) {
     93     Paint* paint = reinterpret_cast<Paint*>(paintPtr);
     94     return SET_AND_DIRTY(mutateLayerProperties().setFromPaint, paint, RenderNode::GENERIC);
     95 }
     96 
     97 static jboolean android_view_RenderNode_setStaticMatrix(JNIEnv* env,
     98         jobject clazz, jlong renderNodePtr, jlong matrixPtr) {
     99     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
    100     return SET_AND_DIRTY(setStaticMatrix, matrix, RenderNode::GENERIC);
    101 }
    102 
    103 static jboolean android_view_RenderNode_setAnimationMatrix(JNIEnv* env,
    104         jobject clazz, jlong renderNodePtr, jlong matrixPtr) {
    105     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
    106     return SET_AND_DIRTY(setAnimationMatrix, matrix, RenderNode::GENERIC);
    107 }
    108 
    109 static jboolean android_view_RenderNode_setClipToBounds(JNIEnv* env,
    110         jobject clazz, jlong renderNodePtr, jboolean clipToBounds) {
    111     return SET_AND_DIRTY(setClipToBounds, clipToBounds, RenderNode::GENERIC);
    112 }
    113 
    114 static jboolean android_view_RenderNode_setClipBounds(JNIEnv* env,
    115         jobject clazz, jlong renderNodePtr, jint left, jint top, jint right, jint bottom) {
    116     android::uirenderer::Rect clipBounds(left, top, right, bottom);
    117     return SET_AND_DIRTY(setClipBounds, clipBounds, RenderNode::GENERIC);
    118 }
    119 
    120 static jboolean android_view_RenderNode_setClipBoundsEmpty(JNIEnv* env,
    121         jobject clazz, jlong renderNodePtr) {
    122     return SET_AND_DIRTY(setClipBoundsEmpty,, RenderNode::GENERIC);
    123 }
    124 
    125 static jboolean android_view_RenderNode_setProjectBackwards(JNIEnv* env,
    126         jobject clazz, jlong renderNodePtr, jboolean shouldProject) {
    127     return SET_AND_DIRTY(setProjectBackwards, shouldProject, RenderNode::GENERIC);
    128 }
    129 
    130 static jboolean android_view_RenderNode_setProjectionReceiver(JNIEnv* env,
    131         jobject clazz, jlong renderNodePtr, jboolean shouldRecieve) {
    132     return SET_AND_DIRTY(setProjectionReceiver, shouldRecieve, RenderNode::GENERIC);
    133 }
    134 
    135 static jboolean android_view_RenderNode_setOutlineRoundRect(JNIEnv* env,
    136         jobject clazz, jlong renderNodePtr, jint left, jint top,
    137         jint right, jint bottom, jfloat radius, jfloat alpha) {
    138     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    139     renderNode->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom,
    140             radius, alpha);
    141     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
    142     return true;
    143 }
    144 
    145 static jboolean android_view_RenderNode_setOutlineConvexPath(JNIEnv* env,
    146         jobject clazz, jlong renderNodePtr, jlong outlinePathPtr, jfloat alpha) {
    147     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    148     SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
    149     renderNode->mutateStagingProperties().mutableOutline().setConvexPath(outlinePath, alpha);
    150     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
    151     return true;
    152 }
    153 
    154 static jboolean android_view_RenderNode_setOutlineEmpty(JNIEnv* env,
    155         jobject clazz, jlong renderNodePtr) {
    156     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    157     renderNode->mutateStagingProperties().mutableOutline().setEmpty();
    158     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
    159     return true;
    160 }
    161 
    162 static jboolean android_view_RenderNode_setOutlineNone(JNIEnv* env,
    163         jobject clazz, jlong renderNodePtr) {
    164     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    165     renderNode->mutateStagingProperties().mutableOutline().setNone();
    166     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
    167     return true;
    168 }
    169 
    170 static jboolean android_view_RenderNode_hasShadow(JNIEnv* env,
    171         jobject clazz, jlong renderNodePtr) {
    172     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    173     return renderNode->stagingProperties().hasShadow();
    174 }
    175 
    176 static jboolean android_view_RenderNode_setClipToOutline(JNIEnv* env,
    177         jobject clazz, jlong renderNodePtr, jboolean clipToOutline) {
    178     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    179     renderNode->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline);
    180     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
    181     return true;
    182 }
    183 
    184 static jboolean android_view_RenderNode_setRevealClip(JNIEnv* env,
    185         jobject clazz, jlong renderNodePtr, jboolean shouldClip,
    186         jfloat x, jfloat y, jfloat radius) {
    187     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    188     renderNode->mutateStagingProperties().mutableRevealClip().set(
    189             shouldClip, x, y, radius);
    190     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
    191     return true;
    192 }
    193 
    194 static jboolean android_view_RenderNode_setAlpha(JNIEnv* env,
    195         jobject clazz, jlong renderNodePtr, float alpha) {
    196     return SET_AND_DIRTY(setAlpha, alpha, RenderNode::ALPHA);
    197 }
    198 
    199 static jboolean android_view_RenderNode_setHasOverlappingRendering(JNIEnv* env,
    200         jobject clazz, jlong renderNodePtr, bool hasOverlappingRendering) {
    201     return SET_AND_DIRTY(setHasOverlappingRendering, hasOverlappingRendering,
    202             RenderNode::GENERIC);
    203 }
    204 
    205 static jboolean android_view_RenderNode_setElevation(JNIEnv* env,
    206         jobject clazz, jlong renderNodePtr, float elevation) {
    207     return SET_AND_DIRTY(setElevation, elevation, RenderNode::Z);
    208 }
    209 
    210 static jboolean android_view_RenderNode_setTranslationX(JNIEnv* env,
    211         jobject clazz, jlong renderNodePtr, float tx) {
    212     return SET_AND_DIRTY(setTranslationX, tx, RenderNode::TRANSLATION_X | RenderNode::X);
    213 }
    214 
    215 static jboolean android_view_RenderNode_setTranslationY(JNIEnv* env,
    216         jobject clazz, jlong renderNodePtr, float ty) {
    217     return SET_AND_DIRTY(setTranslationY, ty, RenderNode::TRANSLATION_Y | RenderNode::Y);
    218 }
    219 
    220 static jboolean android_view_RenderNode_setTranslationZ(JNIEnv* env,
    221         jobject clazz, jlong renderNodePtr, float tz) {
    222     return SET_AND_DIRTY(setTranslationZ, tz, RenderNode::TRANSLATION_Z | RenderNode::Z);
    223 }
    224 
    225 static jboolean android_view_RenderNode_setRotation(JNIEnv* env,
    226         jobject clazz, jlong renderNodePtr, float rotation) {
    227     return SET_AND_DIRTY(setRotation, rotation, RenderNode::ROTATION);
    228 }
    229 
    230 static jboolean android_view_RenderNode_setRotationX(JNIEnv* env,
    231         jobject clazz, jlong renderNodePtr, float rx) {
    232     return SET_AND_DIRTY(setRotationX, rx, RenderNode::ROTATION_X);
    233 }
    234 
    235 static jboolean android_view_RenderNode_setRotationY(JNIEnv* env,
    236         jobject clazz, jlong renderNodePtr, float ry) {
    237     return SET_AND_DIRTY(setRotationY, ry, RenderNode::ROTATION_Y);
    238 }
    239 
    240 static jboolean android_view_RenderNode_setScaleX(JNIEnv* env,
    241         jobject clazz, jlong renderNodePtr, float sx) {
    242     return SET_AND_DIRTY(setScaleX, sx, RenderNode::SCALE_X);
    243 }
    244 
    245 static jboolean android_view_RenderNode_setScaleY(JNIEnv* env,
    246         jobject clazz, jlong renderNodePtr, float sy) {
    247     return SET_AND_DIRTY(setScaleY, sy, RenderNode::SCALE_Y);
    248 }
    249 
    250 static jboolean android_view_RenderNode_setPivotX(JNIEnv* env,
    251         jobject clazz, jlong renderNodePtr, float px) {
    252     return SET_AND_DIRTY(setPivotX, px, RenderNode::GENERIC);
    253 }
    254 
    255 static jboolean android_view_RenderNode_setPivotY(JNIEnv* env,
    256         jobject clazz, jlong renderNodePtr, float py) {
    257     return SET_AND_DIRTY(setPivotY, py, RenderNode::GENERIC);
    258 }
    259 
    260 static jboolean android_view_RenderNode_setCameraDistance(JNIEnv* env,
    261         jobject clazz, jlong renderNodePtr, float distance) {
    262     return SET_AND_DIRTY(setCameraDistance, distance, RenderNode::GENERIC);
    263 }
    264 
    265 static jboolean android_view_RenderNode_setLeft(JNIEnv* env,
    266         jobject clazz, jlong renderNodePtr, int left) {
    267     return SET_AND_DIRTY(setLeft, left, RenderNode::X);
    268 }
    269 
    270 static jboolean android_view_RenderNode_setTop(JNIEnv* env,
    271         jobject clazz, jlong renderNodePtr, int top) {
    272     return SET_AND_DIRTY(setTop, top, RenderNode::Y);
    273 }
    274 
    275 static jboolean android_view_RenderNode_setRight(JNIEnv* env,
    276         jobject clazz, jlong renderNodePtr, int right) {
    277     return SET_AND_DIRTY(setRight, right, RenderNode::X);
    278 }
    279 
    280 static jboolean android_view_RenderNode_setBottom(JNIEnv* env,
    281         jobject clazz, jlong renderNodePtr, int bottom) {
    282     return SET_AND_DIRTY(setBottom, bottom, RenderNode::Y);
    283 }
    284 
    285 static jboolean android_view_RenderNode_setLeftTopRightBottom(JNIEnv* env,
    286         jobject clazz, jlong renderNodePtr, int left, int top,
    287         int right, int bottom) {
    288     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    289     if (renderNode->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom)) {
    290         renderNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
    291         return true;
    292     }
    293     return false;
    294 }
    295 
    296 static jboolean android_view_RenderNode_offsetLeftAndRight(JNIEnv* env,
    297         jobject clazz, jlong renderNodePtr, jint offset) {
    298     return SET_AND_DIRTY(offsetLeftRight, offset, RenderNode::X);
    299 }
    300 
    301 static jboolean android_view_RenderNode_offsetTopAndBottom(JNIEnv* env,
    302         jobject clazz, jlong renderNodePtr, jint offset) {
    303     return SET_AND_DIRTY(offsetTopBottom, offset, RenderNode::Y);
    304 }
    305 
    306 // ----------------------------------------------------------------------------
    307 // RenderProperties - getters
    308 // ----------------------------------------------------------------------------
    309 
    310 static jboolean android_view_RenderNode_hasOverlappingRendering(JNIEnv* env,
    311         jobject clazz, jlong renderNodePtr) {
    312     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    313     return renderNode->stagingProperties().hasOverlappingRendering();
    314 }
    315 
    316 static jboolean android_view_RenderNode_getClipToOutline(JNIEnv* env,
    317         jobject clazz, jlong renderNodePtr) {
    318     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    319     return renderNode->stagingProperties().getOutline().getShouldClip();
    320 }
    321 
    322 static jfloat android_view_RenderNode_getAlpha(JNIEnv* env,
    323         jobject clazz, jlong renderNodePtr) {
    324     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    325     return renderNode->stagingProperties().getAlpha();
    326 }
    327 
    328 static jfloat android_view_RenderNode_getCameraDistance(JNIEnv* env,
    329         jobject clazz, jlong renderNodePtr) {
    330     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    331     return renderNode->stagingProperties().getCameraDistance();
    332 }
    333 
    334 static jfloat android_view_RenderNode_getScaleX(JNIEnv* env,
    335         jobject clazz, jlong renderNodePtr) {
    336     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    337     return renderNode->stagingProperties().getScaleX();
    338 }
    339 
    340 static jfloat android_view_RenderNode_getScaleY(JNIEnv* env,
    341         jobject clazz, jlong renderNodePtr) {
    342     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    343     return renderNode->stagingProperties().getScaleY();
    344 }
    345 
    346 static jfloat android_view_RenderNode_getElevation(JNIEnv* env,
    347         jobject clazz, jlong renderNodePtr) {
    348     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    349     return renderNode->stagingProperties().getElevation();
    350 }
    351 
    352 static jfloat android_view_RenderNode_getTranslationX(JNIEnv* env,
    353         jobject clazz, jlong renderNodePtr) {
    354     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    355     return renderNode->stagingProperties().getTranslationX();
    356 }
    357 
    358 static jfloat android_view_RenderNode_getTranslationY(JNIEnv* env,
    359         jobject clazz, jlong renderNodePtr) {
    360     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    361     return renderNode->stagingProperties().getTranslationY();
    362 }
    363 
    364 static jfloat android_view_RenderNode_getTranslationZ(JNIEnv* env,
    365         jobject clazz, jlong renderNodePtr) {
    366     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    367     return renderNode->stagingProperties().getTranslationZ();
    368 }
    369 
    370 static jfloat android_view_RenderNode_getRotation(JNIEnv* env,
    371         jobject clazz, jlong renderNodePtr) {
    372     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    373     return renderNode->stagingProperties().getRotation();
    374 }
    375 
    376 static jfloat android_view_RenderNode_getRotationX(JNIEnv* env,
    377         jobject clazz, jlong renderNodePtr) {
    378     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    379     return renderNode->stagingProperties().getRotationX();
    380 }
    381 
    382 static jfloat android_view_RenderNode_getRotationY(JNIEnv* env,
    383         jobject clazz, jlong renderNodePtr) {
    384     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    385     return renderNode->stagingProperties().getRotationY();
    386 }
    387 
    388 static jboolean android_view_RenderNode_isPivotExplicitlySet(JNIEnv* env,
    389         jobject clazz, jlong renderNodePtr) {
    390     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    391     return renderNode->stagingProperties().isPivotExplicitlySet();
    392 }
    393 
    394 static jboolean android_view_RenderNode_hasIdentityMatrix(JNIEnv* env,
    395         jobject clazz, jlong renderNodePtr) {
    396     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    397     renderNode->mutateStagingProperties().updateMatrix();
    398     return !renderNode->stagingProperties().hasTransformMatrix();
    399 }
    400 
    401 // ----------------------------------------------------------------------------
    402 // RenderProperties - computed getters
    403 // ----------------------------------------------------------------------------
    404 
    405 static void android_view_RenderNode_getTransformMatrix(JNIEnv* env,
    406         jobject clazz, jlong renderNodePtr, jlong outMatrixPtr) {
    407     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    408     SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
    409 
    410     renderNode->mutateStagingProperties().updateMatrix();
    411     const SkMatrix* transformMatrix = renderNode->stagingProperties().getTransformMatrix();
    412 
    413     if (transformMatrix) {
    414         *outMatrix = *transformMatrix;
    415     } else {
    416         outMatrix->setIdentity();
    417     }
    418 }
    419 
    420 static void android_view_RenderNode_getInverseTransformMatrix(JNIEnv* env,
    421         jobject clazz, jlong renderNodePtr, jlong outMatrixPtr) {
    422     // load transform matrix
    423     android_view_RenderNode_getTransformMatrix(env, clazz, renderNodePtr, outMatrixPtr);
    424     SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
    425 
    426     // return it inverted
    427     if (!outMatrix->invert(outMatrix)) {
    428         // failed to load inverse, pass back identity
    429         outMatrix->setIdentity();
    430     }
    431 }
    432 
    433 static jfloat android_view_RenderNode_getPivotX(JNIEnv* env,
    434         jobject clazz, jlong renderNodePtr) {
    435     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    436     renderNode->mutateStagingProperties().updateMatrix();
    437     return renderNode->stagingProperties().getPivotX();
    438 }
    439 
    440 static jfloat android_view_RenderNode_getPivotY(JNIEnv* env,
    441         jobject clazz, jlong renderNodePtr) {
    442     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    443     renderNode->mutateStagingProperties().updateMatrix();
    444     return renderNode->stagingProperties().getPivotY();
    445 }
    446 
    447 // ----------------------------------------------------------------------------
    448 // RenderProperties - Animations
    449 // ----------------------------------------------------------------------------
    450 
    451 static void android_view_RenderNode_addAnimator(JNIEnv* env, jobject clazz,
    452         jlong renderNodePtr, jlong animatorPtr) {
    453     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    454     RenderPropertyAnimator* animator = reinterpret_cast<RenderPropertyAnimator*>(animatorPtr);
    455     renderNode->addAnimator(animator);
    456 }
    457 
    458 static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz,
    459         jlong renderNodePtr) {
    460     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    461     renderNode->animators().endAllStagingAnimators();
    462 }
    463 
    464 // ----------------------------------------------------------------------------
    465 // JNI Glue
    466 // ----------------------------------------------------------------------------
    467 
    468 const char* const kClassPathName = "android/view/RenderNode";
    469 
    470 static JNINativeMethod gMethods[] = {
    471     { "nCreate",               "(Ljava/lang/String;)J",    (void*) android_view_RenderNode_create },
    472     { "nDestroyRenderNode",   "(J)V",   (void*) android_view_RenderNode_destroyRenderNode },
    473     { "nSetDisplayListData",   "(JJ)V", (void*) android_view_RenderNode_setDisplayListData },
    474     { "nOutput",               "(J)V",  (void*) android_view_RenderNode_output },
    475     { "nGetDebugSize",         "(J)I",  (void*) android_view_RenderNode_getDebugSize },
    476 
    477     { "nSetLayerType",         "!(JI)Z",  (void*) android_view_RenderNode_setLayerType },
    478     { "nSetLayerPaint",        "!(JJ)Z",  (void*) android_view_RenderNode_setLayerPaint },
    479     { "nSetStaticMatrix",      "!(JJ)Z",  (void*) android_view_RenderNode_setStaticMatrix },
    480     { "nSetAnimationMatrix",   "!(JJ)Z",  (void*) android_view_RenderNode_setAnimationMatrix },
    481     { "nSetClipToBounds",      "!(JZ)Z",  (void*) android_view_RenderNode_setClipToBounds },
    482     { "nSetClipBounds",        "!(JIIII)Z", (void*) android_view_RenderNode_setClipBounds },
    483     { "nSetClipBoundsEmpty",   "!(J)Z",   (void*) android_view_RenderNode_setClipBoundsEmpty },
    484     { "nSetProjectBackwards",  "!(JZ)Z",  (void*) android_view_RenderNode_setProjectBackwards },
    485     { "nSetProjectionReceiver","!(JZ)Z",  (void*) android_view_RenderNode_setProjectionReceiver },
    486 
    487     { "nSetOutlineRoundRect",  "(JIIIIFF)Z", (void*) android_view_RenderNode_setOutlineRoundRect },
    488     { "nSetOutlineConvexPath", "(JJF)Z", (void*) android_view_RenderNode_setOutlineConvexPath },
    489     { "nSetOutlineEmpty",      "(J)Z",   (void*) android_view_RenderNode_setOutlineEmpty },
    490     { "nSetOutlineNone",       "(J)Z",   (void*) android_view_RenderNode_setOutlineNone },
    491     { "nHasShadow",            "!(J)Z",   (void*) android_view_RenderNode_hasShadow },
    492     { "nSetClipToOutline",     "!(JZ)Z",  (void*) android_view_RenderNode_setClipToOutline },
    493     { "nSetRevealClip",        "(JZFFF)Z", (void*) android_view_RenderNode_setRevealClip },
    494 
    495     { "nSetAlpha",             "!(JF)Z",  (void*) android_view_RenderNode_setAlpha },
    496     { "nSetHasOverlappingRendering", "!(JZ)Z",
    497             (void*) android_view_RenderNode_setHasOverlappingRendering },
    498     { "nSetElevation",         "!(JF)Z",  (void*) android_view_RenderNode_setElevation },
    499     { "nSetTranslationX",      "!(JF)Z",  (void*) android_view_RenderNode_setTranslationX },
    500     { "nSetTranslationY",      "!(JF)Z",  (void*) android_view_RenderNode_setTranslationY },
    501     { "nSetTranslationZ",      "!(JF)Z",  (void*) android_view_RenderNode_setTranslationZ },
    502     { "nSetRotation",          "!(JF)Z",  (void*) android_view_RenderNode_setRotation },
    503     { "nSetRotationX",         "!(JF)Z",  (void*) android_view_RenderNode_setRotationX },
    504     { "nSetRotationY",         "!(JF)Z",  (void*) android_view_RenderNode_setRotationY },
    505     { "nSetScaleX",            "!(JF)Z",  (void*) android_view_RenderNode_setScaleX },
    506     { "nSetScaleY",            "!(JF)Z",  (void*) android_view_RenderNode_setScaleY },
    507     { "nSetPivotX",            "!(JF)Z",  (void*) android_view_RenderNode_setPivotX },
    508     { "nSetPivotY",            "!(JF)Z",  (void*) android_view_RenderNode_setPivotY },
    509     { "nSetCameraDistance",    "!(JF)Z",  (void*) android_view_RenderNode_setCameraDistance },
    510     { "nSetLeft",              "!(JI)Z",  (void*) android_view_RenderNode_setLeft },
    511     { "nSetTop",               "!(JI)Z",  (void*) android_view_RenderNode_setTop },
    512     { "nSetRight",             "!(JI)Z",  (void*) android_view_RenderNode_setRight },
    513     { "nSetBottom",            "!(JI)Z",  (void*) android_view_RenderNode_setBottom },
    514     { "nSetLeftTopRightBottom","!(JIIII)Z", (void*) android_view_RenderNode_setLeftTopRightBottom },
    515     { "nOffsetLeftAndRight",   "!(JI)Z",  (void*) android_view_RenderNode_offsetLeftAndRight },
    516     { "nOffsetTopAndBottom",   "!(JI)Z",  (void*) android_view_RenderNode_offsetTopAndBottom },
    517 
    518     { "nHasOverlappingRendering", "!(J)Z",  (void*) android_view_RenderNode_hasOverlappingRendering },
    519     { "nGetClipToOutline",        "!(J)Z",  (void*) android_view_RenderNode_getClipToOutline },
    520     { "nGetAlpha",                "!(J)F",  (void*) android_view_RenderNode_getAlpha },
    521     { "nGetCameraDistance",       "!(J)F",  (void*) android_view_RenderNode_getCameraDistance },
    522     { "nGetScaleX",               "!(J)F",  (void*) android_view_RenderNode_getScaleX },
    523     { "nGetScaleY",               "!(J)F",  (void*) android_view_RenderNode_getScaleY },
    524     { "nGetElevation",            "!(J)F",  (void*) android_view_RenderNode_getElevation },
    525     { "nGetTranslationX",         "!(J)F",  (void*) android_view_RenderNode_getTranslationX },
    526     { "nGetTranslationY",         "!(J)F",  (void*) android_view_RenderNode_getTranslationY },
    527     { "nGetTranslationZ",         "!(J)F",  (void*) android_view_RenderNode_getTranslationZ },
    528     { "nGetRotation",             "!(J)F",  (void*) android_view_RenderNode_getRotation },
    529     { "nGetRotationX",            "!(J)F",  (void*) android_view_RenderNode_getRotationX },
    530     { "nGetRotationY",            "!(J)F",  (void*) android_view_RenderNode_getRotationY },
    531     { "nIsPivotExplicitlySet",    "!(J)Z",  (void*) android_view_RenderNode_isPivotExplicitlySet },
    532     { "nHasIdentityMatrix",       "!(J)Z",  (void*) android_view_RenderNode_hasIdentityMatrix },
    533 
    534     { "nGetTransformMatrix",       "!(JJ)V", (void*) android_view_RenderNode_getTransformMatrix },
    535     { "nGetInverseTransformMatrix","!(JJ)V", (void*) android_view_RenderNode_getInverseTransformMatrix },
    536 
    537     { "nGetPivotX",                "!(J)F",  (void*) android_view_RenderNode_getPivotX },
    538     { "nGetPivotY",                "!(J)F",  (void*) android_view_RenderNode_getPivotY },
    539 
    540     { "nAddAnimator",              "(JJ)V", (void*) android_view_RenderNode_addAnimator },
    541     { "nEndAllAnimators",          "(J)V", (void*) android_view_RenderNode_endAllAnimators },
    542 };
    543 
    544 int register_android_view_RenderNode(JNIEnv* env) {
    545     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
    546 }
    547 
    548 };
    549 
    550