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