Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2010 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef GrDrawTarget_DEFINED
     11 #define GrDrawTarget_DEFINED
     12 
     13 #include "GrClipData.h"
     14 #include "GrDrawState.h"
     15 #include "GrIndexBuffer.h"
     16 #include "SkMatrix.h"
     17 #include "GrRefCnt.h"
     18 
     19 #include "SkClipStack.h"
     20 #include "SkPath.h"
     21 #include "SkTLazy.h"
     22 #include "SkTArray.h"
     23 #include "SkXfermode.h"
     24 
     25 class GrClipData;
     26 class GrDrawTargetCaps;
     27 class GrPath;
     28 class GrVertexBuffer;
     29 class SkStrokeRec;
     30 
     31 class GrDrawTarget : public GrRefCnt {
     32 protected:
     33     class DrawInfo;
     34 
     35 public:
     36     SK_DECLARE_INST_COUNT(GrDrawTarget)
     37 
     38     ///////////////////////////////////////////////////////////////////////////
     39 
     40     // The context may not be fully constructed and should not be used during GrDrawTarget
     41     // construction.
     42     GrDrawTarget(GrContext* context);
     43     virtual ~GrDrawTarget();
     44 
     45     /**
     46      * Gets the capabilities of the draw target.
     47      */
     48     const GrDrawTargetCaps* caps() const { return fCaps.get(); }
     49 
     50     /**
     51      * Sets the current clip to the region specified by clip. All draws will be
     52      * clipped against this clip if kClip_StateBit is enabled.
     53      *
     54      * Setting the clip may (or may not) zero out the client's stencil bits.
     55      *
     56      * @param description of the clipping region
     57      */
     58     void setClip(const GrClipData* clip);
     59 
     60     /**
     61      * Gets the current clip.
     62      *
     63      * @return the clip.
     64      */
     65     const GrClipData* getClip() const;
     66 
     67     /**
     68      * Sets the draw state object for the draw target. Note that this does not
     69      * make a copy. The GrDrawTarget will take a reference to passed object.
     70      * Passing NULL will cause the GrDrawTarget to use its own internal draw
     71      * state object rather than an externally provided one.
     72      */
     73     void setDrawState(GrDrawState*  drawState);
     74 
     75     /**
     76      * Read-only access to the GrDrawTarget's current draw state.
     77      */
     78     const GrDrawState& getDrawState() const { return *fDrawState; }
     79 
     80     /**
     81      * Read-write access to the GrDrawTarget's current draw state. Note that
     82      * this doesn't ref.
     83      */
     84     GrDrawState* drawState() { return fDrawState; }
     85 
     86     /**
     87      * Color alpha and coverage are two inputs to the drawing pipeline. For some
     88      * blend modes it is safe to fold the coverage into constant or per-vertex
     89      * color alpha value. For other blend modes they must be handled separately.
     90      * Depending on features available in the underlying 3D API this may or may
     91      * not be possible.
     92      *
     93      * This function considers the current draw state and the draw target's
     94      * capabilities to determine whether coverage can be handled correctly. The
     95      * following assumptions are made:
     96      *    1. The caller intends to somehow specify coverage. This can be
     97      *       specified either by enabling a coverage stage on the GrDrawState or
     98      *       via the vertex layout.
     99      *    2. Other than enabling coverage stages or enabling coverage in the
    100      *       layout, the current configuration of the target's GrDrawState is as
    101      *       it will be at draw time.
    102      */
    103     bool canApplyCoverage() const;
    104 
    105     /**
    106      * Given the current draw state and hw support, will HW AA lines be used (if
    107      * a line primitive type is drawn)?
    108      */
    109     bool willUseHWAALines() const;
    110 
    111     /**
    112      * There are three types of "sources" of geometry (vertices and indices) for
    113      * draw calls made on the target. When performing an indexed draw, the
    114      * indices and vertices can use different source types. Once a source is
    115      * specified it can be used for multiple draws. However, the time at which
    116      * the geometry data is no longer editable depends on the source type.
    117      *
    118      * Sometimes it is necessary to perform a draw while upstack code has
    119      * already specified geometry that it isn't finished with. So there are push
    120      * and pop methods. This allows the client to push the sources, draw
    121      * something using alternate sources, and then pop to restore the original
    122      * sources.
    123      *
    124      * Aside from pushes and pops, a source remains valid until another source
    125      * is set or resetVertexSource / resetIndexSource is called. Drawing from
    126      * a reset source is an error.
    127      *
    128      * The three types of sources are:
    129      *
    130      * 1. A cpu array (set*SourceToArray). This is useful when the caller
    131      *    already provided vertex data in a format compatible with a
    132      *    GrVertexLayout. The data in the array is consumed at the time that
    133      *    set*SourceToArray is called and subsequent edits to the array will not
    134      *    be reflected in draws.
    135      *
    136      * 2. Reserve. This is most useful when the caller has data it must
    137      *    transform before drawing and is not long-lived. The caller requests
    138      *    that the draw target make room for some amount of vertex and/or index
    139      *    data. The target provides ptrs to hold the vertex and/or index data.
    140      *
    141      *    The data is writable up until the next drawIndexed, drawNonIndexed,
    142      *    drawIndexedInstances, drawRect, copySurface, or pushGeometrySource. At
    143      *    this point the data is frozen and the ptrs are no longer valid.
    144      *
    145      *    Where the space is allocated and how it is uploaded to the GPU is
    146      *    subclass-dependent.
    147      *
    148      * 3. Vertex and Index Buffers. This is most useful for geometry that will
    149      *    is long-lived. When the data in the buffer is consumed depends on the
    150      *    GrDrawTarget subclass. For deferred subclasses the caller has to
    151      *    guarantee that the data is still available in the buffers at playback.
    152      *    (TODO: Make this more automatic as we have done for read/write pixels)
    153      *
    154      * The size of each vertex is determined by querying the current GrDrawState.
    155      */
    156 
    157     /**
    158      * Reserves space for vertices and/or indices. Zero can be specifed as
    159      * either the vertex or index count if the caller desires to only reserve
    160      * space for only indices or only vertices. If zero is specifed for
    161      * vertexCount then the vertex source will be unmodified and likewise for
    162      * indexCount.
    163      *
    164      * If the function returns true then the reserve suceeded and the vertices
    165      * and indices pointers will point to the space created.
    166      *
    167      * If the target cannot make space for the request then this function will
    168      * return false. If vertexCount was non-zero then upon failure the vertex
    169      * source is reset and likewise for indexCount.
    170      *
    171      * The pointers to the space allocated for vertices and indices remain valid
    172      * until a drawIndexed, drawNonIndexed, drawIndexedInstances, drawRect,
    173      * copySurface, or push/popGeomtrySource is called. At that point logically a
    174      * snapshot of the data is made and the pointers are invalid.
    175      *
    176      * @param vertexCount  the number of vertices to reserve space for. Can be
    177      *                     0. Vertex size is queried from the current GrDrawState.
    178      * @param indexCount   the number of indices to reserve space for. Can be 0.
    179      * @param vertices     will point to reserved vertex space if vertexCount is
    180      *                     non-zero. Illegal to pass NULL if vertexCount > 0.
    181      * @param indices      will point to reserved index space if indexCount is
    182      *                     non-zero. Illegal to pass NULL if indexCount > 0.
    183      */
    184      bool reserveVertexAndIndexSpace(int vertexCount,
    185                                      int indexCount,
    186                                      void** vertices,
    187                                      void** indices);
    188 
    189     /**
    190      * Provides hints to caller about the number of vertices and indices
    191      * that can be allocated cheaply. This can be useful if caller is reserving
    192      * space but doesn't know exactly how much geometry is needed.
    193      *
    194      * Also may hint whether the draw target should be flushed first. This is
    195      * useful for deferred targets.
    196      *
    197      * @param vertexCount  in: hint about how many vertices the caller would
    198      *                     like to allocate. Vertex size is queried from the
    199      *                     current GrDrawState.
    200      *                     out: a hint about the number of vertices that can be
    201      *                     allocated cheaply. Negative means no hint.
    202      *                     Ignored if NULL.
    203      * @param indexCount   in: hint about how many indices the caller would
    204      *                     like to allocate.
    205      *                     out: a hint about the number of indices that can be
    206      *                     allocated cheaply. Negative means no hint.
    207      *                     Ignored if NULL.
    208      *
    209      * @return  true if target should be flushed based on the input values.
    210      */
    211     virtual bool geometryHints(int* vertexCount,
    212                                int* indexCount) const;
    213 
    214     /**
    215      * Sets source of vertex data for the next draw. Array must contain
    216      * the vertex data when this is called.
    217      *
    218      * @param vertexArray   cpu array containing vertex data.
    219      * @param vertexCount   the number of vertices in the array. Vertex size is
    220      *                      queried from the current GrDrawState.
    221      */
    222     void setVertexSourceToArray(const void* vertexArray, int vertexCount);
    223 
    224     /**
    225      * Sets source of index data for the next indexed draw. Array must contain
    226      * the indices when this is called.
    227      *
    228      * @param indexArray    cpu array containing index data.
    229      * @param indexCount    the number of indices in the array.
    230      */
    231     void setIndexSourceToArray(const void* indexArray, int indexCount);
    232 
    233     /**
    234      * Sets source of vertex data for the next draw. Data does not have to be
    235      * in the buffer until drawIndexed, drawNonIndexed, or drawIndexedInstances.
    236      *
    237      * @param buffer        vertex buffer containing vertex data. Must be
    238      *                      unlocked before draw call. Vertex size is queried
    239      *                      from current GrDrawState.
    240      */
    241     void setVertexSourceToBuffer(const GrVertexBuffer* buffer);
    242 
    243     /**
    244      * Sets source of index data for the next indexed draw. Data does not have
    245      * to be in the buffer until drawIndexed.
    246      *
    247      * @param buffer index buffer containing indices. Must be unlocked
    248      *               before indexed draw call.
    249      */
    250     void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
    251 
    252     /**
    253      * Resets vertex source. Drawing from reset vertices is illegal. Set vertex
    254      * source to reserved, array, or buffer before next draw. May be able to free
    255      * up temporary storage allocated by setVertexSourceToArray or
    256      * reserveVertexSpace.
    257      */
    258     void resetVertexSource();
    259 
    260     /**
    261      * Resets index source. Indexed Drawing from reset indices is illegal. Set
    262      * index source to reserved, array, or buffer before next indexed draw. May
    263      * be able to free up temporary storage allocated by setIndexSourceToArray
    264      * or reserveIndexSpace.
    265      */
    266     void resetIndexSource();
    267 
    268     /**
    269      * Query to find out if the vertex or index source is reserved.
    270      */
    271     bool hasReservedVerticesOrIndices() const {
    272         return kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc ||
    273         kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
    274     }
    275 
    276     /**
    277      * Pushes and resets the vertex/index sources. Any reserved vertex / index
    278      * data is finalized (i.e. cannot be updated after the matching pop but can
    279      * be drawn from). Must be balanced by a pop.
    280      */
    281     void pushGeometrySource();
    282 
    283     /**
    284      * Pops the vertex / index sources from the matching push.
    285      */
    286     void popGeometrySource();
    287 
    288     /**
    289      * Draws indexed geometry using the current state and current vertex / index
    290      * sources.
    291      *
    292      * @param type         The type of primitives to draw.
    293      * @param startVertex  the vertex in the vertex array/buffer corresponding
    294      *                     to index 0
    295      * @param startIndex   first index to read from index src.
    296      * @param vertexCount  one greater than the max index.
    297      * @param indexCount   the number of index elements to read. The index count
    298      *                     is effectively trimmed to the last completely
    299      *                     specified primitive.
    300      * @param devBounds    optional bounds hint. This is a promise from the caller,
    301      *                     not a request for clipping.
    302      */
    303     void drawIndexed(GrPrimitiveType type,
    304                      int startVertex,
    305                      int startIndex,
    306                      int vertexCount,
    307                      int indexCount,
    308                      const SkRect* devBounds = NULL);
    309 
    310     /**
    311      * Draws non-indexed geometry using the current state and current vertex
    312      * sources.
    313      *
    314      * @param type         The type of primitives to draw.
    315      * @param startVertex  the vertex in the vertex array/buffer corresponding
    316      *                     to index 0
    317      * @param vertexCount  one greater than the max index.
    318      * @param devBounds    optional bounds hint. This is a promise from the caller,
    319      *                     not a request for clipping.
    320      */
    321     void drawNonIndexed(GrPrimitiveType type,
    322                         int startVertex,
    323                         int vertexCount,
    324                         const SkRect* devBounds = NULL);
    325 
    326     /**
    327      * Draws path into the stencil buffer. The fill must be either even/odd or
    328      * winding (not inverse or hairline). It will respect the HW antialias flag
    329      * on the draw state (if possible in the 3D API).
    330      */
    331     void stencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill);
    332 
    333     /**
    334      * Helper function for drawing rects. It performs a geometry src push and pop
    335      * and thus will finalize any reserved geometry.
    336      *
    337      * @param rect        the rect to draw
    338      * @param matrix      optional matrix applied to rect (before viewMatrix)
    339      * @param localRect   optional rect that specifies local coords to map onto
    340      *                    rect. If NULL then rect serves as the local coords.
    341      * @param localMatrix optional matrix applied to localRect. If
    342      *                    srcRect is non-NULL and srcMatrix is non-NULL
    343      *                    then srcRect will be transformed by srcMatrix.
    344      *                    srcMatrix can be NULL when no srcMatrix is desired.
    345      */
    346     void drawRect(const SkRect& rect,
    347                   const SkMatrix* matrix,
    348                   const SkRect* localRect,
    349                   const SkMatrix* localMatrix) {
    350         AutoGeometryPush agp(this);
    351         this->onDrawRect(rect, matrix, localRect, localMatrix);
    352     }
    353 
    354     /**
    355      * Helper for drawRect when the caller doesn't need separate local rects or matrices.
    356      */
    357     void drawSimpleRect(const SkRect& rect, const SkMatrix* matrix = NULL) {
    358         this->drawRect(rect, matrix, NULL, NULL);
    359     }
    360     void drawSimpleRect(const SkIRect& irect, const SkMatrix* matrix = NULL) {
    361         SkRect rect = SkRect::MakeFromIRect(irect);
    362         this->drawRect(rect, matrix, NULL, NULL);
    363     }
    364 
    365     /**
    366      * This call is used to draw multiple instances of some geometry with a
    367      * given number of vertices (V) and indices (I) per-instance. The indices in
    368      * the index source must have the form i[k+I] == i[k] + V. Also, all indices
    369      * i[kI] ... i[(k+1)I-1] must be elements of the range kV ... (k+1)V-1. As a
    370      * concrete example, the following index buffer for drawing a series of
    371      * quads each as two triangles each satisfies these conditions with V=4 and
    372      * I=6:
    373      *      (0,1,2,0,2,3, 4,5,6,4,6,7, 8,9,10,8,10,11, ...)
    374      *
    375      * The call assumes that the pattern of indices fills the entire index
    376      * source. The size of the index buffer limits the number of instances that
    377      * can be drawn by the GPU in a single draw. However, the caller may specify
    378      * any (positive) number for instanceCount and if necessary multiple GPU
    379      * draws will be issued. Moreover, when drawIndexedInstances is called
    380      * multiple times it may be possible for GrDrawTarget to group them into a
    381      * single GPU draw.
    382      *
    383      * @param type          the type of primitives to draw
    384      * @param instanceCount the number of instances to draw. Each instance
    385      *                      consists of verticesPerInstance vertices indexed by
    386      *                      indicesPerInstance indices drawn as the primitive
    387      *                      type specified by type.
    388      * @param verticesPerInstance   The number of vertices in each instance (V
    389      *                              in the above description).
    390      * @param indicesPerInstance    The number of indices in each instance (I
    391      *                              in the above description).
    392      * @param devBounds    optional bounds hint. This is a promise from the caller,
    393      *                     not a request for clipping.
    394      */
    395     void drawIndexedInstances(GrPrimitiveType type,
    396                               int instanceCount,
    397                               int verticesPerInstance,
    398                               int indicesPerInstance,
    399                               const SkRect* devBounds = NULL);
    400 
    401     /**
    402      * Clear the current render target if one isn't passed in. Ignores the
    403      * clip and all other draw state (blend mode, stages, etc). Clears the
    404      * whole thing if rect is NULL, otherwise just the rect.
    405      */
    406     virtual void clear(const SkIRect* rect,
    407                        GrColor color,
    408                        GrRenderTarget* renderTarget = NULL) = 0;
    409 
    410     /**
    411      * Copies a pixel rectangle from one surface to another. This call may finalize
    412      * reserved vertex/index data (as though a draw call was made). The src pixels
    413      * copied are specified by srcRect. They are copied to a rect of the same
    414      * size in dst with top left at dstPoint. If the src rect is clipped by the
    415      * src bounds then  pixel values in the dst rect corresponding to area clipped
    416      * by the src rect are not overwritten. This method can fail and return false
    417      * depending on the type of surface, configs, etc, and the backend-specific
    418      * limitations. If rect is clipped out entirely by the src or dst bounds then
    419      * true is returned since there is no actual copy necessary to succeed.
    420      */
    421     bool copySurface(GrSurface* dst,
    422                      GrSurface* src,
    423                      const SkIRect& srcRect,
    424                      const SkIPoint& dstPoint);
    425     /**
    426      * Function that determines whether a copySurface call would succeed without
    427      * performing the copy.
    428      */
    429     bool canCopySurface(GrSurface* dst,
    430                         GrSurface* src,
    431                         const SkIRect& srcRect,
    432                         const SkIPoint& dstPoint);
    433 
    434     /**
    435      * This is can be called before allocating a texture to be a dst for copySurface. It will
    436      * populate the origin, config, and flags fields of the desc such that copySurface is more
    437      * likely to succeed and be efficient.
    438      */
    439     virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc);
    440 
    441 
    442     /**
    443      * Release any resources that are cached but not currently in use. This
    444      * is intended to give an application some recourse when resources are low.
    445      */
    446     virtual void purgeResources() {};
    447 
    448     /**
    449      * For subclass internal use to invoke a call to onDraw(). See DrawInfo below.
    450      */
    451     void executeDraw(const DrawInfo& info) { this->onDraw(info); }
    452 
    453     ////////////////////////////////////////////////////////////////////////////
    454 
    455     /**
    456      * See AutoStateRestore below.
    457      */
    458     enum ASRInit {
    459         kPreserve_ASRInit,
    460         kReset_ASRInit
    461     };
    462 
    463     /**
    464      * Saves off the current state and restores it in the destructor. It will
    465      * install a new GrDrawState object on the target (setDrawState) and restore
    466      * the previous one in the destructor. The caller should call drawState() to
    467      * get the new draw state after the ASR is installed.
    468      *
    469      * GrDrawState* state = target->drawState();
    470      * AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit).
    471      * state->setRenderTarget(rt); // state refers to the GrDrawState set on
    472      *                             // target before asr was initialized.
    473      *                             // Therefore, rt is set on the GrDrawState
    474      *                             // that will be restored after asr's
    475      *                             // destructor rather than target's current
    476      *                             // GrDrawState.
    477      */
    478     class AutoStateRestore : ::GrNoncopyable {
    479     public:
    480         /**
    481          * Default ASR will have no effect unless set() is subsequently called.
    482          */
    483         AutoStateRestore();
    484 
    485         /**
    486          * Saves the state on target. The state will be restored when the ASR
    487          * is destroyed. If this constructor is used do not call set().
    488          *
    489          * @param init  Should the newly installed GrDrawState be a copy of the
    490          *              previous state or a default-initialized GrDrawState.
    491          * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's
    492          *                   matrix will be preconcat'ed with the param. All stages will be
    493                              updated to compensate for the matrix change. If init == kReset
    494                              then the draw state's matrix will be this matrix.
    495          */
    496         AutoStateRestore(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL);
    497 
    498         ~AutoStateRestore();
    499 
    500         /**
    501          * Saves the state on target. The state will be restored when the ASR
    502          * is destroyed. This should only be called once per ASR object and only
    503          * when the default constructor was used. For nested saves use multiple
    504          * ASR objects.
    505          *
    506          * @param init  Should the newly installed GrDrawState be a copy of the
    507          *              previous state or a default-initialized GrDrawState.
    508          * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's
    509          *                   matrix will be preconcat'ed with the param. All stages will be
    510                              updated to compensate for the matrix change. If init == kReset
    511                              then the draw state's matrix will be this matrix.
    512          */
    513         void set(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL);
    514 
    515         /**
    516          * Like set() but makes the view matrix identity. When init is kReset it is as though
    517          * NULL was passed to set's viewMatrix param. When init is kPreserve it is as though
    518          * the inverse view matrix was passed. If kPreserve is passed and the draw state's matrix
    519          * is not invertible then this may fail.
    520          */
    521         bool setIdentity(GrDrawTarget* target, ASRInit init);
    522 
    523     private:
    524         GrDrawTarget*                       fDrawTarget;
    525         SkTLazy<GrDrawState>                fTempState;
    526         GrDrawState*                        fSavedState;
    527     };
    528 
    529     ////////////////////////////////////////////////////////////////////////////
    530 
    531     class AutoReleaseGeometry : ::GrNoncopyable {
    532     public:
    533         AutoReleaseGeometry(GrDrawTarget*  target,
    534                             int            vertexCount,
    535                             int            indexCount);
    536         AutoReleaseGeometry();
    537         ~AutoReleaseGeometry();
    538         bool set(GrDrawTarget*  target,
    539                  int            vertexCount,
    540                  int            indexCount);
    541         bool succeeded() const { return NULL != fTarget; }
    542         void* vertices() const { GrAssert(this->succeeded()); return fVertices; }
    543         void* indices() const { GrAssert(this->succeeded()); return fIndices; }
    544         GrPoint* positions() const {
    545             return static_cast<GrPoint*>(this->vertices());
    546         }
    547 
    548     private:
    549         void reset();
    550 
    551         GrDrawTarget* fTarget;
    552         void*         fVertices;
    553         void*         fIndices;
    554     };
    555 
    556     ////////////////////////////////////////////////////////////////////////////
    557 
    558     class AutoClipRestore : ::GrNoncopyable {
    559     public:
    560         AutoClipRestore(GrDrawTarget* target) {
    561             fTarget = target;
    562             fClip = fTarget->getClip();
    563         }
    564 
    565         AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip);
    566 
    567         ~AutoClipRestore() {
    568             fTarget->setClip(fClip);
    569         }
    570     private:
    571         GrDrawTarget*           fTarget;
    572         const GrClipData*       fClip;
    573         SkTLazy<SkClipStack>    fStack;
    574         GrClipData              fReplacementClip;
    575     };
    576 
    577     ////////////////////////////////////////////////////////////////////////////
    578 
    579     /**
    580      * Saves the geometry src state at construction and restores in the destructor. It also saves
    581      * and then restores the vertex attrib state.
    582      */
    583     class AutoGeometryPush : ::GrNoncopyable {
    584     public:
    585         AutoGeometryPush(GrDrawTarget* target)
    586             : fAttribRestore(target->drawState()) {
    587             GrAssert(NULL != target);
    588             fTarget = target;
    589             target->pushGeometrySource();
    590         }
    591 
    592         ~AutoGeometryPush() { fTarget->popGeometrySource(); }
    593 
    594     private:
    595         GrDrawTarget*                           fTarget;
    596         GrDrawState::AutoVertexAttribRestore    fAttribRestore;
    597     };
    598 
    599     /**
    600      * Combination of AutoGeometryPush and AutoStateRestore. The vertex attribs will be in default
    601      * state regardless of ASRInit value.
    602      */
    603     class AutoGeometryAndStatePush : ::GrNoncopyable {
    604     public:
    605         AutoGeometryAndStatePush(GrDrawTarget* target,
    606                                  ASRInit init,
    607                                  const SkMatrix* viewMatrix = NULL)
    608             : fState(target, init, viewMatrix) {
    609             GrAssert(NULL != target);
    610             fTarget = target;
    611             target->pushGeometrySource();
    612             if (kPreserve_ASRInit == init) {
    613                 target->drawState()->setDefaultVertexAttribs();
    614             }
    615         }
    616 
    617         ~AutoGeometryAndStatePush() { fTarget->popGeometrySource(); }
    618 
    619     private:
    620         AutoStateRestore fState;
    621         GrDrawTarget*    fTarget;
    622     };
    623 
    624 protected:
    625 
    626     enum GeometrySrcType {
    627         kNone_GeometrySrcType,     //<! src has not been specified
    628         kReserved_GeometrySrcType, //<! src was set using reserve*Space
    629         kArray_GeometrySrcType,    //<! src was set using set*SourceToArray
    630         kBuffer_GeometrySrcType    //<! src was set using set*SourceToBuffer
    631     };
    632 
    633     struct GeometrySrcState {
    634         GeometrySrcType         fVertexSrc;
    635         union {
    636             // valid if src type is buffer
    637             const GrVertexBuffer*   fVertexBuffer;
    638             // valid if src type is reserved or array
    639             int                     fVertexCount;
    640         };
    641 
    642         GeometrySrcType         fIndexSrc;
    643         union {
    644             // valid if src type is buffer
    645             const GrIndexBuffer*    fIndexBuffer;
    646             // valid if src type is reserved or array
    647             int                     fIndexCount;
    648         };
    649 
    650         size_t                  fVertexSize;
    651     };
    652 
    653     int indexCountInCurrentSource() const {
    654         const GeometrySrcState& src = this->getGeomSrc();
    655         switch (src.fIndexSrc) {
    656             case kNone_GeometrySrcType:
    657                 return 0;
    658             case kReserved_GeometrySrcType:
    659             case kArray_GeometrySrcType:
    660                 return src.fIndexCount;
    661             case kBuffer_GeometrySrcType:
    662                 return src.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
    663             default:
    664                 GrCrash("Unexpected Index Source.");
    665                 return 0;
    666         }
    667     }
    668 
    669     // This method is called by copySurface  The srcRect is guaranteed to be entirely within the
    670     // src bounds. Likewise, the dst rect implied by dstPoint and srcRect's width and height falls
    671     // entirely within the dst. The default implementation will draw a rect from the src to the
    672     // dst if the src is a texture and the dst is a render target and fail otherwise.
    673     virtual bool onCopySurface(GrSurface* dst,
    674                                GrSurface* src,
    675                                const SkIRect& srcRect,
    676                                const SkIPoint& dstPoint);
    677 
    678     // Called to determine whether an onCopySurface call would succeed or not. This is useful for
    679     // proxy subclasses to test whether the copy would succeed without executing it yet. Derived
    680     // classes must keep this consistent with their implementation of onCopySurface(). The inputs
    681     // are the same as onCopySurface(), i.e. srcRect and dstPoint are clipped to be inside the src
    682     // and dst bounds.
    683     virtual bool onCanCopySurface(GrSurface* dst,
    684                                   GrSurface* src,
    685                                   const SkIRect& srcRect,
    686                                   const SkIPoint& dstPoint);
    687 
    688     GrContext* getContext() { return fContext; }
    689     const GrContext* getContext() const { return fContext; }
    690 
    691     // A subclass may override this function if it wishes to be notified when the clip is changed.
    692     // The override should call INHERITED::clipWillBeSet().
    693     virtual void clipWillBeSet(const GrClipData* clipData);
    694 
    695     // subclasses must call this in their destructors to ensure all vertex
    696     // and index sources have been released (including those held by
    697     // pushGeometrySource())
    698     void releaseGeometry();
    699 
    700     // accessors for derived classes
    701     const GeometrySrcState& getGeomSrc() const { return fGeoSrcStateStack.back(); }
    702     // it is preferable to call this rather than getGeomSrc()->fVertexSize because of the assert.
    703     size_t getVertexSize() const {
    704         // the vertex layout is only valid if a vertex source has been specified.
    705         GrAssert(this->getGeomSrc().fVertexSrc != kNone_GeometrySrcType);
    706         return this->getGeomSrc().fVertexSize;
    707     }
    708 
    709     // Subclass must initialize this in its constructor.
    710     SkAutoTUnref<const GrDrawTargetCaps> fCaps;
    711 
    712     /**
    713      * Used to communicate draws to subclass's onDraw function.
    714      */
    715     class DrawInfo {
    716     public:
    717         DrawInfo(const DrawInfo& di) { (*this) = di; }
    718         DrawInfo& operator =(const DrawInfo& di);
    719 
    720         GrPrimitiveType primitiveType() const { return fPrimitiveType; }
    721         int startVertex() const { return fStartVertex; }
    722         int startIndex() const { return fStartIndex; }
    723         int vertexCount() const { return fVertexCount; }
    724         int indexCount() const { return fIndexCount; }
    725         int verticesPerInstance() const { return fVerticesPerInstance; }
    726         int indicesPerInstance() const { return fIndicesPerInstance; }
    727         int instanceCount() const { return fInstanceCount; }
    728 
    729         bool isIndexed() const { return fIndexCount > 0; }
    730 #if GR_DEBUG
    731         bool isInstanced() const; // this version is longer because of asserts
    732 #else
    733         bool isInstanced() const { return fInstanceCount > 0; }
    734 #endif
    735 
    736         // adds or remove instances
    737         void adjustInstanceCount(int instanceOffset);
    738         // shifts the start vertex
    739         void adjustStartVertex(int vertexOffset);
    740         // shifts the start index
    741         void adjustStartIndex(int indexOffset);
    742 
    743         void setDevBounds(const SkRect& bounds) {
    744             fDevBoundsStorage = bounds;
    745             fDevBounds = &fDevBoundsStorage;
    746         }
    747         const SkRect* getDevBounds() const { return fDevBounds; }
    748 
    749         bool getDevIBounds(SkIRect* bounds) const {
    750             if (NULL != fDevBounds) {
    751                 fDevBounds->roundOut(bounds);
    752                 return true;
    753             } else {
    754                 return false;
    755             }
    756         }
    757 
    758         // NULL if no copy of the dst is needed for the draw.
    759         const GrDeviceCoordTexture* getDstCopy() const {
    760             if (NULL != fDstCopy.texture()) {
    761                 return &fDstCopy;
    762             } else {
    763                 return NULL;
    764             }
    765         }
    766 
    767     private:
    768         DrawInfo() { fDevBounds = NULL; }
    769 
    770         friend class GrDrawTarget;
    771 
    772         GrPrimitiveType         fPrimitiveType;
    773 
    774         int                     fStartVertex;
    775         int                     fStartIndex;
    776         int                     fVertexCount;
    777         int                     fIndexCount;
    778 
    779         int                     fInstanceCount;
    780         int                     fVerticesPerInstance;
    781         int                     fIndicesPerInstance;
    782 
    783         SkRect                  fDevBoundsStorage;
    784         SkRect*                 fDevBounds;
    785 
    786         GrDeviceCoordTexture    fDstCopy;
    787     };
    788 
    789 private:
    790     // A subclass can optionally overload this function to be notified before
    791     // vertex and index space is reserved.
    792     virtual void willReserveVertexAndIndexSpace(int vertexCount, int indexCount) {}
    793 
    794     // implemented by subclass to allocate space for reserved geom
    795     virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) = 0;
    796     virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0;
    797     // implemented by subclass to handle release of reserved geom space
    798     virtual void releaseReservedVertexSpace() = 0;
    799     virtual void releaseReservedIndexSpace() = 0;
    800     // subclass must consume array contents when set
    801     virtual void onSetVertexSourceToArray(const void* vertexArray, int vertexCount) = 0;
    802     virtual void onSetIndexSourceToArray(const void* indexArray, int indexCount) = 0;
    803     // subclass is notified that geom source will be set away from an array
    804     virtual void releaseVertexArray() = 0;
    805     virtual void releaseIndexArray() = 0;
    806     // subclass overrides to be notified just before geo src state is pushed/popped.
    807     virtual void geometrySourceWillPush() = 0;
    808     virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
    809     // subclass called to perform drawing
    810     virtual void onDraw(const DrawInfo&) = 0;
    811     // Implementation of drawRect. The geometry src and vertex attribs will already
    812     // be saved before this is called and restored afterwards. A subclass may override
    813     // this to perform more optimal rect rendering. Its draws should be funneled through
    814     // one of the public GrDrawTarget draw methods (e.g. drawNonIndexed,
    815     // drawIndexedInstances, ...). The base class draws a two triangle fan using
    816     // drawNonIndexed from reserved vertex space.
    817     virtual void onDrawRect(const SkRect& rect,
    818                             const SkMatrix* matrix,
    819                             const SkRect* localRect,
    820                             const SkMatrix* localMatrix);
    821     virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill) = 0;
    822 
    823     // helpers for reserving vertex and index space.
    824     bool reserveVertexSpace(size_t vertexSize,
    825                             int vertexCount,
    826                             void** vertices);
    827     bool reserveIndexSpace(int indexCount, void** indices);
    828 
    829     // called by drawIndexed and drawNonIndexed. Use a negative indexCount to
    830     // indicate non-indexed drawing.
    831     bool checkDraw(GrPrimitiveType type, int startVertex,
    832                    int startIndex, int vertexCount,
    833                    int indexCount) const;
    834     // called when setting a new vert/idx source to unref prev vb/ib
    835     void releasePreviousVertexSource();
    836     void releasePreviousIndexSource();
    837 
    838     // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
    839     // but couldn't be made. Otherwise, returns true.
    840     bool setupDstReadIfNecessary(DrawInfo* info);
    841 
    842     enum {
    843         kPreallocGeoSrcStateStackCnt = 4,
    844     };
    845     SkSTArray<kPreallocGeoSrcStateStackCnt, GeometrySrcState, true> fGeoSrcStateStack;
    846     const GrClipData*                                               fClip;
    847     GrDrawState*                                                    fDrawState;
    848     GrDrawState                                                     fDefaultDrawState;
    849     // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget.
    850     GrContext*                                                      fContext;
    851 
    852     typedef GrRefCnt INHERITED;
    853 };
    854 
    855 #endif
    856