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