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