RenderNode.java revision 1c058e96b3fb5075c34b89cf22773373811abf7a
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.graphics.Matrix; 21import android.graphics.Outline; 22 23import java.util.ArrayList; 24import java.util.List; 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 HardwareCanvas}. 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 HardwareCanvas}. 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 * HardwareCanvas 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 * HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas; 71 * hardwareCanvas.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 * HardwareCanvas 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 * HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas; 109 * hardwareCanvas.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 * Flag used when calling 131 * {@link HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)} 132 * When this flag is set, draw operations lying outside of the bounds of the 133 * display list will be culled early. It is recommeneded to always set this 134 * flag. 135 * 136 * @hide 137 */ 138 public static final int FLAG_CLIP_CHILDREN = 0x1; 139 140 // NOTE: The STATUS_* values *must* match the enum in DrawGlInfo.h 141 142 /** 143 * Indicates that the display list is done drawing. 144 * 145 * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int) 146 * 147 * @hide 148 */ 149 public static final int STATUS_DONE = 0x0; 150 151 /** 152 * Indicates that the display list needs another drawing pass. 153 * 154 * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int) 155 * 156 * @hide 157 */ 158 public static final int STATUS_DRAW = 0x1; 159 160 /** 161 * Indicates that the display list needs to re-execute its GL functors. 162 * 163 * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int) 164 * @see HardwareCanvas#callDrawGLFunction(long) 165 * 166 * @hide 167 */ 168 public static final int STATUS_INVOKE = 0x2; 169 170 /** 171 * Indicates that the display list performed GL drawing operations. 172 * 173 * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int) 174 * 175 * @hide 176 */ 177 public static final int STATUS_DREW = 0x4; 178 179 private boolean mValid; 180 private final long mNativeRenderNode; 181 182 // We need to keep a strong reference to all running animators to ensure that 183 // they can call removeAnimator when they have finished, as the native-side 184 // object can only hold a WeakReference<> to avoid leaking memory due to 185 // cyclic references. 186 private List<RenderNodeAnimator> mActiveAnimators; 187 188 private RenderNode(String name) { 189 mNativeRenderNode = nCreate(name); 190 } 191 192 /** 193 * @see RenderNode#adopt(long) 194 */ 195 private RenderNode(long nativePtr) { 196 mNativeRenderNode = nativePtr; 197 } 198 199 /** 200 * Creates a new display list that can be used to record batches of 201 * drawing operations. 202 * 203 * @param name The name of the display list, used for debugging purpose. May be null. 204 * 205 * @return A new display list. 206 * 207 * @hide 208 */ 209 public static RenderNode create(String name) { 210 return new RenderNode(name); 211 } 212 213 /** 214 * Adopts an existing native render node. 215 * 216 * Note: This will *NOT* incRef() on the native object, however it will 217 * decRef() when it is destroyed. The caller should have already incRef'd it 218 */ 219 public static RenderNode adopt(long nativePtr) { 220 return new RenderNode(nativePtr); 221 } 222 223 224 /** 225 * Starts recording a display list for the render node. All 226 * operations performed on the returned canvas are recorded and 227 * stored in this display list. 228 * 229 * Calling this method will mark the render node invalid until 230 * {@link #end(HardwareCanvas)} is called. 231 * Only valid render nodes can be replayed. 232 * 233 * @param width The width of the recording viewport 234 * @param height The height of the recording viewport 235 * 236 * @return A canvas to record drawing operations. 237 * 238 * @see #end(HardwareCanvas) 239 * @see #isValid() 240 */ 241 public HardwareCanvas start(int width, int height) { 242 HardwareCanvas canvas = GLES20RecordingCanvas.obtain(this); 243 canvas.setViewport(width, height); 244 // The dirty rect should always be null for a display list 245 canvas.onPreDraw(null); 246 return canvas; 247 } 248 249 /** 250 * Ends the recording for this display list. A display list cannot be 251 * replayed if recording is not finished. Calling this method marks 252 * the display list valid and {@link #isValid()} will return true. 253 * 254 * @see #start(int, int) 255 * @see #isValid() 256 */ 257 public void end(HardwareCanvas endCanvas) { 258 if (!(endCanvas instanceof GLES20RecordingCanvas)) { 259 throw new IllegalArgumentException("Passed an invalid canvas to end!"); 260 } 261 262 GLES20RecordingCanvas canvas = (GLES20RecordingCanvas) endCanvas; 263 canvas.onPostDraw(); 264 long renderNodeData = canvas.finishRecording(); 265 nSetDisplayListData(mNativeRenderNode, renderNodeData); 266 canvas.recycle(); 267 mValid = true; 268 } 269 270 /** 271 * Reset native resources. This is called when cleaning up the state of display lists 272 * during destruction of hardware resources, to ensure that we do not hold onto 273 * obsolete resources after related resources are gone. 274 * 275 * @hide 276 */ 277 public void destroyDisplayListData() { 278 if (!mValid) return; 279 280 nSetDisplayListData(mNativeRenderNode, 0); 281 mValid = false; 282 } 283 284 /** 285 * Returns whether the RenderNode's display list content is currently usable. 286 * If this returns false, the display list should be re-recorded prior to replaying it. 287 * 288 * @return boolean true if the display list is able to be replayed, false otherwise. 289 */ 290 public boolean isValid() { return mValid; } 291 292 long getNativeDisplayList() { 293 if (!mValid) { 294 throw new IllegalStateException("The display list is not valid."); 295 } 296 return mNativeRenderNode; 297 } 298 299 /////////////////////////////////////////////////////////////////////////// 300 // Matrix manipulation 301 /////////////////////////////////////////////////////////////////////////// 302 303 public boolean hasIdentityMatrix() { 304 return nHasIdentityMatrix(mNativeRenderNode); 305 } 306 307 public void getMatrix(@NonNull Matrix outMatrix) { 308 nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance); 309 } 310 311 public void getInverseMatrix(@NonNull Matrix outMatrix) { 312 nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance); 313 } 314 315 /////////////////////////////////////////////////////////////////////////// 316 // RenderProperty Setters 317 /////////////////////////////////////////////////////////////////////////// 318 319 /** 320 * Set the caching property on the display list, which indicates whether the display list 321 * holds a layer. Layer display lists should avoid creating an alpha layer, since alpha is 322 * handled in the drawLayer operation directly (and more efficiently). 323 * 324 * @param caching true if the display list represents a hardware layer, false otherwise. 325 * 326 * @hide 327 */ 328 public void setCaching(boolean caching) { 329 nSetCaching(mNativeRenderNode, caching); 330 } 331 332 /** 333 * Set whether the Render node should clip itself to its bounds. This property is controlled by 334 * the view's parent. 335 * 336 * @param clipToBounds true if the display list should clip to its bounds 337 */ 338 public void setClipToBounds(boolean clipToBounds) { 339 nSetClipToBounds(mNativeRenderNode, clipToBounds); 340 } 341 342 /** 343 * Sets whether the display list should be drawn immediately after the 344 * closest ancestor display list containing a projection receiver. 345 * 346 * @param shouldProject true if the display list should be projected onto a 347 * containing volume. 348 */ 349 public void setProjectBackwards(boolean shouldProject) { 350 nSetProjectBackwards(mNativeRenderNode, shouldProject); 351 } 352 353 /** 354 * Sets whether the display list is a projection receiver - that its parent 355 * DisplayList should draw any descendent DisplayLists with 356 * ProjectBackwards=true directly on top of it. Default value is false. 357 */ 358 public void setProjectionReceiver(boolean shouldRecieve) { 359 nSetProjectionReceiver(mNativeRenderNode, shouldRecieve); 360 } 361 362 /** 363 * Sets the outline, defining the shape that casts a shadow, and the path to 364 * be clipped if setClipToOutline is set. 365 * 366 * Deep copies the data into native to simplify reference ownership. 367 */ 368 public void setOutline(Outline outline) { 369 if (outline == null) { 370 nSetOutlineEmpty(mNativeRenderNode); 371 } else if (!outline.isValid()) { 372 throw new IllegalArgumentException("Outline must be valid"); 373 } else if (outline.mRect != null) { 374 nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top, 375 outline.mRect.right, outline.mRect.bottom, outline.mRadius); 376 } else if (outline.mPath != null) { 377 nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath); 378 } 379 } 380 381 /** 382 * Enables or disables clipping to the outline. 383 * 384 * @param clipToOutline true if clipping to the outline. 385 */ 386 public void setClipToOutline(boolean clipToOutline) { 387 nSetClipToOutline(mNativeRenderNode, clipToOutline); 388 } 389 390 /** 391 * Controls the RenderNode's circular reveal clip. 392 */ 393 public void setRevealClip(boolean shouldClip, boolean inverseClip, 394 float x, float y, float radius) { 395 nSetRevealClip(mNativeRenderNode, shouldClip, inverseClip, x, y, radius); 396 } 397 398 /** 399 * Set the static matrix on the display list. The specified matrix is combined with other 400 * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.) 401 * 402 * @param matrix A transform matrix to apply to this display list 403 */ 404 public void setStaticMatrix(Matrix matrix) { 405 nSetStaticMatrix(mNativeRenderNode, matrix.native_instance); 406 } 407 408 /** 409 * Set the Animation matrix on the display list. This matrix exists if an Animation is 410 * currently playing on a View, and is set on the display list during at draw() time. When 411 * the Animation finishes, the matrix should be cleared by sending <code>null</code> 412 * for the matrix parameter. 413 * 414 * @param matrix The matrix, null indicates that the matrix should be cleared. 415 * 416 * @hide 417 */ 418 public void setAnimationMatrix(Matrix matrix) { 419 nSetAnimationMatrix(mNativeRenderNode, 420 (matrix != null) ? matrix.native_instance : 0); 421 } 422 423 /** 424 * Sets the translucency level for the display list. 425 * 426 * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f 427 * 428 * @see View#setAlpha(float) 429 * @see #getAlpha() 430 */ 431 public void setAlpha(float alpha) { 432 nSetAlpha(mNativeRenderNode, alpha); 433 } 434 435 /** 436 * Returns the translucency level of this display list. 437 * 438 * @return A value between 0.0f and 1.0f 439 * 440 * @see #setAlpha(float) 441 */ 442 public float getAlpha() { 443 return nGetAlpha(mNativeRenderNode); 444 } 445 446 /** 447 * Sets whether the display list renders content which overlaps. Non-overlapping rendering 448 * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default 449 * display lists consider they do not have overlapping content. 450 * 451 * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping, 452 * true otherwise. 453 * 454 * @see android.view.View#hasOverlappingRendering() 455 * @see #hasOverlappingRendering() 456 */ 457 public void setHasOverlappingRendering(boolean hasOverlappingRendering) { 458 nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering); 459 } 460 461 /** 462 * Indicates whether the content of this display list overlaps. 463 * 464 * @return True if this display list renders content which overlaps, false otherwise. 465 * 466 * @see #setHasOverlappingRendering(boolean) 467 */ 468 public boolean hasOverlappingRendering() { 469 //noinspection SimplifiableIfStatement 470 return nHasOverlappingRendering(mNativeRenderNode); 471 } 472 473 public void setElevation(float lift) { 474 nSetElevation(mNativeRenderNode, lift); 475 } 476 477 public float getElevation() { 478 return nGetElevation(mNativeRenderNode); 479 } 480 481 /** 482 * Sets the translation value for the display list on the X axis. 483 * 484 * @param translationX The X axis translation value of the display list, in pixels 485 * 486 * @see View#setTranslationX(float) 487 * @see #getTranslationX() 488 */ 489 public void setTranslationX(float translationX) { 490 nSetTranslationX(mNativeRenderNode, translationX); 491 } 492 493 /** 494 * Returns the translation value for this display list on the X axis, in pixels. 495 * 496 * @see #setTranslationX(float) 497 */ 498 public float getTranslationX() { 499 return nGetTranslationX(mNativeRenderNode); 500 } 501 502 /** 503 * Sets the translation value for the display list on the Y axis. 504 * 505 * @param translationY The Y axis translation value of the display list, in pixels 506 * 507 * @see View#setTranslationY(float) 508 * @see #getTranslationY() 509 */ 510 public void setTranslationY(float translationY) { 511 nSetTranslationY(mNativeRenderNode, translationY); 512 } 513 514 /** 515 * Returns the translation value for this display list on the Y axis, in pixels. 516 * 517 * @see #setTranslationY(float) 518 */ 519 public float getTranslationY() { 520 return nGetTranslationY(mNativeRenderNode); 521 } 522 523 /** 524 * Sets the translation value for the display list on the Z axis. 525 * 526 * @see View#setTranslationZ(float) 527 * @see #getTranslationZ() 528 */ 529 public void setTranslationZ(float translationZ) { 530 nSetTranslationZ(mNativeRenderNode, translationZ); 531 } 532 533 /** 534 * Returns the translation value for this display list on the Z axis. 535 * 536 * @see #setTranslationZ(float) 537 */ 538 public float getTranslationZ() { 539 return nGetTranslationZ(mNativeRenderNode); 540 } 541 542 /** 543 * Sets the rotation value for the display list around the Z axis. 544 * 545 * @param rotation The rotation value of the display list, in degrees 546 * 547 * @see View#setRotation(float) 548 * @see #getRotation() 549 */ 550 public void setRotation(float rotation) { 551 nSetRotation(mNativeRenderNode, rotation); 552 } 553 554 /** 555 * Returns the rotation value for this display list around the Z axis, in degrees. 556 * 557 * @see #setRotation(float) 558 */ 559 public float getRotation() { 560 return nGetRotation(mNativeRenderNode); 561 } 562 563 /** 564 * Sets the rotation value for the display list around the X axis. 565 * 566 * @param rotationX The rotation value of the display list, in degrees 567 * 568 * @see View#setRotationX(float) 569 * @see #getRotationX() 570 */ 571 public void setRotationX(float rotationX) { 572 nSetRotationX(mNativeRenderNode, rotationX); 573 } 574 575 /** 576 * Returns the rotation value for this display list around the X axis, in degrees. 577 * 578 * @see #setRotationX(float) 579 */ 580 public float getRotationX() { 581 return nGetRotationX(mNativeRenderNode); 582 } 583 584 /** 585 * Sets the rotation value for the display list around the Y axis. 586 * 587 * @param rotationY The rotation value of the display list, in degrees 588 * 589 * @see View#setRotationY(float) 590 * @see #getRotationY() 591 */ 592 public void setRotationY(float rotationY) { 593 nSetRotationY(mNativeRenderNode, rotationY); 594 } 595 596 /** 597 * Returns the rotation value for this display list around the Y axis, in degrees. 598 * 599 * @see #setRotationY(float) 600 */ 601 public float getRotationY() { 602 return nGetRotationY(mNativeRenderNode); 603 } 604 605 /** 606 * Sets the scale value for the display list on the X axis. 607 * 608 * @param scaleX The scale value of the display list 609 * 610 * @see View#setScaleX(float) 611 * @see #getScaleX() 612 */ 613 public void setScaleX(float scaleX) { 614 nSetScaleX(mNativeRenderNode, scaleX); 615 } 616 617 /** 618 * Returns the scale value for this display list on the X axis. 619 * 620 * @see #setScaleX(float) 621 */ 622 public float getScaleX() { 623 return nGetScaleX(mNativeRenderNode); 624 } 625 626 /** 627 * Sets the scale value for the display list on the Y axis. 628 * 629 * @param scaleY The scale value of the display list 630 * 631 * @see View#setScaleY(float) 632 * @see #getScaleY() 633 */ 634 public void setScaleY(float scaleY) { 635 nSetScaleY(mNativeRenderNode, scaleY); 636 } 637 638 /** 639 * Returns the scale value for this display list on the Y axis. 640 * 641 * @see #setScaleY(float) 642 */ 643 public float getScaleY() { 644 return nGetScaleY(mNativeRenderNode); 645 } 646 647 /** 648 * Sets the pivot value for the display list on the X axis 649 * 650 * @param pivotX The pivot value of the display list on the X axis, in pixels 651 * 652 * @see View#setPivotX(float) 653 * @see #getPivotX() 654 */ 655 public void setPivotX(float pivotX) { 656 nSetPivotX(mNativeRenderNode, pivotX); 657 } 658 659 /** 660 * Returns the pivot value for this display list on the X axis, in pixels. 661 * 662 * @see #setPivotX(float) 663 */ 664 public float getPivotX() { 665 return nGetPivotX(mNativeRenderNode); 666 } 667 668 /** 669 * Sets the pivot value for the display list on the Y axis 670 * 671 * @param pivotY The pivot value of the display list on the Y axis, in pixels 672 * 673 * @see View#setPivotY(float) 674 * @see #getPivotY() 675 */ 676 public void setPivotY(float pivotY) { 677 nSetPivotY(mNativeRenderNode, pivotY); 678 } 679 680 /** 681 * Returns the pivot value for this display list on the Y axis, in pixels. 682 * 683 * @see #setPivotY(float) 684 */ 685 public float getPivotY() { 686 return nGetPivotY(mNativeRenderNode); 687 } 688 689 public boolean isPivotExplicitlySet() { 690 return nIsPivotExplicitlySet(mNativeRenderNode); 691 } 692 693 /** 694 * Sets the camera distance for the display list. Refer to 695 * {@link View#setCameraDistance(float)} for more information on how to 696 * use this property. 697 * 698 * @param distance The distance in Z of the camera of the display list 699 * 700 * @see View#setCameraDistance(float) 701 * @see #getCameraDistance() 702 */ 703 public void setCameraDistance(float distance) { 704 nSetCameraDistance(mNativeRenderNode, distance); 705 } 706 707 /** 708 * Returns the distance in Z of the camera of the display list. 709 * 710 * @see #setCameraDistance(float) 711 */ 712 public float getCameraDistance() { 713 return nGetCameraDistance(mNativeRenderNode); 714 } 715 716 /** 717 * Sets the left position for the display list. 718 * 719 * @param left The left position, in pixels, of the display list 720 * 721 * @see View#setLeft(int) 722 * @see #getLeft() 723 */ 724 public void setLeft(int left) { 725 nSetLeft(mNativeRenderNode, left); 726 } 727 728 /** 729 * Returns the left position for the display list in pixels. 730 * 731 * @see #setLeft(int) 732 */ 733 public float getLeft() { 734 return nGetLeft(mNativeRenderNode); 735 } 736 737 /** 738 * Sets the top position for the display list. 739 * 740 * @param top The top position, in pixels, of the display list 741 * 742 * @see View#setTop(int) 743 * @see #getTop() 744 */ 745 public void setTop(int top) { 746 nSetTop(mNativeRenderNode, top); 747 } 748 749 /** 750 * Returns the top position for the display list in pixels. 751 * 752 * @see #setTop(int) 753 */ 754 public float getTop() { 755 return nGetTop(mNativeRenderNode); 756 } 757 758 /** 759 * Sets the right position for the display list. 760 * 761 * @param right The right position, in pixels, of the display list 762 * 763 * @see View#setRight(int) 764 * @see #getRight() 765 */ 766 public void setRight(int right) { 767 nSetRight(mNativeRenderNode, right); 768 } 769 770 /** 771 * Returns the right position for the display list in pixels. 772 * 773 * @see #setRight(int) 774 */ 775 public float getRight() { 776 return nGetRight(mNativeRenderNode); 777 } 778 779 /** 780 * Sets the bottom position for the display list. 781 * 782 * @param bottom The bottom position, in pixels, of the display list 783 * 784 * @see View#setBottom(int) 785 * @see #getBottom() 786 */ 787 public void setBottom(int bottom) { 788 nSetBottom(mNativeRenderNode, bottom); 789 } 790 791 /** 792 * Returns the bottom position for the display list in pixels. 793 * 794 * @see #setBottom(int) 795 */ 796 public float getBottom() { 797 return nGetBottom(mNativeRenderNode); 798 } 799 800 /** 801 * Sets the left and top positions for the display list 802 * 803 * @param left The left position of the display list, in pixels 804 * @param top The top position of the display list, in pixels 805 * @param right The right position of the display list, in pixels 806 * @param bottom The bottom position of the display list, in pixels 807 * 808 * @see View#setLeft(int) 809 * @see View#setTop(int) 810 * @see View#setRight(int) 811 * @see View#setBottom(int) 812 */ 813 public void setLeftTopRightBottom(int left, int top, int right, int bottom) { 814 nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom); 815 } 816 817 /** 818 * Offsets the left and right positions for the display list 819 * 820 * @param offset The amount that the left and right positions of the display 821 * list are offset, in pixels 822 * 823 * @see View#offsetLeftAndRight(int) 824 */ 825 public void offsetLeftAndRight(float offset) { 826 nOffsetLeftAndRight(mNativeRenderNode, offset); 827 } 828 829 /** 830 * Offsets the top and bottom values for the display list 831 * 832 * @param offset The amount that the top and bottom positions of the display 833 * list are offset, in pixels 834 * 835 * @see View#offsetTopAndBottom(int) 836 */ 837 public void offsetTopAndBottom(float offset) { 838 nOffsetTopAndBottom(mNativeRenderNode, offset); 839 } 840 841 /** 842 * Outputs the display list to the log. This method exists for use by 843 * tools to output display lists for selected nodes to the log. 844 * 845 * @hide 846 */ 847 public void output() { 848 nOutput(mNativeRenderNode); 849 } 850 851 /////////////////////////////////////////////////////////////////////////// 852 // Animations 853 /////////////////////////////////////////////////////////////////////////// 854 855 public void addAnimator(RenderNodeAnimator animator) { 856 if (mActiveAnimators == null) { 857 mActiveAnimators = new ArrayList<RenderNodeAnimator>(); 858 } 859 mActiveAnimators.add(animator); 860 nAddAnimator(mNativeRenderNode, animator.getNativeAnimator()); 861 } 862 863 public void removeAnimator(RenderNodeAnimator animator) { 864 nRemoveAnimator(mNativeRenderNode, animator.getNativeAnimator()); 865 mActiveAnimators.remove(animator); 866 } 867 868 /////////////////////////////////////////////////////////////////////////// 869 // Native methods 870 /////////////////////////////////////////////////////////////////////////// 871 872 private static native long nCreate(String name); 873 private static native void nDestroyRenderNode(long renderNode); 874 private static native void nSetDisplayListData(long renderNode, long newData); 875 876 // Matrix 877 878 private static native void nGetTransformMatrix(long renderNode, long nativeMatrix); 879 private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix); 880 private static native boolean nHasIdentityMatrix(long renderNode); 881 882 // Properties 883 884 private static native void nOffsetTopAndBottom(long renderNode, float offset); 885 private static native void nOffsetLeftAndRight(long renderNode, float offset); 886 private static native void nSetLeftTopRightBottom(long renderNode, int left, int top, 887 int right, int bottom); 888 private static native void nSetBottom(long renderNode, int bottom); 889 private static native void nSetRight(long renderNode, int right); 890 private static native void nSetTop(long renderNode, int top); 891 private static native void nSetLeft(long renderNode, int left); 892 private static native void nSetCameraDistance(long renderNode, float distance); 893 private static native void nSetPivotY(long renderNode, float pivotY); 894 private static native void nSetPivotX(long renderNode, float pivotX); 895 private static native void nSetCaching(long renderNode, boolean caching); 896 private static native void nSetClipToBounds(long renderNode, boolean clipToBounds); 897 private static native void nSetProjectBackwards(long renderNode, boolean shouldProject); 898 private static native void nSetProjectionReceiver(long renderNode, boolean shouldRecieve); 899 private static native void nSetOutlineRoundRect(long renderNode, int left, int top, 900 int right, int bottom, float radius); 901 private static native void nSetOutlineConvexPath(long renderNode, long nativePath); 902 private static native void nSetOutlineEmpty(long renderNode); 903 private static native void nSetClipToOutline(long renderNode, boolean clipToOutline); 904 private static native void nSetRevealClip(long renderNode, 905 boolean shouldClip, boolean inverseClip, float x, float y, float radius); 906 private static native void nSetAlpha(long renderNode, float alpha); 907 private static native void nSetHasOverlappingRendering(long renderNode, 908 boolean hasOverlappingRendering); 909 private static native void nSetElevation(long renderNode, float lift); 910 private static native void nSetTranslationX(long renderNode, float translationX); 911 private static native void nSetTranslationY(long renderNode, float translationY); 912 private static native void nSetTranslationZ(long renderNode, float translationZ); 913 private static native void nSetRotation(long renderNode, float rotation); 914 private static native void nSetRotationX(long renderNode, float rotationX); 915 private static native void nSetRotationY(long renderNode, float rotationY); 916 private static native void nSetScaleX(long renderNode, float scaleX); 917 private static native void nSetScaleY(long renderNode, float scaleY); 918 private static native void nSetStaticMatrix(long renderNode, long nativeMatrix); 919 private static native void nSetAnimationMatrix(long renderNode, long animationMatrix); 920 921 private static native boolean nHasOverlappingRendering(long renderNode); 922 private static native float nGetAlpha(long renderNode); 923 private static native float nGetLeft(long renderNode); 924 private static native float nGetTop(long renderNode); 925 private static native float nGetRight(long renderNode); 926 private static native float nGetBottom(long renderNode); 927 private static native float nGetCameraDistance(long renderNode); 928 private static native float nGetScaleX(long renderNode); 929 private static native float nGetScaleY(long renderNode); 930 private static native float nGetElevation(long renderNode); 931 private static native float nGetTranslationX(long renderNode); 932 private static native float nGetTranslationY(long renderNode); 933 private static native float nGetTranslationZ(long renderNode); 934 private static native float nGetRotation(long renderNode); 935 private static native float nGetRotationX(long renderNode); 936 private static native float nGetRotationY(long renderNode); 937 private static native boolean nIsPivotExplicitlySet(long renderNode); 938 private static native float nGetPivotX(long renderNode); 939 private static native float nGetPivotY(long renderNode); 940 private static native void nOutput(long renderNode); 941 942 /////////////////////////////////////////////////////////////////////////// 943 // Animations 944 /////////////////////////////////////////////////////////////////////////// 945 946 private static native void nAddAnimator(long renderNode, long animatorPtr); 947 private static native void nRemoveAnimator(long renderNode, long animatorPtr); 948 949 /////////////////////////////////////////////////////////////////////////// 950 // Finalization 951 /////////////////////////////////////////////////////////////////////////// 952 953 @Override 954 protected void finalize() throws Throwable { 955 try { 956 nDestroyRenderNode(mNativeRenderNode); 957 } finally { 958 super.finalize(); 959 } 960 } 961} 962