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