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