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 "GrContext.h"
13 #include "GrPathProcessor.h"
14 #include "GrPrimitiveProcessor.h"
15 #include "GrPathRendering.h"
16 #include "GrXferProcessor.h"
17 
18 #include "batches/GrDrawBatch.h"
19 
20 #include "SkClipStack.h"
21 #include "SkMatrix.h"
22 #include "SkPath.h"
23 #include "SkStringUtils.h"
24 #include "SkStrokeRec.h"
25 #include "SkTArray.h"
26 #include "SkTLazy.h"
27 #include "SkTypes.h"
28 #include "SkXfermode.h"
29 
30 //#define ENABLE_MDB 1
31 
32 class GrAuditTrail;
33 class GrBatch;
34 class GrClearBatch;
35 class GrClip;
36 class GrCaps;
37 class GrPath;
38 class GrDrawPathBatchBase;
39 class GrPipelineBuilder;
40 
41 class GrDrawTarget final : public SkRefCnt {
42 public:
43     /** Options for GrDrawTarget behavior. */
44     struct Options {
OptionsOptions45         Options ()
46             : fClipBatchToBounds(false)
47             , fDrawBatchBounds(false)
48             , fMaxBatchLookback(-1)
49             , fMaxBatchLookahead(-1) {}
50         bool fClipBatchToBounds;
51         bool fDrawBatchBounds;
52         int  fMaxBatchLookback;
53         int  fMaxBatchLookahead;
54     };
55 
56     GrDrawTarget(GrRenderTarget*, GrGpu*, GrResourceProvider*, GrAuditTrail*, const Options&);
57 
58     ~GrDrawTarget() override;
59 
makeClosed()60     void makeClosed() {
61         fLastFullClearBatch = nullptr;
62         // We only close drawTargets When MDB is enabled. When MDB is disabled there is only
63         // ever one drawTarget and all calls will be funnelled into it.
64 #ifdef ENABLE_MDB
65         this->setFlag(kClosed_Flag);
66 #endif
67         this->forwardCombine();
68     }
69 
isClosed()70     bool isClosed() const { return this->isSetFlag(kClosed_Flag); }
71 
72     // TODO: this entry point is only needed in the non-MDB world. Remove when
73     // we make the switch to MDB
clearRT()74     void clearRT() { fRenderTarget = nullptr; }
75 
76     /*
77      * Notify this drawTarget that it relies on the contents of 'dependedOn'
78      */
79     void addDependency(GrSurface* dependedOn);
80 
81     /*
82      * Does this drawTarget depend on 'dependedOn'?
83      */
dependsOn(GrDrawTarget * dependedOn)84     bool dependsOn(GrDrawTarget* dependedOn) const {
85         return fDependencies.find(dependedOn) >= 0;
86     }
87 
88     /*
89      * Dump out the drawTarget dependency DAG
90      */
91     SkDEBUGCODE(void dump() const;)
92 
93     /**
94      * Empties the draw buffer of any queued up draws.
95      */
96     void reset();
97 
98     /**
99      * Together these two functions flush all queued up draws to GrCommandBuffer. The return value
100      * of drawBatches() indicates whether any commands were actually issued to the GPU.
101      */
102     void prepareBatches(GrBatchFlushState* flushState);
103     bool drawBatches(GrBatchFlushState* flushState);
104 
105     /**
106      * Gets the capabilities of the draw target.
107      */
caps()108     const GrCaps* caps() const { return fGpu->caps(); }
109 
110     void drawBatch(const GrPipelineBuilder&, GrDrawContext*, const GrClip&, GrDrawBatch*);
111 
112     void addBatch(sk_sp<GrBatch>);
113 
114     /**
115      * Draws the path into user stencil bits. Upon return, all user stencil values
116      * inside the path will be nonzero. The path's fill must be either even/odd or
117      * winding (notnverse or hairline).It will respect the HW antialias boolean (if
118      * possible in the 3D API).  Note, we will never have an inverse fill with
119      * stencil path.
120      */
121     void stencilPath(GrDrawContext*,
122                      const GrClip&,
123                      bool useHWAA,
124                      const SkMatrix& viewMatrix,
125                      const GrPath*);
126 
127     /** Clears the entire render target */
128     void fullClear(GrRenderTarget*, GrColor color);
129 
130     /** Discards the contents render target. */
131     void discard(GrRenderTarget*);
132 
133     /**
134      * Copies a pixel rectangle from one surface to another. This call may finalize
135      * reserved vertex/index data (as though a draw call was made). The src pixels
136      * copied are specified by srcRect. They are copied to a rect of the same
137      * size in dst with top left at dstPoint. If the src rect is clipped by the
138      * src bounds then  pixel values in the dst rect corresponding to area clipped
139      * by the src rect are not overwritten. This method is not guaranteed to succeed
140      * depending on the type of surface, configs, etc, and the backend-specific
141      * limitations.
142      */
143     bool copySurface(GrSurface* dst,
144                      GrSurface* src,
145                      const SkIRect& srcRect,
146                      const SkIPoint& dstPoint);
147 
instancedRendering()148     gr_instanced::InstancedRendering* instancedRendering() const {
149         SkASSERT(fInstancedRendering);
150         return fInstancedRendering;
151     }
152 
153 private:
154     friend class GrDrawingManager; // for resetFlag & TopoSortTraits
155     friend class GrDrawContextPriv; // for clearStencilClip
156 
157     enum Flags {
158         kClosed_Flag    = 0x01,   //!< This drawTarget can't accept any more batches
159 
160         kWasOutput_Flag = 0x02,   //!< Flag for topological sorting
161         kTempMark_Flag  = 0x04,   //!< Flag for topological sorting
162     };
163 
setFlag(uint32_t flag)164     void setFlag(uint32_t flag) {
165         fFlags |= flag;
166     }
167 
resetFlag(uint32_t flag)168     void resetFlag(uint32_t flag) {
169         fFlags &= ~flag;
170     }
171 
isSetFlag(uint32_t flag)172     bool isSetFlag(uint32_t flag) const {
173         return SkToBool(fFlags & flag);
174     }
175 
176     struct TopoSortTraits {
OutputTopoSortTraits177         static void Output(GrDrawTarget* dt, int /* index */) {
178             dt->setFlag(GrDrawTarget::kWasOutput_Flag);
179         }
WasOutputTopoSortTraits180         static bool WasOutput(const GrDrawTarget* dt) {
181             return dt->isSetFlag(GrDrawTarget::kWasOutput_Flag);
182         }
SetTempMarkTopoSortTraits183         static void SetTempMark(GrDrawTarget* dt) {
184             dt->setFlag(GrDrawTarget::kTempMark_Flag);
185         }
ResetTempMarkTopoSortTraits186         static void ResetTempMark(GrDrawTarget* dt) {
187             dt->resetFlag(GrDrawTarget::kTempMark_Flag);
188         }
IsTempMarkedTopoSortTraits189         static bool IsTempMarked(const GrDrawTarget* dt) {
190             return dt->isSetFlag(GrDrawTarget::kTempMark_Flag);
191         }
NumDependenciesTopoSortTraits192         static int NumDependencies(const GrDrawTarget* dt) {
193             return dt->fDependencies.count();
194         }
DependencyTopoSortTraits195         static GrDrawTarget* Dependency(GrDrawTarget* dt, int index) {
196             return dt->fDependencies[index];
197         }
198     };
199 
200     // Returns the batch that the input batch was combined with or the input batch if it wasn't
201     // combined.
202     GrBatch* recordBatch(GrBatch*, const SkRect& clippedBounds);
203     void forwardCombine();
204 
205     // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
206     // but couldn't be made. Otherwise, returns true.  This method needs to be protected because it
207     // needs to be accessed by GLPrograms to setup a correct drawstate
208     bool setupDstReadIfNecessary(const GrPipelineBuilder&,
209                                  GrRenderTarget*,
210                                  const GrClip&,
211                                  const GrPipelineOptimizations& optimizations,
212                                  GrXferProcessor::DstTexture*,
213                                  const SkRect& batchBounds);
214 
215     void addDependency(GrDrawTarget* dependedOn);
216 
217     // Used only by drawContextPriv.
218     void clearStencilClip(const GrFixedClip&, bool insideStencilMask, GrRenderTarget*);
219 
220     struct RecordedBatch {
221         sk_sp<GrBatch> fBatch;
222         SkRect         fClippedBounds;
223     };
224     SkSTArray<256, RecordedBatch, true>             fRecordedBatches;
225     GrClearBatch*                                   fLastFullClearBatch;
226     // The context is only in service of the GrClip, remove once it doesn't need this.
227     GrContext*                                      fContext;
228     GrGpu*                                          fGpu;
229     GrResourceProvider*                             fResourceProvider;
230     GrAuditTrail*                                   fAuditTrail;
231 
232     SkDEBUGCODE(int                                 fDebugID;)
233     uint32_t                                        fFlags;
234 
235     // 'this' drawTarget relies on the output of the drawTargets in 'fDependencies'
236     SkTDArray<GrDrawTarget*>                        fDependencies;
237     GrRenderTarget*                                 fRenderTarget;
238 
239     bool                                            fClipBatchToBounds;
240     bool                                            fDrawBatchBounds;
241     int                                             fMaxBatchLookback;
242     int                                             fMaxBatchLookahead;
243 
244     SkAutoTDelete<gr_instanced::InstancedRendering> fInstancedRendering;
245 
246     typedef SkRefCnt INHERITED;
247 };
248 
249 #endif
250