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