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

Side by Side Diff: src/gpu/GrFlushToGpuDrawTarget.cpp

Issue 773433002: Add a base class for GrIODB that handles geometry data (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: cleanup Created 6 years 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/GrFlushToGpuDrawTarget.h ('k') | src/gpu/GrInOrderDrawBuffer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2014 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 #include "GrFlushToGpuDrawTarget.h"
9 #include "GrContext.h"
10 #include "GrGpu.h"
11 #include "GrTextStrike.h"
12 #include "GrBufferAllocPool.h"
13
14 GrFlushToGpuDrawTarget::GrFlushToGpuDrawTarget(GrGpu* gpu,
15 GrVertexBufferAllocPool* vertexPo ol,
16 GrIndexBufferAllocPool* indexPool )
17 : INHERITED(gpu->getContext())
18 , fGpu(SkRef(gpu))
19 , fVertexPool(vertexPool)
20 , fIndexPool(indexPool)
21 , fFlushing(false) {
22
23 fCaps.reset(SkRef(fGpu->caps()));
24
25 SkASSERT(vertexPool);
26 SkASSERT(indexPool);
27
28 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
29 poolState.fUsedPoolVertexBytes = 0;
30 poolState.fUsedPoolIndexBytes = 0;
31 #ifdef SK_DEBUG
32 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
33 poolState.fPoolStartVertex = ~0;
34 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
35 poolState.fPoolStartIndex = ~0;
36 #endif
37 }
38
39 GrFlushToGpuDrawTarget::~GrFlushToGpuDrawTarget() {
40 // This must be called by before the GrDrawTarget destructor
41 this->releaseGeometry();
42 }
43
44 void GrFlushToGpuDrawTarget::setDrawBuffers(DrawInfo* info, size_t vertexStride) {
45 GeometryPoolState& poolState = fGeoPoolStateStack.back();
46 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
47 info->setVertexBuffer(this->getGeomSrc().fVertexBuffer);
48 } else {
49 // Update the bytes used since the last reserve-geom request.
50 size_t bytes = (info->vertexCount() + info->startVertex()) * vertexStrid e;
51 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes);
52 info->setVertexBuffer(poolState.fPoolVertexBuffer);
53 info->adjustStartVertex(poolState.fPoolStartVertex);
54 }
55
56 if (info->isIndexed()) {
57 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) {
58 info->setIndexBuffer(this->getGeomSrc().fIndexBuffer);
59 } else {
60 // Update the bytes used since the last reserve-geom request.
61 size_t bytes = (info->indexCount() + info->startIndex()) * sizeof(ui nt16_t);
62 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes , bytes);
63 info->setIndexBuffer(poolState.fPoolIndexBuffer);
64 info->adjustStartIndex(poolState.fPoolStartIndex);
65 }
66 }
67 }
68
69 void GrFlushToGpuDrawTarget::reset() {
70 SkASSERT(1 == fGeoPoolStateStack.count());
71 this->resetVertexSource();
72 this->resetIndexSource();
73
74 fVertexPool->reset();
75 fIndexPool->reset();
76
77 this->onReset();
78 }
79
80 void GrFlushToGpuDrawTarget::flush() {
81 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
82 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
83
84 if (fFlushing) {
85 return;
86 }
87 fFlushing = true;
88
89 fGpu->getContext()->getFontCache()->updateTextures();
90 fVertexPool->unmap();
91 fIndexPool->unmap();
92
93 fGpu->saveActiveTraceMarkers();
94
95 this->onFlush();
96
97 fGpu->restoreActiveTraceMarkers();
98
99 fFlushing = false;
100 this->reset();
101 }
102
103 void GrFlushToGpuDrawTarget::willReserveVertexAndIndexSpace(int vertexCount,
104 size_t vertexStride,
105 int indexCount) {
106 // We use geometryHints() to know whether to flush the draw buffer. We
107 // can't flush if we are inside an unbalanced pushGeometrySource.
108 // Moreover, flushing blows away vertex and index data that was
109 // previously reserved. So if the vertex or index data is pulled from
110 // reserved space and won't be released by this request then we can't
111 // flush.
112 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
113
114 bool unreleasedVertexSpace =
115 !vertexCount &&
116 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
117
118 bool unreleasedIndexSpace =
119 !indexCount &&
120 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
121
122 int vcount = vertexCount;
123 int icount = indexCount;
124
125 if (!insideGeoPush &&
126 !unreleasedVertexSpace &&
127 !unreleasedIndexSpace &&
128 this->geometryHints(vertexStride, &vcount, &icount)) {
129 this->flush();
130 }
131 }
132
133 bool GrFlushToGpuDrawTarget::geometryHints(size_t vertexStride,
134 int* vertexCount,
135 int* indexCount) const {
136 // we will recommend a flush if the data could fit in a single
137 // preallocated buffer but none are left and it can't fit
138 // in the current buffer (which may not be prealloced).
139 bool flush = false;
140 if (indexCount) {
141 int32_t currIndices = fIndexPool->currentBufferIndices();
142 if (*indexCount > currIndices &&
143 (!fIndexPool->preallocatedBuffersRemaining() &&
144 *indexCount <= fIndexPool->preallocatedBufferIndices())) {
145
146 flush = true;
147 }
148 *indexCount = currIndices;
149 }
150 if (vertexCount) {
151 int32_t currVertices = fVertexPool->currentBufferVertices(vertexStride);
152 if (*vertexCount > currVertices &&
153 (!fVertexPool->preallocatedBuffersRemaining() &&
154 *vertexCount <= fVertexPool->preallocatedBufferVertices(vertexStrid e))) {
155
156 flush = true;
157 }
158 *vertexCount = currVertices;
159 }
160 return flush;
161 }
162
163 bool GrFlushToGpuDrawTarget::onReserveVertexSpace(size_t vertexSize,
164 int vertexCount,
165 void** vertices) {
166 GeometryPoolState& poolState = fGeoPoolStateStack.back();
167 SkASSERT(vertexCount > 0);
168 SkASSERT(vertices);
169 SkASSERT(0 == poolState.fUsedPoolVertexBytes);
170
171 *vertices = fVertexPool->makeSpace(vertexSize,
172 vertexCount,
173 &poolState.fPoolVertexBuffer,
174 &poolState.fPoolStartVertex);
175 return SkToBool(*vertices);
176 }
177
178 bool GrFlushToGpuDrawTarget::onReserveIndexSpace(int indexCount, void** indices) {
179 GeometryPoolState& poolState = fGeoPoolStateStack.back();
180 SkASSERT(indexCount > 0);
181 SkASSERT(indices);
182 SkASSERT(0 == poolState.fUsedPoolIndexBytes);
183
184 *indices = fIndexPool->makeSpace(indexCount,
185 &poolState.fPoolIndexBuffer,
186 &poolState.fPoolStartIndex);
187 return SkToBool(*indices);
188 }
189
190 void GrFlushToGpuDrawTarget::releaseReservedVertexSpace() {
191 GeometryPoolState& poolState = fGeoPoolStateStack.back();
192 const GeometrySrcState& geoSrc = this->getGeomSrc();
193
194 // If we get a release vertex space call then our current source should eith er be reserved
195 // or array (which we copied into reserved space).
196 SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
197
198 // When the caller reserved vertex buffer space we gave it back a pointer
199 // provided by the vertex buffer pool. At each draw we tracked the largest
200 // offset into the pool's pointer that was referenced. Now we return to the
201 // pool any portion at the tail of the allocation that no draw referenced.
202 size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount;
203 fVertexPool->putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
204 poolState.fUsedPoolVertexBytes = 0;
205 poolState.fPoolVertexBuffer = NULL;
206 poolState.fPoolStartVertex = 0;
207 }
208
209 void GrFlushToGpuDrawTarget::releaseReservedIndexSpace() {
210 GeometryPoolState& poolState = fGeoPoolStateStack.back();
211 const GeometrySrcState& geoSrc = this->getGeomSrc();
212
213 // If we get a release index space call then our current source should eithe r be reserved
214 // or array (which we copied into reserved space).
215 SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
216
217 // Similar to releaseReservedVertexSpace we return any unused portion at
218 // the tail
219 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
220 fIndexPool->putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
221 poolState.fUsedPoolIndexBytes = 0;
222 poolState.fPoolIndexBuffer = NULL;
223 poolState.fPoolStartIndex = 0;
224 }
225
226 void GrFlushToGpuDrawTarget::geometrySourceWillPush() {
227 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
228 poolState.fUsedPoolVertexBytes = 0;
229 poolState.fUsedPoolIndexBytes = 0;
230 #ifdef SK_DEBUG
231 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
232 poolState.fPoolStartVertex = ~0;
233 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
234 poolState.fPoolStartIndex = ~0;
235 #endif
236 }
237
238 void GrFlushToGpuDrawTarget::geometrySourceWillPop(const GeometrySrcState& resto redState) {
239 SkASSERT(fGeoPoolStateStack.count() > 1);
240 fGeoPoolStateStack.pop_back();
241 GeometryPoolState& poolState = fGeoPoolStateStack.back();
242 // we have to assume that any slack we had in our vertex/index data
243 // is now unreleasable because data may have been appended later in the
244 // pool.
245 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) {
246 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta te.fVertexCount;
247 }
248 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) {
249 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC ount;
250 }
251 }
OLDNEW
« no previous file with comments | « src/gpu/GrFlushToGpuDrawTarget.h ('k') | src/gpu/GrInOrderDrawBuffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698