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