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