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 {
OptionsOptions48         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 
makeClosed()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     }
isClosed()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
clearRT()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      */
dependsOn(GrDrawTarget * dependedOn)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      */
caps()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:
CMMAccess(GrDrawTarget * drawTarget)156         CMMAccess(GrDrawTarget* drawTarget) : fDrawTarget(drawTarget) {}
157     private:
clearStencilClip(const SkIRect & rect,bool insideClip,GrRenderTarget * rt)158         void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) const {
159             fDrawTarget->clearStencilClip(rect, insideClip, rt);
160         }
161 
context()162         GrContext* context() const { return fDrawTarget->fContext; }
resourceProvider()163         GrResourceProvider* resourceProvider() const { return fDrawTarget->fResourceProvider; }
164         GrDrawTarget* fDrawTarget;
165         friend class GrClipMaskManager;
166     };
167 
cmmAccess()168     const CMMAccess cmmAccess() { return CMMAccess(this); }
169 
getAuditTrail()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 
setFlag(uint32_t flag)182     void setFlag(uint32_t flag) {
183         fFlags |= flag;
184     }
185 
resetFlag(uint32_t flag)186     void resetFlag(uint32_t flag) {
187         fFlags &= ~flag;
188     }
189 
isSetFlag(uint32_t flag)190     bool isSetFlag(uint32_t flag) const {
191         return SkToBool(fFlags & flag);
192     }
193 
194     struct TopoSortTraits {
OutputTopoSortTraits195         static void Output(GrDrawTarget* dt, int /* index */) {
196             dt->setFlag(GrDrawTarget::kWasOutput_Flag);
197         }
WasOutputTopoSortTraits198         static bool WasOutput(const GrDrawTarget* dt) {
199             return dt->isSetFlag(GrDrawTarget::kWasOutput_Flag);
200         }
SetTempMarkTopoSortTraits201         static void SetTempMark(GrDrawTarget* dt) {
202             dt->setFlag(GrDrawTarget::kTempMark_Flag);
203         }
ResetTempMarkTopoSortTraits204         static void ResetTempMark(GrDrawTarget* dt) {
205             dt->resetFlag(GrDrawTarget::kTempMark_Flag);
206         }
IsTempMarkedTopoSortTraits207         static bool IsTempMarked(const GrDrawTarget* dt) {
208             return dt->isSetFlag(GrDrawTarget::kTempMark_Flag);
209         }
NumDependenciesTopoSortTraits210         static int NumDependencies(const GrDrawTarget* dt) {
211             return dt->fDependencies.count();
212         }
DependencyTopoSortTraits213         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