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 GrDrawBatch_DEFINED
9 #define GrDrawBatch_DEFINED
10 
11 #include <functional>
12 #include "GrBatch.h"
13 #include "GrPipeline.h"
14 
15 struct GrInitInvariantOutput;
16 
17 /**
18  * GrDrawBatches 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. GrBatchToken is used
20  * to sequence the uploads relative to each other and to draws.
21  **/
22 
23 class GrBatchDrawToken {
24 public:
AlreadyFlushedToken()25     static GrBatchDrawToken AlreadyFlushedToken() { return GrBatchDrawToken(0); }
26 
GrBatchDrawToken(const GrBatchDrawToken & that)27     GrBatchDrawToken(const GrBatchDrawToken& that) : fSequenceNumber(that.fSequenceNumber) {}
28     GrBatchDrawToken& operator =(const GrBatchDrawToken& that) {
29         fSequenceNumber = that.fSequenceNumber;
30         return *this;
31     }
32     bool operator==(const GrBatchDrawToken& that) const {
33         return fSequenceNumber == that.fSequenceNumber;
34     }
35     bool operator!=(const GrBatchDrawToken& that) const { return !(*this == that); }
36 
37 private:
38     GrBatchDrawToken();
GrBatchDrawToken(uint64_t sequenceNumber)39     explicit GrBatchDrawToken(uint64_t sequenceNumber) : fSequenceNumber(sequenceNumber) {}
40     friend class GrBatchFlushState;
41     uint64_t fSequenceNumber;
42 };
43 
44 /**
45  * Base class for GrBatches that draw. These batches have a GrPipeline installed by GrDrawTarget.
46  */
47 class GrDrawBatch : public GrBatch {
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 GrDrawBatch::Target definition on how deferred uploaders work. */
55     using DeferredUploadFn = std::function<void(WritePixelsFn&)>;
56 
57     class Target;
58 
59     GrDrawBatch(uint32_t classID);
60     ~GrDrawBatch() override;
61 
62     /**
63      * Fills in a structure informing the XP of overrides to its normal behavior.
64      */
65     void getPipelineOptimizations(GrPipelineOptimizations* override) const;
66 
pipeline()67     const GrPipeline* pipeline() const {
68         SkASSERT(fPipelineInstalled);
69         return reinterpret_cast<const GrPipeline*>(fPipelineStorage.get());
70     }
71 
72     bool installPipeline(const GrPipeline::CreateArgs&);
73 
74     // TODO no GrPrimitiveProcessors yet read fragment position
willReadFragmentPosition()75     bool willReadFragmentPosition() const { return false; }
76 
renderTargetUniqueID()77     uint32_t renderTargetUniqueID() const final {
78         SkASSERT(fPipelineInstalled);
79         return this->pipeline()->getRenderTarget()->uniqueID();
80     }
81 
renderTarget()82     GrRenderTarget* renderTarget() const final {
83         SkASSERT(fPipelineInstalled);
84         return this->pipeline()->getRenderTarget();
85     }
86 
dumpInfo()87     SkString dumpInfo() const override {
88         SkString string;
89         string.appendf("RT: %d\n", this->renderTargetUniqueID());
90         string.append("ColorStages:\n");
91         for (int i = 0; i < this->pipeline()->numColorFragmentProcessors(); i++) {
92             string.appendf("\t\t%s\n\t\t%s\n",
93                            this->pipeline()->getColorFragmentProcessor(i).name(),
94                            this->pipeline()->getColorFragmentProcessor(i).dumpInfo().c_str());
95         }
96         string.append("CoverageStages:\n");
97         for (int i = 0; i < this->pipeline()->numCoverageFragmentProcessors(); i++) {
98             string.appendf("\t\t%s\n\t\t%s\n",
99                            this->pipeline()->getCoverageFragmentProcessor(i).name(),
100                            this->pipeline()->getCoverageFragmentProcessor(i).dumpInfo().c_str());
101         }
102         string.appendf("XP: %s\n", this->pipeline()->getXferProcessor().name());
103 
104         bool scissorEnabled = this->pipeline()->getScissorState().enabled();
105         string.appendf("Scissor: ");
106         if (scissorEnabled) {
107             string.appendf("[L: %d, T: %d, R: %d, B: %d]\n",
108                            this->pipeline()->getScissorState().rect().fLeft,
109                            this->pipeline()->getScissorState().rect().fTop,
110                            this->pipeline()->getScissorState().rect().fRight,
111                            this->pipeline()->getScissorState().rect().fBottom);
112         } else {
113             string.appendf("<disabled>\n");
114         }
115         string.append(INHERITED::dumpInfo());
116 
117         return string;
118     }
119 
120 protected:
121     virtual void computePipelineOptimizations(GrInitInvariantOutput* color,
122                                               GrInitInvariantOutput* coverage,
123                                               GrBatchToXPOverrides* overrides) const = 0;
124 
125 private:
126     /**
127      * initBatchTracker is a hook for the some additional overrides / optimization possibilities
128      * from the GrXferProcessor.
129      */
130     virtual void initBatchTracker(const GrXPOverridesForBatch&) = 0;
131 
132 protected:
133     struct QueuedUpload {
QueuedUploadQueuedUpload134         QueuedUpload(DeferredUploadFn&& upload, GrBatchDrawToken token)
135             : fUpload(std::move(upload))
136             , fUploadBeforeToken(token) {}
137         DeferredUploadFn    fUpload;
138         GrBatchDrawToken    fUploadBeforeToken;
139     };
140     SkTArray<QueuedUpload>   fInlineUploads;
141 
142 private:
143     SkAlignedSTStorage<1, GrPipeline>               fPipelineStorage;
144     bool                                            fPipelineInstalled;
145     typedef GrBatch INHERITED;
146 };
147 
148 #endif
149