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 import android.graphics.drawable.AnimatedVectorDrawable; 26 27 import dalvik.annotation.optimization.CriticalNative; 28 import dalvik.annotation.optimization.FastNative; 29 30 import libcore.util.NativeAllocationRegistry; 31 32 /** 33 * <p>A display list records a series of graphics related operations and can replay 34 * them later. Display lists are usually built by recording operations on a 35 * {@link DisplayListCanvas}. Replaying the operations from a display list avoids 36 * executing application code on every frame, and is thus much more efficient.</p> 37 * 38 * <p>Display lists are used internally for all views by default, and are not 39 * typically used directly. One reason to consider using a display is a custom 40 * {@link View} implementation that needs to issue a large number of drawing commands. 41 * When the view invalidates, all the drawing commands must be reissued, even if 42 * large portions of the drawing command stream stay the same frame to frame, which 43 * can become a performance bottleneck. To solve this issue, a custom View might split 44 * its content into several display lists. A display list is updated only when its 45 * content, and only its content, needs to be updated.</p> 46 * 47 * <p>A text editor might for instance store each paragraph into its own display list. 48 * Thus when the user inserts or removes characters, only the display list of the 49 * affected paragraph needs to be recorded again.</p> 50 * 51 * <h3>Hardware acceleration</h3> 52 * <p>Display lists can only be replayed using a {@link DisplayListCanvas}. They are not 53 * supported in software. Always make sure that the {@link android.graphics.Canvas} 54 * you are using to render a display list is hardware accelerated using 55 * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p> 56 * 57 * <h3>Creating a display list</h3> 58 * <pre class="prettyprint"> 59 * ThreadedRenderer renderer = myView.getThreadedRenderer(); 60 * if (renderer != null) { 61 * DisplayList displayList = renderer.createDisplayList(); 62 * DisplayListCanvas canvas = displayList.start(width, height); 63 * try { 64 * // Draw onto the canvas 65 * // For instance: canvas.drawBitmap(...); 66 * } finally { 67 * displayList.end(); 68 * } 69 * } 70 * </pre> 71 * 72 * <h3>Rendering a display list on a View</h3> 73 * <pre class="prettyprint"> 74 * protected void onDraw(Canvas canvas) { 75 * if (canvas.isHardwareAccelerated()) { 76 * DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; 77 * displayListCanvas.drawDisplayList(mDisplayList); 78 * } 79 * } 80 * </pre> 81 * 82 * <h3>Releasing resources</h3> 83 * <p>This step is not mandatory but recommended if you want to release resources 84 * held by a display list as soon as possible.</p> 85 * <pre class="prettyprint"> 86 * // Mark this display list invalid, it cannot be used for drawing anymore, 87 * // and release resources held by this display list 88 * displayList.clear(); 89 * </pre> 90 * 91 * <h3>Properties</h3> 92 * <p>In addition, a display list offers several properties, such as 93 * {@link #setScaleX(float)} or {@link #setLeft(int)}, that can be used to affect all 94 * the drawing commands recorded within. For instance, these properties can be used 95 * to move around a large number of images without re-issuing all the individual 96 * <code>drawBitmap()</code> calls.</p> 97 * 98 * <pre class="prettyprint"> 99 * private void createDisplayList() { 100 * mDisplayList = DisplayList.create("MyDisplayList"); 101 * DisplayListCanvas canvas = mDisplayList.start(width, height); 102 * try { 103 * for (Bitmap b : mBitmaps) { 104 * canvas.drawBitmap(b, 0.0f, 0.0f, null); 105 * canvas.translate(0.0f, b.getHeight()); 106 * } 107 * } finally { 108 * displayList.end(); 109 * } 110 * } 111 * 112 * protected void onDraw(Canvas canvas) { 113 * if (canvas.isHardwareAccelerated()) { 114 * DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; 115 * displayListCanvas.drawDisplayList(mDisplayList); 116 * } 117 * } 118 * 119 * private void moveContentBy(int x) { 120 * // This will move all the bitmaps recorded inside the display list 121 * // by x pixels to the right and redraw this view. All the commands 122 * // recorded in createDisplayList() won't be re-issued, only onDraw() 123 * // will be invoked and will execute very quickly 124 * mDisplayList.offsetLeftAndRight(x); 125 * invalidate(); 126 * } 127 * </pre> 128 * 129 * <h3>Threading</h3> 130 * <p>Display lists must be created on and manipulated from the UI thread only.</p> 131 * 132 * @hide 133 */ 134 public class RenderNode { 135 136 // Use a Holder to allow static initialization in the boot image. 137 private static class NoImagePreloadHolder { 138 public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( 139 RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024); 140 } 141 142 // Do not access directly unless you are ThreadedRenderer 143 final long mNativeRenderNode; 144 private final View mOwningView; 145 146 private RenderNode(String name, View owningView) { 147 mNativeRenderNode = nCreate(name); 148 NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode); 149 mOwningView = owningView; 150 } 151 152 /** 153 * @see RenderNode#adopt(long) 154 */ 155 private RenderNode(long nativePtr) { 156 mNativeRenderNode = nativePtr; 157 NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode); 158 mOwningView = null; 159 } 160 161 /** 162 * Immediately destroys the RenderNode 163 * Only suitable for testing/benchmarking where waiting for the GC/finalizer 164 * is not feasible. 165 */ 166 public void destroy() { 167 // TODO: Removed temporarily 168 } 169 170 /** 171 * Creates a new RenderNode that can be used to record batches of 172 * drawing operations, and store / apply render properties when drawn. 173 * 174 * @param name The name of the RenderNode, used for debugging purpose. May be null. 175 * 176 * @return A new RenderNode. 177 */ 178 public static RenderNode create(String name, @Nullable View owningView) { 179 return new RenderNode(name, owningView); 180 } 181 182 /** 183 * Adopts an existing native render node. 184 * 185 * Note: This will *NOT* incRef() on the native object, however it will 186 * decRef() when it is destroyed. The caller should have already incRef'd it 187 */ 188 public static RenderNode adopt(long nativePtr) { 189 return new RenderNode(nativePtr); 190 } 191 192 /** 193 * Enable callbacks for position changes. 194 */ 195 public void requestPositionUpdates(SurfaceView view) { 196 nRequestPositionUpdates(mNativeRenderNode, view); 197 } 198 199 200 /** 201 * Starts recording a display list for the render node. All 202 * operations performed on the returned canvas are recorded and 203 * stored in this display list. 204 * 205 * Calling this method will mark the render node invalid until 206 * {@link #end(DisplayListCanvas)} is called. 207 * Only valid render nodes can be replayed. 208 * 209 * @param width The width of the recording viewport 210 * @param height The height of the recording viewport 211 * 212 * @return A canvas to record drawing operations. 213 * 214 * @see #end(DisplayListCanvas) 215 * @see #isValid() 216 */ 217 public DisplayListCanvas start(int width, int height) { 218 return DisplayListCanvas.obtain(this, width, height); 219 } 220 221 /** 222 * Ends the recording for this display list. A display list cannot be 223 * replayed if recording is not finished. Calling this method marks 224 * the display list valid and {@link #isValid()} will return true. 225 * 226 * @see #start(int, int) 227 * @see #isValid() 228 */ 229 public void end(DisplayListCanvas canvas) { 230 long displayList = canvas.finishRecording(); 231 nSetDisplayList(mNativeRenderNode, displayList); 232 canvas.recycle(); 233 } 234 235 /** 236 * Reset native resources. This is called when cleaning up the state of display lists 237 * during destruction of hardware resources, to ensure that we do not hold onto 238 * obsolete resources after related resources are gone. 239 */ 240 public void discardDisplayList() { 241 nSetDisplayList(mNativeRenderNode, 0); 242 } 243 244 /** 245 * Returns whether the RenderNode's display list content is currently usable. 246 * If this returns false, the display list should be re-recorded prior to replaying it. 247 * 248 * @return boolean true if the display list is able to be replayed, false otherwise. 249 */ 250 public boolean isValid() { 251 return nIsValid(mNativeRenderNode); 252 } 253 254 long getNativeDisplayList() { 255 if (!isValid()) { 256 throw new IllegalStateException("The display list is not valid."); 257 } 258 return mNativeRenderNode; 259 } 260 261 /////////////////////////////////////////////////////////////////////////// 262 // Matrix manipulation 263 /////////////////////////////////////////////////////////////////////////// 264 265 public boolean hasIdentityMatrix() { 266 return nHasIdentityMatrix(mNativeRenderNode); 267 } 268 269 public void getMatrix(@NonNull Matrix outMatrix) { 270 nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance); 271 } 272 273 public void getInverseMatrix(@NonNull Matrix outMatrix) { 274 nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance); 275 } 276 277 /////////////////////////////////////////////////////////////////////////// 278 // RenderProperty Setters 279 /////////////////////////////////////////////////////////////////////////// 280 281 public boolean setLayerType(int layerType) { 282 return nSetLayerType(mNativeRenderNode, layerType); 283 } 284 285 public boolean setLayerPaint(@Nullable Paint paint) { 286 return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0); 287 } 288 289 public boolean setClipBounds(@Nullable Rect rect) { 290 if (rect == null) { 291 return nSetClipBoundsEmpty(mNativeRenderNode); 292 } else { 293 return nSetClipBounds(mNativeRenderNode, rect.left, rect.top, rect.right, rect.bottom); 294 } 295 } 296 297 /** 298 * Set whether the Render node should clip itself to its bounds. This property is controlled by 299 * the view's parent. 300 * 301 * @param clipToBounds true if the display list should clip to its bounds 302 */ 303 public boolean setClipToBounds(boolean clipToBounds) { 304 return nSetClipToBounds(mNativeRenderNode, clipToBounds); 305 } 306 307 /** 308 * Sets whether the display list should be drawn immediately after the 309 * closest ancestor display list containing a projection receiver. 310 * 311 * @param shouldProject true if the display list should be projected onto a 312 * containing volume. 313 */ 314 public boolean setProjectBackwards(boolean shouldProject) { 315 return nSetProjectBackwards(mNativeRenderNode, shouldProject); 316 } 317 318 /** 319 * Sets whether the display list is a projection receiver - that its parent 320 * DisplayList should draw any descendent DisplayLists with 321 * ProjectBackwards=true directly on top of it. Default value is false. 322 */ 323 public boolean setProjectionReceiver(boolean shouldRecieve) { 324 return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve); 325 } 326 327 /** 328 * Sets the outline, defining the shape that casts a shadow, and the path to 329 * be clipped if setClipToOutline is set. 330 * 331 * Deep copies the data into native to simplify reference ownership. 332 */ 333 public boolean setOutline(@Nullable Outline outline) { 334 if (outline == null) { 335 return nSetOutlineNone(mNativeRenderNode); 336 } 337 338 switch(outline.mMode) { 339 case Outline.MODE_EMPTY: 340 return nSetOutlineEmpty(mNativeRenderNode); 341 case Outline.MODE_ROUND_RECT: 342 return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top, 343 outline.mRect.right, outline.mRect.bottom, outline.mRadius, outline.mAlpha); 344 case Outline.MODE_CONVEX_PATH: 345 return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath, 346 outline.mAlpha); 347 } 348 349 throw new IllegalArgumentException("Unrecognized outline?"); 350 } 351 352 public boolean hasShadow() { 353 return nHasShadow(mNativeRenderNode); 354 } 355 356 /** setSpotShadowColor */ 357 public boolean setSpotShadowColor(int color) { 358 return nSetSpotShadowColor(mNativeRenderNode, color); 359 } 360 361 /** setAmbientShadowColor */ 362 public boolean setAmbientShadowColor(int color) { 363 return nSetAmbientShadowColor(mNativeRenderNode, color); 364 } 365 366 /** getSpotShadowColor */ 367 public int getSpotShadowColor() { 368 return nGetSpotShadowColor(mNativeRenderNode); 369 } 370 371 /** getAmbientShadowColor */ 372 public int getAmbientShadowColor() { 373 return nGetAmbientShadowColor(mNativeRenderNode); 374 } 375 376 /** 377 * Enables or disables clipping to the outline. 378 * 379 * @param clipToOutline true if clipping to the outline. 380 */ 381 public boolean setClipToOutline(boolean clipToOutline) { 382 return nSetClipToOutline(mNativeRenderNode, clipToOutline); 383 } 384 385 public boolean getClipToOutline() { 386 return nGetClipToOutline(mNativeRenderNode); 387 } 388 389 /** 390 * Controls the RenderNode's circular reveal clip. 391 */ 392 public boolean setRevealClip(boolean shouldClip, 393 float x, float y, float radius) { 394 return nSetRevealClip(mNativeRenderNode, shouldClip, x, y, radius); 395 } 396 397 /** 398 * Set the static matrix on the display list. The specified matrix is combined with other 399 * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.) 400 * 401 * @param matrix A transform matrix to apply to this display list 402 */ 403 public boolean setStaticMatrix(Matrix matrix) { 404 return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance); 405 } 406 407 /** 408 * Set the Animation matrix on the display list. This matrix exists if an Animation is 409 * currently playing on a View, and is set on the display list during at draw() time. When 410 * the Animation finishes, the matrix should be cleared by sending <code>null</code> 411 * for the matrix parameter. 412 * 413 * @param matrix The matrix, null indicates that the matrix should be cleared. 414 */ 415 public boolean setAnimationMatrix(Matrix matrix) { 416 return nSetAnimationMatrix(mNativeRenderNode, 417 (matrix != null) ? matrix.native_instance : 0); 418 } 419 420 /** 421 * Sets the translucency level for the display list. 422 * 423 * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f 424 * 425 * @see View#setAlpha(float) 426 * @see #getAlpha() 427 */ 428 public boolean setAlpha(float alpha) { 429 return nSetAlpha(mNativeRenderNode, alpha); 430 } 431 432 /** 433 * Returns the translucency level of this display list. 434 * 435 * @return A value between 0.0f and 1.0f 436 * 437 * @see #setAlpha(float) 438 */ 439 public float getAlpha() { 440 return nGetAlpha(mNativeRenderNode); 441 } 442 443 /** 444 * Sets whether the display list renders content which overlaps. Non-overlapping rendering 445 * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default 446 * display lists consider they do not have overlapping content. 447 * 448 * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping, 449 * true otherwise. 450 * 451 * @see android.view.View#hasOverlappingRendering() 452 * @see #hasOverlappingRendering() 453 */ 454 public boolean setHasOverlappingRendering(boolean hasOverlappingRendering) { 455 return nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering); 456 } 457 458 /** 459 * Indicates whether the content of this display list overlaps. 460 * 461 * @return True if this display list renders content which overlaps, false otherwise. 462 * 463 * @see #setHasOverlappingRendering(boolean) 464 */ 465 public boolean hasOverlappingRendering() { 466 //noinspection SimplifiableIfStatement 467 return nHasOverlappingRendering(mNativeRenderNode); 468 } 469 470 public boolean setElevation(float lift) { 471 return nSetElevation(mNativeRenderNode, lift); 472 } 473 474 public float getElevation() { 475 return nGetElevation(mNativeRenderNode); 476 } 477 478 /** 479 * Sets the translation value for the display list on the X axis. 480 * 481 * @param translationX The X axis translation value of the display list, in pixels 482 * 483 * @see View#setTranslationX(float) 484 * @see #getTranslationX() 485 */ 486 public boolean setTranslationX(float translationX) { 487 return nSetTranslationX(mNativeRenderNode, translationX); 488 } 489 490 /** 491 * Returns the translation value for this display list on the X axis, in pixels. 492 * 493 * @see #setTranslationX(float) 494 */ 495 public float getTranslationX() { 496 return nGetTranslationX(mNativeRenderNode); 497 } 498 499 /** 500 * Sets the translation value for the display list on the Y axis. 501 * 502 * @param translationY The Y axis translation value of the display list, in pixels 503 * 504 * @see View#setTranslationY(float) 505 * @see #getTranslationY() 506 */ 507 public boolean setTranslationY(float translationY) { 508 return nSetTranslationY(mNativeRenderNode, translationY); 509 } 510 511 /** 512 * Returns the translation value for this display list on the Y axis, in pixels. 513 * 514 * @see #setTranslationY(float) 515 */ 516 public float getTranslationY() { 517 return nGetTranslationY(mNativeRenderNode); 518 } 519 520 /** 521 * Sets the translation value for the display list on the Z axis. 522 * 523 * @see View#setTranslationZ(float) 524 * @see #getTranslationZ() 525 */ 526 public boolean setTranslationZ(float translationZ) { 527 return nSetTranslationZ(mNativeRenderNode, translationZ); 528 } 529 530 /** 531 * Returns the translation value for this display list on the Z axis. 532 * 533 * @see #setTranslationZ(float) 534 */ 535 public float getTranslationZ() { 536 return nGetTranslationZ(mNativeRenderNode); 537 } 538 539 /** 540 * Sets the rotation value for the display list around the Z axis. 541 * 542 * @param rotation The rotation value of the display list, in degrees 543 * 544 * @see View#setRotation(float) 545 * @see #getRotation() 546 */ 547 public boolean setRotation(float rotation) { 548 return nSetRotation(mNativeRenderNode, rotation); 549 } 550 551 /** 552 * Returns the rotation value for this display list around the Z axis, in degrees. 553 * 554 * @see #setRotation(float) 555 */ 556 public float getRotation() { 557 return nGetRotation(mNativeRenderNode); 558 } 559 560 /** 561 * Sets the rotation value for the display list around the X axis. 562 * 563 * @param rotationX The rotation value of the display list, in degrees 564 * 565 * @see View#setRotationX(float) 566 * @see #getRotationX() 567 */ 568 public boolean setRotationX(float rotationX) { 569 return nSetRotationX(mNativeRenderNode, rotationX); 570 } 571 572 /** 573 * Returns the rotation value for this display list around the X axis, in degrees. 574 * 575 * @see #setRotationX(float) 576 */ 577 public float getRotationX() { 578 return nGetRotationX(mNativeRenderNode); 579 } 580 581 /** 582 * Sets the rotation value for the display list around the Y axis. 583 * 584 * @param rotationY The rotation value of the display list, in degrees 585 * 586 * @see View#setRotationY(float) 587 * @see #getRotationY() 588 */ 589 public boolean setRotationY(float rotationY) { 590 return nSetRotationY(mNativeRenderNode, rotationY); 591 } 592 593 /** 594 * Returns the rotation value for this display list around the Y axis, in degrees. 595 * 596 * @see #setRotationY(float) 597 */ 598 public float getRotationY() { 599 return nGetRotationY(mNativeRenderNode); 600 } 601 602 /** 603 * Sets the scale value for the display list on the X axis. 604 * 605 * @param scaleX The scale value of the display list 606 * 607 * @see View#setScaleX(float) 608 * @see #getScaleX() 609 */ 610 public boolean setScaleX(float scaleX) { 611 return nSetScaleX(mNativeRenderNode, scaleX); 612 } 613 614 /** 615 * Returns the scale value for this display list on the X axis. 616 * 617 * @see #setScaleX(float) 618 */ 619 public float getScaleX() { 620 return nGetScaleX(mNativeRenderNode); 621 } 622 623 /** 624 * Sets the scale value for the display list on the Y axis. 625 * 626 * @param scaleY The scale value of the display list 627 * 628 * @see View#setScaleY(float) 629 * @see #getScaleY() 630 */ 631 public boolean setScaleY(float scaleY) { 632 return nSetScaleY(mNativeRenderNode, scaleY); 633 } 634 635 /** 636 * Returns the scale value for this display list on the Y axis. 637 * 638 * @see #setScaleY(float) 639 */ 640 public float getScaleY() { 641 return nGetScaleY(mNativeRenderNode); 642 } 643 644 /** 645 * Sets the pivot value for the display list on the X axis 646 * 647 * @param pivotX The pivot value of the display list on the X axis, in pixels 648 * 649 * @see View#setPivotX(float) 650 * @see #getPivotX() 651 */ 652 public boolean setPivotX(float pivotX) { 653 return nSetPivotX(mNativeRenderNode, pivotX); 654 } 655 656 /** 657 * Returns the pivot value for this display list on the X axis, in pixels. 658 * 659 * @see #setPivotX(float) 660 */ 661 public float getPivotX() { 662 return nGetPivotX(mNativeRenderNode); 663 } 664 665 /** 666 * Sets the pivot value for the display list on the Y axis 667 * 668 * @param pivotY The pivot value of the display list on the Y axis, in pixels 669 * 670 * @see View#setPivotY(float) 671 * @see #getPivotY() 672 */ 673 public boolean setPivotY(float pivotY) { 674 return nSetPivotY(mNativeRenderNode, pivotY); 675 } 676 677 /** 678 * Returns the pivot value for this display list on the Y axis, in pixels. 679 * 680 * @see #setPivotY(float) 681 */ 682 public float getPivotY() { 683 return nGetPivotY(mNativeRenderNode); 684 } 685 686 public boolean isPivotExplicitlySet() { 687 return nIsPivotExplicitlySet(mNativeRenderNode); 688 } 689 690 /** lint */ 691 public boolean resetPivot() { 692 return nResetPivot(mNativeRenderNode); 693 } 694 695 /** 696 * Sets the camera distance for the display list. Refer to 697 * {@link View#setCameraDistance(float)} for more information on how to 698 * use this property. 699 * 700 * @param distance The distance in Z of the camera of the display list 701 * 702 * @see View#setCameraDistance(float) 703 * @see #getCameraDistance() 704 */ 705 public boolean setCameraDistance(float distance) { 706 return nSetCameraDistance(mNativeRenderNode, distance); 707 } 708 709 /** 710 * Returns the distance in Z of the camera of the display list. 711 * 712 * @see #setCameraDistance(float) 713 */ 714 public float getCameraDistance() { 715 return nGetCameraDistance(mNativeRenderNode); 716 } 717 718 /** 719 * Sets the left position for the display list. 720 * 721 * @param left The left position, in pixels, of the display list 722 * 723 * @see View#setLeft(int) 724 */ 725 public boolean setLeft(int left) { 726 return nSetLeft(mNativeRenderNode, left); 727 } 728 729 /** 730 * Sets the top position for the display list. 731 * 732 * @param top The top position, in pixels, of the display list 733 * 734 * @see View#setTop(int) 735 */ 736 public boolean setTop(int top) { 737 return nSetTop(mNativeRenderNode, top); 738 } 739 740 /** 741 * Sets the right position for the display list. 742 * 743 * @param right The right position, in pixels, of the display list 744 * 745 * @see View#setRight(int) 746 */ 747 public boolean setRight(int right) { 748 return nSetRight(mNativeRenderNode, right); 749 } 750 751 /** 752 * Sets the bottom position for the display list. 753 * 754 * @param bottom The bottom position, in pixels, of the display list 755 * 756 * @see View#setBottom(int) 757 */ 758 public boolean setBottom(int bottom) { 759 return nSetBottom(mNativeRenderNode, bottom); 760 } 761 762 /** 763 * Sets the left and top positions for the display list 764 * 765 * @param left The left position of the display list, in pixels 766 * @param top The top position of the display list, in pixels 767 * @param right The right position of the display list, in pixels 768 * @param bottom The bottom position of the display list, in pixels 769 * 770 * @see View#setLeft(int) 771 * @see View#setTop(int) 772 * @see View#setRight(int) 773 * @see View#setBottom(int) 774 */ 775 public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) { 776 return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom); 777 } 778 779 /** 780 * Offsets the left and right positions for the display list 781 * 782 * @param offset The amount that the left and right positions of the display 783 * list are offset, in pixels 784 * 785 * @see View#offsetLeftAndRight(int) 786 */ 787 public boolean offsetLeftAndRight(int offset) { 788 return nOffsetLeftAndRight(mNativeRenderNode, offset); 789 } 790 791 /** 792 * Offsets the top and bottom values for the display list 793 * 794 * @param offset The amount that the top and bottom positions of the display 795 * list are offset, in pixels 796 * 797 * @see View#offsetTopAndBottom(int) 798 */ 799 public boolean offsetTopAndBottom(int offset) { 800 return nOffsetTopAndBottom(mNativeRenderNode, offset); 801 } 802 803 /** 804 * Outputs the display list to the log. This method exists for use by 805 * tools to output display lists for selected nodes to the log. 806 */ 807 public void output() { 808 nOutput(mNativeRenderNode); 809 } 810 811 /** 812 * Gets the size of the DisplayList for debug purposes. 813 */ 814 public int getDebugSize() { 815 return nGetDebugSize(mNativeRenderNode); 816 } 817 818 /////////////////////////////////////////////////////////////////////////// 819 // Animations 820 /////////////////////////////////////////////////////////////////////////// 821 822 public void addAnimator(RenderNodeAnimator animator) { 823 if (mOwningView == null || mOwningView.mAttachInfo == null) { 824 throw new IllegalStateException("Cannot start this animator on a detached view!"); 825 } 826 nAddAnimator(mNativeRenderNode, animator.getNativeAnimator()); 827 mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this); 828 } 829 830 public boolean isAttached() { 831 return mOwningView != null && mOwningView.mAttachInfo != null; 832 } 833 834 public void registerVectorDrawableAnimator( 835 AnimatedVectorDrawable.VectorDrawableAnimatorRT animatorSet) { 836 if (mOwningView == null || mOwningView.mAttachInfo == null) { 837 throw new IllegalStateException("Cannot start this animator on a detached view!"); 838 } 839 mOwningView.mAttachInfo.mViewRootImpl.registerVectorDrawableAnimator(animatorSet); 840 } 841 842 public void endAllAnimators() { 843 nEndAllAnimators(mNativeRenderNode); 844 } 845 846 /////////////////////////////////////////////////////////////////////////// 847 // Regular JNI methods 848 /////////////////////////////////////////////////////////////////////////// 849 850 private static native long nCreate(String name); 851 852 private static native long nGetNativeFinalizer(); 853 private static native void nOutput(long renderNode); 854 private static native int nGetDebugSize(long renderNode); 855 private static native void nRequestPositionUpdates(long renderNode, SurfaceView callback); 856 857 // Animations 858 859 private static native void nAddAnimator(long renderNode, long animatorPtr); 860 private static native void nEndAllAnimators(long renderNode); 861 862 863 /////////////////////////////////////////////////////////////////////////// 864 // @FastNative methods 865 /////////////////////////////////////////////////////////////////////////// 866 867 @FastNative 868 private static native void nSetDisplayList(long renderNode, long newData); 869 870 871 /////////////////////////////////////////////////////////////////////////// 872 // @CriticalNative methods 873 /////////////////////////////////////////////////////////////////////////// 874 875 @CriticalNative 876 private static native boolean nIsValid(long renderNode); 877 878 // Matrix 879 880 @CriticalNative 881 private static native void nGetTransformMatrix(long renderNode, long nativeMatrix); 882 @CriticalNative 883 private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix); 884 @CriticalNative 885 private static native boolean nHasIdentityMatrix(long renderNode); 886 887 // Properties 888 889 @CriticalNative 890 private static native boolean nOffsetTopAndBottom(long renderNode, int offset); 891 @CriticalNative 892 private static native boolean nOffsetLeftAndRight(long renderNode, int offset); 893 @CriticalNative 894 private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top, 895 int right, int bottom); 896 @CriticalNative 897 private static native boolean nSetBottom(long renderNode, int bottom); 898 @CriticalNative 899 private static native boolean nSetRight(long renderNode, int right); 900 @CriticalNative 901 private static native boolean nSetTop(long renderNode, int top); 902 @CriticalNative 903 private static native boolean nSetLeft(long renderNode, int left); 904 @CriticalNative 905 private static native boolean nSetCameraDistance(long renderNode, float distance); 906 @CriticalNative 907 private static native boolean nSetPivotY(long renderNode, float pivotY); 908 @CriticalNative 909 private static native boolean nSetPivotX(long renderNode, float pivotX); 910 @CriticalNative 911 private static native boolean nResetPivot(long renderNode); 912 @CriticalNative 913 private static native boolean nSetLayerType(long renderNode, int layerType); 914 @CriticalNative 915 private static native boolean nSetLayerPaint(long renderNode, long paint); 916 @CriticalNative 917 private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds); 918 @CriticalNative 919 private static native boolean nSetClipBounds(long renderNode, int left, int top, 920 int right, int bottom); 921 @CriticalNative 922 private static native boolean nSetClipBoundsEmpty(long renderNode); 923 @CriticalNative 924 private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject); 925 @CriticalNative 926 private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve); 927 @CriticalNative 928 private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top, 929 int right, int bottom, float radius, float alpha); 930 @CriticalNative 931 private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath, 932 float alpha); 933 @CriticalNative 934 private static native boolean nSetOutlineEmpty(long renderNode); 935 @CriticalNative 936 private static native boolean nSetOutlineNone(long renderNode); 937 @CriticalNative 938 private static native boolean nHasShadow(long renderNode); 939 @CriticalNative 940 private static native boolean nSetSpotShadowColor(long renderNode, int color); 941 @CriticalNative 942 private static native boolean nSetAmbientShadowColor(long renderNode, int color); 943 @CriticalNative 944 private static native int nGetSpotShadowColor(long renderNode); 945 @CriticalNative 946 private static native int nGetAmbientShadowColor(long renderNode); 947 @CriticalNative 948 private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline); 949 @CriticalNative 950 private static native boolean nSetRevealClip(long renderNode, 951 boolean shouldClip, float x, float y, float radius); 952 @CriticalNative 953 private static native boolean nSetAlpha(long renderNode, float alpha); 954 @CriticalNative 955 private static native boolean nSetHasOverlappingRendering(long renderNode, 956 boolean hasOverlappingRendering); 957 @CriticalNative 958 private static native boolean nSetElevation(long renderNode, float lift); 959 @CriticalNative 960 private static native boolean nSetTranslationX(long renderNode, float translationX); 961 @CriticalNative 962 private static native boolean nSetTranslationY(long renderNode, float translationY); 963 @CriticalNative 964 private static native boolean nSetTranslationZ(long renderNode, float translationZ); 965 @CriticalNative 966 private static native boolean nSetRotation(long renderNode, float rotation); 967 @CriticalNative 968 private static native boolean nSetRotationX(long renderNode, float rotationX); 969 @CriticalNative 970 private static native boolean nSetRotationY(long renderNode, float rotationY); 971 @CriticalNative 972 private static native boolean nSetScaleX(long renderNode, float scaleX); 973 @CriticalNative 974 private static native boolean nSetScaleY(long renderNode, float scaleY); 975 @CriticalNative 976 private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix); 977 @CriticalNative 978 private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix); 979 980 @CriticalNative 981 private static native boolean nHasOverlappingRendering(long renderNode); 982 @CriticalNative 983 private static native boolean nGetClipToOutline(long renderNode); 984 @CriticalNative 985 private static native float nGetAlpha(long renderNode); 986 @CriticalNative 987 private static native float nGetCameraDistance(long renderNode); 988 @CriticalNative 989 private static native float nGetScaleX(long renderNode); 990 @CriticalNative 991 private static native float nGetScaleY(long renderNode); 992 @CriticalNative 993 private static native float nGetElevation(long renderNode); 994 @CriticalNative 995 private static native float nGetTranslationX(long renderNode); 996 @CriticalNative 997 private static native float nGetTranslationY(long renderNode); 998 @CriticalNative 999 private static native float nGetTranslationZ(long renderNode); 1000 @CriticalNative 1001 private static native float nGetRotation(long renderNode); 1002 @CriticalNative 1003 private static native float nGetRotationX(long renderNode); 1004 @CriticalNative 1005 private static native float nGetRotationY(long renderNode); 1006 @CriticalNative 1007 private static native boolean nIsPivotExplicitlySet(long renderNode); 1008 @CriticalNative 1009 private static native float nGetPivotX(long renderNode); 1010 @CriticalNative 1011 private static native float nGetPivotY(long renderNode); 1012 } 1013