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