RenderNode.java revision 8c271ca63b62061fd22cfee78fd6a574b44476fd
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.view;
18
19import android.graphics.Matrix;
20import android.graphics.Outline;
21
22/**
23 * <p>A display list records a series of graphics related operations and can replay
24 * them later. Display lists are usually built by recording operations on a
25 * {@link HardwareCanvas}. Replaying the operations from a display list avoids
26 * executing application code on every frame, and is thus much more efficient.</p>
27 *
28 * <p>Display lists are used internally for all views by default, and are not
29 * typically used directly. One reason to consider using a display is a custom
30 * {@link View} implementation that needs to issue a large number of drawing commands.
31 * When the view invalidates, all the drawing commands must be reissued, even if
32 * large portions of the drawing command stream stay the same frame to frame, which
33 * can become a performance bottleneck. To solve this issue, a custom View might split
34 * its content into several display lists. A display list is updated only when its
35 * content, and only its content, needs to be updated.</p>
36 *
37 * <p>A text editor might for instance store each paragraph into its own display list.
38 * Thus when the user inserts or removes characters, only the display list of the
39 * affected paragraph needs to be recorded again.</p>
40 *
41 * <h3>Hardware acceleration</h3>
42 * <p>Display lists can only be replayed using a {@link HardwareCanvas}. They are not
43 * supported in software. Always make sure that the {@link android.graphics.Canvas}
44 * you are using to render a display list is hardware accelerated using
45 * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
46 *
47 * <h3>Creating a display list</h3>
48 * <pre class="prettyprint">
49 *     HardwareRenderer renderer = myView.getHardwareRenderer();
50 *     if (renderer != null) {
51 *         DisplayList displayList = renderer.createDisplayList();
52 *         HardwareCanvas canvas = displayList.start(width, height);
53 *         try {
54 *             // Draw onto the canvas
55 *             // For instance: canvas.drawBitmap(...);
56 *         } finally {
57 *             displayList.end();
58 *         }
59 *     }
60 * </pre>
61 *
62 * <h3>Rendering a display list on a View</h3>
63 * <pre class="prettyprint">
64 *     protected void onDraw(Canvas canvas) {
65 *         if (canvas.isHardwareAccelerated()) {
66 *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
67 *             hardwareCanvas.drawDisplayList(mDisplayList);
68 *         }
69 *     }
70 * </pre>
71 *
72 * <h3>Releasing resources</h3>
73 * <p>This step is not mandatory but recommended if you want to release resources
74 * held by a display list as soon as possible.</p>
75 * <pre class="prettyprint">
76 *     // Mark this display list invalid, it cannot be used for drawing anymore,
77 *     // and release resources held by this display list
78 *     displayList.clear();
79 * </pre>
80 *
81 * <h3>Properties</h3>
82 * <p>In addition, a display list offers several properties, such as
83 * {@link #setScaleX(float)} or {@link #setLeft(int)}, that can be used to affect all
84 * the drawing commands recorded within. For instance, these properties can be used
85 * to move around a large number of images without re-issuing all the individual
86 * <code>drawBitmap()</code> calls.</p>
87 *
88 * <pre class="prettyprint">
89 *     private void createDisplayList() {
90 *         mDisplayList = DisplayList.create("MyDisplayList");
91 *         HardwareCanvas canvas = mDisplayList.start(width, height);
92 *         try {
93 *             for (Bitmap b : mBitmaps) {
94 *                 canvas.drawBitmap(b, 0.0f, 0.0f, null);
95 *                 canvas.translate(0.0f, b.getHeight());
96 *             }
97 *         } finally {
98 *             displayList.end();
99 *         }
100 *     }
101 *
102 *     protected void onDraw(Canvas canvas) {
103 *         if (canvas.isHardwareAccelerated()) {
104 *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
105 *             hardwareCanvas.drawDisplayList(mDisplayList);
106 *         }
107 *     }
108 *
109 *     private void moveContentBy(int x) {
110 *          // This will move all the bitmaps recorded inside the display list
111 *          // by x pixels to the right and redraw this view. All the commands
112 *          // recorded in createDisplayList() won't be re-issued, only onDraw()
113 *          // will be invoked and will execute very quickly
114 *          mDisplayList.offsetLeftAndRight(x);
115 *          invalidate();
116 *     }
117 * </pre>
118 *
119 * <h3>Threading</h3>
120 * <p>Display lists must be created on and manipulated from the UI thread only.</p>
121 *
122 * @hide
123 */
124public class RenderNode {
125    /**
126     * Flag used when calling
127     * {@link HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)}
128     * When this flag is set, draw operations lying outside of the bounds of the
129     * display list will be culled early. It is recommeneded to always set this
130     * flag.
131     *
132     * @hide
133     */
134    public static final int FLAG_CLIP_CHILDREN = 0x1;
135
136    // NOTE: The STATUS_* values *must* match the enum in DrawGlInfo.h
137
138    /**
139     * Indicates that the display list is done drawing.
140     *
141     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
142     *
143     * @hide
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#drawDisplayList(RenderNode, android.graphics.Rect, int)
151     *
152     * @hide
153     */
154    public static final int STATUS_DRAW = 0x1;
155
156    /**
157     * Indicates that the display list needs to re-execute its GL functors.
158     *
159     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
160     * @see HardwareCanvas#callDrawGLFunction(long)
161     *
162     * @hide
163     */
164    public static final int STATUS_INVOKE = 0x2;
165
166    /**
167     * Indicates that the display list performed GL drawing operations.
168     *
169     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
170     *
171     * @hide
172     */
173    public static final int STATUS_DREW = 0x4;
174
175    private boolean mValid;
176    private final long mNativeDisplayList;
177    private HardwareRenderer mRenderer;
178
179    private RenderNode(String name) {
180        mNativeDisplayList = nCreate();
181        nSetDisplayListName(mNativeDisplayList, name);
182    }
183
184    /**
185     * Creates a new display list that can be used to record batches of
186     * drawing operations.
187     *
188     * @param name The name of the display list, used for debugging purpose. May be null.
189     *
190     * @return A new display list.
191     *
192     * @hide
193     */
194    public static RenderNode create(String name) {
195        return new RenderNode(name);
196    }
197
198    /**
199     * Starts recording the display list. All operations performed on the
200     * returned canvas are recorded and stored in this display list.
201     *
202     * Calling this method will mark the display list invalid until
203     * {@link #end()} is called. Only valid display lists can be replayed.
204     *
205     * @param width The width of the display list's viewport
206     * @param height The height of the display list's viewport
207     *
208     * @return A canvas to record drawing operations.
209     *
210     * @see #end()
211     * @see #isValid()
212     */
213    public HardwareCanvas start(int width, int height) {
214        HardwareCanvas canvas = GLES20RecordingCanvas.obtain();
215        canvas.setViewport(width, height);
216        // The dirty rect should always be null for a display list
217        canvas.onPreDraw(null);
218        return canvas;
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(HardwareRenderer renderer, HardwareCanvas endCanvas) {
230        if (!(endCanvas instanceof GLES20RecordingCanvas)) {
231            throw new IllegalArgumentException("Passed an invalid canvas to end!");
232        }
233
234        GLES20RecordingCanvas canvas = (GLES20RecordingCanvas) endCanvas;
235        canvas.onPostDraw();
236        long displayListData = canvas.finishRecording();
237        if (renderer != mRenderer) {
238            // If we are changing renderers first destroy with the old
239            // renderer, then set with the new one
240            destroyDisplayListData();
241        }
242        mRenderer = renderer;
243        setDisplayListData(displayListData);
244        canvas.recycle();
245        mValid = true;
246    }
247
248    /**
249     * Reset native resources. This is called when cleaning up the state of display lists
250     * during destruction of hardware resources, to ensure that we do not hold onto
251     * obsolete resources after related resources are gone.
252     *
253     * @hide
254     */
255    public void destroyDisplayListData() {
256        if (!mValid) return;
257
258        setDisplayListData(0);
259        mRenderer = null;
260        mValid = false;
261    }
262
263    private void setDisplayListData(long newData) {
264        if (mRenderer != null) {
265            mRenderer.setDisplayListData(mNativeDisplayList, newData);
266        } else {
267            throw new IllegalStateException("Trying to set data without a renderer! data=" + newData);
268        }
269    }
270
271    /**
272     * Returns whether the display list is currently usable. If this returns false,
273     * the display list should be re-recorded prior to replaying it.
274     *
275     * @return boolean true if the display list is able to be replayed, false otherwise.
276     */
277    public boolean isValid() { return mValid; }
278
279    long getNativeDisplayList() {
280        if (!mValid) {
281            throw new IllegalStateException("The display list is not valid.");
282        }
283        return mNativeDisplayList;
284    }
285
286    ///////////////////////////////////////////////////////////////////////////
287    // DisplayList Property Setters
288    ///////////////////////////////////////////////////////////////////////////
289
290    /**
291     * Set the caching property on the display list, which indicates whether the display list
292     * holds a layer. Layer display lists should avoid creating an alpha layer, since alpha is
293     * handled in the drawLayer operation directly (and more efficiently).
294     *
295     * @param caching true if the display list represents a hardware layer, false otherwise.
296     *
297     * @hide
298     */
299    public void setCaching(boolean caching) {
300        nSetCaching(mNativeDisplayList, caching);
301    }
302
303    /**
304     * Set whether the display list should clip itself to its bounds. This property is controlled by
305     * the view's parent.
306     *
307     * @param clipToBounds true if the display list should clip to its bounds
308     */
309    public void setClipToBounds(boolean clipToBounds) {
310        nSetClipToBounds(mNativeDisplayList, clipToBounds);
311    }
312
313    /**
314     * Sets whether the display list should be drawn immediately after the
315     * closest ancestor display list where isolateZVolume is true. If the
316     * display list itself satisfies this constraint, changing this attribute
317     * has no effect on drawing order.
318     *
319     * @param shouldProject true if the display list should be projected onto a
320     *            containing volume.
321     */
322    public void setProjectBackwards(boolean shouldProject) {
323        nSetProjectBackwards(mNativeDisplayList, shouldProject);
324    }
325
326    /**
327     * Sets whether the display list is a projection receiver - that its parent
328     * DisplayList should draw any descendent DisplayLists with
329     * ProjectBackwards=true directly on top of it. Default value is false.
330     */
331    public void setProjectionReceiver(boolean shouldRecieve) {
332        nSetProjectionReceiver(mNativeDisplayList, shouldRecieve);
333    }
334
335    /**
336     * Sets the outline, defining the shape that casts a shadow, and the path to
337     * be clipped if setClipToOutline is set.
338     *
339     * Deep copies the data into native to simplify reference ownership.
340     */
341    public void setOutline(Outline outline) {
342        if (outline == null) {
343            nSetOutlineEmpty(mNativeDisplayList);
344        } else if (!outline.isValid()) {
345            throw new IllegalArgumentException("Outline must be valid");
346        } else if (outline.mRect != null) {
347            nSetOutlineRoundRect(mNativeDisplayList, outline.mRect.left, outline.mRect.top,
348                    outline.mRect.right, outline.mRect.bottom, outline.mRadius);
349        } else if (outline.mPath != null) {
350            nSetOutlineConvexPath(mNativeDisplayList, outline.mPath.mNativePath);
351        }
352    }
353
354    /**
355     * Enables or disables clipping to the outline.
356     *
357     * @param clipToOutline true if clipping to the outline.
358     */
359    public void setClipToOutline(boolean clipToOutline) {
360        nSetClipToOutline(mNativeDisplayList, clipToOutline);
361    }
362
363    /**
364     * Controls the RenderNode's circular reveal clip.
365     */
366    public void setRevealClip(boolean shouldClip, boolean inverseClip,
367            float x, float y, float radius) {
368        nSetRevealClip(mNativeDisplayList, shouldClip, inverseClip, x, y, radius);
369    }
370
371    /**
372     * Set the static matrix on the display list. The specified matrix is combined with other
373     * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
374     *
375     * @param matrix A transform matrix to apply to this display list
376     *
377     * @see #getMatrix(android.graphics.Matrix)
378     * @see #getMatrix()
379     */
380    public void setStaticMatrix(Matrix matrix) {
381        nSetStaticMatrix(mNativeDisplayList, matrix.native_instance);
382    }
383
384    /**
385     * Set the Animation matrix on the display list. This matrix exists if an Animation is
386     * currently playing on a View, and is set on the display list during at draw() time. When
387     * the Animation finishes, the matrix should be cleared by sending <code>null</code>
388     * for the matrix parameter.
389     *
390     * @param matrix The matrix, null indicates that the matrix should be cleared.
391     *
392     * @hide
393     */
394    public void setAnimationMatrix(Matrix matrix) {
395        nSetAnimationMatrix(mNativeDisplayList,
396                (matrix != null) ? matrix.native_instance : 0);
397    }
398
399    /**
400     * Sets the translucency level for the display list.
401     *
402     * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
403     *
404     * @see View#setAlpha(float)
405     * @see #getAlpha()
406     */
407    public void setAlpha(float alpha) {
408        nSetAlpha(mNativeDisplayList, alpha);
409    }
410
411    /**
412     * Returns the translucency level of this display list.
413     *
414     * @return A value between 0.0f and 1.0f
415     *
416     * @see #setAlpha(float)
417     */
418    public float getAlpha() {
419        return nGetAlpha(mNativeDisplayList);
420    }
421
422    /**
423     * Sets whether the display list renders content which overlaps. Non-overlapping rendering
424     * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
425     * display lists consider they do not have overlapping content.
426     *
427     * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
428     *                                true otherwise.
429     *
430     * @see android.view.View#hasOverlappingRendering()
431     * @see #hasOverlappingRendering()
432     */
433    public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
434        nSetHasOverlappingRendering(mNativeDisplayList, hasOverlappingRendering);
435    }
436
437    /**
438     * Indicates whether the content of this display list overlaps.
439     *
440     * @return True if this display list renders content which overlaps, false otherwise.
441     *
442     * @see #setHasOverlappingRendering(boolean)
443     */
444    public boolean hasOverlappingRendering() {
445        //noinspection SimplifiableIfStatement
446        return nHasOverlappingRendering(mNativeDisplayList);
447    }
448
449    /**
450     * Sets the translation value for the display list on the X axis.
451     *
452     * @param translationX The X axis translation value of the display list, in pixels
453     *
454     * @see View#setTranslationX(float)
455     * @see #getTranslationX()
456     */
457    public void setTranslationX(float translationX) {
458        nSetTranslationX(mNativeDisplayList, translationX);
459    }
460
461    /**
462     * Returns the translation value for this display list on the X axis, in pixels.
463     *
464     * @see #setTranslationX(float)
465     */
466    public float getTranslationX() {
467        return nGetTranslationX(mNativeDisplayList);
468    }
469
470    /**
471     * Sets the translation value for the display list on the Y axis.
472     *
473     * @param translationY The Y axis translation value of the display list, in pixels
474     *
475     * @see View#setTranslationY(float)
476     * @see #getTranslationY()
477     */
478    public void setTranslationY(float translationY) {
479        nSetTranslationY(mNativeDisplayList, translationY);
480    }
481
482    /**
483     * Returns the translation value for this display list on the Y axis, in pixels.
484     *
485     * @see #setTranslationY(float)
486     */
487    public float getTranslationY() {
488        return nGetTranslationY(mNativeDisplayList);
489    }
490
491    /**
492     * Sets the translation value for the display list on the Z axis.
493     *
494     * @see View#setTranslationZ(float)
495     * @see #getTranslationZ()
496     */
497    public void setTranslationZ(float translationZ) {
498        nSetTranslationZ(mNativeDisplayList, translationZ);
499    }
500
501    /**
502     * Returns the translation value for this display list on the Z axis.
503     *
504     * @see #setTranslationZ(float)
505     */
506    public float getTranslationZ() {
507        return nGetTranslationZ(mNativeDisplayList);
508    }
509
510    /**
511     * Sets the rotation value for the display list around the Z axis.
512     *
513     * @param rotation The rotation value of the display list, in degrees
514     *
515     * @see View#setRotation(float)
516     * @see #getRotation()
517     */
518    public void setRotation(float rotation) {
519        nSetRotation(mNativeDisplayList, rotation);
520    }
521
522    /**
523     * Returns the rotation value for this display list around the Z axis, in degrees.
524     *
525     * @see #setRotation(float)
526     */
527    public float getRotation() {
528        return nGetRotation(mNativeDisplayList);
529    }
530
531    /**
532     * Sets the rotation value for the display list around the X axis.
533     *
534     * @param rotationX The rotation value of the display list, in degrees
535     *
536     * @see View#setRotationX(float)
537     * @see #getRotationX()
538     */
539    public void setRotationX(float rotationX) {
540        nSetRotationX(mNativeDisplayList, rotationX);
541    }
542
543    /**
544     * Returns the rotation value for this display list around the X axis, in degrees.
545     *
546     * @see #setRotationX(float)
547     */
548    public float getRotationX() {
549        return nGetRotationX(mNativeDisplayList);
550    }
551
552    /**
553     * Sets the rotation value for the display list around the Y axis.
554     *
555     * @param rotationY The rotation value of the display list, in degrees
556     *
557     * @see View#setRotationY(float)
558     * @see #getRotationY()
559     */
560    public void setRotationY(float rotationY) {
561        nSetRotationY(mNativeDisplayList, rotationY);
562    }
563
564    /**
565     * Returns the rotation value for this display list around the Y axis, in degrees.
566     *
567     * @see #setRotationY(float)
568     */
569    public float getRotationY() {
570        return nGetRotationY(mNativeDisplayList);
571    }
572
573    /**
574     * Sets the scale value for the display list on the X axis.
575     *
576     * @param scaleX The scale value of the display list
577     *
578     * @see View#setScaleX(float)
579     * @see #getScaleX()
580     */
581    public void setScaleX(float scaleX) {
582        nSetScaleX(mNativeDisplayList, scaleX);
583    }
584
585    /**
586     * Returns the scale value for this display list on the X axis.
587     *
588     * @see #setScaleX(float)
589     */
590    public float getScaleX() {
591        return nGetScaleX(mNativeDisplayList);
592    }
593
594    /**
595     * Sets the scale value for the display list on the Y axis.
596     *
597     * @param scaleY The scale value of the display list
598     *
599     * @see View#setScaleY(float)
600     * @see #getScaleY()
601     */
602    public void setScaleY(float scaleY) {
603        nSetScaleY(mNativeDisplayList, scaleY);
604    }
605
606    /**
607     * Returns the scale value for this display list on the Y axis.
608     *
609     * @see #setScaleY(float)
610     */
611    public float getScaleY() {
612        return nGetScaleY(mNativeDisplayList);
613    }
614
615    /**
616     * Sets all of the transform-related values of the display list
617     *
618     * @param alpha The alpha value of the display list
619     * @param translationX The translationX value of the display list
620     * @param translationY The translationY value of the display list
621     * @param rotation The rotation value of the display list
622     * @param rotationX The rotationX value of the display list
623     * @param rotationY The rotationY value of the display list
624     * @param scaleX The scaleX value of the display list
625     * @param scaleY The scaleY value of the display list
626     *
627     * @hide
628     */
629    public void setTransformationInfo(float alpha,
630            float translationX, float translationY, float translationZ,
631            float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
632        nSetTransformationInfo(mNativeDisplayList, alpha,
633                translationX, translationY, translationZ,
634                rotation, rotationX, rotationY, scaleX, scaleY);
635    }
636
637    /**
638     * Sets the pivot value for the display list on the X axis
639     *
640     * @param pivotX The pivot value of the display list on the X axis, in pixels
641     *
642     * @see View#setPivotX(float)
643     * @see #getPivotX()
644     */
645    public void setPivotX(float pivotX) {
646        nSetPivotX(mNativeDisplayList, pivotX);
647    }
648
649    /**
650     * Returns the pivot value for this display list on the X axis, in pixels.
651     *
652     * @see #setPivotX(float)
653     */
654    public float getPivotX() {
655        return nGetPivotX(mNativeDisplayList);
656    }
657
658    /**
659     * Sets the pivot value for the display list on the Y axis
660     *
661     * @param pivotY The pivot value of the display list on the Y axis, in pixels
662     *
663     * @see View#setPivotY(float)
664     * @see #getPivotY()
665     */
666    public void setPivotY(float pivotY) {
667        nSetPivotY(mNativeDisplayList, pivotY);
668    }
669
670    /**
671     * Returns the pivot value for this display list on the Y axis, in pixels.
672     *
673     * @see #setPivotY(float)
674     */
675    public float getPivotY() {
676        return nGetPivotY(mNativeDisplayList);
677    }
678
679    /**
680     * Sets the camera distance for the display list. Refer to
681     * {@link View#setCameraDistance(float)} for more information on how to
682     * use this property.
683     *
684     * @param distance The distance in Z of the camera of the display list
685     *
686     * @see View#setCameraDistance(float)
687     * @see #getCameraDistance()
688     */
689    public void setCameraDistance(float distance) {
690        nSetCameraDistance(mNativeDisplayList, distance);
691    }
692
693    /**
694     * Returns the distance in Z of the camera of the display list.
695     *
696     * @see #setCameraDistance(float)
697     */
698    public float getCameraDistance() {
699        return nGetCameraDistance(mNativeDisplayList);
700    }
701
702    /**
703     * Sets the left position for the display list.
704     *
705     * @param left The left position, in pixels, of the display list
706     *
707     * @see View#setLeft(int)
708     * @see #getLeft()
709     */
710    public void setLeft(int left) {
711        nSetLeft(mNativeDisplayList, left);
712    }
713
714    /**
715     * Returns the left position for the display list in pixels.
716     *
717     * @see #setLeft(int)
718     */
719    public float getLeft() {
720        return nGetLeft(mNativeDisplayList);
721    }
722
723    /**
724     * Sets the top position for the display list.
725     *
726     * @param top The top position, in pixels, of the display list
727     *
728     * @see View#setTop(int)
729     * @see #getTop()
730     */
731    public void setTop(int top) {
732        nSetTop(mNativeDisplayList, top);
733    }
734
735    /**
736     * Returns the top position for the display list in pixels.
737     *
738     * @see #setTop(int)
739     */
740    public float getTop() {
741        return nGetTop(mNativeDisplayList);
742    }
743
744    /**
745     * Sets the right position for the display list.
746     *
747     * @param right The right position, in pixels, of the display list
748     *
749     * @see View#setRight(int)
750     * @see #getRight()
751     */
752    public void setRight(int right) {
753        nSetRight(mNativeDisplayList, right);
754    }
755
756    /**
757     * Returns the right position for the display list in pixels.
758     *
759     * @see #setRight(int)
760     */
761    public float getRight() {
762        return nGetRight(mNativeDisplayList);
763    }
764
765    /**
766     * Sets the bottom position for the display list.
767     *
768     * @param bottom The bottom position, in pixels, of the display list
769     *
770     * @see View#setBottom(int)
771     * @see #getBottom()
772     */
773    public void setBottom(int bottom) {
774        nSetBottom(mNativeDisplayList, bottom);
775    }
776
777    /**
778     * Returns the bottom position for the display list in pixels.
779     *
780     * @see #setBottom(int)
781     */
782    public float getBottom() {
783        return nGetBottom(mNativeDisplayList);
784    }
785
786    /**
787     * Sets the left and top positions for the display list
788     *
789     * @param left The left position of the display list, in pixels
790     * @param top The top position of the display list, in pixels
791     * @param right The right position of the display list, in pixels
792     * @param bottom The bottom position of the display list, in pixels
793     *
794     * @see View#setLeft(int)
795     * @see View#setTop(int)
796     * @see View#setRight(int)
797     * @see View#setBottom(int)
798     */
799    public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
800        nSetLeftTopRightBottom(mNativeDisplayList, left, top, right, bottom);
801    }
802
803    /**
804     * Offsets the left and right positions for the display list
805     *
806     * @param offset The amount that the left and right positions of the display
807     *               list are offset, in pixels
808     *
809     * @see View#offsetLeftAndRight(int)
810     */
811    public void offsetLeftAndRight(float offset) {
812        nOffsetLeftAndRight(mNativeDisplayList, offset);
813    }
814
815    /**
816     * Offsets the top and bottom values for the display list
817     *
818     * @param offset The amount that the top and bottom positions of the display
819     *               list are offset, in pixels
820     *
821     * @see View#offsetTopAndBottom(int)
822     */
823    public void offsetTopAndBottom(float offset) {
824        nOffsetTopAndBottom(mNativeDisplayList, offset);
825    }
826
827    /**
828     * Outputs the display list to the log. This method exists for use by
829     * tools to output display lists for selected nodes to the log.
830     *
831     * @hide
832     */
833    public void output() {
834        nOutput(mNativeDisplayList);
835    }
836
837    ///////////////////////////////////////////////////////////////////////////
838    // Native methods
839    ///////////////////////////////////////////////////////////////////////////
840
841    private static native long nCreate();
842    private static native void nDestroyDisplayList(long displayList);
843    private static native void nSetDisplayListName(long displayList, String name);
844
845    // Properties
846
847    private static native void nOffsetTopAndBottom(long displayList, float offset);
848    private static native void nOffsetLeftAndRight(long displayList, float offset);
849    private static native void nSetLeftTopRightBottom(long displayList, int left, int top,
850            int right, int bottom);
851    private static native void nSetBottom(long displayList, int bottom);
852    private static native void nSetRight(long displayList, int right);
853    private static native void nSetTop(long displayList, int top);
854    private static native void nSetLeft(long displayList, int left);
855    private static native void nSetCameraDistance(long displayList, float distance);
856    private static native void nSetPivotY(long displayList, float pivotY);
857    private static native void nSetPivotX(long displayList, float pivotX);
858    private static native void nSetCaching(long displayList, boolean caching);
859    private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
860    private static native void nSetProjectBackwards(long displayList, boolean shouldProject);
861    private static native void nSetProjectionReceiver(long displayList, boolean shouldRecieve);
862    private static native void nSetOutlineRoundRect(long displayList, int left, int top,
863            int right, int bottom, float radius);
864    private static native void nSetOutlineConvexPath(long displayList, long nativePath);
865    private static native void nSetOutlineEmpty(long displayList);
866    private static native void nSetClipToOutline(long displayList, boolean clipToOutline);
867    private static native void nSetRevealClip(long displayList,
868            boolean shouldClip, boolean inverseClip, float x, float y, float radius);
869    private static native void nSetAlpha(long displayList, float alpha);
870    private static native void nSetHasOverlappingRendering(long displayList,
871            boolean hasOverlappingRendering);
872    private static native void nSetTranslationX(long displayList, float translationX);
873    private static native void nSetTranslationY(long displayList, float translationY);
874    private static native void nSetTranslationZ(long displayList, float translationZ);
875    private static native void nSetRotation(long displayList, float rotation);
876    private static native void nSetRotationX(long displayList, float rotationX);
877    private static native void nSetRotationY(long displayList, float rotationY);
878    private static native void nSetScaleX(long displayList, float scaleX);
879    private static native void nSetScaleY(long displayList, float scaleY);
880    private static native void nSetTransformationInfo(long displayList, float alpha,
881            float translationX, float translationY, float translationZ,
882            float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
883    private static native void nSetStaticMatrix(long displayList, long nativeMatrix);
884    private static native void nSetAnimationMatrix(long displayList, long animationMatrix);
885
886    private static native boolean nHasOverlappingRendering(long displayList);
887    private static native float nGetAlpha(long displayList);
888    private static native float nGetLeft(long displayList);
889    private static native float nGetTop(long displayList);
890    private static native float nGetRight(long displayList);
891    private static native float nGetBottom(long displayList);
892    private static native float nGetCameraDistance(long displayList);
893    private static native float nGetScaleX(long displayList);
894    private static native float nGetScaleY(long displayList);
895    private static native float nGetTranslationX(long displayList);
896    private static native float nGetTranslationY(long displayList);
897    private static native float nGetTranslationZ(long displayList);
898    private static native float nGetRotation(long displayList);
899    private static native float nGetRotationX(long displayList);
900    private static native float nGetRotationY(long displayList);
901    private static native float nGetPivotX(long displayList);
902    private static native float nGetPivotY(long displayList);
903    private static native void nOutput(long displayList);
904
905    ///////////////////////////////////////////////////////////////////////////
906    // Finalization
907    ///////////////////////////////////////////////////////////////////////////
908
909    @Override
910    protected void finalize() throws Throwable {
911        try {
912            destroyDisplayListData();
913            nDestroyDisplayList(mNativeDisplayList);
914        } finally {
915            super.finalize();
916        }
917    }
918}
919