Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2010 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GrDrawTarget_DEFINED
      9 #define GrDrawTarget_DEFINED
     10 
     11 #include "GrClip.h"
     12 #include "GrClipMaskManager.h"
     13 #include "GrContext.h"
     14 #include "GrPathProcessor.h"
     15 #include "GrPrimitiveProcessor.h"
     16 #include "GrIndexBuffer.h"
     17 #include "GrPathRendering.h"
     18 #include "GrPipelineBuilder.h"
     19 #include "GrTraceMarker.h"
     20 #include "GrVertexBuffer.h"
     21 
     22 #include "SkClipStack.h"
     23 #include "SkMatrix.h"
     24 #include "SkPath.h"
     25 #include "SkStrokeRec.h"
     26 #include "SkTArray.h"
     27 #include "SkTLazy.h"
     28 #include "SkTypes.h"
     29 #include "SkXfermode.h"
     30 
     31 class GrClip;
     32 class GrDrawTargetCaps;
     33 class GrPath;
     34 class GrPathRange;
     35 class GrPipeline;
     36 
     37 class GrDrawTarget : public SkRefCnt {
     38 public:
     39     SK_DECLARE_INST_COUNT(GrDrawTarget)
     40 
     41     typedef GrPathRange::PathIndexType PathIndexType;
     42     typedef GrPathRendering::PathTransformType PathTransformType;
     43 
     44     ///////////////////////////////////////////////////////////////////////////
     45 
     46     // The context may not be fully constructed and should not be used during GrDrawTarget
     47     // construction.
     48     GrDrawTarget(GrContext* context);
     49 
     50     virtual ~GrDrawTarget() {}
     51 
     52     /**
     53      * Empties the draw buffer of any queued up draws.
     54      */
     55     void reset() { this->onReset(); }
     56 
     57     /**
     58      * This plays any queued up draws to its GrGpu target. It also resets this object (i.e. flushing
     59      * is destructive).
     60      */
     61     void flush();
     62 
     63     /**
     64      * Gets the capabilities of the draw target.
     65      */
     66     const GrDrawTargetCaps* caps() const { return fCaps.get(); }
     67 
     68     void drawBatch(GrPipelineBuilder*, GrBatch*);
     69 
     70     /**
     71      * Draws path into the stencil buffer. The fill must be either even/odd or
     72      * winding (not inverse or hairline). It will respect the HW antialias flag
     73      * on the GrPipelineBuilder (if possible in the 3D API).  Note, we will never have an inverse
     74      * fill with stencil path
     75      */
     76     void stencilPath(GrPipelineBuilder*, const GrPathProcessor*, const GrPath*,
     77                      GrPathRendering::FillType);
     78 
     79     /**
     80      * Draws a path. Fill must not be a hairline. It will respect the HW
     81      * antialias flag on the GrPipelineBuilder (if possible in the 3D API).
     82      */
     83     void drawPath(GrPipelineBuilder*, const GrPathProcessor*, const GrPath*,
     84                   GrPathRendering::FillType);
     85 
     86     /**
     87      * Draws the aggregate path from combining multiple. Note that this will not
     88      * always be equivalent to back-to-back calls to drawPath(). It will respect
     89      * the HW antialias flag on the GrPipelineBuilder (if possible in the 3D API).
     90      *
     91      * @param pathRange       Source paths to draw from
     92      * @param indices         Array of path indices to draw
     93      * @param indexType       Data type of the array elements in indexBuffer
     94      * @param transformValues Array of transforms for the individual paths
     95      * @param transformType   Type of transforms in transformBuffer
     96      * @param count           Number of paths to draw
     97      * @param fill            Fill type for drawing all the paths
     98      */
     99     void drawPaths(GrPipelineBuilder*,
    100                    const GrPathProcessor*,
    101                    const GrPathRange* pathRange,
    102                    const void* indices,
    103                    PathIndexType indexType,
    104                    const float transformValues[],
    105                    PathTransformType transformType,
    106                    int count,
    107                    GrPathRendering::FillType fill);
    108 
    109     /**
    110      * Helper function for drawing rects.
    111      *
    112      * @param rect        the rect to draw
    113      * @param localRect   optional rect that specifies local coords to map onto
    114      *                    rect. If NULL then rect serves as the local coords.
    115      * @param localMatrix Optional local matrix. The local coordinates are specified by localRect,
    116      *                    or if it is NULL by rect. This matrix applies to the coordinate implied by
    117      *                    that rectangle before it is input to GrCoordTransforms that read local
    118      *                    coordinates
    119      */
    120     void drawRect(GrPipelineBuilder* pipelineBuilder,
    121                   GrColor color,
    122                   const SkMatrix& viewMatrix,
    123                   const SkRect& rect,
    124                   const SkRect* localRect,
    125                   const SkMatrix* localMatrix);
    126 
    127     /**
    128      * Helper for drawRect when the caller doesn't need separate local rects or matrices.
    129      */
    130     void drawSimpleRect(GrPipelineBuilder* ds, GrColor color, const SkMatrix& viewM,
    131                         const SkRect& rect) {
    132         this->drawRect(ds, color, viewM, rect, NULL, NULL);
    133     }
    134     void drawSimpleRect(GrPipelineBuilder* ds, GrColor color, const SkMatrix& viewM,
    135                         const SkIRect& irect) {
    136         SkRect rect = SkRect::Make(irect);
    137         this->drawRect(ds, color, viewM, rect, NULL, NULL);
    138     }
    139 
    140 
    141     /**
    142      * Clear the passed in render target. Ignores the GrPipelineBuilder and clip. Clears the whole
    143      * thing if rect is NULL, otherwise just the rect. If canIgnoreRect is set then the entire
    144      * render target can be optionally cleared.
    145      */
    146     void clear(const SkIRect* rect,
    147                GrColor color,
    148                bool canIgnoreRect,
    149                GrRenderTarget* renderTarget);
    150 
    151     /**
    152      * Discards the contents render target.
    153      **/
    154     virtual void discard(GrRenderTarget*) = 0;
    155 
    156     /**
    157      * Called at start and end of gpu trace marking
    158      * GR_CREATE_GPU_TRACE_MARKER(marker_str, target) will automatically call these at the start
    159      * and end of a code block respectively
    160      */
    161     void addGpuTraceMarker(const GrGpuTraceMarker* marker);
    162     void removeGpuTraceMarker(const GrGpuTraceMarker* marker);
    163 
    164     /**
    165      * Takes the current active set of markers and stores them for later use. Any current marker
    166      * in the active set is removed from the active set and the targets remove function is called.
    167      * These functions do not work as a stack so you cannot call save a second time before calling
    168      * restore. Also, it is assumed that when restore is called the current active set of markers
    169      * is empty. When the stored markers are added back into the active set, the targets add marker
    170      * is called.
    171      */
    172     void saveActiveTraceMarkers();
    173     void restoreActiveTraceMarkers();
    174 
    175     /**
    176      * Copies a pixel rectangle from one surface to another. This call may finalize
    177      * reserved vertex/index data (as though a draw call was made). The src pixels
    178      * copied are specified by srcRect. They are copied to a rect of the same
    179      * size in dst with top left at dstPoint. If the src rect is clipped by the
    180      * src bounds then  pixel values in the dst rect corresponding to area clipped
    181      * by the src rect are not overwritten. This method can fail and return false
    182      * depending on the type of surface, configs, etc, and the backend-specific
    183      * limitations. If rect is clipped out entirely by the src or dst bounds then
    184      * true is returned since there is no actual copy necessary to succeed.
    185      */
    186     bool copySurface(GrSurface* dst,
    187                      GrSurface* src,
    188                      const SkIRect& srcRect,
    189                      const SkIPoint& dstPoint);
    190     /**
    191      * Function that determines whether a copySurface call would succeed without actually
    192      * performing the copy.
    193      */
    194     bool canCopySurface(const GrSurface* dst,
    195                         const GrSurface* src,
    196                         const SkIRect& srcRect,
    197                         const SkIPoint& dstPoint);
    198 
    199     /**
    200      * Release any resources that are cached but not currently in use. This
    201      * is intended to give an application some recourse when resources are low.
    202      */
    203     virtual void purgeResources() {};
    204 
    205     ///////////////////////////////////////////////////////////////////////////
    206     // Draw execution tracking (for font atlases and other resources)
    207     class DrawToken {
    208     public:
    209         DrawToken(GrDrawTarget* drawTarget, uint32_t drawID) :
    210                   fDrawTarget(drawTarget), fDrawID(drawID) {}
    211 
    212         bool isIssued() { return fDrawTarget && fDrawTarget->isIssued(fDrawID); }
    213 
    214     private:
    215         GrDrawTarget*  fDrawTarget;
    216         uint32_t       fDrawID;   // this may wrap, but we're doing direct comparison
    217                                   // so that should be okay
    218     };
    219 
    220     virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
    221 
    222     bool programUnitTest(int maxStages);
    223 
    224 protected:
    225     friend class GrCommandBuilder; // for PipelineInfo
    226     friend class GrInOrderCommandBuilder; // for PipelineInfo
    227     friend class GrReorderCommandBuilder; // for PipelineInfo
    228     friend class GrTargetCommands; // for PipelineInfo
    229 
    230     GrContext* getContext() { return fContext; }
    231     const GrContext* getContext() const { return fContext; }
    232 
    233     GrGpu* getGpu() {
    234         SkASSERT(fContext && fContext->getGpu());
    235         return fContext->getGpu();
    236     }
    237     const GrGpu* getGpu() const {
    238         SkASSERT(fContext && fContext->getGpu());
    239         return fContext->getGpu();
    240     }
    241 
    242     const GrTraceMarkerSet& getActiveTraceMarkers() { return fActiveTraceMarkers; }
    243 
    244     // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
    245     // but couldn't be made. Otherwise, returns true.  This method needs to be protected because it
    246     // needs to be accessed by GLPrograms to setup a correct drawstate
    247     bool setupDstReadIfNecessary(const GrPipelineBuilder&,
    248                                  const GrProcOptInfo& colorPOI,
    249                                  const GrProcOptInfo& coveragePOI,
    250                                  GrDeviceCoordTexture* dstCopy,
    251                                  const SkRect* drawBounds);
    252 
    253     struct PipelineInfo {
    254         PipelineInfo(GrPipelineBuilder* pipelineBuilder, GrScissorState* scissor,
    255                      const GrPrimitiveProcessor* primProc,
    256                      const SkRect* devBounds, GrDrawTarget* target);
    257 
    258         PipelineInfo(GrPipelineBuilder* pipelineBuilder, GrScissorState* scissor,
    259                      const GrBatch* batch, const SkRect* devBounds,
    260                      GrDrawTarget* target);
    261 
    262         bool willBlendWithDst(const GrPrimitiveProcessor* primProc) const {
    263             return fPipelineBuilder->willBlendWithDst(primProc);
    264         }
    265     private:
    266         friend class GrDrawTarget;
    267 
    268         bool mustSkipDraw() const { return (NULL == fPipelineBuilder); }
    269 
    270         GrPipelineBuilder*      fPipelineBuilder;
    271         GrScissorState*         fScissor;
    272         GrProcOptInfo           fColorPOI;
    273         GrProcOptInfo           fCoveragePOI;
    274         GrDeviceCoordTexture    fDstCopy;
    275     };
    276 
    277     void setupPipeline(const PipelineInfo& pipelineInfo, GrPipeline* pipeline);
    278 
    279 private:
    280     virtual void onReset() = 0;
    281 
    282     virtual void onFlush() = 0;
    283 
    284     virtual void onDrawBatch(GrBatch*, const PipelineInfo&) = 0;
    285     virtual void onStencilPath(const GrPipelineBuilder&,
    286                                const GrPathProcessor*,
    287                                const GrPath*,
    288                                const GrScissorState&,
    289                                const GrStencilSettings&) = 0;
    290     virtual void onDrawPath(const GrPathProcessor*,
    291                             const GrPath*,
    292                             const GrStencilSettings&,
    293                             const PipelineInfo&) = 0;
    294     virtual void onDrawPaths(const GrPathProcessor*,
    295                              const GrPathRange*,
    296                              const void* indices,
    297                              PathIndexType,
    298                              const float transformValues[],
    299                              PathTransformType,
    300                              int count,
    301                              const GrStencilSettings&,
    302                              const PipelineInfo&) = 0;
    303 
    304     virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
    305                          GrRenderTarget* renderTarget) = 0;
    306 
    307     /** The subclass's copy surface implementation. It should assume that any clipping has already
    308         been performed on the rect and point and that the GrGpu supports the copy. */
    309     virtual void onCopySurface(GrSurface* dst,
    310                                GrSurface* src,
    311                                const SkIRect& srcRect,
    312                                const SkIPoint& dstPoint) = 0;
    313 
    314     // Check to see if this set of draw commands has been sent out
    315     virtual bool       isIssued(uint32_t drawID) { return true; }
    316     void getPathStencilSettingsForFilltype(GrPathRendering::FillType,
    317                                            const GrStencilAttachment*,
    318                                            GrStencilSettings*);
    319     virtual GrClipMaskManager* clipMaskManager() = 0;
    320     virtual bool setupClip(GrPipelineBuilder*,
    321                            GrPipelineBuilder::AutoRestoreFragmentProcessors*,
    322                            GrPipelineBuilder::AutoRestoreStencil*,
    323                            GrScissorState*,
    324                            const SkRect* devBounds) = 0;
    325 
    326     // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget.
    327     GrContext*                                                      fContext;
    328     SkAutoTUnref<const GrDrawTargetCaps>                            fCaps;
    329     // To keep track that we always have at least as many debug marker adds as removes
    330     int                                                             fGpuTraceMarkerCount;
    331     GrTraceMarkerSet                                                fActiveTraceMarkers;
    332     GrTraceMarkerSet                                                fStoredTraceMarkers;
    333     bool                                                            fFlushing;
    334 
    335     typedef SkRefCnt INHERITED;
    336 };
    337 
    338 /*
    339  * This class is JUST for clip mask manager.  Everyone else should just use draw target above.
    340  */
    341 class GrClipTarget : public GrDrawTarget {
    342 public:
    343     GrClipTarget(GrContext* context)
    344         : INHERITED(context) {
    345         fClipMaskManager.setClipTarget(this);
    346     }
    347 
    348     /* Clip mask manager needs access to the context.
    349      * TODO we only need a very small subset of context in the CMM.
    350      */
    351     GrContext* getContext() { return INHERITED::getContext(); }
    352     const GrContext* getContext() const { return INHERITED::getContext(); }
    353 
    354     /**
    355      * Clip Mask Manager(and no one else) needs to clear private stencil bits.
    356      * ClipTarget subclass sets clip bit in the stencil buffer. The subclass
    357      * is free to clear the remaining bits to zero if masked clears are more
    358      * expensive than clearing all bits.
    359      */
    360     virtual void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* = NULL) = 0;
    361 
    362     /**
    363      * Release any resources that are cached but not currently in use. This
    364      * is intended to give an application some recourse when resources are low.
    365      */
    366     void purgeResources() override {
    367         // The clip mask manager can rebuild all its clip masks so just
    368         // get rid of them all.
    369         fClipMaskManager.purgeResources();
    370     };
    371 
    372 protected:
    373     GrClipMaskManager           fClipMaskManager;
    374 
    375 private:
    376     GrClipMaskManager* clipMaskManager() override { return &fClipMaskManager; }
    377 
    378     virtual bool setupClip(GrPipelineBuilder*,
    379                            GrPipelineBuilder::AutoRestoreFragmentProcessors*,
    380                            GrPipelineBuilder::AutoRestoreStencil*,
    381                            GrScissorState* scissorState,
    382                            const SkRect* devBounds) override;
    383 
    384     typedef GrDrawTarget INHERITED;
    385 };
    386 
    387 #endif
    388