RenderNode.java revision 003cc3dec8e2a92e51086fbcd5ee1bb236efa701
1/* 2 * Copyright (C) 2010 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 17package android.view; 18 19import android.annotation.NonNull; 20import android.annotation.Nullable; 21import android.graphics.Matrix; 22import android.graphics.Outline; 23import android.graphics.Paint; 24import android.graphics.Rect; 25 26/** 27 * <p>A display list records a series of graphics related operations and can replay 28 * them later. Display lists are usually built by recording operations on a 29 * {@link DisplayListCanvas}. Replaying the operations from a display list avoids 30 * executing application code on every frame, and is thus much more efficient.</p> 31 * 32 * <p>Display lists are used internally for all views by default, and are not 33 * typically used directly. One reason to consider using a display is a custom 34 * {@link View} implementation that needs to issue a large number of drawing commands. 35 * When the view invalidates, all the drawing commands must be reissued, even if 36 * large portions of the drawing command stream stay the same frame to frame, which 37 * can become a performance bottleneck. To solve this issue, a custom View might split 38 * its content into several display lists. A display list is updated only when its 39 * content, and only its content, needs to be updated.</p> 40 * 41 * <p>A text editor might for instance store each paragraph into its own display list. 42 * Thus when the user inserts or removes characters, only the display list of the 43 * affected paragraph needs to be recorded again.</p> 44 * 45 * <h3>Hardware acceleration</h3> 46 * <p>Display lists can only be replayed using a {@link DisplayListCanvas}. They are not 47 * supported in software. Always make sure that the {@link android.graphics.Canvas} 48 * you are using to render a display list is hardware accelerated using 49 * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p> 50 * 51 * <h3>Creating a display list</h3> 52 * <pre class="prettyprint"> 53 * HardwareRenderer renderer = myView.getHardwareRenderer(); 54 * if (renderer != null) { 55 * DisplayList displayList = renderer.createDisplayList(); 56 * DisplayListCanvas canvas = displayList.start(width, height); 57 * try { 58 * // Draw onto the canvas 59 * // For instance: canvas.drawBitmap(...); 60 * } finally { 61 * displayList.end(); 62 * } 63 * } 64 * </pre> 65 * 66 * <h3>Rendering a display list on a View</h3> 67 * <pre class="prettyprint"> 68 * protected void onDraw(Canvas canvas) { 69 * if (canvas.isHardwareAccelerated()) { 70 * DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; 71 * displayListCanvas.drawDisplayList(mDisplayList); 72 * } 73 * } 74 * </pre> 75 * 76 * <h3>Releasing resources</h3> 77 * <p>This step is not mandatory but recommended if you want to release resources 78 * held by a display list as soon as possible.</p> 79 * <pre class="prettyprint"> 80 * // Mark this display list invalid, it cannot be used for drawing anymore, 81 * // and release resources held by this display list 82 * displayList.clear(); 83 * </pre> 84 * 85 * <h3>Properties</h3> 86 * <p>In addition, a display list offers several properties, such as 87 * {@link #setScaleX(float)} or {@link #setLeft(int)}, that can be used to affect all 88 * the drawing commands recorded within. For instance, these properties can be used 89 * to move around a large number of images without re-issuing all the individual 90 * <code>drawBitmap()</code> calls.</p> 91 * 92 * <pre class="prettyprint"> 93 * private void createDisplayList() { 94 * mDisplayList = DisplayList.create("MyDisplayList"); 95 * DisplayListCanvas canvas = mDisplayList.start(width, height); 96 * try { 97 * for (Bitmap b : mBitmaps) { 98 * canvas.drawBitmap(b, 0.0f, 0.0f, null); 99 * canvas.translate(0.0f, b.getHeight()); 100 * } 101 * } finally { 102 * displayList.end(); 103 * } 104 * } 105 * 106 * protected void onDraw(Canvas canvas) { 107 * if (canvas.isHardwareAccelerated()) { 108 * DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; 109 * displayListCanvas.drawDisplayList(mDisplayList); 110 * } 111 * } 112 * 113 * private void moveContentBy(int x) { 114 * // This will move all the bitmaps recorded inside the display list 115 * // by x pixels to the right and redraw this view. All the commands 116 * // recorded in createDisplayList() won't be re-issued, only onDraw() 117 * // will be invoked and will execute very quickly 118 * mDisplayList.offsetLeftAndRight(x); 119 * invalidate(); 120 * } 121 * </pre> 122 * 123 * <h3>Threading</h3> 124 * <p>Display lists must be created on and manipulated from the UI thread only.</p> 125 * 126 * @hide 127 */ 128public class RenderNode { 129 130 private boolean mValid; 131 // Do not access directly unless you are ThreadedRenderer 132 final long mNativeRenderNode; 133 private final View mOwningView; 134 135 private RenderNode(String name, View owningView) { 136 mNativeRenderNode = nCreate(name); 137 mOwningView = owningView; 138 } 139 140 /** 141 * @see RenderNode#adopt(long) 142 */ 143 private RenderNode(long nativePtr) { 144 mNativeRenderNode = nativePtr; 145 mOwningView = null; 146 } 147 148 /** 149 * Creates a new RenderNode that can be used to record batches of 150 * drawing operations, and store / apply render properties when drawn. 151 * 152 * @param name The name of the RenderNode, used for debugging purpose. May be null. 153 * 154 * @return A new RenderNode. 155 */ 156 public static RenderNode create(String name, @Nullable View owningView) { 157 return new RenderNode(name, owningView); 158 } 159 160 /** 161 * Adopts an existing native render node. 162 * 163 * Note: This will *NOT* incRef() on the native object, however it will 164 * decRef() when it is destroyed. The caller should have already incRef'd it 165 */ 166 public static RenderNode adopt(long nativePtr) { 167 return new RenderNode(nativePtr); 168 } 169 170 171 /** 172 * Starts recording a display list for the render node. All 173 * operations performed on the returned canvas are recorded and 174 * stored in this display list. 175 * 176 * Calling this method will mark the render node invalid until 177 * {@link #end(DisplayListCanvas)} is called. 178 * Only valid render nodes can be replayed. 179 * 180 * @param width The width of the recording viewport 181 * @param height The height of the recording viewport 182 * 183 * @return A canvas to record drawing operations. 184 * 185 * @see #end(DisplayListCanvas) 186 * @see #isValid() 187 */ 188 public DisplayListCanvas start(int width, int height) { 189 return DisplayListCanvas.obtain(this, width, height); 190 } 191 192 /** 193 * Ends the recording for this display list. A display list cannot be 194 * replayed if recording is not finished. Calling this method marks 195 * the display list valid and {@link #isValid()} will return true. 196 * 197 * @see #start(int, int) 198 * @see #isValid() 199 */ 200 public void end(DisplayListCanvas canvas) { 201 long displayList = canvas.finishRecording(); 202 nSetDisplayList(mNativeRenderNode, displayList); 203 canvas.recycle(); 204 mValid = true; 205 } 206 207 /** 208 * Reset native resources. This is called when cleaning up the state of display lists 209 * during destruction of hardware resources, to ensure that we do not hold onto 210 * obsolete resources after related resources are gone. 211 */ 212 public void discardDisplayList() { 213 if (!mValid) return; 214 215 nSetDisplayList(mNativeRenderNode, 0); 216 mValid = false; 217 } 218 219 /** 220 * Returns whether the RenderNode's display list content is currently usable. 221 * If this returns false, the display list should be re-recorded prior to replaying it. 222 * 223 * @return boolean true if the display list is able to be replayed, false otherwise. 224 */ 225 public boolean isValid() { return mValid; } 226 227 long getNativeDisplayList() { 228 if (!mValid) { 229 throw new IllegalStateException("The display list is not valid."); 230 } 231 return mNativeRenderNode; 232 } 233 234 /////////////////////////////////////////////////////////////////////////// 235 // Matrix manipulation 236 /////////////////////////////////////////////////////////////////////////// 237 238 public boolean hasIdentityMatrix() { 239 return nHasIdentityMatrix(mNativeRenderNode); 240 } 241 242 public void getMatrix(@NonNull Matrix outMatrix) { 243 nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance); 244 } 245 246 public void getInverseMatrix(@NonNull Matrix outMatrix) { 247 nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance); 248 } 249 250 /////////////////////////////////////////////////////////////////////////// 251 // RenderProperty Setters 252 /////////////////////////////////////////////////////////////////////////// 253 254 public boolean setLayerType(int layerType) { 255 return nSetLayerType(mNativeRenderNode, layerType); 256 } 257 258 public boolean setLayerPaint(Paint paint) { 259 return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0); 260 } 261 262 public boolean setClipBounds(@Nullable Rect rect) { 263 if (rect == null) { 264 return nSetClipBoundsEmpty(mNativeRenderNode); 265 } else { 266 return nSetClipBounds(mNativeRenderNode, rect.left, rect.top, rect.right, rect.bottom); 267 } 268 } 269 270 /** 271 * Set whether the Render node should clip itself to its bounds. This property is controlled by 272 * the view's parent. 273 * 274 * @param clipToBounds true if the display list should clip to its bounds 275 */ 276 public boolean setClipToBounds(boolean clipToBounds) { 277 return nSetClipToBounds(mNativeRenderNode, clipToBounds); 278 } 279 280 /** 281 * Sets whether the display list should be drawn immediately after the 282 * closest ancestor display list containing a projection receiver. 283 * 284 * @param shouldProject true if the display list should be projected onto a 285 * containing volume. 286 */ 287 public boolean setProjectBackwards(boolean shouldProject) { 288 return nSetProjectBackwards(mNativeRenderNode, shouldProject); 289 } 290 291 /** 292 * Sets whether the display list is a projection receiver - that its parent 293 * DisplayList should draw any descendent DisplayLists with 294 * ProjectBackwards=true directly on top of it. Default value is false. 295 */ 296 public boolean setProjectionReceiver(boolean shouldRecieve) { 297 return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve); 298 } 299 300 /** 301 * Sets the outline, defining the shape that casts a shadow, and the path to 302 * be clipped if setClipToOutline is set. 303 * 304 * Deep copies the data into native to simplify reference ownership. 305 */ 306 public boolean setOutline(Outline outline) { 307 if (outline == null) { 308 return nSetOutlineNone(mNativeRenderNode); 309 } else if (outline.isEmpty()) { 310 return nSetOutlineEmpty(mNativeRenderNode); 311 } else if (outline.mRect != null) { 312 return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top, 313 outline.mRect.right, outline.mRect.bottom, outline.mRadius, outline.mAlpha); 314 } else if (outline.mPath != null) { 315 return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath, 316 outline.mAlpha); 317 } 318 throw new IllegalArgumentException("Unrecognized outline?"); 319 } 320 321 public boolean hasShadow() { 322 return nHasShadow(mNativeRenderNode); 323 } 324 325 /** 326 * Enables or disables clipping to the outline. 327 * 328 * @param clipToOutline true if clipping to the outline. 329 */ 330 public boolean setClipToOutline(boolean clipToOutline) { 331 return nSetClipToOutline(mNativeRenderNode, clipToOutline); 332 } 333 334 public boolean getClipToOutline() { 335 return nGetClipToOutline(mNativeRenderNode); 336 } 337 338 /** 339 * Controls the RenderNode's circular reveal clip. 340 */ 341 public boolean setRevealClip(boolean shouldClip, 342 float x, float y, float radius) { 343 return nSetRevealClip(mNativeRenderNode, shouldClip, x, y, radius); 344 } 345 346 /** 347 * Set the static matrix on the display list. The specified matrix is combined with other 348 * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.) 349 * 350 * @param matrix A transform matrix to apply to this display list 351 */ 352 public boolean setStaticMatrix(Matrix matrix) { 353 return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance); 354 } 355 356 /** 357 * Set the Animation matrix on the display list. This matrix exists if an Animation is 358 * currently playing on a View, and is set on the display list during at draw() time. When 359 * the Animation finishes, the matrix should be cleared by sending <code>null</code> 360 * for the matrix parameter. 361 * 362 * @param matrix The matrix, null indicates that the matrix should be cleared. 363 */ 364 public boolean setAnimationMatrix(Matrix matrix) { 365 return nSetAnimationMatrix(mNativeRenderNode, 366 (matrix != null) ? matrix.native_instance : 0); 367 } 368 369 /** 370 * Sets the translucency level for the display list. 371 * 372 * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f 373 * 374 * @see View#setAlpha(float) 375 * @see #getAlpha() 376 */ 377 public boolean setAlpha(float alpha) { 378 return nSetAlpha(mNativeRenderNode, alpha); 379 } 380 381 /** 382 * Returns the translucency level of this display list. 383 * 384 * @return A value between 0.0f and 1.0f 385 * 386 * @see #setAlpha(float) 387 */ 388 public float getAlpha() { 389 return nGetAlpha(mNativeRenderNode); 390 } 391 392 /** 393 * Sets whether the display list renders content which overlaps. Non-overlapping rendering 394 * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default 395 * display lists consider they do not have overlapping content. 396 * 397 * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping, 398 * true otherwise. 399 * 400 * @see android.view.View#hasOverlappingRendering() 401 * @see #hasOverlappingRendering() 402 */ 403 public boolean setHasOverlappingRendering(boolean hasOverlappingRendering) { 404 return nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering); 405 } 406 407 /** 408 * Indicates whether the content of this display list overlaps. 409 * 410 * @return True if this display list renders content which overlaps, false otherwise. 411 * 412 * @see #setHasOverlappingRendering(boolean) 413 */ 414 public boolean hasOverlappingRendering() { 415 //noinspection SimplifiableIfStatement 416 return nHasOverlappingRendering(mNativeRenderNode); 417 } 418 419 public boolean setElevation(float lift) { 420 return nSetElevation(mNativeRenderNode, lift); 421 } 422 423 public float getElevation() { 424 return nGetElevation(mNativeRenderNode); 425 } 426 427 /** 428 * Sets the translation value for the display list on the X axis. 429 * 430 * @param translationX The X axis translation value of the display list, in pixels 431 * 432 * @see View#setTranslationX(float) 433 * @see #getTranslationX() 434 */ 435 public boolean setTranslationX(float translationX) { 436 return nSetTranslationX(mNativeRenderNode, translationX); 437 } 438 439 /** 440 * Returns the translation value for this display list on the X axis, in pixels. 441 * 442 * @see #setTranslationX(float) 443 */ 444 public float getTranslationX() { 445 return nGetTranslationX(mNativeRenderNode); 446 } 447 448 /** 449 * Sets the translation value for the display list on the Y axis. 450 * 451 * @param translationY The Y axis translation value of the display list, in pixels 452 * 453 * @see View#setTranslationY(float) 454 * @see #getTranslationY() 455 */ 456 public boolean setTranslationY(float translationY) { 457 return nSetTranslationY(mNativeRenderNode, translationY); 458 } 459 460 /** 461 * Returns the translation value for this display list on the Y axis, in pixels. 462 * 463 * @see #setTranslationY(float) 464 */ 465 public float getTranslationY() { 466 return nGetTranslationY(mNativeRenderNode); 467 } 468 469 /** 470 * Sets the translation value for the display list on the Z axis. 471 * 472 * @see View#setTranslationZ(float) 473 * @see #getTranslationZ() 474 */ 475 public boolean setTranslationZ(float translationZ) { 476 return nSetTranslationZ(mNativeRenderNode, translationZ); 477 } 478 479 /** 480 * Returns the translation value for this display list on the Z axis. 481 * 482 * @see #setTranslationZ(float) 483 */ 484 public float getTranslationZ() { 485 return nGetTranslationZ(mNativeRenderNode); 486 } 487 488 /** 489 * Sets the rotation value for the display list around the Z axis. 490 * 491 * @param rotation The rotation value of the display list, in degrees 492 * 493 * @see View#setRotation(float) 494 * @see #getRotation() 495 */ 496 public boolean setRotation(float rotation) { 497 return nSetRotation(mNativeRenderNode, rotation); 498 } 499 500 /** 501 * Returns the rotation value for this display list around the Z axis, in degrees. 502 * 503 * @see #setRotation(float) 504 */ 505 public float getRotation() { 506 return nGetRotation(mNativeRenderNode); 507 } 508 509 /** 510 * Sets the rotation value for the display list around the X axis. 511 * 512 * @param rotationX The rotation value of the display list, in degrees 513 * 514 * @see View#setRotationX(float) 515 * @see #getRotationX() 516 */ 517 public boolean setRotationX(float rotationX) { 518 return nSetRotationX(mNativeRenderNode, rotationX); 519 } 520 521 /** 522 * Returns the rotation value for this display list around the X axis, in degrees. 523 * 524 * @see #setRotationX(float) 525 */ 526 public float getRotationX() { 527 return nGetRotationX(mNativeRenderNode); 528 } 529 530 /** 531 * Sets the rotation value for the display list around the Y axis. 532 * 533 * @param rotationY The rotation value of the display list, in degrees 534 * 535 * @see View#setRotationY(float) 536 * @see #getRotationY() 537 */ 538 public boolean setRotationY(float rotationY) { 539 return nSetRotationY(mNativeRenderNode, rotationY); 540 } 541 542 /** 543 * Returns the rotation value for this display list around the Y axis, in degrees. 544 * 545 * @see #setRotationY(float) 546 */ 547 public float getRotationY() { 548 return nGetRotationY(mNativeRenderNode); 549 } 550 551 /** 552 * Sets the scale value for the display list on the X axis. 553 * 554 * @param scaleX The scale value of the display list 555 * 556 * @see View#setScaleX(float) 557 * @see #getScaleX() 558 */ 559 public boolean setScaleX(float scaleX) { 560 return nSetScaleX(mNativeRenderNode, scaleX); 561 } 562 563 /** 564 * Returns the scale value for this display list on the X axis. 565 * 566 * @see #setScaleX(float) 567 */ 568 public float getScaleX() { 569 return nGetScaleX(mNativeRenderNode); 570 } 571 572 /** 573 * Sets the scale value for the display list on the Y axis. 574 * 575 * @param scaleY The scale value of the display list 576 * 577 * @see View#setScaleY(float) 578 * @see #getScaleY() 579 */ 580 public boolean setScaleY(float scaleY) { 581 return nSetScaleY(mNativeRenderNode, scaleY); 582 } 583 584 /** 585 * Returns the scale value for this display list on the Y axis. 586 * 587 * @see #setScaleY(float) 588 */ 589 public float getScaleY() { 590 return nGetScaleY(mNativeRenderNode); 591 } 592 593 /** 594 * Sets the pivot value for the display list on the X axis 595 * 596 * @param pivotX The pivot value of the display list on the X axis, in pixels 597 * 598 * @see View#setPivotX(float) 599 * @see #getPivotX() 600 */ 601 public boolean setPivotX(float pivotX) { 602 return nSetPivotX(mNativeRenderNode, pivotX); 603 } 604 605 /** 606 * Returns the pivot value for this display list on the X axis, in pixels. 607 * 608 * @see #setPivotX(float) 609 */ 610 public float getPivotX() { 611 return nGetPivotX(mNativeRenderNode); 612 } 613 614 /** 615 * Sets the pivot value for the display list on the Y axis 616 * 617 * @param pivotY The pivot value of the display list on the Y axis, in pixels 618 * 619 * @see View#setPivotY(float) 620 * @see #getPivotY() 621 */ 622 public boolean setPivotY(float pivotY) { 623 return nSetPivotY(mNativeRenderNode, pivotY); 624 } 625 626 /** 627 * Returns the pivot value for this display list on the Y axis, in pixels. 628 * 629 * @see #setPivotY(float) 630 */ 631 public float getPivotY() { 632 return nGetPivotY(mNativeRenderNode); 633 } 634 635 public boolean isPivotExplicitlySet() { 636 return nIsPivotExplicitlySet(mNativeRenderNode); 637 } 638 639 /** 640 * Sets the camera distance for the display list. Refer to 641 * {@link View#setCameraDistance(float)} for more information on how to 642 * use this property. 643 * 644 * @param distance The distance in Z of the camera of the display list 645 * 646 * @see View#setCameraDistance(float) 647 * @see #getCameraDistance() 648 */ 649 public boolean setCameraDistance(float distance) { 650 return nSetCameraDistance(mNativeRenderNode, distance); 651 } 652 653 /** 654 * Returns the distance in Z of the camera of the display list. 655 * 656 * @see #setCameraDistance(float) 657 */ 658 public float getCameraDistance() { 659 return nGetCameraDistance(mNativeRenderNode); 660 } 661 662 /** 663 * Sets the left position for the display list. 664 * 665 * @param left The left position, in pixels, of the display list 666 * 667 * @see View#setLeft(int) 668 */ 669 public boolean setLeft(int left) { 670 return nSetLeft(mNativeRenderNode, left); 671 } 672 673 /** 674 * Sets the top position for the display list. 675 * 676 * @param top The top position, in pixels, of the display list 677 * 678 * @see View#setTop(int) 679 */ 680 public boolean setTop(int top) { 681 return nSetTop(mNativeRenderNode, top); 682 } 683 684 /** 685 * Sets the right position for the display list. 686 * 687 * @param right The right position, in pixels, of the display list 688 * 689 * @see View#setRight(int) 690 */ 691 public boolean setRight(int right) { 692 return nSetRight(mNativeRenderNode, right); 693 } 694 695 /** 696 * Sets the bottom position for the display list. 697 * 698 * @param bottom The bottom position, in pixels, of the display list 699 * 700 * @see View#setBottom(int) 701 */ 702 public boolean setBottom(int bottom) { 703 return nSetBottom(mNativeRenderNode, bottom); 704 } 705 706 /** 707 * Sets the left and top positions for the display list 708 * 709 * @param left The left position of the display list, in pixels 710 * @param top The top position of the display list, in pixels 711 * @param right The right position of the display list, in pixels 712 * @param bottom The bottom position of the display list, in pixels 713 * 714 * @see View#setLeft(int) 715 * @see View#setTop(int) 716 * @see View#setRight(int) 717 * @see View#setBottom(int) 718 */ 719 public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) { 720 return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom); 721 } 722 723 /** 724 * Offsets the left and right positions for the display list 725 * 726 * @param offset The amount that the left and right positions of the display 727 * list are offset, in pixels 728 * 729 * @see View#offsetLeftAndRight(int) 730 */ 731 public boolean offsetLeftAndRight(int offset) { 732 return nOffsetLeftAndRight(mNativeRenderNode, offset); 733 } 734 735 /** 736 * Offsets the top and bottom values for the display list 737 * 738 * @param offset The amount that the top and bottom positions of the display 739 * list are offset, in pixels 740 * 741 * @see View#offsetTopAndBottom(int) 742 */ 743 public boolean offsetTopAndBottom(int offset) { 744 return nOffsetTopAndBottom(mNativeRenderNode, offset); 745 } 746 747 /** 748 * Outputs the display list to the log. This method exists for use by 749 * tools to output display lists for selected nodes to the log. 750 */ 751 public void output() { 752 nOutput(mNativeRenderNode); 753 } 754 755 /** 756 * Gets the size of the DisplayList for debug purposes. 757 */ 758 public int getDebugSize() { 759 return nGetDebugSize(mNativeRenderNode); 760 } 761 762 /////////////////////////////////////////////////////////////////////////// 763 // Animations 764 /////////////////////////////////////////////////////////////////////////// 765 766 public void addAnimator(RenderNodeAnimator animator) { 767 if (mOwningView == null || mOwningView.mAttachInfo == null) { 768 throw new IllegalStateException("Cannot start this animator on a detached view!"); 769 } 770 nAddAnimator(mNativeRenderNode, animator.getNativeAnimator()); 771 mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this); 772 } 773 774 public void endAllAnimators() { 775 nEndAllAnimators(mNativeRenderNode); 776 } 777 778 /////////////////////////////////////////////////////////////////////////// 779 // Native methods 780 /////////////////////////////////////////////////////////////////////////// 781 782 private static native long nCreate(String name); 783 private static native void nDestroyRenderNode(long renderNode); 784 private static native void nSetDisplayList(long renderNode, long newData); 785 786 // Matrix 787 788 private static native void nGetTransformMatrix(long renderNode, long nativeMatrix); 789 private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix); 790 private static native boolean nHasIdentityMatrix(long renderNode); 791 792 // Properties 793 794 private static native boolean nOffsetTopAndBottom(long renderNode, int offset); 795 private static native boolean nOffsetLeftAndRight(long renderNode, int offset); 796 private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top, 797 int right, int bottom); 798 private static native boolean nSetBottom(long renderNode, int bottom); 799 private static native boolean nSetRight(long renderNode, int right); 800 private static native boolean nSetTop(long renderNode, int top); 801 private static native boolean nSetLeft(long renderNode, int left); 802 private static native boolean nSetCameraDistance(long renderNode, float distance); 803 private static native boolean nSetPivotY(long renderNode, float pivotY); 804 private static native boolean nSetPivotX(long renderNode, float pivotX); 805 private static native boolean nSetLayerType(long renderNode, int layerType); 806 private static native boolean nSetLayerPaint(long renderNode, long paint); 807 private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds); 808 private static native boolean nSetClipBounds(long renderNode, int left, int top, 809 int right, int bottom); 810 private static native boolean nSetClipBoundsEmpty(long renderNode); 811 private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject); 812 private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve); 813 private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top, 814 int right, int bottom, float radius, float alpha); 815 private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath, 816 float alpha); 817 private static native boolean nSetOutlineEmpty(long renderNode); 818 private static native boolean nSetOutlineNone(long renderNode); 819 private static native boolean nHasShadow(long renderNode); 820 private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline); 821 private static native boolean nSetRevealClip(long renderNode, 822 boolean shouldClip, float x, float y, float radius); 823 private static native boolean nSetAlpha(long renderNode, float alpha); 824 private static native boolean nSetHasOverlappingRendering(long renderNode, 825 boolean hasOverlappingRendering); 826 private static native boolean nSetElevation(long renderNode, float lift); 827 private static native boolean nSetTranslationX(long renderNode, float translationX); 828 private static native boolean nSetTranslationY(long renderNode, float translationY); 829 private static native boolean nSetTranslationZ(long renderNode, float translationZ); 830 private static native boolean nSetRotation(long renderNode, float rotation); 831 private static native boolean nSetRotationX(long renderNode, float rotationX); 832 private static native boolean nSetRotationY(long renderNode, float rotationY); 833 private static native boolean nSetScaleX(long renderNode, float scaleX); 834 private static native boolean nSetScaleY(long renderNode, float scaleY); 835 private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix); 836 private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix); 837 838 private static native boolean nHasOverlappingRendering(long renderNode); 839 private static native boolean nGetClipToOutline(long renderNode); 840 private static native float nGetAlpha(long renderNode); 841 private static native float nGetCameraDistance(long renderNode); 842 private static native float nGetScaleX(long renderNode); 843 private static native float nGetScaleY(long renderNode); 844 private static native float nGetElevation(long renderNode); 845 private static native float nGetTranslationX(long renderNode); 846 private static native float nGetTranslationY(long renderNode); 847 private static native float nGetTranslationZ(long renderNode); 848 private static native float nGetRotation(long renderNode); 849 private static native float nGetRotationX(long renderNode); 850 private static native float nGetRotationY(long renderNode); 851 private static native boolean nIsPivotExplicitlySet(long renderNode); 852 private static native float nGetPivotX(long renderNode); 853 private static native float nGetPivotY(long renderNode); 854 private static native void nOutput(long renderNode); 855 private static native int nGetDebugSize(long renderNode); 856 857 /////////////////////////////////////////////////////////////////////////// 858 // Animations 859 /////////////////////////////////////////////////////////////////////////// 860 861 private static native void nAddAnimator(long renderNode, long animatorPtr); 862 private static native void nEndAllAnimators(long renderNode); 863 864 /////////////////////////////////////////////////////////////////////////// 865 // Finalization 866 /////////////////////////////////////////////////////////////////////////// 867 868 @Override 869 protected void finalize() throws Throwable { 870 try { 871 nDestroyRenderNode(mNativeRenderNode); 872 } finally { 873 super.finalize(); 874 } 875 } 876} 877