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
32namespace android {
33
34using 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
45static void android_view_RenderNode_output(JNIEnv* env,
46        jobject clazz, jlong renderNodePtr) {
47    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
48    renderNode->output();
49}
50
51static 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
57static 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
68static 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
74static 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
85static 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
91static 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
97static 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
103static 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
109static 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
114static 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
120static jboolean android_view_RenderNode_setClipBoundsEmpty(JNIEnv* env,
121        jobject clazz, jlong renderNodePtr) {
122    return SET_AND_DIRTY(setClipBoundsEmpty,, RenderNode::GENERIC);
123}
124
125static 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
130static 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
135static 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
145static 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
154static 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
162static 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
170static 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
176static 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
184static 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
194static 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
199static 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
205static 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
210static 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
215static 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
220static 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
225static 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
230static 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
235static 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
240static 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
245static 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
250static 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
255static 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
260static 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
265static 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
270static 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
275static 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
280static 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
285static 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
296static 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
301static 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
310static 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
316static 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
322static 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
328static 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
334static 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
340static 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
346static 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
352static 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
358static 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
364static 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
370static 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
376static 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
382static 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
388static 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
394static 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
405static 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
420static 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
433static 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
440static 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
451static 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
458static 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
468const char* const kClassPathName = "android/view/RenderNode";
469
470static 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
544int register_android_view_RenderNode(JNIEnv* env) {
545    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
546}
547
548};
549
550