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
22class GrInOrderDrawBuffer;
23
24
25class GrTargetCommands : ::SkNoncopyable {
26public:
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
45        Cmd(CmdType type) : fMarkerID(-1), fType(type) {}
46        virtual ~Cmd() {}
47
48        virtual void execute(GrGpu*) = 0;
49
50        CmdType type() const { return fType; }
51
52        // trace markers
53        bool isTraced() const { return -1 != fMarkerID; }
54        void setMarkerID(int markerID) { SkASSERT(-1 == fMarkerID); fMarkerID = 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
65private:
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)
78            : fPrimitiveProcessor(primProc)
79            , fCompiled(false) {}
80
81        ~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.
85        GrPipeline* pipelineLocation() { return reinterpret_cast<GrPipeline*>(fPipeline.get()); }
86
87        const GrPipeline* getPipeline() const {
88            return reinterpret_cast<const GrPipeline*>(fPipeline.get());
89        }
90        GrRenderTarget* getRenderTarget() const {
91            return this->getPipeline()->getRenderTarget();
92        }
93        const GrXferProcessor* getXferProcessor() const {
94            return this->getPipeline()->getXferProcessor();
95        }
96
97        void operator delete(void* p) {}
98        void* operator new(size_t) {
99            SkFAIL("All States are created by placement new.");
100            return sk_malloc_throw(0);
101        }
102
103        void* operator new(size_t, void* p) { return p; }
104        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 {
119        StencilPath(const GrPath* path, GrRenderTarget* rt)
120            : Cmd(kStencilPath_CmdType)
121            , fRenderTarget(rt)
122            , fPath(path) {}
123
124        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 {
138        DrawPath(State* state, const GrPath* path)
139            : Cmd(kDrawPath_CmdType)
140            , fState(SkRef(state))
141            , fPath(path) {}
142
143        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 {
154        DrawPaths(State* state, const GrPathRange* pathRange)
155            : Cmd(kDrawPaths_CmdType)
156            , fState(SkRef(state))
157            , fPathRange(pathRange) {}
158
159        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 {
177        Clear(GrRenderTarget* rt) : Cmd(kClear_CmdType), fRenderTarget(rt) {}
178
179        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 {
193        ClearStencilClip(GrRenderTarget* rt) : Cmd(kClear_CmdType), fRenderTarget(rt) {}
194
195        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 {
207        CopySurface(GrSurface* dst, GrSurface* src)
208            : Cmd(kCopySurface_CmdType)
209            , fDst(dst)
210            , fSrc(src) {
211        }
212
213        GrSurface* dst() const { return fDst.get(); }
214        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 {
227        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 {
245        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
263    CmdBuffer* cmdBuffer() { return &fCmdBuffer; }
264    GrBatchTarget* batchTarget() { return &fBatchTarget; }
265
266    CmdBuffer                           fCmdBuffer;
267    GrBatchTarget                       fBatchTarget;
268};
269
270#endif
271
272