1 /*
2  * Copyright 2015 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 GrTargetCommands_DEFINED
9 #define GrTargetCommands_DEFINED
10 
11 #include "GrBatch.h"
12 #include "GrBatchTarget.h"
13 #include "GrDrawTarget.h"
14 #include "GrGpu.h"
15 #include "GrPath.h"
16 #include "GrPendingProgramElement.h"
17 #include "GrRenderTarget.h"
18 #include "GrTRecorder.h"
19 #include "SkRect.h"
20 #include "SkTypes.h"
21 
22 class GrInOrderDrawBuffer;
23 
24 
25 class GrTargetCommands : ::SkNoncopyable {
26 public:
GrTargetCommands(GrGpu * gpu)27     GrTargetCommands(GrGpu* gpu)
28         : fCmdBuffer(kCmdBufferInitialSizeInBytes)
29         , fBatchTarget(gpu) {
30     }
31 
32     class Cmd : ::SkNoncopyable {
33     public:
34         enum CmdType {
35             kStencilPath_CmdType       = 1,
36             kSetState_CmdType          = 2,
37             kClear_CmdType             = 3,
38             kCopySurface_CmdType       = 4,
39             kDrawPath_CmdType          = 5,
40             kDrawPaths_CmdType         = 6,
41             kDrawBatch_CmdType         = 7,
42             kXferBarrier_CmdType       = 8,
43         };
44 
Cmd(CmdType type)45         Cmd(CmdType type) : fMarkerID(-1), fType(type) {}
~Cmd()46         virtual ~Cmd() {}
47 
48         virtual void execute(GrGpu*) = 0;
49 
type()50         CmdType type() const { return fType; }
51 
52         // trace markers
isTraced()53         bool isTraced() const { return -1 != fMarkerID; }
setMarkerID(int markerID)54         void setMarkerID(int markerID) { SkASSERT(-1 == fMarkerID); fMarkerID = markerID; }
markerID()55         int markerID() const { return fMarkerID; }
56 
57     private:
58         int              fMarkerID;
59         CmdType          fType;
60     };
61 
62     void reset();
63     void flush(GrInOrderDrawBuffer*);
64 
65 private:
66     friend class GrCommandBuilder;
67     friend class GrInOrderDrawBuffer; // This goes away when State becomes just a pipeline
68     friend class GrReorderCommandBuilder;
69 
70     typedef GrGpu::DrawArgs DrawArgs;
71 
72     void recordXferBarrierIfNecessary(const GrPipeline&, GrInOrderDrawBuffer*);
73 
74     // TODO: This can be just a pipeline once paths are in batch, and it should live elsewhere
75     struct State : public SkNVRefCnt<State> {
76         // TODO get rid of the prim proc parameter when we use batch everywhere
77         State(const GrPrimitiveProcessor* primProc = NULL)
fPrimitiveProcessorState78             : fPrimitiveProcessor(primProc)
79             , fCompiled(false) {}
80 
~StateState81         ~State() { reinterpret_cast<GrPipeline*>(fPipeline.get())->~GrPipeline(); }
82 
83         // This function is only for getting the location in memory where we will create our
84         // pipeline object.
pipelineLocationState85         GrPipeline* pipelineLocation() { return reinterpret_cast<GrPipeline*>(fPipeline.get()); }
86 
getPipelineState87         const GrPipeline* getPipeline() const {
88             return reinterpret_cast<const GrPipeline*>(fPipeline.get());
89         }
getRenderTargetState90         GrRenderTarget* getRenderTarget() const {
91             return this->getPipeline()->getRenderTarget();
92         }
getXferProcessorState93         const GrXferProcessor* getXferProcessor() const {
94             return this->getPipeline()->getXferProcessor();
95         }
96 
deleteState97         void operator delete(void* p) {}
newState98         void* operator new(size_t) {
99             SkFAIL("All States are created by placement new.");
100             return sk_malloc_throw(0);
101         }
102 
newState103         void* operator new(size_t, void* p) { return p; }
deleteState104         void operator delete(void* target, void* placement) {
105             ::operator delete(target, placement);
106         }
107 
108         typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
109         ProgramPrimitiveProcessor               fPrimitiveProcessor;
110         SkAlignedSStorage<sizeof(GrPipeline)>   fPipeline;
111         GrProgramDesc                           fDesc;
112         GrBatchTracker                          fBatchTracker;
113         bool                                    fCompiled;
114     };
115     // TODO remove this when State is just a pipeline
116     friend SkNVRefCnt<State>;
117 
118     struct StencilPath : public Cmd {
StencilPathStencilPath119         StencilPath(const GrPath* path, GrRenderTarget* rt)
120             : Cmd(kStencilPath_CmdType)
121             , fRenderTarget(rt)
122             , fPath(path) {}
123 
pathStencilPath124         const GrPath* path() const { return fPath.get(); }
125 
126         void execute(GrGpu*) override;
127 
128         SkMatrix                                                fViewMatrix;
129         bool                                                    fUseHWAA;
130         GrStencilSettings                                       fStencil;
131         GrScissorState                                          fScissor;
132     private:
133         GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>    fRenderTarget;
134         GrPendingIOResource<const GrPath, kRead_GrIOType>       fPath;
135     };
136 
137     struct DrawPath : public Cmd {
DrawPathDrawPath138         DrawPath(State* state, const GrPath* path)
139             : Cmd(kDrawPath_CmdType)
140             , fState(SkRef(state))
141             , fPath(path) {}
142 
pathDrawPath143         const GrPath* path() const { return fPath.get(); }
144 
145         void execute(GrGpu*) override;
146 
147         SkAutoTUnref<State>     fState;
148         GrStencilSettings       fStencilSettings;
149     private:
150         GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
151     };
152 
153     struct DrawPaths : public Cmd {
DrawPathsDrawPaths154         DrawPaths(State* state, const GrPathRange* pathRange)
155             : Cmd(kDrawPaths_CmdType)
156             , fState(SkRef(state))
157             , fPathRange(pathRange) {}
158 
pathRangeDrawPaths159         const GrPathRange* pathRange() const { return fPathRange.get();  }
160 
161         void execute(GrGpu*) override;
162 
163         SkAutoTUnref<State>             fState;
164         char*                           fIndices;
165         GrDrawTarget::PathIndexType     fIndexType;
166         float*                          fTransforms;
167         GrDrawTarget::PathTransformType fTransformType;
168         int                             fCount;
169         GrStencilSettings               fStencilSettings;
170 
171     private:
172         GrPendingIOResource<const GrPathRange, kRead_GrIOType> fPathRange;
173     };
174 
175     // This is also used to record a discard by setting the color to GrColor_ILLEGAL
176     struct Clear : public Cmd {
ClearClear177         Clear(GrRenderTarget* rt) : Cmd(kClear_CmdType), fRenderTarget(rt) {}
178 
renderTargetClear179         GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
180 
181         void execute(GrGpu*) override;
182 
183         SkIRect fRect;
184         GrColor fColor;
185         bool    fCanIgnoreRect;
186 
187     private:
188         GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
189     };
190 
191     // This command is ONLY used by the clip mask manager to clear the stencil clip bits
192     struct ClearStencilClip : public Cmd {
ClearStencilClipClearStencilClip193         ClearStencilClip(GrRenderTarget* rt) : Cmd(kClear_CmdType), fRenderTarget(rt) {}
194 
renderTargetClearStencilClip195         GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
196 
197         void execute(GrGpu*) override;
198 
199         SkIRect fRect;
200         bool    fInsideClip;
201 
202     private:
203         GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
204     };
205 
206     struct CopySurface : public Cmd {
CopySurfaceCopySurface207         CopySurface(GrSurface* dst, GrSurface* src)
208             : Cmd(kCopySurface_CmdType)
209             , fDst(dst)
210             , fSrc(src) {
211         }
212 
dstCopySurface213         GrSurface* dst() const { return fDst.get(); }
srcCopySurface214         GrSurface* src() const { return fSrc.get(); }
215 
216         void execute(GrGpu*) override;
217 
218         SkIPoint    fDstPoint;
219         SkIRect     fSrcRect;
220 
221     private:
222         GrPendingIOResource<GrSurface, kWrite_GrIOType> fDst;
223         GrPendingIOResource<GrSurface, kRead_GrIOType> fSrc;
224     };
225 
226     struct DrawBatch : public Cmd {
DrawBatchDrawBatch227         DrawBatch(State* state, GrBatch* batch, GrBatchTarget* batchTarget)
228             : Cmd(kDrawBatch_CmdType)
229             , fState(SkRef(state))
230             , fBatch(SkRef(batch))
231             , fBatchTarget(batchTarget) {
232             SkASSERT(!batch->isUsed());
233         }
234 
235         void execute(GrGpu*) override;
236 
237         SkAutoTUnref<State>    fState;
238         SkAutoTUnref<GrBatch>  fBatch;
239 
240     private:
241         GrBatchTarget*         fBatchTarget;
242     };
243 
244     struct XferBarrier : public Cmd {
XferBarrierXferBarrier245         XferBarrier(GrRenderTarget* rt)
246             : Cmd(kXferBarrier_CmdType)
247             , fRenderTarget(rt) {
248         }
249 
250         void execute(GrGpu*) override;
251 
252         GrXferBarrierType   fBarrierType;
253 
254     private:
255         GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
256     };
257 
258     static const int kCmdBufferInitialSizeInBytes = 8 * 1024;
259 
260     typedef void* TCmdAlign; // This wouldn't be enough align if a command used long double.
261     typedef GrTRecorder<Cmd, TCmdAlign> CmdBuffer;
262 
cmdBuffer()263     CmdBuffer* cmdBuffer() { return &fCmdBuffer; }
batchTarget()264     GrBatchTarget* batchTarget() { return &fBatchTarget; }
265 
266     CmdBuffer                           fCmdBuffer;
267     GrBatchTarget                       fBatchTarget;
268 };
269 
270 #endif
271 
272