• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ATRACE_TAG ATRACE_TAG_VIEW
18 #include "GraphicsJNI.h"
19 
20 #include <Animator.h>
21 #include <DamageAccumulator.h>
22 #include <Matrix.h>
23 #include <RenderNode.h>
24 #ifdef __ANDROID__ // Layoutlib does not support CanvasContext
25 #include <renderthread/CanvasContext.h>
26 #endif
27 #include <TreeInfo.h>
28 #include <hwui/Paint.h>
29 #include <utils/TraceUtils.h>
30 
31 namespace android {
32 
33 using namespace uirenderer;
34 
35 #define SET_AND_DIRTY(prop, val, dirtyFlag) \
36     (reinterpret_cast<RenderNode*>(renderNodePtr)->mutateStagingProperties().prop(val) \
37         ? (reinterpret_cast<RenderNode*>(renderNodePtr)->setPropertyFieldsDirty(dirtyFlag), true) \
38         : false)
39 
40 // ----------------------------------------------------------------------------
41 // DisplayList view properties
42 // ----------------------------------------------------------------------------
43 
android_view_RenderNode_output(JNIEnv * env,jobject clazz,jlong renderNodePtr)44 static void android_view_RenderNode_output(JNIEnv* env, jobject clazz, jlong renderNodePtr) {
45     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
46     renderNode->output();
47 }
48 
android_view_RenderNode_getUsageSize(JNIEnv * env,jobject clazz,jlong renderNodePtr)49 static jint android_view_RenderNode_getUsageSize(JNIEnv* env, jobject clazz, jlong renderNodePtr) {
50     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
51     return renderNode->getUsageSize();
52 }
53 
android_view_RenderNode_getAllocatedSize(JNIEnv * env,jobject clazz,jlong renderNodePtr)54 static jint android_view_RenderNode_getAllocatedSize(JNIEnv* env, jobject clazz, jlong renderNodePtr) {
55     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
56     return renderNode->getAllocatedSize();
57 }
58 
android_view_RenderNode_create(JNIEnv * env,jobject,jstring name)59 static jlong android_view_RenderNode_create(JNIEnv* env, jobject, jstring name) {
60     RenderNode* renderNode = new RenderNode();
61     renderNode->incStrong(0);
62     if (name != NULL) {
63         const char* textArray = env->GetStringUTFChars(name, NULL);
64         renderNode->setName(textArray);
65         env->ReleaseStringUTFChars(name, textArray);
66     }
67     return reinterpret_cast<jlong>(renderNode);
68 }
69 
releaseRenderNode(RenderNode * renderNode)70 static void releaseRenderNode(RenderNode* renderNode) {
71     renderNode->decStrong(0);
72 }
73 
android_view_RenderNode_getNativeFinalizer(JNIEnv * env,jobject clazz)74 static jlong android_view_RenderNode_getNativeFinalizer(JNIEnv* env,
75         jobject clazz) {
76     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseRenderNode));
77 }
78 
android_view_RenderNode_setDisplayList(JNIEnv * env,jobject clazz,jlong renderNodePtr,jlong displayListPtr)79 static void android_view_RenderNode_setDisplayList(JNIEnv* env,
80         jobject clazz, jlong renderNodePtr, jlong displayListPtr) {
81     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
82     DisplayList* newData = reinterpret_cast<DisplayList*>(displayListPtr);
83     renderNode->setStagingDisplayList(newData);
84 }
85 
android_view_RenderNode_isValid(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)86 static jboolean android_view_RenderNode_isValid(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
87     return reinterpret_cast<RenderNode*>(renderNodePtr)->isValid();
88 }
89 
90 // ----------------------------------------------------------------------------
91 // RenderProperties - setters
92 // ----------------------------------------------------------------------------
93 
android_view_RenderNode_setLayerType(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jint jlayerType)94 static jboolean android_view_RenderNode_setLayerType(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint jlayerType) {
95     LayerType layerType = static_cast<LayerType>(jlayerType);
96     return SET_AND_DIRTY(mutateLayerProperties().setType, layerType, RenderNode::GENERIC);
97 }
98 
android_view_RenderNode_setLayerPaint(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jlong paintPtr)99 static jboolean android_view_RenderNode_setLayerPaint(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong paintPtr) {
100     Paint* paint = reinterpret_cast<Paint*>(paintPtr);
101     return SET_AND_DIRTY(mutateLayerProperties().setFromPaint, paint, RenderNode::GENERIC);
102 }
103 
android_view_RenderNode_setStaticMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jlong matrixPtr)104 static jboolean android_view_RenderNode_setStaticMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong matrixPtr) {
105     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
106     return SET_AND_DIRTY(setStaticMatrix, matrix, RenderNode::GENERIC);
107 }
108 
android_view_RenderNode_setAnimationMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jlong matrixPtr)109 static jboolean android_view_RenderNode_setAnimationMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong matrixPtr) {
110     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
111     return SET_AND_DIRTY(setAnimationMatrix, matrix, RenderNode::GENERIC);
112 }
113 
android_view_RenderNode_setClipToBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jboolean clipToBounds)114 static jboolean android_view_RenderNode_setClipToBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
115         jboolean clipToBounds) {
116     return SET_AND_DIRTY(setClipToBounds, clipToBounds, RenderNode::GENERIC);
117 }
118 
android_view_RenderNode_setClipBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jint left,jint top,jint right,jint bottom)119 static jboolean android_view_RenderNode_setClipBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
120         jint left, jint top, jint right, jint bottom) {
121     android::uirenderer::Rect clipBounds(left, top, right, bottom);
122     return SET_AND_DIRTY(setClipBounds, clipBounds, RenderNode::GENERIC);
123 }
124 
android_view_RenderNode_setClipBoundsEmpty(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)125 static jboolean android_view_RenderNode_setClipBoundsEmpty(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
126     return SET_AND_DIRTY(setClipBoundsEmpty,, RenderNode::GENERIC);
127 }
128 
android_view_RenderNode_setProjectBackwards(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jboolean shouldProject)129 static jboolean android_view_RenderNode_setProjectBackwards(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
130         jboolean shouldProject) {
131     return SET_AND_DIRTY(setProjectBackwards, shouldProject, RenderNode::GENERIC);
132 }
133 
android_view_RenderNode_setProjectionReceiver(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jboolean shouldRecieve)134 static jboolean android_view_RenderNode_setProjectionReceiver(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
135         jboolean shouldRecieve) {
136     return SET_AND_DIRTY(setProjectionReceiver, shouldRecieve, RenderNode::GENERIC);
137 }
138 
android_view_RenderNode_setOutlineRoundRect(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jint left,jint top,jint right,jint bottom,jfloat radius,jfloat alpha)139 static jboolean android_view_RenderNode_setOutlineRoundRect(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
140         jint left, jint top, jint right, jint bottom, jfloat radius, jfloat alpha) {
141     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
142     renderNode->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom,
143             radius, alpha);
144     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
145     return true;
146 }
147 
android_view_RenderNode_setOutlinePath(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jlong outlinePathPtr,jfloat alpha)148 static jboolean android_view_RenderNode_setOutlinePath(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
149         jlong outlinePathPtr, jfloat alpha) {
150     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
151     SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
152     renderNode->mutateStagingProperties().mutableOutline().setPath(outlinePath, alpha);
153     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
154     return true;
155 }
156 
android_view_RenderNode_setOutlineEmpty(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)157 static jboolean android_view_RenderNode_setOutlineEmpty(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
158     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
159     renderNode->mutateStagingProperties().mutableOutline().setEmpty();
160     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
161     return true;
162 }
163 
android_view_RenderNode_setOutlineNone(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)164 static jboolean android_view_RenderNode_setOutlineNone(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
165     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
166     renderNode->mutateStagingProperties().mutableOutline().setNone();
167     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
168     return true;
169 }
170 
android_view_RenderNode_hasShadow(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)171 static jboolean android_view_RenderNode_hasShadow(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
172     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
173     return renderNode->stagingProperties().hasShadow();
174 }
175 
android_view_RenderNode_setSpotShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jint shadowColor)176 static jboolean android_view_RenderNode_setSpotShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint shadowColor) {
177     return SET_AND_DIRTY(setSpotShadowColor,
178             static_cast<SkColor>(shadowColor), RenderNode::GENERIC);
179 }
180 
android_view_RenderNode_getSpotShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)181 static jint android_view_RenderNode_getSpotShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
182     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
183     return renderNode->stagingProperties().getSpotShadowColor();
184 }
185 
android_view_RenderNode_setAmbientShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jint shadowColor)186 static jboolean android_view_RenderNode_setAmbientShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
187         jint shadowColor) {
188     return SET_AND_DIRTY(setAmbientShadowColor,
189             static_cast<SkColor>(shadowColor), RenderNode::GENERIC);
190 }
191 
android_view_RenderNode_getAmbientShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)192 static jint android_view_RenderNode_getAmbientShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
193     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
194     return renderNode->stagingProperties().getAmbientShadowColor();
195 }
196 
android_view_RenderNode_setClipToOutline(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jboolean clipToOutline)197 static jboolean android_view_RenderNode_setClipToOutline(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
198         jboolean clipToOutline) {
199     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
200     renderNode->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline);
201     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
202     return true;
203 }
204 
android_view_RenderNode_setRevealClip(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jboolean shouldClip,jfloat x,jfloat y,jfloat radius)205 static jboolean android_view_RenderNode_setRevealClip(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jboolean shouldClip,
206         jfloat x, jfloat y, jfloat radius) {
207     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
208     renderNode->mutateStagingProperties().mutableRevealClip().set(
209             shouldClip, x, y, radius);
210     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
211     return true;
212 }
213 
android_view_RenderNode_setAlpha(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float alpha)214 static jboolean android_view_RenderNode_setAlpha(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float alpha) {
215     return SET_AND_DIRTY(setAlpha, alpha, RenderNode::ALPHA);
216 }
217 
android_view_RenderNode_setHasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,bool hasOverlappingRendering)218 static jboolean android_view_RenderNode_setHasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
219         bool hasOverlappingRendering) {
220     return SET_AND_DIRTY(setHasOverlappingRendering, hasOverlappingRendering,
221             RenderNode::GENERIC);
222 }
223 
android_view_RenderNode_setUsageHint(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jint usageHint)224 static void android_view_RenderNode_setUsageHint(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint usageHint) {
225     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
226     renderNode->setUsageHint(static_cast<UsageHint>(usageHint));
227 }
228 
android_view_RenderNode_setElevation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float elevation)229 static jboolean android_view_RenderNode_setElevation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float elevation) {
230     return SET_AND_DIRTY(setElevation, elevation, RenderNode::Z);
231 }
232 
android_view_RenderNode_setTranslationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float tx)233 static jboolean android_view_RenderNode_setTranslationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float tx) {
234     return SET_AND_DIRTY(setTranslationX, tx, RenderNode::TRANSLATION_X | RenderNode::X);
235 }
236 
android_view_RenderNode_setTranslationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float ty)237 static jboolean android_view_RenderNode_setTranslationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float ty) {
238     return SET_AND_DIRTY(setTranslationY, ty, RenderNode::TRANSLATION_Y | RenderNode::Y);
239 }
240 
android_view_RenderNode_setTranslationZ(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float tz)241 static jboolean android_view_RenderNode_setTranslationZ(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float tz) {
242     return SET_AND_DIRTY(setTranslationZ, tz, RenderNode::TRANSLATION_Z | RenderNode::Z);
243 }
244 
android_view_RenderNode_setRotation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float rotation)245 static jboolean android_view_RenderNode_setRotation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float rotation) {
246     return SET_AND_DIRTY(setRotation, rotation, RenderNode::ROTATION);
247 }
248 
android_view_RenderNode_setRotationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float rx)249 static jboolean android_view_RenderNode_setRotationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float rx) {
250     return SET_AND_DIRTY(setRotationX, rx, RenderNode::ROTATION_X);
251 }
252 
android_view_RenderNode_setRotationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float ry)253 static jboolean android_view_RenderNode_setRotationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float ry) {
254     return SET_AND_DIRTY(setRotationY, ry, RenderNode::ROTATION_Y);
255 }
256 
android_view_RenderNode_setScaleX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float sx)257 static jboolean android_view_RenderNode_setScaleX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float sx) {
258     return SET_AND_DIRTY(setScaleX, sx, RenderNode::SCALE_X);
259 }
260 
android_view_RenderNode_setScaleY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float sy)261 static jboolean android_view_RenderNode_setScaleY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float sy) {
262     return SET_AND_DIRTY(setScaleY, sy, RenderNode::SCALE_Y);
263 }
264 
android_view_RenderNode_setPivotX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float px)265 static jboolean android_view_RenderNode_setPivotX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float px) {
266     return SET_AND_DIRTY(setPivotX, px, RenderNode::GENERIC);
267 }
268 
android_view_RenderNode_setPivotY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float py)269 static jboolean android_view_RenderNode_setPivotY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float py) {
270     return SET_AND_DIRTY(setPivotY, py, RenderNode::GENERIC);
271 }
272 
android_view_RenderNode_resetPivot(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)273 static jboolean android_view_RenderNode_resetPivot(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
274     return SET_AND_DIRTY(resetPivot, /* void */, RenderNode::GENERIC);
275 }
276 
android_view_RenderNode_setCameraDistance(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,float distance)277 static jboolean android_view_RenderNode_setCameraDistance(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float distance) {
278     return SET_AND_DIRTY(setCameraDistance, distance, RenderNode::GENERIC);
279 }
280 
android_view_RenderNode_setLeft(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,int left)281 static jboolean android_view_RenderNode_setLeft(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int left) {
282     return SET_AND_DIRTY(setLeft, left, RenderNode::X);
283 }
284 
android_view_RenderNode_setTop(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,int top)285 static jboolean android_view_RenderNode_setTop(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int top) {
286     return SET_AND_DIRTY(setTop, top, RenderNode::Y);
287 }
288 
android_view_RenderNode_setRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,int right)289 static jboolean android_view_RenderNode_setRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int right) {
290     return SET_AND_DIRTY(setRight, right, RenderNode::X);
291 }
292 
android_view_RenderNode_setBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,int bottom)293 static jboolean android_view_RenderNode_setBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int bottom) {
294     return SET_AND_DIRTY(setBottom, bottom, RenderNode::Y);
295 }
296 
android_view_RenderNode_getLeft(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)297 static jint android_view_RenderNode_getLeft(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
298     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getLeft();
299 }
300 
android_view_RenderNode_getTop(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)301 static jint android_view_RenderNode_getTop(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
302     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getTop();
303 }
304 
android_view_RenderNode_getRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)305 static jint android_view_RenderNode_getRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
306     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getRight();
307 }
308 
android_view_RenderNode_getBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)309 static jint android_view_RenderNode_getBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
310     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getBottom();
311 }
312 
android_view_RenderNode_setLeftTopRightBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,int left,int top,int right,int bottom)313 static jboolean android_view_RenderNode_setLeftTopRightBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
314         int left, int top, int right, int bottom) {
315     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
316     if (renderNode->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom)) {
317         renderNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
318         return true;
319     }
320     return false;
321 }
322 
android_view_RenderNode_offsetLeftAndRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jint offset)323 static jboolean android_view_RenderNode_offsetLeftAndRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint offset) {
324     return SET_AND_DIRTY(offsetLeftRight, offset, RenderNode::X);
325 }
326 
android_view_RenderNode_offsetTopAndBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jint offset)327 static jboolean android_view_RenderNode_offsetTopAndBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint offset) {
328     return SET_AND_DIRTY(offsetTopBottom, offset, RenderNode::Y);
329 }
330 
331 // ----------------------------------------------------------------------------
332 // RenderProperties - getters
333 // ----------------------------------------------------------------------------
334 
android_view_RenderNode_hasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)335 static jboolean android_view_RenderNode_hasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
336     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
337     return renderNode->stagingProperties().hasOverlappingRendering();
338 }
339 
android_view_RenderNode_getAnimationMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jlong outMatrixPtr)340 static jboolean android_view_RenderNode_getAnimationMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong outMatrixPtr) {
341     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
342     SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
343 
344     const SkMatrix* animationMatrix = renderNode->stagingProperties().getAnimationMatrix();
345 
346     if (animationMatrix) {
347         *outMatrix = *animationMatrix;
348         return JNI_TRUE;
349     }
350     return JNI_FALSE;
351 }
352 
android_view_RenderNode_getClipToBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)353 static jboolean android_view_RenderNode_getClipToBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
354     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
355     return renderNode->stagingProperties().getClipToBounds();
356 }
357 
android_view_RenderNode_getClipToOutline(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)358 static jboolean android_view_RenderNode_getClipToOutline(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
359     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
360     return renderNode->stagingProperties().getOutline().getShouldClip();
361 }
362 
android_view_RenderNode_getAlpha(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)363 static jfloat android_view_RenderNode_getAlpha(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
364     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
365     return renderNode->stagingProperties().getAlpha();
366 }
367 
android_view_RenderNode_getCameraDistance(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)368 static jfloat android_view_RenderNode_getCameraDistance(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
369     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
370     return renderNode->stagingProperties().getCameraDistance();
371 }
372 
android_view_RenderNode_getScaleX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)373 static jfloat android_view_RenderNode_getScaleX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
374     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
375     return renderNode->stagingProperties().getScaleX();
376 }
377 
android_view_RenderNode_getScaleY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)378 static jfloat android_view_RenderNode_getScaleY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
379     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
380     return renderNode->stagingProperties().getScaleY();
381 }
382 
android_view_RenderNode_getElevation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)383 static jfloat android_view_RenderNode_getElevation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
384     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
385     return renderNode->stagingProperties().getElevation();
386 }
387 
android_view_RenderNode_getTranslationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)388 static jfloat android_view_RenderNode_getTranslationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
389     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
390     return renderNode->stagingProperties().getTranslationX();
391 }
392 
android_view_RenderNode_getTranslationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)393 static jfloat android_view_RenderNode_getTranslationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
394     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
395     return renderNode->stagingProperties().getTranslationY();
396 }
397 
android_view_RenderNode_getTranslationZ(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)398 static jfloat android_view_RenderNode_getTranslationZ(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
399     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
400     return renderNode->stagingProperties().getTranslationZ();
401 }
402 
android_view_RenderNode_getRotation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)403 static jfloat android_view_RenderNode_getRotation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
404     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
405     return renderNode->stagingProperties().getRotation();
406 }
407 
android_view_RenderNode_getRotationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)408 static jfloat android_view_RenderNode_getRotationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
409     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
410     return renderNode->stagingProperties().getRotationX();
411 }
412 
android_view_RenderNode_getRotationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)413 static jfloat android_view_RenderNode_getRotationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
414     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
415     return renderNode->stagingProperties().getRotationY();
416 }
417 
android_view_RenderNode_isPivotExplicitlySet(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)418 static jboolean android_view_RenderNode_isPivotExplicitlySet(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
419     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
420     return renderNode->stagingProperties().isPivotExplicitlySet();
421 }
422 
android_view_RenderNode_hasIdentityMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)423 static jboolean android_view_RenderNode_hasIdentityMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
424     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
425     renderNode->mutateStagingProperties().updateMatrix();
426     return !renderNode->stagingProperties().hasTransformMatrix();
427 }
428 
android_view_RenderNode_getLayerType(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)429 static jint android_view_RenderNode_getLayerType(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
430     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
431     return static_cast<int>(renderNode->stagingProperties().layerProperties().type());
432 }
433 
434 // ----------------------------------------------------------------------------
435 // RenderProperties - computed getters
436 // ----------------------------------------------------------------------------
437 
getTransformMatrix(jlong renderNodePtr,jlong outMatrixPtr)438 static void getTransformMatrix(jlong renderNodePtr, jlong outMatrixPtr) {
439     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
440     SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
441 
442     renderNode->mutateStagingProperties().updateMatrix();
443     const SkMatrix* transformMatrix = renderNode->stagingProperties().getTransformMatrix();
444 
445     if (transformMatrix) {
446         *outMatrix = *transformMatrix;
447     } else {
448         outMatrix->setIdentity();
449     }
450 }
451 
android_view_RenderNode_getTransformMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jlong outMatrixPtr)452 static void android_view_RenderNode_getTransformMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong outMatrixPtr) {
453     getTransformMatrix(renderNodePtr, outMatrixPtr);
454 }
455 
android_view_RenderNode_getInverseTransformMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jlong outMatrixPtr)456 static void android_view_RenderNode_getInverseTransformMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
457         jlong outMatrixPtr) {
458     // load transform matrix
459     getTransformMatrix(renderNodePtr, outMatrixPtr);
460     SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
461 
462     // return it inverted
463     if (!outMatrix->invert(outMatrix)) {
464         // failed to load inverse, pass back identity
465         outMatrix->setIdentity();
466     }
467 }
468 
android_view_RenderNode_getPivotX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)469 static jfloat android_view_RenderNode_getPivotX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
470     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
471     renderNode->mutateStagingProperties().updateMatrix();
472     return renderNode->stagingProperties().getPivotX();
473 }
474 
android_view_RenderNode_getPivotY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)475 static jfloat android_view_RenderNode_getPivotY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
476     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
477     renderNode->mutateStagingProperties().updateMatrix();
478     return renderNode->stagingProperties().getPivotY();
479 }
480 
android_view_RenderNode_getWidth(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)481 static jint android_view_RenderNode_getWidth(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
482     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getWidth();
483 }
484 
android_view_RenderNode_getHeight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)485 static jint android_view_RenderNode_getHeight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
486     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getHeight();
487 }
488 
android_view_RenderNode_setAllowForceDark(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jboolean allow)489 static jboolean android_view_RenderNode_setAllowForceDark(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jboolean allow) {
490     return SET_AND_DIRTY(setAllowForceDark, allow, RenderNode::GENERIC);
491 }
492 
android_view_RenderNode_getAllowForceDark(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)493 static jboolean android_view_RenderNode_getAllowForceDark(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
494     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getAllowForceDark();
495 }
496 
android_view_RenderNode_getUniqueId(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr)497 static jlong android_view_RenderNode_getUniqueId(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
498     return reinterpret_cast<RenderNode*>(renderNodePtr)->uniqueId();
499 }
500 
501 // ----------------------------------------------------------------------------
502 // RenderProperties - Animations
503 // ----------------------------------------------------------------------------
504 
android_view_RenderNode_addAnimator(JNIEnv * env,jobject clazz,jlong renderNodePtr,jlong animatorPtr)505 static void android_view_RenderNode_addAnimator(JNIEnv* env, jobject clazz, jlong renderNodePtr,
506         jlong animatorPtr) {
507     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
508     RenderPropertyAnimator* animator = reinterpret_cast<RenderPropertyAnimator*>(animatorPtr);
509     renderNode->addAnimator(animator);
510 }
511 
android_view_RenderNode_endAllAnimators(JNIEnv * env,jobject clazz,jlong renderNodePtr)512 static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz,
513         jlong renderNodePtr) {
514     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
515     renderNode->animators().endAllStagingAnimators();
516 }
517 
518 // ----------------------------------------------------------------------------
519 // SurfaceView position callback
520 // ----------------------------------------------------------------------------
521 
522 jmethodID gPositionListener_PositionChangedMethod;
523 jmethodID gPositionListener_PositionLostMethod;
524 
android_view_RenderNode_requestPositionUpdates(JNIEnv * env,jobject,jlong renderNodePtr,jobject listener)525 static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
526         jlong renderNodePtr, jobject listener) {
527     class PositionListenerTrampoline : public RenderNode::PositionListener {
528     public:
529         PositionListenerTrampoline(JNIEnv* env, jobject listener) {
530             env->GetJavaVM(&mVm);
531             mWeakRef = env->NewWeakGlobalRef(listener);
532         }
533 
534         virtual ~PositionListenerTrampoline() {
535             jnienv()->DeleteWeakGlobalRef(mWeakRef);
536             mWeakRef = nullptr;
537         }
538 
539         virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) override {
540             if (CC_UNLIKELY(!mWeakRef || !info.updateWindowPositions)) return;
541 
542             Matrix4 transform;
543             info.damageAccumulator->computeCurrentTransform(&transform);
544             const RenderProperties& props = node.properties();
545             uirenderer::Rect bounds(props.getWidth(), props.getHeight());
546             transform.mapRect(bounds);
547 
548             if (CC_LIKELY(transform.isPureTranslate())) {
549                 // snap/round the computed bounds, so they match the rounding behavior
550                 // of the clear done in SurfaceView#draw().
551                 bounds.snapGeometryToPixelBoundaries(false);
552             } else {
553                 // Conservatively round out so the punched hole (in the ZOrderOnTop = true case)
554                 // doesn't extend beyond the other window
555                 bounds.roundOut();
556             }
557 
558             if (mPreviousPosition == bounds) {
559                 return;
560             }
561             mPreviousPosition = bounds;
562 
563 #ifdef __ANDROID__ // Layoutlib does not support CanvasContext
564             incStrong(0);
565             auto functor = std::bind(
566                 std::mem_fn(&PositionListenerTrampoline::doUpdatePositionAsync), this,
567                 (jlong) info.canvasContext.getFrameNumber(),
568                 (jint) bounds.left, (jint) bounds.top,
569                 (jint) bounds.right, (jint) bounds.bottom);
570 
571             info.canvasContext.enqueueFrameWork(std::move(functor));
572 #endif
573         }
574 
575         virtual void onPositionLost(RenderNode& node, const TreeInfo* info) override {
576             if (CC_UNLIKELY(!mWeakRef || (info && !info->updateWindowPositions))) return;
577 
578             if (mPreviousPosition.isEmpty()) {
579                 return;
580             }
581             mPreviousPosition.setEmpty();
582 
583             ATRACE_NAME("SurfaceView position lost");
584             JNIEnv* env = jnienv();
585             jobject localref = env->NewLocalRef(mWeakRef);
586             if (CC_UNLIKELY(!localref)) {
587                 jnienv()->DeleteWeakGlobalRef(mWeakRef);
588                 mWeakRef = nullptr;
589                 return;
590             }
591 #ifdef __ANDROID__ // Layoutlib does not support CanvasContext
592             // TODO: Remember why this is synchronous and then make a comment
593             env->CallVoidMethod(localref, gPositionListener_PositionLostMethod,
594                     info ? info->canvasContext.getFrameNumber() : 0);
595 #endif
596             env->DeleteLocalRef(localref);
597         }
598 
599     private:
600         JNIEnv* jnienv() {
601             JNIEnv* env;
602             if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
603                 LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", mVm);
604             }
605             return env;
606         }
607 
608         void doUpdatePositionAsync(jlong frameNumber, jint left, jint top,
609                 jint right, jint bottom) {
610             ATRACE_NAME("Update SurfaceView position");
611 
612             JNIEnv* env = jnienv();
613             jobject localref = env->NewLocalRef(mWeakRef);
614             if (CC_UNLIKELY(!localref)) {
615                 env->DeleteWeakGlobalRef(mWeakRef);
616                 mWeakRef = nullptr;
617             } else {
618                 env->CallVoidMethod(localref, gPositionListener_PositionChangedMethod,
619                         frameNumber, left, top, right, bottom);
620                 env->DeleteLocalRef(localref);
621             }
622 
623             // We need to release ourselves here
624             decStrong(0);
625         }
626 
627         JavaVM* mVm;
628         jobject mWeakRef;
629         uirenderer::Rect mPreviousPosition;
630     };
631 
632     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
633     renderNode->setPositionListener(new PositionListenerTrampoline(env, listener));
634 }
635 
636 // ----------------------------------------------------------------------------
637 // JNI Glue
638 // ----------------------------------------------------------------------------
639 
640 const char* const kClassPathName = "android/graphics/RenderNode";
641 
642 static const JNINativeMethod gMethods[] = {
643 // ----------------------------------------------------------------------------
644 // Regular JNI
645 // ----------------------------------------------------------------------------
646     { "nCreate",               "(Ljava/lang/String;)J", (void*) android_view_RenderNode_create },
647     { "nGetNativeFinalizer",   "()J",    (void*) android_view_RenderNode_getNativeFinalizer },
648     { "nOutput",               "(J)V",    (void*) android_view_RenderNode_output },
649     { "nGetUsageSize",         "(J)I",    (void*) android_view_RenderNode_getUsageSize },
650     { "nGetAllocatedSize",         "(J)I",    (void*) android_view_RenderNode_getAllocatedSize },
651     { "nAddAnimator",              "(JJ)V", (void*) android_view_RenderNode_addAnimator },
652     { "nEndAllAnimators",          "(J)V", (void*) android_view_RenderNode_endAllAnimators },
653     { "nRequestPositionUpdates",   "(JLandroid/graphics/RenderNode$PositionUpdateListener;)V", (void*) android_view_RenderNode_requestPositionUpdates },
654     { "nSetDisplayList",       "(JJ)V",   (void*) android_view_RenderNode_setDisplayList },
655 
656 
657 // ----------------------------------------------------------------------------
658 // Fast JNI via @CriticalNative annotation in RenderNode.java
659 // ----------------------------------------------------------------------------
660     { "nSetDisplayList",       "(JJ)V",   (void*) android_view_RenderNode_setDisplayList },
661 
662 
663 // ----------------------------------------------------------------------------
664 // Critical JNI via @CriticalNative annotation in RenderNode.java
665 // ----------------------------------------------------------------------------
666     { "nIsValid",              "(J)Z",   (void*) android_view_RenderNode_isValid },
667     { "nSetLayerType",         "(JI)Z",  (void*) android_view_RenderNode_setLayerType },
668     { "nGetLayerType",         "(J)I",   (void*) android_view_RenderNode_getLayerType },
669     { "nSetLayerPaint",        "(JJ)Z",  (void*) android_view_RenderNode_setLayerPaint },
670     { "nSetStaticMatrix",      "(JJ)Z",  (void*) android_view_RenderNode_setStaticMatrix },
671     { "nSetAnimationMatrix",   "(JJ)Z",  (void*) android_view_RenderNode_setAnimationMatrix },
672     { "nGetAnimationMatrix",   "(JJ)Z",  (void*) android_view_RenderNode_getAnimationMatrix },
673     { "nSetClipToBounds",      "(JZ)Z",  (void*) android_view_RenderNode_setClipToBounds },
674     { "nGetClipToBounds",      "(J)Z",   (void*) android_view_RenderNode_getClipToBounds },
675     { "nSetClipBounds",        "(JIIII)Z", (void*) android_view_RenderNode_setClipBounds },
676     { "nSetClipBoundsEmpty",   "(J)Z",   (void*) android_view_RenderNode_setClipBoundsEmpty },
677     { "nSetProjectBackwards",  "(JZ)Z",  (void*) android_view_RenderNode_setProjectBackwards },
678     { "nSetProjectionReceiver","(JZ)Z",  (void*) android_view_RenderNode_setProjectionReceiver },
679 
680     { "nSetOutlineRoundRect",  "(JIIIIFF)Z", (void*) android_view_RenderNode_setOutlineRoundRect },
681     { "nSetOutlinePath",       "(JJF)Z", (void*) android_view_RenderNode_setOutlinePath },
682     { "nSetOutlineEmpty",      "(J)Z",   (void*) android_view_RenderNode_setOutlineEmpty },
683     { "nSetOutlineNone",       "(J)Z",   (void*) android_view_RenderNode_setOutlineNone },
684     { "nHasShadow",            "(J)Z",   (void*) android_view_RenderNode_hasShadow },
685     { "nSetSpotShadowColor",   "(JI)Z",  (void*) android_view_RenderNode_setSpotShadowColor },
686     { "nGetSpotShadowColor",   "(J)I",   (void*) android_view_RenderNode_getSpotShadowColor },
687     { "nSetAmbientShadowColor","(JI)Z",  (void*) android_view_RenderNode_setAmbientShadowColor },
688     { "nGetAmbientShadowColor","(J)I",   (void*) android_view_RenderNode_getAmbientShadowColor },
689     { "nSetClipToOutline",     "(JZ)Z",  (void*) android_view_RenderNode_setClipToOutline },
690     { "nSetRevealClip",        "(JZFFF)Z", (void*) android_view_RenderNode_setRevealClip },
691 
692     { "nSetAlpha",             "(JF)Z",  (void*) android_view_RenderNode_setAlpha },
693     { "nSetHasOverlappingRendering", "(JZ)Z",
694             (void*) android_view_RenderNode_setHasOverlappingRendering },
695     { "nSetUsageHint",    "(JI)V", (void*) android_view_RenderNode_setUsageHint },
696     { "nSetElevation",         "(JF)Z",  (void*) android_view_RenderNode_setElevation },
697     { "nSetTranslationX",      "(JF)Z",  (void*) android_view_RenderNode_setTranslationX },
698     { "nSetTranslationY",      "(JF)Z",  (void*) android_view_RenderNode_setTranslationY },
699     { "nSetTranslationZ",      "(JF)Z",  (void*) android_view_RenderNode_setTranslationZ },
700     { "nSetRotation",          "(JF)Z",  (void*) android_view_RenderNode_setRotation },
701     { "nSetRotationX",         "(JF)Z",  (void*) android_view_RenderNode_setRotationX },
702     { "nSetRotationY",         "(JF)Z",  (void*) android_view_RenderNode_setRotationY },
703     { "nSetScaleX",            "(JF)Z",  (void*) android_view_RenderNode_setScaleX },
704     { "nSetScaleY",            "(JF)Z",  (void*) android_view_RenderNode_setScaleY },
705     { "nSetPivotX",            "(JF)Z",  (void*) android_view_RenderNode_setPivotX },
706     { "nSetPivotY",            "(JF)Z",  (void*) android_view_RenderNode_setPivotY },
707     { "nResetPivot",           "(J)Z",   (void*) android_view_RenderNode_resetPivot },
708     { "nSetCameraDistance",    "(JF)Z",  (void*) android_view_RenderNode_setCameraDistance },
709     { "nSetLeft",              "(JI)Z",  (void*) android_view_RenderNode_setLeft },
710     { "nSetTop",               "(JI)Z",  (void*) android_view_RenderNode_setTop },
711     { "nSetRight",             "(JI)Z",  (void*) android_view_RenderNode_setRight },
712     { "nSetBottom",            "(JI)Z",  (void*) android_view_RenderNode_setBottom },
713     { "nGetLeft",              "(J)I",  (void*) android_view_RenderNode_getLeft },
714     { "nGetTop",               "(J)I",  (void*) android_view_RenderNode_getTop },
715     { "nGetRight",             "(J)I",  (void*) android_view_RenderNode_getRight },
716     { "nGetBottom",            "(J)I",  (void*) android_view_RenderNode_getBottom },
717     { "nSetLeftTopRightBottom","(JIIII)Z", (void*) android_view_RenderNode_setLeftTopRightBottom },
718     { "nOffsetLeftAndRight",   "(JI)Z",  (void*) android_view_RenderNode_offsetLeftAndRight },
719     { "nOffsetTopAndBottom",   "(JI)Z",  (void*) android_view_RenderNode_offsetTopAndBottom },
720 
721     { "nHasOverlappingRendering", "(J)Z",  (void*) android_view_RenderNode_hasOverlappingRendering },
722     { "nGetClipToOutline",        "(J)Z",  (void*) android_view_RenderNode_getClipToOutline },
723     { "nGetAlpha",                "(J)F",  (void*) android_view_RenderNode_getAlpha },
724     { "nGetCameraDistance",       "(J)F",  (void*) android_view_RenderNode_getCameraDistance },
725     { "nGetScaleX",               "(J)F",  (void*) android_view_RenderNode_getScaleX },
726     { "nGetScaleY",               "(J)F",  (void*) android_view_RenderNode_getScaleY },
727     { "nGetElevation",            "(J)F",  (void*) android_view_RenderNode_getElevation },
728     { "nGetTranslationX",         "(J)F",  (void*) android_view_RenderNode_getTranslationX },
729     { "nGetTranslationY",         "(J)F",  (void*) android_view_RenderNode_getTranslationY },
730     { "nGetTranslationZ",         "(J)F",  (void*) android_view_RenderNode_getTranslationZ },
731     { "nGetRotation",             "(J)F",  (void*) android_view_RenderNode_getRotation },
732     { "nGetRotationX",            "(J)F",  (void*) android_view_RenderNode_getRotationX },
733     { "nGetRotationY",            "(J)F",  (void*) android_view_RenderNode_getRotationY },
734     { "nIsPivotExplicitlySet",    "(J)Z",  (void*) android_view_RenderNode_isPivotExplicitlySet },
735     { "nHasIdentityMatrix",       "(J)Z",  (void*) android_view_RenderNode_hasIdentityMatrix },
736 
737     { "nGetTransformMatrix",       "(JJ)V", (void*) android_view_RenderNode_getTransformMatrix },
738     { "nGetInverseTransformMatrix","(JJ)V", (void*) android_view_RenderNode_getInverseTransformMatrix },
739 
740     { "nGetPivotX",                "(J)F",  (void*) android_view_RenderNode_getPivotX },
741     { "nGetPivotY",                "(J)F",  (void*) android_view_RenderNode_getPivotY },
742     { "nGetWidth",                 "(J)I",  (void*) android_view_RenderNode_getWidth },
743     { "nGetHeight",                "(J)I",  (void*) android_view_RenderNode_getHeight },
744     { "nSetAllowForceDark",        "(JZ)Z", (void*) android_view_RenderNode_setAllowForceDark },
745     { "nGetAllowForceDark",        "(J)Z",  (void*) android_view_RenderNode_getAllowForceDark },
746     { "nGetUniqueId",              "(J)J",  (void*) android_view_RenderNode_getUniqueId },
747 };
748 
register_android_view_RenderNode(JNIEnv * env)749 int register_android_view_RenderNode(JNIEnv* env) {
750     jclass clazz = FindClassOrDie(env, "android/graphics/RenderNode$PositionUpdateListener");
751     gPositionListener_PositionChangedMethod = GetMethodIDOrDie(env, clazz,
752             "positionChanged", "(JIIII)V");
753     gPositionListener_PositionLostMethod = GetMethodIDOrDie(env, clazz,
754             "positionLost", "(J)V");
755     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
756 }
757 
758 };
759 
760