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

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

Issue 732693002: Drawstate on stack (Closed) Base URL: https://skia.googlesource.com/skia.git@real_def_gp
Patch Set: tiny fix Created 6 years, 1 month 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/GrInOrderDrawBuffer.h ('k') | src/gpu/GrOptDrawState.h » ('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 2011 Google Inc. 2 * Copyright 2011 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 #include "GrInOrderDrawBuffer.h" 8 #include "GrInOrderDrawBuffer.h"
9 9
10 #include "GrBufferAllocPool.h" 10 #include "GrBufferAllocPool.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 kTraceCmdBit = 0x80, 126 kTraceCmdBit = 0x80,
127 kCmdMask = 0x7f, 127 kCmdMask = 0x7f,
128 }; 128 };
129 129
130 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; } 130 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; }
131 131
132 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } 132 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; }
133 133
134 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr aceCmdBit); } 134 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr aceCmdBit); }
135 135
136 void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect, 136 void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
137 const SkRect& rect,
137 const SkRect* localRect, 138 const SkRect* localRect,
138 const SkMatrix* localMatrix) { 139 const SkMatrix* localMatrix) {
139 GrDrawState* drawState = this->drawState(); 140 GrDrawState::AutoRestoreEffects are(ds);
140 GrDrawState::AutoRestoreEffects are(drawState);
141 141
142 GrColor color = drawState->getColor(); 142 GrColor color = ds->getColor();
143 set_vertex_attributes(ds, SkToBool(localRect), color);
143 144
144 set_vertex_attributes(drawState, SkToBool(localRect), color); 145 AutoReleaseGeometry geo(this, 4, ds->getVertexStride(), 0);
145
146 AutoReleaseGeometry geo(this, 4, 0);
147 if (!geo.succeeded()) { 146 if (!geo.succeeded()) {
148 SkDebugf("Failed to get space for vertices!\n"); 147 SkDebugf("Failed to get space for vertices!\n");
149 return; 148 return;
150 } 149 }
151 150
152 // Go to device coords to allow batching across matrix changes 151 // Go to device coords to allow batching across matrix changes
153 SkMatrix matrix = drawState->getViewMatrix(); 152 SkMatrix matrix = ds->getViewMatrix();
154 153
155 // When the caller has provided an explicit source rect for a stage then we don't want to 154 // When the caller has provided an explicit source rect for a stage then we don't want to
156 // modify that stage's matrix. Otherwise if the effect is generating its sou rce rect from 155 // modify that stage's matrix. Otherwise if the effect is generating its sou rce rect from
157 // the vertex positions then we have to account for the view matrix change. 156 // the vertex positions then we have to account for the view matrix change.
158 GrDrawState::AutoViewMatrixRestore avmr; 157 GrDrawState::AutoViewMatrixRestore avmr;
159 if (!avmr.setIdentity(drawState)) { 158 if (!avmr.setIdentity(ds)) {
160 return; 159 return;
161 } 160 }
162 161
163 size_t vstride = drawState->getVertexStride(); 162 size_t vstride = ds->getVertexStride();
164 163
165 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom , vstride); 164 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom , vstride);
166 matrix.mapPointsWithStride(geo.positions(), vstride, 4); 165 matrix.mapPointsWithStride(geo.positions(), vstride, 4);
167 166
168 SkRect devBounds; 167 SkRect devBounds;
169 // since we already computed the dev verts, set the bounds hint. This will h elp us avoid 168 // since we already computed the dev verts, set the bounds hint. This will h elp us avoid
170 // unnecessary clipping in our onDraw(). 169 // unnecessary clipping in our onDraw().
171 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds); 170 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds);
172 171
173 if (localRect) { 172 if (localRect) {
174 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); 173 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
175 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset); 174 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset);
176 coords->setRectFan(localRect->fLeft, localRect->fTop, 175 coords->setRectFan(localRect->fLeft, localRect->fTop,
177 localRect->fRight, localRect->fBottom, 176 localRect->fRight, localRect->fBottom,
178 vstride); 177 vstride);
179 if (localMatrix) { 178 if (localMatrix) {
180 localMatrix->mapPointsWithStride(coords, vstride, 4); 179 localMatrix->mapPointsWithStride(coords, vstride, 4);
181 } 180 }
182 } 181 }
183 182
184 static const int kColorOffset = sizeof(SkPoint); 183 static const int kColorOffset = sizeof(SkPoint);
185 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + k ColorOffset); 184 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + k ColorOffset);
186 for (int i = 0; i < 4; ++i) { 185 for (int i = 0; i < 4; ++i) {
187 *vertColor = color; 186 *vertColor = color;
188 vertColor = (GrColor*) ((intptr_t) vertColor + vstride); 187 vertColor = (GrColor*) ((intptr_t) vertColor + vstride);
189 } 188 }
190 189
191 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer()); 190 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
192 this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds); 191 this->drawIndexedInstances(ds, kTriangles_GrPrimitiveType, 1, 4, 6, &devBoun ds);
193
194 // to ensure that stashing the drawState ptr is valid
195 SkASSERT(this->drawState() == drawState);
196 } 192 }
197 193
198 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info, 194 int GrInOrderDrawBuffer::concatInstancedDraw(const GrDrawState& ds,
195 const DrawInfo& info,
199 const GrClipMaskManager::ScissorSta te& scissorState) { 196 const GrClipMaskManager::ScissorSta te& scissorState) {
200 SkASSERT(!fCmdBuffer.empty()); 197 SkASSERT(!fCmdBuffer.empty());
201 SkASSERT(info.isInstanced()); 198 SkASSERT(info.isInstanced());
202 199
203 const GeometrySrcState& geomSrc = this->getGeomSrc(); 200 const GeometrySrcState& geomSrc = this->getGeomSrc();
204 const GrDrawState& drawState = this->getDrawState();
205 201
206 // we only attempt to concat the case when reserved verts are used with a cl ient-specified index 202 // we only attempt to concat the case when reserved verts are used with a cl ient-specified index
207 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated 203 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
208 // between draws. 204 // between draws.
209 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || 205 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
210 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { 206 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
211 return 0; 207 return 0;
212 } 208 }
213 // Check if there is a draw info that is compatible that uses the same VB fr om the pool and 209 // Check if there is a draw info that is compatible that uses the same VB fr om the pool and
214 // the same IB 210 // the same IB
(...skipping 21 matching lines...) Expand all
236 } 232 }
237 233
238 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fIn fo.vertexCount()); 234 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fIn fo.vertexCount());
239 235
240 // how many instances can be concat'ed onto draw given the size of the index buffer 236 // how many instances can be concat'ed onto draw given the size of the index buffer
241 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI nstance(); 237 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI nstance();
242 instancesToConcat -= draw->fInfo.instanceCount(); 238 instancesToConcat -= draw->fInfo.instanceCount();
243 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); 239 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
244 240
245 // update the amount of reserved vertex data actually referenced in draws 241 // update the amount of reserved vertex data actually referenced in draws
246 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * 242 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * ds.get VertexStride();
247 drawState.getVertexStride();
248 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert exBytes); 243 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert exBytes);
249 244
250 draw->fInfo.adjustInstanceCount(instancesToConcat); 245 draw->fInfo.adjustInstanceCount(instancesToConcat);
251 246
252 // update last fGpuCmdMarkers to include any additional trace markers that h ave been added 247 // update last fGpuCmdMarkers to include any additional trace markers that h ave been added
253 if (this->getActiveTraceMarkers().count() > 0) { 248 if (this->getActiveTraceMarkers().count() > 0) {
254 if (cmd_has_trace_marker(draw->fType)) { 249 if (cmd_has_trace_marker(draw->fType)) {
255 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); 250 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
256 } else { 251 } else {
257 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); 252 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
258 draw->fType = add_trace_bit(draw->fType); 253 draw->fType = add_trace_bit(draw->fType);
259 } 254 }
260 } 255 }
261 256
262 return instancesToConcat; 257 return instancesToConcat;
263 } 258 }
264 259
265 void GrInOrderDrawBuffer::onDraw(const DrawInfo& info, 260 void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds,
261 const DrawInfo& info,
266 const GrClipMaskManager::ScissorState& scissorS tate) { 262 const GrClipMaskManager::ScissorState& scissorS tate) {
267 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 263 GeometryPoolState& poolState = fGeoPoolStateStack.back();
268 const GrDrawState& drawState = this->getDrawState();
269 264
270 this->recordStateIfNecessary(GrGpu::PrimTypeToDrawType(info.primitiveType()) , 265 this->recordStateIfNecessary(ds,
266 GrGpu::PrimTypeToDrawType(info.primitiveType()) ,
271 info.getDstCopy()); 267 info.getDstCopy());
272 268
273 const GrVertexBuffer* vb; 269 const GrVertexBuffer* vb;
274 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { 270 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
275 vb = this->getGeomSrc().fVertexBuffer; 271 vb = this->getGeomSrc().fVertexBuffer;
276 } else { 272 } else {
277 vb = poolState.fPoolVertexBuffer; 273 vb = poolState.fPoolVertexBuffer;
278 } 274 }
279 275
280 const GrIndexBuffer* ib = NULL; 276 const GrIndexBuffer* ib = NULL;
281 if (info.isIndexed()) { 277 if (info.isIndexed()) {
282 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { 278 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) {
283 ib = this->getGeomSrc().fIndexBuffer; 279 ib = this->getGeomSrc().fIndexBuffer;
284 } else { 280 } else {
285 ib = poolState.fPoolIndexBuffer; 281 ib = poolState.fPoolIndexBuffer;
286 } 282 }
287 } 283 }
288 284
289 Draw* draw; 285 Draw* draw;
290 if (info.isInstanced()) { 286 if (info.isInstanced()) {
291 int instancesConcated = this->concatInstancedDraw(info, scissorState); 287 int instancesConcated = this->concatInstancedDraw(ds, info, scissorState );
292 if (info.instanceCount() > instancesConcated) { 288 if (info.instanceCount() > instancesConcated) {
293 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorStat e, vb, ib)); 289 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorStat e, vb, ib));
294 draw->fInfo.adjustInstanceCount(-instancesConcated); 290 draw->fInfo.adjustInstanceCount(-instancesConcated);
295 } else { 291 } else {
296 return; 292 return;
297 } 293 }
298 } else { 294 } else {
299 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, v b, ib)); 295 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, v b, ib));
300 } 296 }
301 this->recordTraceMarkersIfNecessary(); 297 this->recordTraceMarkersIfNecessary();
302 298
303 // Adjust the starting vertex and index when we are using reserved or array sources to 299 // Adjust the starting vertex and index when we are using reserved or array sources to
304 // compensate for the fact that the data was inserted into a larger vb/ib ow ned by the pool. 300 // compensate for the fact that the data was inserted into a larger vb/ib ow ned by the pool.
305 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { 301 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) {
306 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get VertexStride(); 302 size_t bytes = (info.vertexCount() + info.startVertex()) * ds.getVertexS tride();
307 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes); 303 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes);
308 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex); 304 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex);
309 } 305 }
310 306
311 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex Src) { 307 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex Src) {
312 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t ); 308 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t );
313 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by tes); 309 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by tes);
314 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); 310 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex);
315 } 311 }
316 } 312 }
317 313
318 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, 314 void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds,
315 const GrPath* path,
319 const GrClipMaskManager::ScissorState& s cissorState, 316 const GrClipMaskManager::ScissorState& s cissorState,
320 const GrStencilSettings& stencilSettings ) { 317 const GrStencilSettings& stencilSettings ) {
321 // Only compare the subset of GrDrawState relevant to path stenciling? 318 // Only compare the subset of GrDrawState relevant to path stenciling?
322 this->recordStateIfNecessary(GrGpu::kStencilPath_DrawType, NULL); 319 this->recordStateIfNecessary(ds, GrGpu::kStencilPath_DrawType, NULL);
323 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); 320 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path));
324 sp->fScissorState = scissorState; 321 sp->fScissorState = scissorState;
325 sp->fStencilSettings = stencilSettings; 322 sp->fStencilSettings = stencilSettings;
326 this->recordTraceMarkersIfNecessary(); 323 this->recordTraceMarkersIfNecessary();
327 } 324 }
328 325
329 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, 326 void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
327 const GrPath* path,
330 const GrClipMaskManager::ScissorState& scis sorState, 328 const GrClipMaskManager::ScissorState& scis sorState,
331 const GrStencilSettings& stencilSettings, 329 const GrStencilSettings& stencilSettings,
332 const GrDeviceCoordTexture* dstCopy) { 330 const GrDeviceCoordTexture* dstCopy) {
333 // TODO: Only compare the subset of GrDrawState relevant to path covering? 331 // TODO: Only compare the subset of GrDrawState relevant to path covering?
334 this->recordStateIfNecessary(GrGpu::kDrawPath_DrawType, dstCopy); 332 this->recordStateIfNecessary(ds, GrGpu::kDrawPath_DrawType, dstCopy);
335 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); 333 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
336 if (dstCopy) { 334 if (dstCopy) {
337 dp->fDstCopy = *dstCopy; 335 dp->fDstCopy = *dstCopy;
338 } 336 }
339 dp->fScissorState = scissorState; 337 dp->fScissorState = scissorState;
340 dp->fStencilSettings = stencilSettings; 338 dp->fStencilSettings = stencilSettings;
341 this->recordTraceMarkersIfNecessary(); 339 this->recordTraceMarkersIfNecessary();
342 } 340 }
343 341
344 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, 342 void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
343 const GrPathRange* pathRange,
345 const uint32_t indices[], 344 const uint32_t indices[],
346 int count, 345 int count,
347 const float transforms[], 346 const float transforms[],
348 PathTransformType transformsType, 347 PathTransformType transformsType,
349 const GrClipMaskManager::ScissorState& sci ssorState, 348 const GrClipMaskManager::ScissorState& sci ssorState,
350 const GrStencilSettings& stencilSettings, 349 const GrStencilSettings& stencilSettings,
351 const GrDeviceCoordTexture* dstCopy) { 350 const GrDeviceCoordTexture* dstCopy) {
352 SkASSERT(pathRange); 351 SkASSERT(pathRange);
353 SkASSERT(indices); 352 SkASSERT(indices);
354 SkASSERT(transforms); 353 SkASSERT(transforms);
355 354
356 this->recordStateIfNecessary(GrGpu::kDrawPaths_DrawType, dstCopy); 355 this->recordStateIfNecessary(ds, GrGpu::kDrawPaths_DrawType, dstCopy);
357 356
358 uint32_t* savedIndices = fPathIndexBuffer.append(count, indices); 357 uint32_t* savedIndices = fPathIndexBuffer.append(count, indices);
359 float* savedTransforms = fPathTransformBuffer.append(count * 358 float* savedTransforms = fPathTransformBuffer.append(count *
360 GrPathRendering::PathTransformSize(transformsTy pe), transforms); 359 GrPathRendering::PathTransformSize(transformsTy pe), transforms);
361 360
362 if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) { 361 if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) {
363 // The previous command was also DrawPaths. Try to collapse this call in to the one 362 // The previous command was also DrawPaths. Try to collapse this call in to the one
364 // before. Note that stencilling all the paths at once, then covering, m ay not be 363 // before. Note that stencilling all the paths at once, then covering, m ay not be
365 // equivalent to two separate draw calls if there is overlap. Blending w on't work, 364 // equivalent to two separate draw calls if there is overlap. Blending w on't work,
366 // and the combined calls may also cancel each other's winding numbers i n some 365 // and the combined calls may also cancel each other's winding numbers i n some
367 // places. For now the winding numbers are only an issue if the fill is even/odd, 366 // places. For now the winding numbers are only an issue if the fill is even/odd,
368 // because DrawPaths is currently only used for glyphs, and glyphs in th e same 367 // because DrawPaths is currently only used for glyphs, and glyphs in th e same
369 // font tend to all wind in the same direction. 368 // font tend to all wind in the same direction.
370 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); 369 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
371 if (pathRange == previous->pathRange() && 370 if (pathRange == previous->pathRange() &&
372 transformsType == previous->fTransformsType && 371 transformsType == previous->fTransformsType &&
373 scissorState == previous->fScissorState && 372 scissorState == previous->fScissorState &&
374 stencilSettings == previous->fStencilSettings && 373 stencilSettings == previous->fStencilSettings &&
375 path_fill_type_is_winding(stencilSettings) && 374 path_fill_type_is_winding(stencilSettings) &&
376 !this->getDrawState().willBlendWithDst()) { 375 !ds.willBlendWithDst()) {
377 // Fold this DrawPaths call into the one previous. 376 // Fold this DrawPaths call into the one previous.
378 previous->fCount += count; 377 previous->fCount += count;
379 return; 378 return;
380 } 379 }
381 } 380 }
382 381
383 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange)) ; 382 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange)) ;
384 dp->fIndicesLocation = savedIndices - fPathIndexBuffer.begin(); 383 dp->fIndicesLocation = savedIndices - fPathIndexBuffer.begin();
385 dp->fCount = count; 384 dp->fCount = count;
386 dp->fTransformsLocation = savedTransforms - fPathTransformBuffer.begin(); 385 dp->fTransformsLocation = savedTransforms - fPathTransformBuffer.begin();
387 dp->fTransformsType = transformsType; 386 dp->fTransformsType = transformsType;
388 dp->fScissorState = scissorState; 387 dp->fScissorState = scissorState;
389 dp->fStencilSettings = stencilSettings; 388 dp->fStencilSettings = stencilSettings;
390 if (dstCopy) { 389 if (dstCopy) {
391 dp->fDstCopy = *dstCopy; 390 dp->fDstCopy = *dstCopy;
392 } 391 }
393 392
394 this->recordTraceMarkersIfNecessary(); 393 this->recordTraceMarkersIfNecessary();
395 } 394 }
396 395
397 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, 396 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
398 bool canIgnoreRect, GrRenderTarget* renderTarg et) { 397 bool canIgnoreRect, GrRenderTarget* renderTarg et) {
398 SkASSERT(renderTarget);
399 SkIRect r; 399 SkIRect r;
400 if (NULL == renderTarget) {
401 renderTarget = this->drawState()->getRenderTarget();
402 SkASSERT(renderTarget);
403 }
404 if (NULL == rect) { 400 if (NULL == rect) {
405 // We could do something smart and remove previous draws and clears to 401 // We could do something smart and remove previous draws and clears to
406 // the current render target. If we get that smart we have to make sure 402 // the current render target. If we get that smart we have to make sure
407 // those draws aren't read before this clear (render-to-texture). 403 // those draws aren't read before this clear (render-to-texture).
408 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); 404 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
409 rect = &r; 405 rect = &r;
410 } 406 }
411 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); 407 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
412 GrColorIsPMAssert(color); 408 GrColorIsPMAssert(color);
413 clr->fColor = color; 409 clr->fColor = color;
414 clr->fRect = *rect; 410 clr->fRect = *rect;
415 clr->fCanIgnoreRect = canIgnoreRect; 411 clr->fCanIgnoreRect = canIgnoreRect;
416 this->recordTraceMarkersIfNecessary(); 412 this->recordTraceMarkersIfNecessary();
417 } 413 }
418 414
419 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect, 415 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
420 bool insideClip, 416 bool insideClip,
421 GrRenderTarget* renderTarget) { 417 GrRenderTarget* renderTarget) {
422 if (NULL == renderTarget) { 418 SkASSERT(renderTarget);
423 renderTarget = this->drawState()->getRenderTarget();
424 SkASSERT(renderTarget);
425 }
426 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli p, (renderTarget)); 419 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli p, (renderTarget));
427 clr->fRect = rect; 420 clr->fRect = rect;
428 clr->fInsideClip = insideClip; 421 clr->fInsideClip = insideClip;
429 this->recordTraceMarkersIfNecessary(); 422 this->recordTraceMarkersIfNecessary();
430 } 423 }
431 424
432 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { 425 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
433 SkASSERT(renderTarget); 426 SkASSERT(renderTarget);
434 if (!this->caps()->discardRenderTargetSupport()) { 427 if (!this->caps()->discardRenderTargetSupport()) {
435 return; 428 return;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 GrGpuTraceMarker newMarker("", -1); 479 GrGpuTraceMarker newMarker("", -1);
487 SkString traceString; 480 SkString traceString;
488 if (cmd_has_trace_marker(iter->fType)) { 481 if (cmd_has_trace_marker(iter->fType)) {
489 traceString = fGpuCmdMarkers[currCmdMarker].toString(); 482 traceString = fGpuCmdMarkers[currCmdMarker].toString();
490 newMarker.fMarker = traceString.c_str(); 483 newMarker.fMarker = traceString.c_str();
491 fDstGpu->addGpuTraceMarker(&newMarker); 484 fDstGpu->addGpuTraceMarker(&newMarker);
492 ++currCmdMarker; 485 ++currCmdMarker;
493 } 486 }
494 487
495 if (kSetState_Cmd == strip_trace_bit(iter->fType)) { 488 if (kSetState_Cmd == strip_trace_bit(iter->fType)) {
496 const SetState* ss = reinterpret_cast<const SetState*>(iter.get()); 489 SetState* ss = reinterpret_cast<SetState*>(iter.get());
497 currentOptState.reset(GrOptDrawState::Create(ss->fState, 490 currentOptState.reset(GrOptDrawState::Create(ss->fState,
498 fDstGpu, 491 fDstGpu,
499 &ss->fDstCopy, 492 &ss->fDstCopy,
500 ss->fDrawType)); 493 ss->fDrawType));
501 } else { 494 } else {
502 iter->execute(this, currentOptState.get()); 495 iter->execute(this, currentOptState.get());
503 } 496 }
504 497
505 if (cmd_has_trace_marker(iter->fType)) { 498 if (cmd_has_trace_marker(iter->fType)) {
506 fDstGpu->removeGpuTraceMarker(&newMarker); 499 fDstGpu->removeGpuTraceMarker(&newMarker);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 this->recordTraceMarkersIfNecessary(); 578 this->recordTraceMarkersIfNecessary();
586 return true; 579 return true;
587 } else if (GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) { 580 } else if (GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) {
588 GrDrawTarget::copySurface(dst, src, srcRect, dstPoint); 581 GrDrawTarget::copySurface(dst, src, srcRect, dstPoint);
589 return true; 582 return true;
590 } else { 583 } else {
591 return false; 584 return false;
592 } 585 }
593 } 586 }
594 587
595 bool GrInOrderDrawBuffer::canCopySurface(GrSurface* dst, 588 bool GrInOrderDrawBuffer::canCopySurface(const GrSurface* dst,
596 GrSurface* src, 589 const GrSurface* src,
597 const SkIRect& srcRect, 590 const SkIRect& srcRect,
598 const SkIPoint& dstPoint) { 591 const SkIPoint& dstPoint) {
599 return fDstGpu->canCopySurface(dst, src, srcRect, dstPoint) || 592 return fDstGpu->canCopySurface(dst, src, srcRect, dstPoint) ||
600 GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint); 593 GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint);
601 } 594 }
602 595
603 void GrInOrderDrawBuffer::initCopySurfaceDstDesc(const GrSurface* src, GrSurface Desc* desc) { 596 void GrInOrderDrawBuffer::initCopySurfaceDstDesc(const GrSurface* src, GrSurface Desc* desc) {
604 fDstGpu->initCopySurfaceDstDesc(src, desc); 597 fDstGpu->initCopySurfaceDstDesc(src, desc);
605 } 598 }
606 599
607 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, 600 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
601 size_t vertexStride,
608 int indexCount) { 602 int indexCount) {
609 // We use geometryHints() to know whether to flush the draw buffer. We 603 // We use geometryHints() to know whether to flush the draw buffer. We
610 // can't flush if we are inside an unbalanced pushGeometrySource. 604 // can't flush if we are inside an unbalanced pushGeometrySource.
611 // Moreover, flushing blows away vertex and index data that was 605 // Moreover, flushing blows away vertex and index data that was
612 // previously reserved. So if the vertex or index data is pulled from 606 // previously reserved. So if the vertex or index data is pulled from
613 // reserved space and won't be released by this request then we can't 607 // reserved space and won't be released by this request then we can't
614 // flush. 608 // flush.
615 bool insideGeoPush = fGeoPoolStateStack.count() > 1; 609 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
616 610
617 bool unreleasedVertexSpace = 611 bool unreleasedVertexSpace =
618 !vertexCount && 612 !vertexCount &&
619 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc; 613 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
620 614
621 bool unreleasedIndexSpace = 615 bool unreleasedIndexSpace =
622 !indexCount && 616 !indexCount &&
623 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; 617 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
624 618
625 int vcount = vertexCount; 619 int vcount = vertexCount;
626 int icount = indexCount; 620 int icount = indexCount;
627 621
628 if (!insideGeoPush && 622 if (!insideGeoPush &&
629 !unreleasedVertexSpace && 623 !unreleasedVertexSpace &&
630 !unreleasedIndexSpace && 624 !unreleasedIndexSpace &&
631 this->geometryHints(&vcount, &icount)) { 625 this->geometryHints(vertexStride, &vcount, &icount)) {
632 this->flush(); 626 this->flush();
633 } 627 }
634 } 628 }
635 629
636 bool GrInOrderDrawBuffer::geometryHints(int* vertexCount, 630 bool GrInOrderDrawBuffer::geometryHints(size_t vertexStride,
631 int* vertexCount,
637 int* indexCount) const { 632 int* indexCount) const {
638 // we will recommend a flush if the data could fit in a single 633 // we will recommend a flush if the data could fit in a single
639 // preallocated buffer but none are left and it can't fit 634 // preallocated buffer but none are left and it can't fit
640 // in the current buffer (which may not be prealloced). 635 // in the current buffer (which may not be prealloced).
641 bool flush = false; 636 bool flush = false;
642 if (indexCount) { 637 if (indexCount) {
643 int32_t currIndices = fIndexPool.currentBufferIndices(); 638 int32_t currIndices = fIndexPool.currentBufferIndices();
644 if (*indexCount > currIndices && 639 if (*indexCount > currIndices &&
645 (!fIndexPool.preallocatedBuffersRemaining() && 640 (!fIndexPool.preallocatedBuffersRemaining() &&
646 *indexCount <= fIndexPool.preallocatedBufferIndices())) { 641 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
647 642
648 flush = true; 643 flush = true;
649 } 644 }
650 *indexCount = currIndices; 645 *indexCount = currIndices;
651 } 646 }
652 if (vertexCount) { 647 if (vertexCount) {
653 size_t vertexStride = this->getDrawState().getVertexStride();
654 int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride); 648 int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride);
655 if (*vertexCount > currVertices && 649 if (*vertexCount > currVertices &&
656 (!fVertexPool.preallocatedBuffersRemaining() && 650 (!fVertexPool.preallocatedBuffersRemaining() &&
657 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride ))) { 651 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride ))) {
658 652
659 flush = true; 653 flush = true;
660 } 654 }
661 *vertexCount = currVertices; 655 *vertexCount = currVertices;
662 } 656 }
663 return flush; 657 return flush;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 // is now unreleasable because data may have been appended later in the 740 // is now unreleasable because data may have been appended later in the
747 // pool. 741 // pool.
748 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { 742 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) {
749 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta te.fVertexCount; 743 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta te.fVertexCount;
750 } 744 }
751 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { 745 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) {
752 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC ount; 746 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC ount;
753 } 747 }
754 } 748 }
755 749
756 void GrInOrderDrawBuffer::recordStateIfNecessary(GrGpu::DrawType drawType, 750 void GrInOrderDrawBuffer::recordStateIfNecessary(const GrDrawState& ds,
751 GrGpu::DrawType drawType,
757 const GrDeviceCoordTexture* dst Copy) { 752 const GrDeviceCoordTexture* dst Copy) {
758 if (!fLastState) { 753 if (!fLastState) {
759 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->get DrawState())); 754 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds));
760 fLastState = &ss->fState; 755 fLastState = &ss->fState;
761 if (dstCopy) { 756 if (dstCopy) {
762 ss->fDstCopy = *dstCopy; 757 ss->fDstCopy = *dstCopy;
763 } 758 }
764 ss->fDrawType = drawType; 759 ss->fDrawType = drawType;
765 this->convertDrawStateToPendingExec(fLastState); 760 this->convertDrawStateToPendingExec(fLastState);
766 this->recordTraceMarkersIfNecessary(); 761 this->recordTraceMarkersIfNecessary();
767 return; 762 return;
768 } 763 }
769 const GrDrawState& curr = this->getDrawState(); 764 switch (GrDrawState::CombineIfPossible(*fLastState, ds, *this->caps())) {
770 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) {
771 case GrDrawState::kIncompatible_CombinedState: { 765 case GrDrawState::kIncompatible_CombinedState: {
772 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr) ); 766 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds));
773 fLastState = &ss->fState; 767 fLastState = &ss->fState;
774 if (dstCopy) { 768 if (dstCopy) {
775 ss->fDstCopy = *dstCopy; 769 ss->fDstCopy = *dstCopy;
776 } 770 }
777 ss->fDrawType = drawType; 771 ss->fDrawType = drawType;
778 this->convertDrawStateToPendingExec(fLastState); 772 this->convertDrawStateToPendingExec(fLastState);
779 this->recordTraceMarkersIfNecessary(); 773 this->recordTraceMarkersIfNecessary();
780 break; 774 break;
781 } 775 }
782 case GrDrawState::kA_CombinedState: 776 case GrDrawState::kA_CombinedState:
783 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. 777 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA.
784 break; 778 break;
785 case GrDrawState::kB_CombinedState: 779 case GrDrawState::kB_CombinedState:
786 // prev has already been converted to pending execution. That is a o ne-way ticket. 780 // prev has already been converted to pending execution. That is a o ne-way ticket.
787 // So here we just destruct the previous state and reinit with a new copy of curr. 781 // So here we just destruct the previous state and reinit with a new copy of curr.
788 // Note that this goes away when we move GrIODB over to taking optim ized snapshots 782 // Note that this goes away when we move GrIODB over to taking optim ized snapshots
789 // of draw states. 783 // of draw states.
790 fLastState->~GrDrawState(); 784 fLastState->~GrDrawState();
791 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr)); 785 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (ds));
792 this->convertDrawStateToPendingExec(fLastState); 786 this->convertDrawStateToPendingExec(fLastState);
793 break; 787 break;
794 } 788 }
795 } 789 }
796 790
797 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { 791 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
798 SkASSERT(!fCmdBuffer.empty()); 792 SkASSERT(!fCmdBuffer.empty());
799 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); 793 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType));
800 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); 794 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
801 if (activeTraceMarkers.count() > 0) { 795 if (activeTraceMarkers.count() > 0) {
802 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); 796 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType);
803 fGpuCmdMarkers.push_back(activeTraceMarkers); 797 fGpuCmdMarkers.push_back(activeTraceMarkers);
804 } 798 }
805 } 799 }
OLDNEW
« no previous file with comments | « src/gpu/GrInOrderDrawBuffer.h ('k') | src/gpu/GrOptDrawState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698