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 RenderNode(String name, View owningView)174 private RenderNode(String name, View owningView) { 175 mNativeRenderNode = nCreate(name); 176 mOwningView = owningView; 177 } 178 179 /** 180 * @see RenderNode#adopt(long) 181 */ RenderNode(long nativePtr)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 */ create(String name, @Nullable View owningView)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 */ adopt(long nativePtr)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 */ start(int width, int height)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 */ end(DisplayListCanvas canvas)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 */ destroyDisplayListData()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 */ isValid()269 public boolean isValid() { return mValid; } 270 getNativeDisplayList()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 hasIdentityMatrix()282 public boolean hasIdentityMatrix() { 283 return nHasIdentityMatrix(mNativeRenderNode); 284 } 285 getMatrix(@onNull Matrix outMatrix)286 public void getMatrix(@NonNull Matrix outMatrix) { 287 nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance); 288 } 289 getInverseMatrix(@onNull Matrix outMatrix)290 public void getInverseMatrix(@NonNull Matrix outMatrix) { 291 nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance); 292 } 293 294 /////////////////////////////////////////////////////////////////////////// 295 // RenderProperty Setters 296 /////////////////////////////////////////////////////////////////////////// 297 setLayerType(int layerType)298 public boolean setLayerType(int layerType) { 299 return nSetLayerType(mNativeRenderNode, layerType); 300 } 301 setLayerPaint(Paint paint)302 public boolean setLayerPaint(Paint paint) { 303 return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0); 304 } 305 setClipBounds(@ullable Rect rect)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 */ setClipToBounds(boolean clipToBounds)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 */ setProjectBackwards(boolean shouldProject)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 */ setProjectionReceiver(boolean shouldRecieve)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 */ setOutline(Outline outline)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 hasShadow()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 */ setClipToOutline(boolean clipToOutline)374 public boolean setClipToOutline(boolean clipToOutline) { 375 return nSetClipToOutline(mNativeRenderNode, clipToOutline); 376 } 377 getClipToOutline()378 public boolean getClipToOutline() { 379 return nGetClipToOutline(mNativeRenderNode); 380 } 381 382 /** 383 * Controls the RenderNode's circular reveal clip. 384 */ setRevealClip(boolean shouldClip, float x, float y, float radius)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 */ setStaticMatrix(Matrix matrix)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 */ setAnimationMatrix(Matrix matrix)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 */ setAlpha(float alpha)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 */ getAlpha()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 */ setHasOverlappingRendering(boolean hasOverlappingRendering)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 */ hasOverlappingRendering()458 public boolean hasOverlappingRendering() { 459 //noinspection SimplifiableIfStatement 460 return nHasOverlappingRendering(mNativeRenderNode); 461 } 462 setElevation(float lift)463 public boolean setElevation(float lift) { 464 return nSetElevation(mNativeRenderNode, lift); 465 } 466 getElevation()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 */ setTranslationX(float translationX)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 */ getTranslationX()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 */ setTranslationY(float translationY)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 */ getTranslationY()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 */ setTranslationZ(float translationZ)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 */ getTranslationZ()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 */ setRotation(float rotation)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 */ getRotation()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 */ setRotationX(float rotationX)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 */ getRotationX()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 */ setRotationY(float rotationY)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 */ getRotationY()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 */ setScaleX(float scaleX)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 */ getScaleX()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 */ setScaleY(float scaleY)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 */ getScaleY()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 */ setPivotX(float pivotX)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 */ getPivotX()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 */ setPivotY(float pivotY)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 */ getPivotY()675 public float getPivotY() { 676 return nGetPivotY(mNativeRenderNode); 677 } 678 isPivotExplicitlySet()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 */ setCameraDistance(float distance)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 */ getCameraDistance()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 */ setLeft(int left)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 */ setTop(int top)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 */ setRight(int right)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 */ setBottom(int bottom)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 */ setLeftTopRightBottom(int left, int top, int right, int bottom)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 */ offsetLeftAndRight(int offset)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 */ offsetTopAndBottom(int offset)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 */ output()795 public void output() { 796 nOutput(mNativeRenderNode); 797 } 798 799 /** 800 * Gets the size of the DisplayList for debug purposes. 801 */ getDebugSize()802 public int getDebugSize() { 803 return nGetDebugSize(mNativeRenderNode); 804 } 805 806 /////////////////////////////////////////////////////////////////////////// 807 // Animations 808 /////////////////////////////////////////////////////////////////////////// 809 addAnimator(RenderNodeAnimator animator)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 endAllAnimators()818 public void endAllAnimators() { 819 nEndAllAnimators(mNativeRenderNode); 820 } 821 822 /////////////////////////////////////////////////////////////////////////// 823 // Native methods 824 /////////////////////////////////////////////////////////////////////////// 825 nCreate(String name)826 private static native long nCreate(String name); nDestroyRenderNode(long renderNode)827 private static native void nDestroyRenderNode(long renderNode); nSetDisplayListData(long renderNode, long newData)828 private static native void nSetDisplayListData(long renderNode, long newData); 829 830 // Matrix 831 nGetTransformMatrix(long renderNode, long nativeMatrix)832 private static native void nGetTransformMatrix(long renderNode, long nativeMatrix); nGetInverseTransformMatrix(long renderNode, long nativeMatrix)833 private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix); nHasIdentityMatrix(long renderNode)834 private static native boolean nHasIdentityMatrix(long renderNode); 835 836 // Properties 837 nOffsetTopAndBottom(long renderNode, int offset)838 private static native boolean nOffsetTopAndBottom(long renderNode, int offset); nOffsetLeftAndRight(long renderNode, int offset)839 private static native boolean nOffsetLeftAndRight(long renderNode, int offset); nSetLeftTopRightBottom(long renderNode, int left, int top, int right, int bottom)840 private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top, 841 int right, int bottom); nSetBottom(long renderNode, int bottom)842 private static native boolean nSetBottom(long renderNode, int bottom); nSetRight(long renderNode, int right)843 private static native boolean nSetRight(long renderNode, int right); nSetTop(long renderNode, int top)844 private static native boolean nSetTop(long renderNode, int top); nSetLeft(long renderNode, int left)845 private static native boolean nSetLeft(long renderNode, int left); nSetCameraDistance(long renderNode, float distance)846 private static native boolean nSetCameraDistance(long renderNode, float distance); nSetPivotY(long renderNode, float pivotY)847 private static native boolean nSetPivotY(long renderNode, float pivotY); nSetPivotX(long renderNode, float pivotX)848 private static native boolean nSetPivotX(long renderNode, float pivotX); nSetLayerType(long renderNode, int layerType)849 private static native boolean nSetLayerType(long renderNode, int layerType); nSetLayerPaint(long renderNode, long paint)850 private static native boolean nSetLayerPaint(long renderNode, long paint); nSetClipToBounds(long renderNode, boolean clipToBounds)851 private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds); nSetClipBounds(long renderNode, int left, int top, int right, int bottom)852 private static native boolean nSetClipBounds(long renderNode, int left, int top, 853 int right, int bottom); nSetClipBoundsEmpty(long renderNode)854 private static native boolean nSetClipBoundsEmpty(long renderNode); nSetProjectBackwards(long renderNode, boolean shouldProject)855 private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject); nSetProjectionReceiver(long renderNode, boolean shouldRecieve)856 private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve); nSetOutlineRoundRect(long renderNode, int left, int top, int right, int bottom, float radius, float alpha)857 private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top, 858 int right, int bottom, float radius, float alpha); nSetOutlineConvexPath(long renderNode, long nativePath, float alpha)859 private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath, 860 float alpha); nSetOutlineEmpty(long renderNode)861 private static native boolean nSetOutlineEmpty(long renderNode); nSetOutlineNone(long renderNode)862 private static native boolean nSetOutlineNone(long renderNode); nHasShadow(long renderNode)863 private static native boolean nHasShadow(long renderNode); nSetClipToOutline(long renderNode, boolean clipToOutline)864 private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline); nSetRevealClip(long renderNode, boolean shouldClip, float x, float y, float radius)865 private static native boolean nSetRevealClip(long renderNode, 866 boolean shouldClip, float x, float y, float radius); nSetAlpha(long renderNode, float alpha)867 private static native boolean nSetAlpha(long renderNode, float alpha); nSetHasOverlappingRendering(long renderNode, boolean hasOverlappingRendering)868 private static native boolean nSetHasOverlappingRendering(long renderNode, 869 boolean hasOverlappingRendering); nSetElevation(long renderNode, float lift)870 private static native boolean nSetElevation(long renderNode, float lift); nSetTranslationX(long renderNode, float translationX)871 private static native boolean nSetTranslationX(long renderNode, float translationX); nSetTranslationY(long renderNode, float translationY)872 private static native boolean nSetTranslationY(long renderNode, float translationY); nSetTranslationZ(long renderNode, float translationZ)873 private static native boolean nSetTranslationZ(long renderNode, float translationZ); nSetRotation(long renderNode, float rotation)874 private static native boolean nSetRotation(long renderNode, float rotation); nSetRotationX(long renderNode, float rotationX)875 private static native boolean nSetRotationX(long renderNode, float rotationX); nSetRotationY(long renderNode, float rotationY)876 private static native boolean nSetRotationY(long renderNode, float rotationY); nSetScaleX(long renderNode, float scaleX)877 private static native boolean nSetScaleX(long renderNode, float scaleX); nSetScaleY(long renderNode, float scaleY)878 private static native boolean nSetScaleY(long renderNode, float scaleY); nSetStaticMatrix(long renderNode, long nativeMatrix)879 private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix); nSetAnimationMatrix(long renderNode, long animationMatrix)880 private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix); 881 nHasOverlappingRendering(long renderNode)882 private static native boolean nHasOverlappingRendering(long renderNode); nGetClipToOutline(long renderNode)883 private static native boolean nGetClipToOutline(long renderNode); nGetAlpha(long renderNode)884 private static native float nGetAlpha(long renderNode); nGetCameraDistance(long renderNode)885 private static native float nGetCameraDistance(long renderNode); nGetScaleX(long renderNode)886 private static native float nGetScaleX(long renderNode); nGetScaleY(long renderNode)887 private static native float nGetScaleY(long renderNode); nGetElevation(long renderNode)888 private static native float nGetElevation(long renderNode); nGetTranslationX(long renderNode)889 private static native float nGetTranslationX(long renderNode); nGetTranslationY(long renderNode)890 private static native float nGetTranslationY(long renderNode); nGetTranslationZ(long renderNode)891 private static native float nGetTranslationZ(long renderNode); nGetRotation(long renderNode)892 private static native float nGetRotation(long renderNode); nGetRotationX(long renderNode)893 private static native float nGetRotationX(long renderNode); nGetRotationY(long renderNode)894 private static native float nGetRotationY(long renderNode); nIsPivotExplicitlySet(long renderNode)895 private static native boolean nIsPivotExplicitlySet(long renderNode); nGetPivotX(long renderNode)896 private static native float nGetPivotX(long renderNode); nGetPivotY(long renderNode)897 private static native float nGetPivotY(long renderNode); nOutput(long renderNode)898 private static native void nOutput(long renderNode); nGetDebugSize(long renderNode)899 private static native int nGetDebugSize(long renderNode); 900 901 /////////////////////////////////////////////////////////////////////////// 902 // Animations 903 /////////////////////////////////////////////////////////////////////////// 904 nAddAnimator(long renderNode, long animatorPtr)905 private static native void nAddAnimator(long renderNode, long animatorPtr); nEndAllAnimators(long renderNode)906 private static native void nEndAllAnimators(long renderNode); 907 908 /////////////////////////////////////////////////////////////////////////// 909 // Finalization 910 /////////////////////////////////////////////////////////////////////////// 911 912 @Override finalize()913 protected void finalize() throws Throwable { 914 try { 915 nDestroyRenderNode(mNativeRenderNode); 916 } finally { 917 super.finalize(); 918 } 919 } 920 } 921