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 GrDrawOp_DEFINED
9 #define GrDrawOp_DEFINED
10 
11 #include <functional>
12 #include "GrOp.h"
13 #include "GrPipeline.h"
14 
15 class GrAppliedClip;
16 
17 /**
18  * GrDrawOps are flushed in two phases (preDraw, and draw). In preDraw uploads to GrGpuResources
19  * and draws are determined and scheduled. They are issued in the draw phase. GrDrawOpUploadToken is
20  * used to sequence the uploads relative to each other and to draws.
21  **/
22 
23 class GrDrawOpUploadToken {
24 public:
AlreadyFlushedToken()25     static GrDrawOpUploadToken AlreadyFlushedToken() { return GrDrawOpUploadToken(0); }
26 
GrDrawOpUploadToken(const GrDrawOpUploadToken & that)27     GrDrawOpUploadToken(const GrDrawOpUploadToken& that) : fSequenceNumber(that.fSequenceNumber) {}
28     GrDrawOpUploadToken& operator =(const GrDrawOpUploadToken& that) {
29         fSequenceNumber = that.fSequenceNumber;
30         return *this;
31     }
32     bool operator==(const GrDrawOpUploadToken& that) const {
33         return fSequenceNumber == that.fSequenceNumber;
34     }
35     bool operator!=(const GrDrawOpUploadToken& that) const { return !(*this == that); }
36 
37 private:
38     GrDrawOpUploadToken();
GrDrawOpUploadToken(uint64_t sequenceNumber)39     explicit GrDrawOpUploadToken(uint64_t sequenceNumber) : fSequenceNumber(sequenceNumber) {}
40     friend class GrOpFlushState;
41     uint64_t fSequenceNumber;
42 };
43 
44 /**
45  * Base class for GrOps that draw. These ops have a GrPipeline installed by GrOpList.
46  */
47 class GrDrawOp : public GrOp {
48 public:
49     /** Method that performs an upload on behalf of a DeferredUploadFn. */
50     using WritePixelsFn = std::function<bool(GrSurface* texture,
51                                              int left, int top, int width, int height,
52                                              GrPixelConfig config, const void* buffer,
53                                              size_t rowBytes)>;
54     /** See comments before GrDrawOp::Target definition on how deferred uploaders work. */
55     using DeferredUploadFn = std::function<void(WritePixelsFn&)>;
56 
57     class Target;
58 
GrDrawOp(uint32_t classID)59     GrDrawOp(uint32_t classID) : INHERITED(classID) {}
60 
61     /**
62      * This information is required to determine how to compute a GrAppliedClip from a GrClip for
63      * this op.
64      */
65     enum class FixedFunctionFlags : uint32_t {
66         kNone = 0x0,
67         /** Indices that the op will enable MSAA or mixed samples rendering. */
68         kUsesHWAA = 0x1,
69         /** Indices that the op reads and/or writes the stencil buffer */
70         kUsesStencil = 0x2,
71     };
72     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(FixedFunctionFlags);
73     virtual FixedFunctionFlags fixedFunctionFlags() const = 0;
74 
75     /**
76      * This is called after the GrAppliedClip has been computed and just prior to recording the op
77      * or combining it with a previously recorded op. It is used to determine whether a copy of the
78      * destination (or destination texture itself) needs to be provided to the xp when this op
79      * executes.
80      */
81     virtual bool xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*) = 0;
82 
83 protected:
DumpPipelineInfo(const GrPipeline & pipeline)84     static SkString DumpPipelineInfo(const GrPipeline& pipeline) {
85         SkString string;
86         string.appendf("RT: %d\n", pipeline.getRenderTarget()->uniqueID().asUInt());
87         string.append("ColorStages:\n");
88         for (int i = 0; i < pipeline.numColorFragmentProcessors(); i++) {
89             string.appendf("\t\t%s\n\t\t%s\n",
90                            pipeline.getColorFragmentProcessor(i).name(),
91                            pipeline.getColorFragmentProcessor(i).dumpInfo().c_str());
92         }
93         string.append("CoverageStages:\n");
94         for (int i = 0; i < pipeline.numCoverageFragmentProcessors(); i++) {
95             string.appendf("\t\t%s\n\t\t%s\n",
96                            pipeline.getCoverageFragmentProcessor(i).name(),
97                            pipeline.getCoverageFragmentProcessor(i).dumpInfo().c_str());
98         }
99         string.appendf("XP: %s\n", pipeline.getXferProcessor().name());
100 
101         bool scissorEnabled = pipeline.getScissorState().enabled();
102         string.appendf("Scissor: ");
103         if (scissorEnabled) {
104             string.appendf("[L: %d, T: %d, R: %d, B: %d]\n",
105                            pipeline.getScissorState().rect().fLeft,
106                            pipeline.getScissorState().rect().fTop,
107                            pipeline.getScissorState().rect().fRight,
108                            pipeline.getScissorState().rect().fBottom);
109         } else {
110             string.appendf("<disabled>\n");
111         }
112         return string;
113     }
114 
115     struct QueuedUpload {
QueuedUploadQueuedUpload116         QueuedUpload(DeferredUploadFn&& upload, GrDrawOpUploadToken token)
117             : fUpload(std::move(upload))
118             , fUploadBeforeToken(token) {}
119         DeferredUploadFn fUpload;
120         GrDrawOpUploadToken fUploadBeforeToken;
121     };
122 
123     SkTArray<QueuedUpload> fInlineUploads;
124 
125 private:
126     typedef GrOp INHERITED;
127 };
128 
129 GR_MAKE_BITFIELD_CLASS_OPS(GrDrawOp::FixedFunctionFlags);
130 
131 #endif
132