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