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

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

Issue 628453002: Create a single command buffer for GrInOrderDrawBuffer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 2 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/GrInOrderDrawBuffer.h ('k') | src/gpu/GrTRecorder.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"
11 #include "GrDrawTargetCaps.h" 11 #include "GrDrawTargetCaps.h"
12 #include "GrTextStrike.h" 12 #include "GrTextStrike.h"
13 #include "GrGpu.h" 13 #include "GrGpu.h"
14 #include "GrTemplates.h" 14 #include "GrTemplates.h"
15 #include "GrTexture.h" 15 #include "GrTexture.h"
16 16
17 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, 17 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
18 GrVertexBufferAllocPool* vertexPool, 18 GrVertexBufferAllocPool* vertexPool,
19 GrIndexBufferAllocPool* indexPool) 19 GrIndexBufferAllocPool* indexPool)
20 : GrDrawTarget(gpu->getContext()) 20 : GrDrawTarget(gpu->getContext())
21 , fCmdBuffer(kCmdBufferInitialSizeInBytes)
22 , fLastState(NULL)
23 , fLastClip(NULL)
21 , fDstGpu(gpu) 24 , fDstGpu(gpu)
22 , fClipSet(true) 25 , fClipSet(true)
23 , fClipProxyState(kUnknown_ClipProxyState) 26 , fClipProxyState(kUnknown_ClipProxyState)
24 , fVertexPool(*vertexPool) 27 , fVertexPool(*vertexPool)
25 , fIndexPool(*indexPool) 28 , fIndexPool(*indexPool)
26 , fFlushing(false) 29 , fFlushing(false)
27 , fDrawID(0) { 30 , fDrawID(0) {
28 31
29 fDstGpu->ref(); 32 fDstGpu->ref();
30 fCaps.reset(SkRef(fDstGpu->caps())); 33 fCaps.reset(SkRef(fDstGpu->caps()));
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 return fClipProxy.contains(devBounds); 212 return fClipProxy.contains(devBounds);
210 } 213 }
211 SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX), 214 SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX),
212 SkIntToScalar(this->getClip()->fOrigin.fY)}; 215 SkIntToScalar(this->getClip()->fOrigin.fY)};
213 SkRect clipSpaceBounds = devBounds; 216 SkRect clipSpaceBounds = devBounds;
214 clipSpaceBounds.offset(originOffset); 217 clipSpaceBounds.offset(originOffset);
215 return this->getClip()->fClipStack->quickContains(clipSpaceBounds); 218 return this->getClip()->fClipStack->quickContains(clipSpaceBounds);
216 } 219 }
217 220
218 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { 221 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
222 SkASSERT(!fCmdBuffer.empty());
219 SkASSERT(info.isInstanced()); 223 SkASSERT(info.isInstanced());
220 224
221 const GeometrySrcState& geomSrc = this->getGeomSrc(); 225 const GeometrySrcState& geomSrc = this->getGeomSrc();
222 const GrDrawState& drawState = this->getDrawState(); 226 const GrDrawState& drawState = this->getDrawState();
223 227
224 // we only attempt to concat the case when reserved verts are used with a cl ient-specified index 228 // we only attempt to concat the case when reserved verts are used with a cl ient-specified index
225 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated 229 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
226 // between draws. 230 // between draws.
227 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || 231 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
228 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { 232 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
229 return 0; 233 return 0;
230 } 234 }
231 // Check if there is a draw info that is compatible that uses the same VB fr om the pool and 235 // Check if there is a draw info that is compatible that uses the same VB fr om the pool and
232 // the same IB 236 // the same IB
233 if (kDraw_Cmd != strip_trace_bit(fCmds.back())) { 237 if (kDraw_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) {
234 return 0; 238 return 0;
235 } 239 }
236 240
237 Draw* draw = &fDraws.back(); 241 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
238 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 242 GeometryPoolState& poolState = fGeoPoolStateStack.back();
239 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; 243 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
240 244
241 if (!draw->isInstanced() || 245 if (!draw->fInfo.isInstanced() ||
242 draw->verticesPerInstance() != info.verticesPerInstance() || 246 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
243 draw->indicesPerInstance() != info.indicesPerInstance() || 247 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
244 draw->vertexBuffer() != vertexBuffer || 248 draw->vertexBuffer() != vertexBuffer ||
245 draw->indexBuffer() != geomSrc.fIndexBuffer) { 249 draw->indexBuffer() != geomSrc.fIndexBuffer) {
246 return 0; 250 return 0;
247 } 251 }
248 // info does not yet account for the offset from the start of the pool's VB while the previous 252 // info does not yet account for the offset from the start of the pool's VB while the previous
249 // draw record does. 253 // draw record does.
250 int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex(); 254 int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex();
251 if (draw->startVertex() + draw->vertexCount() != adjustedStartVertex) { 255 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != adjustedStartVe rtex) {
252 return 0; 256 return 0;
253 } 257 }
254 258
255 SkASSERT(poolState.fPoolStartVertex == draw->startVertex() + draw->vertexCou nt()); 259 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fIn fo.vertexCount());
256 260
257 // how many instances can be concat'ed onto draw given the size of the index buffer 261 // how many instances can be concat'ed onto draw given the size of the index buffer
258 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI nstance(); 262 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI nstance();
259 instancesToConcat -= draw->instanceCount(); 263 instancesToConcat -= draw->fInfo.instanceCount();
260 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); 264 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
261 265
262 // update the amount of reserved vertex data actually referenced in draws 266 // update the amount of reserved vertex data actually referenced in draws
263 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * 267 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() *
264 drawState.getVertexStride(); 268 drawState.getVertexStride();
265 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert exBytes); 269 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert exBytes);
266 270
267 draw->adjustInstanceCount(instancesToConcat); 271 draw->fInfo.adjustInstanceCount(instancesToConcat);
268 272
269 // update last fGpuCmdMarkers to include any additional trace markers that h ave been added 273 // update last fGpuCmdMarkers to include any additional trace markers that h ave been added
270 if (this->getActiveTraceMarkers().count() > 0) { 274 if (this->getActiveTraceMarkers().count() > 0) {
271 if (cmd_has_trace_marker(fCmds.back())) { 275 if (cmd_has_trace_marker(draw->fType)) {
272 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); 276 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
273 } else { 277 } else {
274 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); 278 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
275 fCmds.back() = add_trace_bit(fCmds.back()); 279 draw->fType = add_trace_bit(draw->fType);
276 } 280 }
277 } 281 }
278 282
279 return instancesToConcat; 283 return instancesToConcat;
280 } 284 }
281 285
282 class AutoClipReenable { 286 class AutoClipReenable {
283 public: 287 public:
284 AutoClipReenable() : fDrawState(NULL) {} 288 AutoClipReenable() : fDrawState(NULL) {}
285 ~AutoClipReenable() { 289 ~AutoClipReenable() {
(...skipping 16 matching lines...) Expand all
302 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 306 GeometryPoolState& poolState = fGeoPoolStateStack.back();
303 const GrDrawState& drawState = this->getDrawState(); 307 const GrDrawState& drawState = this->getDrawState();
304 AutoClipReenable acr; 308 AutoClipReenable acr;
305 309
306 if (drawState.isClipState() && 310 if (drawState.isClipState() &&
307 info.getDevBounds() && 311 info.getDevBounds() &&
308 this->quickInsideClip(*info.getDevBounds())) { 312 this->quickInsideClip(*info.getDevBounds())) {
309 acr.set(this->drawState()); 313 acr.set(this->drawState());
310 } 314 }
311 315
312 if (this->needsNewClip()) { 316 this->recordClipIfNecessary();
313 this->recordClip();
314 }
315 this->recordStateIfNecessary(); 317 this->recordStateIfNecessary();
316 318
317 const GrVertexBuffer* vb; 319 const GrVertexBuffer* vb;
318 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { 320 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
319 vb = this->getGeomSrc().fVertexBuffer; 321 vb = this->getGeomSrc().fVertexBuffer;
320 } else { 322 } else {
321 vb = poolState.fPoolVertexBuffer; 323 vb = poolState.fPoolVertexBuffer;
322 } 324 }
323 325
324 const GrIndexBuffer* ib = NULL; 326 const GrIndexBuffer* ib = NULL;
325 if (info.isIndexed()) { 327 if (info.isIndexed()) {
326 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { 328 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) {
327 ib = this->getGeomSrc().fIndexBuffer; 329 ib = this->getGeomSrc().fIndexBuffer;
328 } else { 330 } else {
329 ib = poolState.fPoolIndexBuffer; 331 ib = poolState.fPoolIndexBuffer;
330 } 332 }
331 } 333 }
332 334
333 Draw* draw; 335 Draw* draw;
334 if (info.isInstanced()) { 336 if (info.isInstanced()) {
335 int instancesConcated = this->concatInstancedDraw(info); 337 int instancesConcated = this->concatInstancedDraw(info);
336 if (info.instanceCount() > instancesConcated) { 338 if (info.instanceCount() > instancesConcated) {
337 draw = this->recordDraw(info, vb, ib); 339 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, vb, ib));
338 draw->adjustInstanceCount(-instancesConcated); 340 draw->fInfo.adjustInstanceCount(-instancesConcated);
339 } else { 341 } else {
340 return; 342 return;
341 } 343 }
342 } else { 344 } else {
343 draw = this->recordDraw(info, vb, ib); 345 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, vb, ib));
344 } 346 }
347 this->recordTraceMarkersIfNecessary();
345 348
346 // Adjust the starting vertex and index when we are using reserved or array sources to 349 // Adjust the starting vertex and index when we are using reserved or array sources to
347 // compensate for the fact that the data was inserted into a larger vb/ib ow ned by the pool. 350 // compensate for the fact that the data was inserted into a larger vb/ib ow ned by the pool.
348 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { 351 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) {
349 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get VertexStride(); 352 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get VertexStride();
350 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes); 353 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes);
351 draw->adjustStartVertex(poolState.fPoolStartVertex); 354 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex);
352 } 355 }
353 356
354 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex Src) { 357 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex Src) {
355 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t ); 358 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t );
356 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by tes); 359 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by tes);
357 draw->adjustStartIndex(poolState.fPoolStartIndex); 360 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex);
358 } 361 }
359 } 362 }
360 363
361 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil l) { 364 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil l) {
362 if (this->needsNewClip()) { 365 this->recordClipIfNecessary();
363 this->recordClip();
364 }
365 // Only compare the subset of GrDrawState relevant to path stenciling? 366 // Only compare the subset of GrDrawState relevant to path stenciling?
366 this->recordStateIfNecessary(); 367 this->recordStateIfNecessary();
367 StencilPath* sp = this->recordStencilPath(path); 368 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path));
368 sp->fFill = fill; 369 sp->fFill = fill;
370 this->recordTraceMarkersIfNecessary();
369 } 371 }
370 372
371 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, 373 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path,
372 SkPath::FillType fill, const GrDeviceCoordT exture* dstCopy) { 374 SkPath::FillType fill, const GrDeviceCoordT exture* dstCopy) {
373 if (this->needsNewClip()) { 375 this->recordClipIfNecessary();
374 this->recordClip();
375 }
376 // TODO: Only compare the subset of GrDrawState relevant to path covering? 376 // TODO: Only compare the subset of GrDrawState relevant to path covering?
377 this->recordStateIfNecessary(); 377 this->recordStateIfNecessary();
378 DrawPath* cp = this->recordDrawPath(path); 378 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
379 cp->fFill = fill; 379 dp->fFill = fill;
380 if (dstCopy) { 380 if (dstCopy) {
381 cp->fDstCopy = *dstCopy; 381 dp->fDstCopy = *dstCopy;
382 } 382 }
383 this->recordTraceMarkersIfNecessary();
383 } 384 }
384 385
385 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, 386 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange,
386 const uint32_t indices[], int count, 387 const uint32_t indices[], int count,
387 const float transforms[], PathTransformTyp e transformsType, 388 const float transforms[], PathTransformTyp e transformsType,
388 SkPath::FillType fill, const GrDeviceCoord Texture* dstCopy) { 389 SkPath::FillType fill, const GrDeviceCoord Texture* dstCopy) {
389 SkASSERT(pathRange); 390 SkASSERT(pathRange);
390 SkASSERT(indices); 391 SkASSERT(indices);
391 SkASSERT(transforms); 392 SkASSERT(transforms);
392 393
393 if (this->needsNewClip()) { 394 this->recordClipIfNecessary();
394 this->recordClip();
395 }
396 this->recordStateIfNecessary(); 395 this->recordStateIfNecessary();
397 DrawPaths* dp = this->recordDrawPaths(pathRange); 396
398 dp->fIndices = SkNEW_ARRAY(uint32_t, count); // TODO: Accomplish this withou t a malloc 397 int sizeOfIndices = sizeof(uint32_t) * count;
399 memcpy(dp->fIndices, indices, sizeof(uint32_t) * count); 398 int sizeOfTransforms = sizeof(float) * count *
399 GrPathRendering::PathTransformSize(transformsType);
400
401 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (p athRange),
402 sizeOfIndices + sizeOfTra nsforms);
403 memcpy(dp->indices(), indices, sizeOfIndices);
400 dp->fCount = count; 404 dp->fCount = count;
401 405 memcpy(dp->transforms(), transforms, sizeOfTransforms);
402 const int transformsLength = GrPathRendering::PathTransformSize(transformsTy pe) * count;
403 dp->fTransforms = SkNEW_ARRAY(float, transformsLength);
404 memcpy(dp->fTransforms, transforms, sizeof(float) * transformsLength);
405 dp->fTransformsType = transformsType; 406 dp->fTransformsType = transformsType;
406
407 dp->fFill = fill; 407 dp->fFill = fill;
408
409 if (dstCopy) { 408 if (dstCopy) {
410 dp->fDstCopy = *dstCopy; 409 dp->fDstCopy = *dstCopy;
411 } 410 }
411
412 this->recordTraceMarkersIfNecessary();
412 } 413 }
413 414
414 void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, 415 void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color,
415 bool canIgnoreRect, GrRenderTarget* renderTarget ) { 416 bool canIgnoreRect, GrRenderTarget* renderTarget ) {
416 SkIRect r; 417 SkIRect r;
417 if (NULL == renderTarget) { 418 if (NULL == renderTarget) {
418 renderTarget = this->drawState()->getRenderTarget(); 419 renderTarget = this->drawState()->getRenderTarget();
419 SkASSERT(renderTarget); 420 SkASSERT(renderTarget);
420 } 421 }
421 if (NULL == rect) { 422 if (NULL == rect) {
422 // We could do something smart and remove previous draws and clears to 423 // We could do something smart and remove previous draws and clears to
423 // the current render target. If we get that smart we have to make sure 424 // the current render target. If we get that smart we have to make sure
424 // those draws aren't read before this clear (render-to-texture). 425 // those draws aren't read before this clear (render-to-texture).
425 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); 426 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
426 rect = &r; 427 rect = &r;
427 } 428 }
428 Clear* clr = this->recordClear(renderTarget); 429 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
429 GrColorIsPMAssert(color); 430 GrColorIsPMAssert(color);
430 clr->fColor = color; 431 clr->fColor = color;
431 clr->fRect = *rect; 432 clr->fRect = *rect;
432 clr->fCanIgnoreRect = canIgnoreRect; 433 clr->fCanIgnoreRect = canIgnoreRect;
434 this->recordTraceMarkersIfNecessary();
433 } 435 }
434 436
435 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { 437 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
436 if (!this->caps()->discardRenderTargetSupport()) { 438 if (!this->caps()->discardRenderTargetSupport()) {
437 return; 439 return;
438 } 440 }
439 if (NULL == renderTarget) { 441 if (NULL == renderTarget) {
440 renderTarget = this->drawState()->getRenderTarget(); 442 renderTarget = this->drawState()->getRenderTarget();
441 SkASSERT(renderTarget); 443 SkASSERT(renderTarget);
442 } 444 }
443 Clear* clr = this->recordClear(renderTarget); 445 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
444 clr->fColor = GrColor_ILLEGAL; 446 clr->fColor = GrColor_ILLEGAL;
447 this->recordTraceMarkersIfNecessary();
445 } 448 }
446 449
447 void GrInOrderDrawBuffer::reset() { 450 void GrInOrderDrawBuffer::reset() {
448 SkASSERT(1 == fGeoPoolStateStack.count()); 451 SkASSERT(1 == fGeoPoolStateStack.count());
449 this->resetVertexSource(); 452 this->resetVertexSource();
450 this->resetIndexSource(); 453 this->resetIndexSource();
451 454
452 fCmds.reset(); 455 fCmdBuffer.reset();
453 fDraws.reset(); 456 fLastState = NULL;
454 fStencilPaths.reset(); 457 fLastClip = NULL;
455 fDrawPath.reset();
456 fDrawPaths.reset();
457 fStates.reset();
458 fClears.reset();
459 fVertexPool.reset(); 458 fVertexPool.reset();
460 fIndexPool.reset(); 459 fIndexPool.reset();
461 fClips.reset();
462 fCopySurfaces.reset();
463 fGpuCmdMarkers.reset(); 460 fGpuCmdMarkers.reset();
464 fClipSet = true; 461 fClipSet = true;
465 } 462 }
466 463
467 void GrInOrderDrawBuffer::flush() { 464 void GrInOrderDrawBuffer::flush() {
468 if (fFlushing) { 465 if (fFlushing) {
469 return; 466 return;
470 } 467 }
471 468
472 this->getContext()->getFontCache()->updateTextures(); 469 this->getContext()->getFontCache()->updateTextures();
473 470
474 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); 471 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
475 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); 472 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
476 473
477 int numCmds = fCmds.count(); 474 if (fCmdBuffer.empty()) {
478 if (0 == numCmds) {
479 return; 475 return;
480 } 476 }
481 477
482 GrAutoTRestore<bool> flushRestore(&fFlushing); 478 GrAutoTRestore<bool> flushRestore(&fFlushing);
483 fFlushing = true; 479 fFlushing = true;
484 480
485 fVertexPool.unmap(); 481 fVertexPool.unmap();
486 fIndexPool.unmap(); 482 fIndexPool.unmap();
487 483
488 GrDrawTarget::AutoClipRestore acr(fDstGpu); 484 GrDrawTarget::AutoClipRestore acr(fDstGpu);
489 AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit); 485 AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit);
490 486
491 GrDrawState* prevDrawState = SkRef(fDstGpu->drawState()); 487 GrDrawState* prevDrawState = SkRef(fDstGpu->drawState());
492 488
493 GrClipData clipData; 489 CmdBuffer::Iter iter(fCmdBuffer);
494 490
495 StateAllocator::Iter stateIter(&fStates); 491 int currCmdMarker = 0;
496 ClipAllocator::Iter clipIter(&fClips); 492 fDstGpu->saveActiveTraceMarkers();
497 ClearAllocator::Iter clearIter(&fClears);
498 DrawAllocator::Iter drawIter(&fDraws);
499 StencilPathAllocator::Iter stencilPathIter(&fStencilPaths);
500 DrawPathAllocator::Iter drawPathIter(&fDrawPath);
501 DrawPathsAllocator::Iter drawPathsIter(&fDrawPaths);
502 CopySurfaceAllocator::Iter copySurfaceIter(&fCopySurfaces);
503 493
504 int currCmdMarker = 0; 494 while (iter.next()) {
505
506 fDstGpu->saveActiveTraceMarkers();
507 for (int c = 0; c < numCmds; ++c) {
508 GrGpuTraceMarker newMarker("", -1); 495 GrGpuTraceMarker newMarker("", -1);
509 SkString traceString; 496 SkString traceString;
510 if (cmd_has_trace_marker(fCmds[c])) { 497 if (cmd_has_trace_marker(iter->fType)) {
511 traceString = fGpuCmdMarkers[currCmdMarker].toString(); 498 traceString = fGpuCmdMarkers[currCmdMarker].toString();
512 newMarker.fMarker = traceString.c_str(); 499 newMarker.fMarker = traceString.c_str();
513 fDstGpu->addGpuTraceMarker(&newMarker); 500 fDstGpu->addGpuTraceMarker(&newMarker);
514 ++currCmdMarker; 501 ++currCmdMarker;
515 } 502 }
516 switch (strip_trace_bit(fCmds[c])) { 503
517 case kDraw_Cmd: { 504 SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) ||
518 SkASSERT(fDstGpu->drawState() != prevDrawState); 505 kStencilPath_Cmd == strip_trace_bit(iter->fTyp e) ||
519 SkAssertResult(drawIter.next()); 506 kDrawPath_Cmd == strip_trace_bit(iter->fType) ||
520 fDstGpu->setVertexSourceToBuffer(drawIter->vertexBuffer()); 507 kDrawPaths_Cmd == strip_trace_bit(iter->fType) );
521 if (drawIter->isIndexed()) { 508 SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState);
522 fDstGpu->setIndexSourceToBuffer(drawIter->indexBuffer()); 509
523 } 510 iter->execute(fDstGpu);
524 fDstGpu->executeDraw(*drawIter); 511
525 break; 512 if (cmd_has_trace_marker(iter->fType)) {
526 }
527 case kStencilPath_Cmd: {
528 SkASSERT(fDstGpu->drawState() != prevDrawState);
529 SkAssertResult(stencilPathIter.next());
530 fDstGpu->stencilPath(stencilPathIter->path(), stencilPathIter->f Fill);
531 break;
532 }
533 case kDrawPath_Cmd: {
534 SkASSERT(fDstGpu->drawState() != prevDrawState);
535 SkAssertResult(drawPathIter.next());
536 fDstGpu->executeDrawPath(drawPathIter->path(), drawPathIter->fFi ll,
537 drawPathIter->fDstCopy.texture() ?
538 &drawPathIter->fDstCopy :
539 NULL);
540 break;
541 }
542 case kDrawPaths_Cmd: {
543 SkASSERT(fDstGpu->drawState() != prevDrawState);
544 SkAssertResult(drawPathsIter.next());
545 const GrDeviceCoordTexture* dstCopy =
546 drawPathsIter->fDstCopy.texture() ? &drawPathsIter->fDstCopy : NULL;
547 fDstGpu->executeDrawPaths(drawPathsIter->pathRange(),
548 drawPathsIter->fIndices,
549 drawPathsIter->fCount,
550 drawPathsIter->fTransforms,
551 drawPathsIter->fTransformsType,
552 drawPathsIter->fFill,
553 dstCopy);
554 break;
555 }
556 case kSetState_Cmd:
557 SkAssertResult(stateIter.next());
558 fDstGpu->setDrawState(stateIter.get());
559 break;
560 case kSetClip_Cmd:
561 SkAssertResult(clipIter.next());
562 clipData.fClipStack = &clipIter->fStack;
563 clipData.fOrigin = clipIter->fOrigin;
564 fDstGpu->setClip(&clipData);
565 break;
566 case kClear_Cmd:
567 SkAssertResult(clearIter.next());
568 if (GrColor_ILLEGAL == clearIter->fColor) {
569 fDstGpu->discard(clearIter->renderTarget());
570 } else {
571 fDstGpu->clear(&clearIter->fRect,
572 clearIter->fColor,
573 clearIter->fCanIgnoreRect,
574 clearIter->renderTarget());
575 }
576 break;
577 case kCopySurface_Cmd:
578 SkAssertResult(copySurfaceIter.next());
579 fDstGpu->copySurface(copySurfaceIter->dst(),
580 copySurfaceIter->src(),
581 copySurfaceIter->fSrcRect,
582 copySurfaceIter->fDstPoint);
583 break;
584 }
585 if (cmd_has_trace_marker(fCmds[c])) {
586 fDstGpu->removeGpuTraceMarker(&newMarker); 513 fDstGpu->removeGpuTraceMarker(&newMarker);
587 } 514 }
588 } 515 }
516
589 fDstGpu->restoreActiveTraceMarkers(); 517 fDstGpu->restoreActiveTraceMarkers();
590 // we should have consumed all the states, clips, etc.
591 SkASSERT(!stateIter.next());
592 SkASSERT(!clipIter.next());
593 SkASSERT(!clearIter.next());
594 SkASSERT(!drawIter.next());
595 SkASSERT(!copySurfaceIter.next());
596 SkASSERT(!stencilPathIter.next());
597 SkASSERT(!drawPathIter.next());
598 SkASSERT(!drawPathsIter.next());
599
600 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); 518 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
601 519
602 fDstGpu->setDrawState(prevDrawState); 520 fDstGpu->setDrawState(prevDrawState);
603 prevDrawState->unref(); 521 prevDrawState->unref();
604 this->reset(); 522 this->reset();
605 ++fDrawID; 523 ++fDrawID;
606 } 524 }
607 525
526 void GrInOrderDrawBuffer::Draw::execute(GrDrawTarget* gpu) {
527 gpu->setVertexSourceToBuffer(this->vertexBuffer());
528 if (fInfo.isIndexed()) {
529 gpu->setIndexSourceToBuffer(this->indexBuffer());
530 }
531 gpu->executeDraw(fInfo);
532 }
533
534 void GrInOrderDrawBuffer::StencilPath::execute(GrDrawTarget* gpu) {
535 gpu->stencilPath(this->path(), fFill);
536 }
537
538 void GrInOrderDrawBuffer::DrawPath::execute(GrDrawTarget* gpu) {
539 gpu->executeDrawPath(this->path(), fFill, fDstCopy.texture() ? &fDstCopy : N ULL);
540 }
541
542 void GrInOrderDrawBuffer::DrawPaths::execute(GrDrawTarget* gpu) {
543 gpu->executeDrawPaths(this->pathRange(), this->indices(), fCount, this->tran sforms(),
544 fTransformsType, fFill, fDstCopy.texture() ? &fDstCopy : NULL);
545 }
546
547 void GrInOrderDrawBuffer::SetState::execute(GrDrawTarget* gpu) {
548 gpu->setDrawState(&fState);
549 }
550
551 void GrInOrderDrawBuffer::SetClip::execute(GrDrawTarget* gpu) {
552 // Our fClipData is referenced directly, so we must remain alive for the ent ire
553 // duration of the flush (after which the gpu's previous clip is restored).
554 gpu->setClip(&fClipData);
555 }
556
557 void GrInOrderDrawBuffer::Clear::execute(GrDrawTarget* gpu) {
558 if (GrColor_ILLEGAL == fColor) {
559 gpu->discard(this->renderTarget());
560 } else {
561 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
562 }
563 }
564
565 void GrInOrderDrawBuffer::CopySurface::execute(GrDrawTarget* gpu) {
566 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
567 }
568
608 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, 569 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
609 GrSurface* src, 570 GrSurface* src,
610 const SkIRect& srcRect, 571 const SkIRect& srcRect,
611 const SkIPoint& dstPoint) { 572 const SkIPoint& dstPoint) {
612 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { 573 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) {
613 CopySurface* cs = this->recordCopySurface(dst, src); 574 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst , src));
614 cs->fSrcRect = srcRect; 575 cs->fSrcRect = srcRect;
615 cs->fDstPoint = dstPoint; 576 cs->fDstPoint = dstPoint;
577 this->recordTraceMarkersIfNecessary();
616 return true; 578 return true;
617 } else { 579 } else {
618 return false; 580 return false;
619 } 581 }
620 } 582 }
621 583
622 bool GrInOrderDrawBuffer::onCanCopySurface(GrSurface* dst, 584 bool GrInOrderDrawBuffer::onCanCopySurface(GrSurface* dst,
623 GrSurface* src, 585 GrSurface* src,
624 const SkIRect& srcRect, 586 const SkIRect& srcRect,
625 const SkIPoint& dstPoint) { 587 const SkIPoint& dstPoint) {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta te.fVertexCount; 787 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta te.fVertexCount;
826 } 788 }
827 if (kReserved_GeometrySrcType == restoredState.fIndexSrc || 789 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
828 kArray_GeometrySrcType == restoredState.fIndexSrc) { 790 kArray_GeometrySrcType == restoredState.fIndexSrc) {
829 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * 791 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
830 restoredState.fIndexCount; 792 restoredState.fIndexCount;
831 } 793 }
832 } 794 }
833 795
834 void GrInOrderDrawBuffer::recordStateIfNecessary() { 796 void GrInOrderDrawBuffer::recordStateIfNecessary() {
835 if (fStates.empty()) { 797 if (!fLastState) {
836 this->convertDrawStateToPendingExec(&fStates.push_back(this->getDrawStat e())); 798 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->get DrawState()));
837 this->addToCmdBuffer(kSetState_Cmd); 799 fLastState = &ss->fState;
800 this->convertDrawStateToPendingExec(fLastState);
801 this->recordTraceMarkersIfNecessary();
838 return; 802 return;
839 } 803 }
840 const GrDrawState& curr = this->getDrawState(); 804 const GrDrawState& curr = this->getDrawState();
841 GrDrawState& prev = fStates.back(); 805 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) {
842 switch (GrDrawState::CombineIfPossible(prev, curr, *this->caps())) {
843 case GrDrawState::kIncompatible_CombinedState: 806 case GrDrawState::kIncompatible_CombinedState:
844 this->convertDrawStateToPendingExec(&fStates.push_back(curr)); 807 fLastState = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr)) ->fState;
845 this->addToCmdBuffer(kSetState_Cmd); 808 this->convertDrawStateToPendingExec(fLastState);
809 this->recordTraceMarkersIfNecessary();
846 break; 810 break;
847 case GrDrawState::kA_CombinedState: 811 case GrDrawState::kA_CombinedState:
848 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. 812 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA.
849 break; 813 break;
850 case GrDrawState::kB_CombinedState: 814 case GrDrawState::kB_CombinedState:
851 // prev has already been converted to pending execution. That is a o ne-way ticket. 815 // prev has already been converted to pending execution. That is a o ne-way ticket.
852 // So here we just delete prev and push back a new copy of curr. Not e that this 816 // So here we just destruct the previous state and reinit with a new copy of curr.
853 // goes away when we move GrIODB over to taking optimized snapshots of draw states. 817 // Note that this goes away when we move GrIODB over to taking optim ized snapshots
854 fStates.pop_back(); 818 // of draw states.
855 this->convertDrawStateToPendingExec(&fStates.push_back(curr)); 819 fLastState->~GrDrawState();
820 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr));
821 this->convertDrawStateToPendingExec(fLastState);
856 break; 822 break;
857 } 823 }
858 } 824 }
859 825
860 bool GrInOrderDrawBuffer::needsNewClip() const { 826 void GrInOrderDrawBuffer::recordClipIfNecessary() {
861 if (this->getDrawState().isClipState()) { 827 if (this->getDrawState().isClipState() &&
862 if (fClipSet && 828 fClipSet &&
863 (fClips.empty() || 829 (!fLastClip || *fLastClip != *this->getClip())) {
864 fClips.back().fStack != *this->getClip()->fClipStack || 830 fLastClip = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetClip, (this->getCli p()))->fClipData;
865 fClips.back().fOrigin != this->getClip()->fOrigin)) { 831 this->recordTraceMarkersIfNecessary();
866 return true; 832 fClipSet = false;
867 }
868 }
869 return false;
870 }
871
872 void GrInOrderDrawBuffer::addToCmdBuffer(uint8_t cmd) {
873 SkASSERT(!cmd_has_trace_marker(cmd));
874 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
875 if (activeTraceMarkers.count() > 0) {
876 fCmds.push_back(add_trace_bit(cmd));
877 fGpuCmdMarkers.push_back(activeTraceMarkers);
878 } else {
879 fCmds.push_back(cmd);
880 } 833 }
881 } 834 }
882 835
883 void GrInOrderDrawBuffer::recordClip() { 836 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
884 fClips.push_back().fStack = *this->getClip()->fClipStack; 837 SkASSERT(!fCmdBuffer.empty());
885 fClips.back().fOrigin = this->getClip()->fOrigin; 838 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType));
886 fClipSet = false; 839 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
887 this->addToCmdBuffer(kSetClip_Cmd); 840 if (activeTraceMarkers.count() > 0) {
888 } 841 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType);
889 842 fGpuCmdMarkers.push_back(activeTraceMarkers);
890 GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info, 843 }
891 const GrVertexBuffer* vb,
892 const GrIndexBuffer* ib) {
893 this->addToCmdBuffer(kDraw_Cmd);
894 return GrNEW_APPEND_TO_ALLOCATOR(&fDraws, Draw, (info, vb, ib));
895 }
896
897 GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath(const G rPath* path) {
898 this->addToCmdBuffer(kStencilPath_Cmd);
899 return GrNEW_APPEND_TO_ALLOCATOR(&fStencilPaths, StencilPath, (path));
900 }
901
902 GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath(const GrPath* path) {
903 this->addToCmdBuffer(kDrawPath_Cmd);
904 return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPath, DrawPath, (path));
905 }
906
907 GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths(const GrPat hRange* pathRange) {
908 this->addToCmdBuffer(kDrawPaths_Cmd);
909 return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPaths, DrawPaths, (pathRange));
910 }
911
912 GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear(GrRenderTarget* rt) {
913 this->addToCmdBuffer(kClear_Cmd);
914 return GrNEW_APPEND_TO_ALLOCATOR(&fClears, Clear, (rt));
915 }
916
917 GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface(GrSurfa ce* dst,
918 GrSurfa ce* src) {
919 this->addToCmdBuffer(kCopySurface_Cmd);
920 return GrNEW_APPEND_TO_ALLOCATOR(&fCopySurfaces, CopySurface, (dst, src));
921 } 844 }
922 845
923 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) { 846 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {
924 INHERITED::clipWillBeSet(newClipData); 847 INHERITED::clipWillBeSet(newClipData);
925 fClipSet = true; 848 fClipSet = true;
926 fClipProxyState = kUnknown_ClipProxyState; 849 fClipProxyState = kUnknown_ClipProxyState;
927 } 850 }
OLDNEW
« no previous file with comments | « src/gpu/GrInOrderDrawBuffer.h ('k') | src/gpu/GrTRecorder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698