1 /*
2 * Copyright 2016 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 GrGpuCommandBuffer_DEFINED
9 #define GrGpuCommandBuffer_DEFINED
10 
11 #include "GrColor.h"
12 #include "ops/GrDrawOp.h"
13 
14 class GrOpFlushState;
15 class GrFixedClip;
16 class GrGpu;
17 class GrMesh;
18 class GrPipeline;
19 class GrPrimitiveProcessor;
20 class GrRenderTarget;
21 struct SkIRect;
22 struct SkRect;
23 
24 /**
25  * The GrGpuCommandBuffer is a series of commands (draws, clears, and discards), which all target
26  * the same render target. It is possible that these commands execute immediately (GL), or get
27  * buffered up for later execution (Vulkan). GrOps will execute their draw commands into a
28  * GrGpuCommandBuffer.
29  *
30  * Ideally we'd know the GrRenderTarget, or at least its properties when the GrGpuCommandBuffer, is
31  * created. We also then wouldn't include it in the GrPipeline or as a parameter to the clear and
32  * discard methods. The logical place for that will be in GrRenderTargetOpList post-MDB. For now
33  * the render target is redundantly passed to each operation, though it will always be the same
34  * render target for a given command buffer even pre-MDB.
35  */
36 class GrGpuCommandBuffer {
37 public:
38     enum class LoadOp {
39         kLoad,
40         kClear,
41         kDiscard,
42     };
43 
44     enum class StoreOp {
45         kStore,
46         kDiscard,
47     };
48 
49     struct LoadAndStoreInfo {
50         LoadOp  fLoadOp;
51         StoreOp fStoreOp;
52         GrColor fClearColor;
53     };
54 
GrGpuCommandBuffer()55     GrGpuCommandBuffer() {}
~GrGpuCommandBuffer()56     virtual ~GrGpuCommandBuffer() {}
57 
58     // Signals the end of recording to the command buffer and that it can now be submitted.
59     virtual void end() = 0;
60 
61     // Sends the command buffer off to the GPU object to execute the commands built up in the
62     // buffer. The gpu object is allowed to defer execution of the commands until it is flushed.
63     void submit();
64 
65     // We pass in an array of meshCount GrMesh to the draw. The backend should loop over each
66     // GrMesh object and emit a draw for it. Each draw will use the same GrPipeline and
67     // GrPrimitiveProcessor. This may fail if the draw would exceed any resource limits (e.g.
68     // number of vertex attributes is too large).
69     bool draw(const GrPipeline&,
70               const GrPrimitiveProcessor&,
71               const GrMesh*,
72               int meshCount,
73               const SkRect& bounds);
74 
75     // Performs an upload of vertex data in the middle of a set of a set of draws
76     virtual void inlineUpload(GrOpFlushState* state, GrDrawOp::DeferredUploadFn& upload,
77                               GrRenderTarget* rt) = 0;
78 
79     /**
80      * Clear the passed in render target. Ignores the draw state and clip.
81      */
82     void clear(GrRenderTarget*, const GrFixedClip&, GrColor);
83 
84     void clearStencilClip(GrRenderTarget*, const GrFixedClip&, bool insideStencilMask);
85 
86     /**
87      * Discards the contents render target. nullptr indicates that the current render target should
88      * be discarded.
89      */
90     // TODO: This should be removed in the future to favor using the load and store ops for discard
91     virtual void discard(GrRenderTarget*) = 0;
92 
93 private:
94     virtual GrGpu* gpu() = 0;
95     virtual GrRenderTarget* renderTarget() = 0;
96 
97     virtual void onSubmit() = 0;
98 
99     // overridden by backend-specific derived class to perform the draw call.
100     virtual void onDraw(const GrPipeline&,
101                         const GrPrimitiveProcessor&,
102                         const GrMesh*,
103                         int meshCount,
104                         const SkRect& bounds) = 0;
105 
106     // overridden by backend-specific derived class to perform the clear.
107     virtual void onClear(GrRenderTarget*, const GrFixedClip&, GrColor) = 0;
108 
109     virtual void onClearStencilClip(GrRenderTarget*, const GrFixedClip&,
110                                     bool insideStencilMask) = 0;
111 
112 };
113 
114 #endif
115