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