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