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