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 "GrPipeline.h"
     20 #include "GrVertexBuffer.h"
     21 #include "GrXferProcessor.h"
     22 
     23 #include "batches/GrDrawBatch.h"
     24 
     25 #include "SkClipStack.h"
     26 #include "SkMatrix.h"
     27 #include "SkPath.h"
     28 #include "SkStringUtils.h"
     29 #include "SkStrokeRec.h"
     30 #include "SkTArray.h"
     31 #include "SkTLazy.h"
     32 #include "SkTypes.h"
     33 #include "SkXfermode.h"
     34 
     35 //#define ENABLE_MDB 1
     36 
     37 class GrAuditTrail;
     38 class GrBatch;
     39 class GrClip;
     40 class GrCaps;
     41 class GrPath;
     42 class GrDrawPathBatchBase;
     43 
     44 class GrDrawTarget final : public SkRefCnt {
     45 public:
     46     /** Options for GrDrawTarget behavior. */
     47     struct Options {
     48         Options () : fClipBatchToBounds(false), fDrawBatchBounds(false), fMaxBatchLookback(-1) {}
     49         bool fClipBatchToBounds;
     50         bool fDrawBatchBounds;
     51         int  fMaxBatchLookback;
     52     };
     53 
     54     GrDrawTarget(GrRenderTarget*, GrGpu*, GrResourceProvider*, GrAuditTrail*, const Options&);
     55 
     56     ~GrDrawTarget() override;
     57 
     58     void makeClosed() {
     59         // We only close drawTargets When MDB is enabled. When MDB is disabled there is only
     60         // ever one drawTarget and all calls will be funnelled into it.
     61 #ifdef ENABLE_MDB
     62         this->setFlag(kClosed_Flag);
     63 #endif
     64     }
     65     bool isClosed() const { return this->isSetFlag(kClosed_Flag); }
     66 
     67     // TODO: this entry point is only needed in the non-MDB world. Remove when
     68     // we make the switch to MDB
     69     void clearRT() { fRenderTarget = nullptr; }
     70 
     71     /*
     72      * Notify this drawTarget that it relies on the contents of 'dependedOn'
     73      */
     74     void addDependency(GrSurface* dependedOn);
     75 
     76     /*
     77      * Does this drawTarget depend on 'dependedOn'?
     78      */
     79     bool dependsOn(GrDrawTarget* dependedOn) const {
     80         return fDependencies.find(dependedOn) >= 0;
     81     }
     82 
     83     /*
     84      * Dump out the drawTarget dependency DAG
     85      */
     86     SkDEBUGCODE(void dump() const;)
     87 
     88     /**
     89      * Empties the draw buffer of any queued up draws.
     90      */
     91     void reset();
     92 
     93     /**
     94      * Together these two functions flush all queued up draws to the Gpu.
     95      */
     96     void prepareBatches(GrBatchFlushState* flushState);
     97     void drawBatches(GrBatchFlushState* flushState);
     98 
     99     /**
    100      * Gets the capabilities of the draw target.
    101      */
    102     const GrCaps* caps() const { return fGpu->caps(); }
    103 
    104     void drawBatch(const GrPipelineBuilder&, GrDrawBatch*);
    105 
    106     /**
    107      * Draws path into the stencil buffer. The fill must be either even/odd or
    108      * winding (not inverse or hairline). It will respect the HW antialias flag
    109      * on the GrPipelineBuilder (if possible in the 3D API).  Note, we will never have an inverse
    110      * fill with stencil path
    111      */
    112     void stencilPath(const GrPipelineBuilder&, const SkMatrix& viewMatrix, const GrPath*,
    113                      GrPathRendering::FillType);
    114 
    115     /**
    116      * Draws a path batch. Fill must not be a hairline. It will respect the HW antialias flag on
    117      * the GrPipelineBuilder (if possible in the 3D API). This needs to be separate from drawBatch
    118      * because we install path stencil settings late.
    119      *
    120      * TODO: Figure out a better model that allows us to roll this method into drawBatch.
    121      */
    122     void drawPathBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawPathBatchBase* batch);
    123 
    124     /**
    125      * Clear the passed in render target. Ignores the GrPipelineBuilder and clip. Clears the whole
    126      * thing if rect is nullptr, otherwise just the rect. If canIgnoreRect is set then the entire
    127      * render target can be optionally cleared.
    128      */
    129     void clear(const SkIRect* rect,
    130                GrColor color,
    131                bool canIgnoreRect,
    132                GrRenderTarget* renderTarget);
    133 
    134     /** Discards the contents render target. */
    135     void discard(GrRenderTarget*);
    136 
    137     /**
    138      * Copies a pixel rectangle from one surface to another. This call may finalize
    139      * reserved vertex/index data (as though a draw call was made). The src pixels
    140      * copied are specified by srcRect. They are copied to a rect of the same
    141      * size in dst with top left at dstPoint. If the src rect is clipped by the
    142      * src bounds then  pixel values in the dst rect corresponding to area clipped
    143      * by the src rect are not overwritten. This method is not guaranteed to succeed
    144      * depending on the type of surface, configs, etc, and the backend-specific
    145      * limitations.
    146      */
    147     bool copySurface(GrSurface* dst,
    148                      GrSurface* src,
    149                      const SkIRect& srcRect,
    150                      const SkIPoint& dstPoint);
    151 
    152     /** Provides access to internal functions to GrClipMaskManager without friending all of
    153         GrDrawTarget to CMM. */
    154     class CMMAccess {
    155     public:
    156         CMMAccess(GrDrawTarget* drawTarget) : fDrawTarget(drawTarget) {}
    157     private:
    158         void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) const {
    159             fDrawTarget->clearStencilClip(rect, insideClip, rt);
    160         }
    161 
    162         GrContext* context() const { return fDrawTarget->fContext; }
    163         GrResourceProvider* resourceProvider() const { return fDrawTarget->fResourceProvider; }
    164         GrDrawTarget* fDrawTarget;
    165         friend class GrClipMaskManager;
    166     };
    167 
    168     const CMMAccess cmmAccess() { return CMMAccess(this); }
    169 
    170     GrAuditTrail* getAuditTrail() const { return fAuditTrail; }
    171 
    172 private:
    173     friend class GrDrawingManager; // for resetFlag & TopoSortTraits
    174 
    175     enum Flags {
    176         kClosed_Flag    = 0x01,   //!< This drawTarget can't accept any more batches
    177 
    178         kWasOutput_Flag = 0x02,   //!< Flag for topological sorting
    179         kTempMark_Flag  = 0x04,   //!< Flag for topological sorting
    180     };
    181 
    182     void setFlag(uint32_t flag) {
    183         fFlags |= flag;
    184     }
    185 
    186     void resetFlag(uint32_t flag) {
    187         fFlags &= ~flag;
    188     }
    189 
    190     bool isSetFlag(uint32_t flag) const {
    191         return SkToBool(fFlags & flag);
    192     }
    193 
    194     struct TopoSortTraits {
    195         static void Output(GrDrawTarget* dt, int /* index */) {
    196             dt->setFlag(GrDrawTarget::kWasOutput_Flag);
    197         }
    198         static bool WasOutput(const GrDrawTarget* dt) {
    199             return dt->isSetFlag(GrDrawTarget::kWasOutput_Flag);
    200         }
    201         static void SetTempMark(GrDrawTarget* dt) {
    202             dt->setFlag(GrDrawTarget::kTempMark_Flag);
    203         }
    204         static void ResetTempMark(GrDrawTarget* dt) {
    205             dt->resetFlag(GrDrawTarget::kTempMark_Flag);
    206         }
    207         static bool IsTempMarked(const GrDrawTarget* dt) {
    208             return dt->isSetFlag(GrDrawTarget::kTempMark_Flag);
    209         }
    210         static int NumDependencies(const GrDrawTarget* dt) {
    211             return dt->fDependencies.count();
    212         }
    213         static GrDrawTarget* Dependency(GrDrawTarget* dt, int index) {
    214             return dt->fDependencies[index];
    215         }
    216     };
    217 
    218     void recordBatch(GrBatch*);
    219     bool installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
    220                                     const GrScissorState* scissor,
    221                                     GrDrawBatch* batch);
    222 
    223     // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
    224     // but couldn't be made. Otherwise, returns true.  This method needs to be protected because it
    225     // needs to be accessed by GLPrograms to setup a correct drawstate
    226     bool setupDstReadIfNecessary(const GrPipelineBuilder&,
    227         const GrPipelineOptimizations& optimizations,
    228         GrXferProcessor::DstTexture*,
    229         const SkRect& batchBounds);
    230 
    231     // Check to see if this set of draw commands has been sent out
    232     void getPathStencilSettingsForFilltype(GrPathRendering::FillType,
    233                                            const GrStencilAttachment*,
    234                                            GrStencilSettings*);
    235     bool setupClip(const GrPipelineBuilder&,
    236                            GrPipelineBuilder::AutoRestoreFragmentProcessorState*,
    237                            GrPipelineBuilder::AutoRestoreStencil*,
    238                            GrScissorState*,
    239                            const SkRect* devBounds);
    240 
    241     void addDependency(GrDrawTarget* dependedOn);
    242 
    243     // Used only by CMM.
    244     void clearStencilClip(const SkIRect&, bool insideClip, GrRenderTarget*);
    245 
    246     SkSTArray<256, SkAutoTUnref<GrBatch>, true> fBatches;
    247     SkAutoTDelete<GrClipMaskManager>            fClipMaskManager;
    248     // The context is only in service of the clip mask manager, remove once CMM doesn't need this.
    249     GrContext*                                  fContext;
    250     GrGpu*                                      fGpu;
    251     GrResourceProvider*                         fResourceProvider;
    252     GrAuditTrail*                               fAuditTrail;
    253 
    254     SkDEBUGCODE(int                             fDebugID;)
    255     uint32_t                                    fFlags;
    256 
    257     // 'this' drawTarget relies on the output of the drawTargets in 'fDependencies'
    258     SkTDArray<GrDrawTarget*>                    fDependencies;
    259     GrRenderTarget*                             fRenderTarget;
    260 
    261     bool                                        fDrawBatchBounds;
    262     int                                         fMaxBatchLookback;
    263 
    264     typedef SkRefCnt INHERITED;
    265 };
    266 
    267 #endif
    268