Home | History | Annotate | Download | only in view
      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.graphics.Matrix;
     20 
     21 /**
     22  * <p>A display list records a series of graphics related operations and can replay
     23  * them later. Display lists are usually built by recording operations on a
     24  * {@link HardwareCanvas}. Replaying the operations from a display list avoids
     25  * executing application code on every frame, and is thus much more efficient.</p>
     26  *
     27  * <p>Display lists are used internally for all views by default, and are not
     28  * typically used directly. One reason to consider using a display is a custom
     29  * {@link View} implementation that needs to issue a large number of drawing commands.
     30  * When the view invalidates, all the drawing commands must be reissued, even if
     31  * large portions of the drawing command stream stay the same frame to frame, which
     32  * can become a performance bottleneck. To solve this issue, a custom View might split
     33  * its content into several display lists. A display list is updated only when its
     34  * content, and only its content, needs to be updated.</p>
     35  *
     36  * <p>A text editor might for instance store each paragraph into its own display list.
     37  * Thus when the user inserts or removes characters, only the display list of the
     38  * affected paragraph needs to be recorded again.</p>
     39  *
     40  * <h3>Hardware acceleration</h3>
     41  * <p>Display lists can only be replayed using a {@link HardwareCanvas}. They are not
     42  * supported in software. Always make sure that the {@link android.graphics.Canvas}
     43  * you are using to render a display list is hardware accelerated using
     44  * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
     45  *
     46  * <h3>Creating a display list</h3>
     47  * <pre class="prettyprint">
     48  *     HardwareRenderer renderer = myView.getHardwareRenderer();
     49  *     if (renderer != null) {
     50  *         DisplayList displayList = renderer.createDisplayList();
     51  *         HardwareCanvas canvas = displayList.start(width, height);
     52  *         try {
     53  *             // Draw onto the canvas
     54  *             // For instance: canvas.drawBitmap(...);
     55  *         } finally {
     56  *             displayList.end();
     57  *         }
     58  *     }
     59  * </pre>
     60  *
     61  * <h3>Rendering a display list on a View</h3>
     62  * <pre class="prettyprint">
     63  *     protected void onDraw(Canvas canvas) {
     64  *         if (canvas.isHardwareAccelerated()) {
     65  *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
     66  *             hardwareCanvas.drawDisplayList(mDisplayList);
     67  *         }
     68  *     }
     69  * </pre>
     70  *
     71  * <h3>Releasing resources</h3>
     72  * <p>This step is not mandatory but recommended if you want to release resources
     73  * held by a display list as soon as possible.</p>
     74  * <pre class="prettyprint">
     75  *     // Mark this display list invalid, it cannot be used for drawing anymore,
     76  *     // and release resources held by this display list
     77  *     displayList.clear();
     78  * </pre>
     79  *
     80  * <h3>Properties</h3>
     81  * <p>In addition, a display list offers several properties, such as
     82  * {@link #setScaleX(float)} or {@link #setLeft(int)}, that can be used to affect all
     83  * the drawing commands recorded within. For instance, these properties can be used
     84  * to move around a large number of images without re-issuing all the individual
     85  * <code>drawBitmap()</code> calls.</p>
     86  *
     87  * <pre class="prettyprint">
     88  *     private void createDisplayList() {
     89  *         HardwareRenderer renderer = getHardwareRenderer();
     90  *         if (renderer != null) {
     91  *             mDisplayList = renderer.createDisplayList();
     92  *             HardwareCanvas canvas = mDisplayList.start(width, height);
     93  *             try {
     94  *                 for (Bitmap b : mBitmaps) {
     95  *                     canvas.drawBitmap(b, 0.0f, 0.0f, null);
     96  *                     canvas.translate(0.0f, b.getHeight());
     97  *                 }
     98  *             } finally {
     99  *                 displayList.end();
    100  *             }
    101  *         }
    102  *     }
    103  *
    104  *     protected void onDraw(Canvas canvas) {
    105  *         if (canvas.isHardwareAccelerated()) {
    106  *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
    107  *             hardwareCanvas.drawDisplayList(mDisplayList);
    108  *         }
    109  *     }
    110  *
    111  *     private void moveContentBy(int x) {
    112  *          // This will move all the bitmaps recorded inside the display list
    113  *          // by x pixels to the right and redraw this view. All the commands
    114  *          // recorded in createDisplayList() won't be re-issued, only onDraw()
    115  *          // will be invoked and will execute very quickly
    116  *          mDisplayList.offsetLeftAndRight(x);
    117  *          invalidate();
    118  *     }
    119  * </pre>
    120  *
    121  * <h3>Threading</h3>
    122  * <p>Display lists must be created on and manipulated from the UI thread only.</p>
    123  *
    124  * @hide
    125  */
    126 public abstract class DisplayList {
    127     private boolean mDirty;
    128 
    129     /**
    130      * Flag used when calling
    131      * {@link HardwareCanvas#drawDisplayList(DisplayList, 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      * @hide
    137      */
    138     public static final int FLAG_CLIP_CHILDREN = 0x1;
    139 
    140     // NOTE: The STATUS_* values *must* match the enum in DrawGlInfo.h
    141 
    142     /**
    143      * Indicates that the display list is done drawing.
    144      *
    145      * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
    146      *
    147      * @hide
    148      */
    149     public static final int STATUS_DONE = 0x0;
    150 
    151     /**
    152      * Indicates that the display list needs another drawing pass.
    153      *
    154      * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
    155      *
    156      * @hide
    157      */
    158     public static final int STATUS_DRAW = 0x1;
    159 
    160     /**
    161      * Indicates that the display list needs to re-execute its GL functors.
    162      *
    163      * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
    164      * @see HardwareCanvas#callDrawGLFunction(int)
    165      *
    166      * @hide
    167      */
    168     public static final int STATUS_INVOKE = 0x2;
    169 
    170     /**
    171      * Indicates that the display list performed GL drawing operations.
    172      *
    173      * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
    174      *
    175      * @hide
    176      */
    177     public static final int STATUS_DREW = 0x4;
    178 
    179     /**
    180      * Starts recording the display list. All operations performed on the
    181      * returned canvas are recorded and stored in this display list.
    182      *
    183      * Calling this method will mark the display list invalid until
    184      * {@link #end()} is called. Only valid display lists can be replayed.
    185      *
    186      * @param width The width of the display list's viewport
    187      * @param height The height of the display list's viewport
    188      *
    189      * @return A canvas to record drawing operations.
    190      *
    191      * @see #end()
    192      * @see #isValid()
    193      */
    194     public abstract HardwareCanvas start(int width, int height);
    195 
    196     /**
    197      * Ends the recording for this display list. A display list cannot be
    198      * replayed if recording is not finished. Calling this method marks
    199      * the display list valid and {@link #isValid()} will return true.
    200      *
    201      * @see #start(int, int)
    202      * @see #isValid()
    203      */
    204     public abstract void end();
    205 
    206     /**
    207      * Clears resources held onto by this display list. After calling this method
    208      * {@link #isValid()} will return false.
    209      *
    210      * @see #isValid()
    211      */
    212     public abstract void clear();
    213 
    214     /**
    215      * Sets the dirty flag. When a display list is dirty, {@link #clear()} should
    216      * be invoked whenever possible.
    217      *
    218      * @see #isDirty()
    219      * @see #clear()
    220      *
    221      * @hide
    222      */
    223     public void markDirty() {
    224         mDirty = true;
    225     }
    226 
    227     /**
    228      * Removes the dirty flag. This method can be used to cancel a cleanup
    229      * previously scheduled by setting the dirty flag.
    230      *
    231      * @see #isDirty()
    232      * @see #clear()
    233      *
    234      * @hide
    235      */
    236     protected void clearDirty() {
    237         mDirty = false;
    238     }
    239 
    240     /**
    241      * Indicates whether the display list is dirty.
    242      *
    243      * @see #markDirty()
    244      * @see #clear()
    245      *
    246      * @hide
    247      */
    248     public boolean isDirty() {
    249         return mDirty;
    250     }
    251 
    252     /**
    253      * Returns whether the display list is currently usable. If this returns false,
    254      * the display list should be re-recorded prior to replaying it.
    255      *
    256      * @return boolean true if the display list is able to be replayed, false otherwise.
    257      */
    258     public abstract boolean isValid();
    259 
    260     /**
    261      * Return the amount of memory used by this display list.
    262      *
    263      * @return The size of this display list in bytes
    264      *
    265      * @hide
    266      */
    267     public abstract int getSize();
    268 
    269     ///////////////////////////////////////////////////////////////////////////
    270     // DisplayList Property Setters
    271     ///////////////////////////////////////////////////////////////////////////
    272 
    273     /**
    274      * Set the caching property on the display list, which indicates whether the display list
    275      * holds a layer. Layer display lists should avoid creating an alpha layer, since alpha is
    276      * handled in the drawLayer operation directly (and more efficiently).
    277      *
    278      * @param caching true if the display list represents a hardware layer, false otherwise.
    279      *
    280      * @hide
    281      */
    282     public abstract void setCaching(boolean caching);
    283 
    284     /**
    285      * Set whether the display list should clip itself to its bounds. This property is controlled by
    286      * the view's parent.
    287      *
    288      * @param clipToBounds true if the display list should clip to its bounds
    289      */
    290     public abstract void setClipToBounds(boolean clipToBounds);
    291 
    292     /**
    293      * Set the static matrix on the display list. The specified matrix is combined with other
    294      * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
    295      *
    296      * @param matrix A transform matrix to apply to this display list
    297      *
    298      * @see #getMatrix(android.graphics.Matrix)
    299      * @see #getMatrix()
    300      */
    301     public abstract void setMatrix(Matrix matrix);
    302 
    303     /**
    304      * Returns the static matrix set on this display list.
    305      *
    306      * @return A new {@link Matrix} instance populated with this display list's static
    307      *         matrix
    308      *
    309      * @see #getMatrix(android.graphics.Matrix)
    310      * @see #setMatrix(android.graphics.Matrix)
    311      */
    312     public Matrix getMatrix() {
    313         return getMatrix(new Matrix());
    314     }
    315 
    316     /**
    317      * Copies this display list's static matrix into the specified matrix.
    318      *
    319      * @param matrix The {@link Matrix} instance in which to copy this display
    320      *               list's static matrix. Cannot be null
    321      *
    322      * @return The <code>matrix</code> parameter, for convenience
    323      *
    324      * @see #getMatrix()
    325      * @see #setMatrix(android.graphics.Matrix)
    326      */
    327     public abstract Matrix getMatrix(Matrix matrix);
    328 
    329     /**
    330      * Set the Animation matrix on the display list. This matrix exists if an Animation is
    331      * currently playing on a View, and is set on the display list during at draw() time. When
    332      * the Animation finishes, the matrix should be cleared by sending <code>null</code>
    333      * for the matrix parameter.
    334      *
    335      * @param matrix The matrix, null indicates that the matrix should be cleared.
    336      *
    337      * @hide
    338      */
    339     public abstract void setAnimationMatrix(Matrix matrix);
    340 
    341     /**
    342      * Sets the translucency level for the display list.
    343      *
    344      * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
    345      *
    346      * @see View#setAlpha(float)
    347      * @see #getAlpha()
    348      */
    349     public abstract void setAlpha(float alpha);
    350 
    351     /**
    352      * Returns the translucency level of this display list.
    353      *
    354      * @return A value between 0.0f and 1.0f
    355      *
    356      * @see #setAlpha(float)
    357      */
    358     public abstract float getAlpha();
    359 
    360     /**
    361      * Sets whether the display list renders content which overlaps. Non-overlapping rendering
    362      * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
    363      * display lists consider they do not have overlapping content.
    364      *
    365      * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
    366      *                                true otherwise.
    367      *
    368      * @see android.view.View#hasOverlappingRendering()
    369      * @see #hasOverlappingRendering()
    370      */
    371     public abstract void setHasOverlappingRendering(boolean hasOverlappingRendering);
    372 
    373     /**
    374      * Indicates whether the content of this display list overlaps.
    375      *
    376      * @return True if this display list renders content which overlaps, false otherwise.
    377      *
    378      * @see #setHasOverlappingRendering(boolean)
    379      */
    380     public abstract boolean hasOverlappingRendering();
    381 
    382     /**
    383      * Sets the translation value for the display list on the X axis
    384      *
    385      * @param translationX The X axis translation value of the display list, in pixels
    386      *
    387      * @see View#setTranslationX(float)
    388      * @see #getTranslationX()
    389      */
    390     public abstract void setTranslationX(float translationX);
    391 
    392     /**
    393      * Returns the translation value for this display list on the X axis, in pixels.
    394      *
    395      * @see #setTranslationX(float)
    396      */
    397     public abstract float getTranslationX();
    398 
    399     /**
    400      * Sets the translation value for the display list on the Y axis
    401      *
    402      * @param translationY The Y axis translation value of the display list, in pixels
    403      *
    404      * @see View#setTranslationY(float)
    405      * @see #getTranslationY()
    406      */
    407     public abstract void setTranslationY(float translationY);
    408 
    409     /**
    410      * Returns the translation value for this display list on the Y axis, in pixels.
    411      *
    412      * @see #setTranslationY(float)
    413      */
    414     public abstract float getTranslationY();
    415 
    416     /**
    417      * Sets the rotation value for the display list around the Z axis
    418      *
    419      * @param rotation The rotation value of the display list, in degrees
    420      *
    421      * @see View#setRotation(float)
    422      * @see #getRotation()
    423      */
    424     public abstract void setRotation(float rotation);
    425 
    426     /**
    427      * Returns the rotation value for this display list around the Z axis, in degrees.
    428      *
    429      * @see #setRotation(float)
    430      */
    431     public abstract float getRotation();
    432 
    433     /**
    434      * Sets the rotation value for the display list around the X axis
    435      *
    436      * @param rotationX The rotation value of the display list, in degrees
    437      *
    438      * @see View#setRotationX(float)
    439      * @see #getRotationX()
    440      */
    441     public abstract void setRotationX(float rotationX);
    442 
    443     /**
    444      * Returns the rotation value for this display list around the X axis, in degrees.
    445      *
    446      * @see #setRotationX(float)
    447      */
    448     public abstract float getRotationX();
    449 
    450     /**
    451      * Sets the rotation value for the display list around the Y axis
    452      *
    453      * @param rotationY The rotation value of the display list, in degrees
    454      *
    455      * @see View#setRotationY(float)
    456      * @see #getRotationY()
    457      */
    458     public abstract void setRotationY(float rotationY);
    459 
    460     /**
    461      * Returns the rotation value for this display list around the Y axis, in degrees.
    462      *
    463      * @see #setRotationY(float)
    464      */
    465     public abstract float getRotationY();
    466 
    467     /**
    468      * Sets the scale value for the display list on the X axis
    469      *
    470      * @param scaleX The scale value of the display list
    471      *
    472      * @see View#setScaleX(float)
    473      * @see #getScaleX()
    474      */
    475     public abstract void setScaleX(float scaleX);
    476 
    477     /**
    478      * Returns the scale value for this display list on the X axis.
    479      *
    480      * @see #setScaleX(float)
    481      */
    482     public abstract float getScaleX();
    483 
    484     /**
    485      * Sets the scale value for the display list on the Y axis
    486      *
    487      * @param scaleY The scale value of the display list
    488      *
    489      * @see View#setScaleY(float)
    490      * @see #getScaleY()
    491      */
    492     public abstract void setScaleY(float scaleY);
    493 
    494     /**
    495      * Returns the scale value for this display list on the Y axis.
    496      *
    497      * @see #setScaleY(float)
    498      */
    499     public abstract float getScaleY();
    500 
    501     /**
    502      * Sets all of the transform-related values of the display list
    503      *
    504      * @param alpha The alpha value of the display list
    505      * @param translationX The translationX value of the display list
    506      * @param translationY The translationY value of the display list
    507      * @param rotation The rotation value of the display list
    508      * @param rotationX The rotationX value of the display list
    509      * @param rotationY The rotationY value of the display list
    510      * @param scaleX The scaleX value of the display list
    511      * @param scaleY The scaleY value of the display list
    512      *
    513      * @hide
    514      */
    515     public abstract void setTransformationInfo(float alpha, float translationX, float translationY,
    516             float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
    517 
    518     /**
    519      * Sets the pivot value for the display list on the X axis
    520      *
    521      * @param pivotX The pivot value of the display list on the X axis, in pixels
    522      *
    523      * @see View#setPivotX(float)
    524      * @see #getPivotX()
    525      */
    526     public abstract void setPivotX(float pivotX);
    527 
    528     /**
    529      * Returns the pivot value for this display list on the X axis, in pixels.
    530      *
    531      * @see #setPivotX(float)
    532      */
    533     public abstract float getPivotX();
    534 
    535     /**
    536      * Sets the pivot value for the display list on the Y axis
    537      *
    538      * @param pivotY The pivot value of the display list on the Y axis, in pixels
    539      *
    540      * @see View#setPivotY(float)
    541      * @see #getPivotY()
    542      */
    543     public abstract void setPivotY(float pivotY);
    544 
    545     /**
    546      * Returns the pivot value for this display list on the Y axis, in pixels.
    547      *
    548      * @see #setPivotY(float)
    549      */
    550     public abstract float getPivotY();
    551 
    552     /**
    553      * Sets the camera distance for the display list. Refer to
    554      * {@link View#setCameraDistance(float)} for more information on how to
    555      * use this property.
    556      *
    557      * @param distance The distance in Z of the camera of the display list
    558      *
    559      * @see View#setCameraDistance(float)
    560      * @see #getCameraDistance()
    561      */
    562     public abstract void setCameraDistance(float distance);
    563 
    564     /**
    565      * Returns the distance in Z of the camera of the display list.
    566      *
    567      * @see #setCameraDistance(float)
    568      */
    569     public abstract float getCameraDistance();
    570 
    571     /**
    572      * Sets the left position for the display list.
    573      *
    574      * @param left The left position, in pixels, of the display list
    575      *
    576      * @see View#setLeft(int)
    577      * @see #getLeft()
    578      */
    579     public abstract void setLeft(int left);
    580 
    581     /**
    582      * Returns the left position for the display list in pixels.
    583      *
    584      * @see #setLeft(int)
    585      */
    586     public abstract float getLeft();
    587 
    588     /**
    589      * Sets the top position for the display list.
    590      *
    591      * @param top The top position, in pixels, of the display list
    592      *
    593      * @see View#setTop(int)
    594      * @see #getTop()
    595      */
    596     public abstract void setTop(int top);
    597 
    598     /**
    599      * Returns the top position for the display list in pixels.
    600      *
    601      * @see #setTop(int)
    602      */
    603     public abstract float getTop();
    604 
    605     /**
    606      * Sets the right position for the display list.
    607      *
    608      * @param right The right position, in pixels, of the display list
    609      *
    610      * @see View#setRight(int)
    611      * @see #getRight()
    612      */
    613     public abstract void setRight(int right);
    614 
    615     /**
    616      * Returns the right position for the display list in pixels.
    617      *
    618      * @see #setRight(int)
    619      */
    620     public abstract float getRight();
    621 
    622     /**
    623      * Sets the bottom position for the display list.
    624      *
    625      * @param bottom The bottom position, in pixels, of the display list
    626      *
    627      * @see View#setBottom(int)
    628      * @see #getBottom()
    629      */
    630     public abstract void setBottom(int bottom);
    631 
    632     /**
    633      * Returns the bottom position for the display list in pixels.
    634      *
    635      * @see #setBottom(int)
    636      */
    637     public abstract float getBottom();
    638 
    639     /**
    640      * Sets the left and top positions for the display list
    641      *
    642      * @param left The left position of the display list, in pixels
    643      * @param top The top position of the display list, in pixels
    644      * @param right The right position of the display list, in pixels
    645      * @param bottom The bottom position of the display list, in pixels
    646      *
    647      * @see View#setLeft(int)
    648      * @see View#setTop(int)
    649      * @see View#setRight(int)
    650      * @see View#setBottom(int)
    651      */
    652     public abstract void setLeftTopRightBottom(int left, int top, int right, int bottom);
    653 
    654     /**
    655      * Offsets the left and right positions for the display list
    656      *
    657      * @param offset The amount that the left and right positions of the display
    658      *               list are offset, in pixels
    659      *
    660      * @see View#offsetLeftAndRight(int)
    661      */
    662     public abstract void offsetLeftAndRight(float offset);
    663 
    664     /**
    665      * Offsets the top and bottom values for the display list
    666      *
    667      * @param offset The amount that the top and bottom positions of the display
    668      *               list are offset, in pixels
    669      *
    670      * @see View#offsetTopAndBottom(int)
    671      */
    672     public abstract void offsetTopAndBottom(float offset);
    673 
    674     /**
    675      * Reset native resources. This is called when cleaning up the state of display lists
    676      * during destruction of hardware resources, to ensure that we do not hold onto
    677      * obsolete resources after related resources are gone.
    678      *
    679      * @hide
    680      */
    681     public abstract void reset();
    682 }
    683