Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: src/gpu/GrBatchFlushState.h

Issue 1835283002: Simplify GrDrawBatch uploads and token uage. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrBatchAtlas.cpp ('k') | src/gpu/GrBatchFlushState.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef GrBatchBuffer_DEFINED 8 #ifndef GrBatchBuffer_DEFINED
9 #define GrBatchBuffer_DEFINED 9 #define GrBatchBuffer_DEFINED
10 10
11 #include "GrBufferAllocPool.h" 11 #include "GrBufferAllocPool.h"
12 #include "batches/GrVertexBatch.h" 12 #include "batches/GrVertexBatch.h"
13 13
14 class GrResourceProvider; 14 class GrResourceProvider;
15 15
16 /** Simple class that performs the upload on behalf of a GrBatchUploader. */
17 class GrBatchUploader::TextureUploader {
18 public:
19 TextureUploader(GrGpu* gpu) : fGpu(gpu) { SkASSERT(gpu); }
20
21 /**
22 * Updates the pixels in a rectangle of a texture.
23 *
24 * @param left left edge of the rectangle to write (inclusive)
25 * @param top top edge of the rectangle to write (inclusive)
26 * @param width width of rectangle to write in pixels.
27 * @param height height of rectangle to write in pixels.
28 * @param config the pixel config of the source buffer
29 * @param buffer memory to read pixels from
30 * @param rowBytes number of bytes between consecutive rows. Zero
31 * means rows are tightly packed.
32 */
33 bool writeTexturePixels(GrTexture* texture,
34 int left, int top, int width, int height,
35 GrPixelConfig config, const void* buffer,
36 size_t rowBytes) {
37 return fGpu->writePixels(texture, left, top, width, height, config, buff er, rowBytes);
38 }
39
40 private:
41 GrGpu* fGpu;
42 };
43
44 /** Tracks the state across all the GrBatches in a GrDrawTarget flush. */ 16 /** Tracks the state across all the GrBatches in a GrDrawTarget flush. */
45 class GrBatchFlushState { 17 class GrBatchFlushState {
46 public: 18 public:
47 GrBatchFlushState(GrGpu*, GrResourceProvider*); 19 GrBatchFlushState(GrGpu*, GrResourceProvider*);
48 20
49 ~GrBatchFlushState() { this->reset(); } 21 ~GrBatchFlushState() { this->reset(); }
50 22
51 void advanceToken() { ++fCurrentToken; } 23 /** Inserts an upload to be executed after all batches in the flush prepared their draws
52
53 void advanceLastFlushedToken() { ++fLastFlushedToken; }
54
55 /** Inserts an upload to be executred after all batches in the flush prepare d their draws
56 but before the draws are executed to the backend 3D API. */ 24 but before the draws are executed to the backend 3D API. */
57 void addASAPUpload(GrBatchUploader* upload) { 25 void addASAPUpload(GrDrawBatch::DeferredUploadFn&& upload) {
58 fAsapUploads.push_back().reset(SkRef(upload)); 26 fAsapUploads.emplace_back(std::move(upload));
59 } 27 }
60 28
61 const GrCaps& caps() const { return *fGpu->caps(); } 29 const GrCaps& caps() const { return *fGpu->caps(); }
62 GrResourceProvider* resourceProvider() const { return fResourceProvider; } 30 GrResourceProvider* resourceProvider() const { return fResourceProvider; }
63 31
64 /** Has the token been flushed to the backend 3D API. */ 32 /** Has the token been flushed to the backend 3D API. */
65 bool hasTokenBeenFlushed(GrBatchToken token) const { return fLastFlushedToke n >= token; } 33 bool hasDrawBeenFlushed(GrBatchDrawToken token) const {
34 return token.fSequenceNumber <= fLastFlushedToken.fSequenceNumber;
35 }
66 36
67 /** The current token advances once for every contiguous set of uninterrupte d draws prepared 37 /** Issue a token to an operation that is being enqueued. */
68 by a batch. */ 38 GrBatchDrawToken issueDrawToken() {
69 GrBatchToken currentToken() const { return fCurrentToken; } 39 return GrBatchDrawToken(++fLastIssuedToken.fSequenceNumber);
40 }
41
42 /** Call every time a draw that was issued a token is flushed */
43 void flushToken() { ++fLastFlushedToken.fSequenceNumber; }
44
45 /** Gets the next draw token that will be issued. */
46 GrBatchDrawToken nextDrawToken() const {
47 return GrBatchDrawToken(fLastIssuedToken.fSequenceNumber + 1);
48 }
70 49
71 /** The last token flushed to all the way to the backend API. */ 50 /** The last token flushed to all the way to the backend API. */
72 GrBatchToken lastFlushedToken() const { return fLastFlushedToken; } 51 GrBatchDrawToken nextTokenToFlush() const {
73 52 return GrBatchDrawToken(fLastFlushedToken.fSequenceNumber + 1);
74 /** This is a magic token that can be used to indicate that an upload should occur before 53 }
75 any draws for any batch in the current flush execute. */
76 GrBatchToken asapToken() const { return fLastFlushedToken + 1; }
77 54
78 void* makeVertexSpace(size_t vertexSize, int vertexCount, 55 void* makeVertexSpace(size_t vertexSize, int vertexCount,
79 const GrBuffer** buffer, int* startVertex); 56 const GrBuffer** buffer, int* startVertex);
80 uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* start Index); 57 uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* start Index);
81 58
82 /** This is called after each batch has a chance to prepare its draws and be fore the draws 59 /** This is called after each batch has a chance to prepare its draws and be fore the draws
83 are issued. */ 60 are issued. */
84 void preIssueDraws() { 61 void preIssueDraws() {
85 fVertexPool.unmap(); 62 fVertexPool.unmap();
86 fIndexPool.unmap(); 63 fIndexPool.unmap();
87 int uploadCount = fAsapUploads.count(); 64 int uploadCount = fAsapUploads.count();
65
88 for (int i = 0; i < uploadCount; i++) { 66 for (int i = 0; i < uploadCount; i++) {
89 fAsapUploads[i]->upload(&fUploader); 67 this->doUpload(fAsapUploads[i]);
90 } 68 }
91 fAsapUploads.reset(); 69 fAsapUploads.reset();
92 } 70 }
93 71
72 void doUpload(GrDrawBatch::DeferredUploadFn& upload) {
73 GrDrawBatch::WritePixelsFn wp = [this] (GrSurface* surface,
74 int left, int top, int width, int height,
75 GrPixelConfig config, const void* buffer,
76 size_t rowBytes) -> bool {
77 return this->fGpu->writePixels(surface, left, top, width, height, co nfig, buffer,
78 rowBytes);
79 };
80 upload(wp);
81 }
82
94 void putBackIndices(size_t indices) { fIndexPool.putBack(indices * sizeof(ui nt16_t)); } 83 void putBackIndices(size_t indices) { fIndexPool.putBack(indices * sizeof(ui nt16_t)); }
95 84
96 void putBackVertexSpace(size_t sizeInBytes) { fVertexPool.putBack(sizeInByte s); } 85 void putBackVertexSpace(size_t sizeInBytes) { fVertexPool.putBack(sizeInByte s); }
97 86
98 GrBatchUploader::TextureUploader* uploader() { return &fUploader; }
99
100 GrGpu* gpu() { return fGpu; } 87 GrGpu* gpu() { return fGpu; }
101 88
102 void reset() { 89 void reset() {
103 fVertexPool.reset(); 90 fVertexPool.reset();
104 fIndexPool.reset(); 91 fIndexPool.reset();
105 } 92 }
106 93
107 private: 94 private:
108 GrGpu* fGpu;
109 GrBatchUploader::TextureUploader fUploader;
110 95
111 GrResourceProvider* fResourceProvider; 96 GrGpu* fGpu;
112 97
113 GrVertexBufferAllocPool fVertexPool; 98 GrResourceProvider* fResourceProvider;
114 GrIndexBufferAllocPool fIndexPool;
115 99
116 SkTArray<SkAutoTUnref<GrBatchUploader>, true> fAsapUploads; 100 GrVertexBufferAllocPool fVertexPool;
101 GrIndexBufferAllocPool fIndexPool;
117 102
118 GrBatchToken fCurrentToken; 103 SkSTArray<4, GrDrawBatch::DeferredUploadFn> fAsapUploads;
119 104
120 GrBatchToken fLastFlushedToken; 105 GrBatchDrawToken fLastIssuedToken;
106
107 GrBatchDrawToken fLastFlushedToken;
121 }; 108 };
122 109
123 /** 110 /**
111 * A word about uploads and tokens: Batches should usually schedule their upload s to occur at the
112 * begining of a frame whenever possible. These are called ASAP uploads. Of cour se, this requires
113 * that there are no draws that have yet to be flushed that rely on the old text ure contents. In
114 * that case the ASAP upload would happen prior to the previous draw causing the draw to read the
115 * new (wrong) texture data. In that case they should schedule an inline upload.
116 *
117 * Batches, in conjunction with helpers such as GrBatchAtlas, can use the token system to know
118 * what the most recent draw was that referenced a resource (or portion of a res ource). Each draw
119 * is assigned a token. A resource (or portion) can be tagged with the most rece nt draw's
120 * token. The target provides a facility for testing whether the draw correspond ing to the token
121 * has been flushed. If it has not been flushed then the batch must perform an i nline upload
122 * instead. When scheduling an inline upload the batch provides the token of the draw that the
123 * upload must occur before. The upload will then occur between the draw that re quires the new
124 * data but after the token that requires the old data.
125 *
126 * TODO: Currently the token/upload interface is spread over GrDrawBatch, GrVert exBatch,
127 * GrDrawBatch::Target, and GrVertexBatch::Target. However, the interface at the GrDrawBatch
128 * level is not complete and isn't useful. We should push it down to GrVertexBat ch until it
129 * is required at the GrDrawBatch level.
130 */
131
132 /**
124 * GrDrawBatch instances use this object to allocate space for their geometry an d to issue the draws 133 * GrDrawBatch instances use this object to allocate space for their geometry an d to issue the draws
125 * that render their batch. 134 * that render their batch.
126 */ 135 */
127 class GrDrawBatch::Target { 136 class GrDrawBatch::Target {
128 public: 137 public:
129 Target(GrBatchFlushState* state, GrDrawBatch* batch) : fState(state), fBatch (batch) {} 138 Target(GrBatchFlushState* state, GrDrawBatch* batch) : fState(state), fBatch (batch) {}
130 139
131 void upload(GrBatchUploader* upload) { 140 /** Returns the token of the draw that this upload will occur before. */
132 if (this->asapToken() == upload->lastUploadToken()) { 141 GrBatchDrawToken addInlineUpload(DeferredUploadFn&& upload) {
133 fState->addASAPUpload(upload); 142 fBatch->fInlineUploads.emplace_back(std::move(upload), fState->nextDrawT oken());
134 } else { 143 return fBatch->fInlineUploads.back().fUploadBeforeToken;
135 fBatch->fInlineUploads.push_back().reset(SkRef(upload));
136 }
137 } 144 }
138 145
139 bool hasTokenBeenFlushed(GrBatchToken token) const { 146 /** Returns the token of the draw that this upload will occur before. Since ASAP uploads
140 return fState->hasTokenBeenFlushed(token); 147 are done first during a flush, this will be the first token since the mo st recent
148 flush. */
149 GrBatchDrawToken addAsapUpload(DeferredUploadFn&& upload) {
150 fState->addASAPUpload(std::move(upload));
151 return fState->nextTokenToFlush();
141 } 152 }
142 GrBatchToken currentToken() const { return fState->currentToken(); } 153
143 GrBatchToken asapToken() const { return fState->asapToken(); } 154 bool hasDrawBeenFlushed(GrBatchDrawToken token) const {
155 return fState->hasDrawBeenFlushed(token);
156 }
157
158 /** Gets the next draw token that will be issued by this target. This can be used by a batch
159 to record that the next draw it issues will use a resource (e.g. texture ) while preparing
160 that draw. */
161 GrBatchDrawToken nextDrawToken() const { return fState->nextDrawToken(); }
144 162
145 const GrCaps& caps() const { return fState->caps(); } 163 const GrCaps& caps() const { return fState->caps(); }
146 164
147 GrResourceProvider* resourceProvider() const { return fState->resourceProvid er(); } 165 GrResourceProvider* resourceProvider() const { return fState->resourceProvid er(); }
148 166
149 protected: 167 protected:
150 GrDrawBatch* batch() { return fBatch; } 168 GrDrawBatch* batch() { return fBatch; }
151 GrBatchFlushState* state() { return fState; } 169 GrBatchFlushState* state() { return fState; }
152 170
153 private: 171 private:
154 GrBatchFlushState* fState; 172 GrBatchFlushState* fState;
155 GrDrawBatch* fBatch; 173 GrDrawBatch* fBatch;
156 }; 174 };
157 175
158 /** Extension of GrDrawBatch::Target for use by GrVertexBatch. Adds the ability to create vertex 176 /** Extension of GrDrawBatch::Target for use by GrVertexBatch. Adds the ability to create vertex
159 draws. */ 177 draws. */
160 class GrVertexBatch::Target : public GrDrawBatch::Target { 178 class GrVertexBatch::Target : public GrDrawBatch::Target {
161 public: 179 public:
162 Target(GrBatchFlushState* state, GrVertexBatch* batch) : INHERITED(state, ba tch) {} 180 Target(GrBatchFlushState* state, GrVertexBatch* batch) : INHERITED(state, ba tch) {}
163 181
164 void initDraw(const GrPrimitiveProcessor* primProc) { 182 void draw(const GrGeometryProcessor* gp, const GrMesh& mesh);
165 GrVertexBatch::DrawArray* draws = this->vertexBatch()->fDrawArrays.addTo Tail();
166 draws->fPrimitiveProcessor.reset(primProc);
167 this->state()->advanceToken();
168 }
169
170 void draw(const GrMesh& mesh) {
171 this->vertexBatch()->fDrawArrays.tail()->fDraws.push_back(mesh);
172 }
173 183
174 void* makeVertexSpace(size_t vertexSize, int vertexCount, 184 void* makeVertexSpace(size_t vertexSize, int vertexCount,
175 const GrBuffer** buffer, int* startVertex) { 185 const GrBuffer** buffer, int* startVertex) {
176 return this->state()->makeVertexSpace(vertexSize, vertexCount, buffer, s tartVertex); 186 return this->state()->makeVertexSpace(vertexSize, vertexCount, buffer, s tartVertex);
177 } 187 }
178 188
179 uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* start Index) { 189 uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* start Index) {
180 return this->state()->makeIndexSpace(indexCount, buffer, startIndex); 190 return this->state()->makeIndexSpace(indexCount, buffer, startIndex);
181 } 191 }
182 192
183 /** Helpers for batches which over-allocate and then return data to the pool . */ 193 /** Helpers for batches which over-allocate and then return data to the pool . */
184 void putBackIndices(int indices) { this->state()->putBackIndices(indices); } 194 void putBackIndices(int indices) { this->state()->putBackIndices(indices); }
185 void putBackVertices(int vertices, size_t vertexStride) { 195 void putBackVertices(int vertices, size_t vertexStride) {
186 this->state()->putBackVertexSpace(vertices * vertexStride); 196 this->state()->putBackVertexSpace(vertices * vertexStride);
187 } 197 }
188 198
189 private: 199 private:
190 GrVertexBatch* vertexBatch() { return static_cast<GrVertexBatch*>(this->batc h()); } 200 GrVertexBatch* vertexBatch() { return static_cast<GrVertexBatch*>(this->batc h()); }
191 typedef GrDrawBatch::Target INHERITED; 201 typedef GrDrawBatch::Target INHERITED;
192 }; 202 };
193 203
194 #endif 204 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrBatchAtlas.cpp ('k') | src/gpu/GrBatchFlushState.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698