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