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