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

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

Issue 979493002: Split GrTargetCommands into its own files (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 9 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/GrTargetCommands.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"
11 #include "GrDefaultGeoProcFactory.h" 10 #include "GrDefaultGeoProcFactory.h"
12 #include "GrDrawTargetCaps.h"
13 #include "GrGpu.h"
14 #include "GrTemplates.h" 11 #include "GrTemplates.h"
15 #include "GrFontCache.h"
16 #include "GrTexture.h"
17 12
18 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, 13 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
19 GrVertexBufferAllocPool* vertexPool, 14 GrVertexBufferAllocPool* vertexPool,
20 GrIndexBufferAllocPool* indexPool) 15 GrIndexBufferAllocPool* indexPool)
21 : INHERITED(gpu, vertexPool, indexPool) 16 : INHERITED(gpu, vertexPool, indexPool)
22 , fCommands(gpu, vertexPool, indexPool) 17 , fCommands(gpu, vertexPool, indexPool)
23 , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4) 18 , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
24 , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4) 19 , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
25 , fDrawID(0) { 20 , fDrawID(0) {
26 21
27 SkASSERT(vertexPool); 22 SkASSERT(vertexPool);
28 SkASSERT(indexPool); 23 SkASSERT(indexPool);
29 } 24 }
30 25
31 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() { 26 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
32 this->reset(); 27 this->reset();
33 } 28 }
34 29
35 void GrTargetCommands::closeBatch() {
36 if (fDrawBatch) {
37 fBatchTarget.resetNumberOfDraws();
38 fDrawBatch->execute(NULL, fPrevState);
39 fDrawBatch->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws());
40 fDrawBatch = NULL;
41 }
42 }
43
44 //////////////////////////////////////////////////////////////////////////////// 30 ////////////////////////////////////////////////////////////////////////////////
45 31
46 /** We always use per-vertex colors so that rects can be batched across color ch anges. Sometimes we 32 /** We always use per-vertex colors so that rects can be batched across color ch anges. Sometimes we
47 have explicit local coords and sometimes not. We *could* always provide expl icit local coords 33 have explicit local coords and sometimes not. We *could* always provide expl icit local coords
48 and just duplicate the positions when the caller hasn't provided a local coo rd rect, but we 34 and just duplicate the positions when the caller hasn't provided a local coo rd rect, but we
49 haven't seen a use case which frequently switches between local rect and no local rect draws. 35 haven't seen a use case which frequently switches between local rect and no local rect draws.
50 36
51 The color param is used to determine whether the opaque hint can be set on t he draw state. 37 The color param is used to determine whether the opaque hint can be set on t he draw state.
52 The caller must populate the vertex colors itself. 38 The caller must populate the vertex colors itself.
53 39
54 The vertex attrib order is always pos, color, [local coords]. 40 The vertex attrib order is always pos, color, [local coords].
55 */ 41 */
56 static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords, 42 static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords,
57 GrColor color, 43 GrColor color,
58 const SkMatrix* localMatrix) { 44 const SkMatrix* localMatrix) {
59 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType | 45 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
60 GrDefaultGeoProcFactory::kColor_GPType; 46 GrDefaultGeoProcFactory::kColor_GPType;
61 flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPTyp e : 0; 47 flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPTyp e : 0;
62 if (localMatrix) { 48 if (localMatrix) {
63 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *loc alMatrix, 49 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *loc alMatrix,
64 GrColorIsOpaque(color)); 50 GrColorIsOpaque(color));
65 } else { 51 } else {
66 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMa trix::I(), 52 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMa trix::I(),
67 GrColorIsOpaque(color)); 53 GrColorIsOpaque(color));
68 } 54 }
69 } 55 }
70 56
71 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin gs) {
72 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Fa ce;
73 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace);
74 if (isWinding) {
75 // Double check that it is in fact winding.
76 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace));
77 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace));
78 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace));
79 SkASSERT(!pathStencilSettings.isTwoSided());
80 }
81 return isWinding;
82 }
83
84 class RectBatch : public GrBatch { 57 class RectBatch : public GrBatch {
85 public: 58 public:
86 struct Geometry { 59 struct Geometry {
87 GrColor fColor; 60 GrColor fColor;
88 SkMatrix fViewMatrix; 61 SkMatrix fViewMatrix;
89 SkRect fRect; 62 SkRect fRect;
90 bool fHasLocalRect; 63 bool fHasLocalRect;
91 bool fHasLocalMatrix; 64 bool fHasLocalMatrix;
92 SkRect fLocalRect; 65 SkRect fLocalRect;
93 SkMatrix fLocalMatrix; 66 SkMatrix fLocalMatrix;
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 geometry.fHasLocalMatrix = false; 285 geometry.fHasLocalMatrix = false;
313 } 286 }
314 287
315 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry)); 288 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry));
316 289
317 SkRect bounds = rect; 290 SkRect bounds = rect;
318 viewMatrix.mapRect(&bounds); 291 viewMatrix.mapRect(&bounds);
319 this->drawBatch(pipelineBuilder, batch, &bounds); 292 this->drawBatch(pipelineBuilder, batch, &bounds);
320 } 293 }
321 294
322 int GrTargetCommands::concatInstancedDraw(GrInOrderDrawBuffer* iodb,
323 const GrDrawTarget::DrawInfo& info) {
324 SkASSERT(!fCmdBuffer.empty());
325 SkASSERT(info.isInstanced());
326
327 const GrIndexBuffer* ib;
328 if (!iodb->canConcatToIndexBuffer(&ib)) {
329 return 0;
330 }
331
332 // Check if there is a draw info that is compatible that uses the same VB fr om the pool and
333 // the same IB
334 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) {
335 return 0;
336 }
337
338 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
339
340 if (!draw->fInfo.isInstanced() ||
341 draw->fInfo.primitiveType() != info.primitiveType() ||
342 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
343 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
344 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
345 draw->fInfo.indexBuffer() != ib) {
346 return 0;
347 }
348 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVerte x()) {
349 return 0;
350 }
351
352 // how many instances can be concat'ed onto draw given the size of the index buffer
353 int instancesToConcat = iodb->indexCountInCurrentSource() / info.indicesPerI nstance();
354 instancesToConcat -= draw->fInfo.instanceCount();
355 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
356
357 draw->fInfo.adjustInstanceCount(instancesToConcat);
358
359 // update last fGpuCmdMarkers to include any additional trace markers that h ave been added
360 iodb->recordTraceMarkersIfNecessary(draw);
361 return instancesToConcat;
362 }
363
364 void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp, 295 void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
365 const DrawInfo& info, 296 const DrawInfo& info,
366 const PipelineInfo& pipelineInfo) { 297 const PipelineInfo& pipelineInfo) {
367 GrTargetCommands::Cmd* cmd = fCommands.recordDraw(this, gp, info, pipelineIn fo); 298 GrTargetCommands::Cmd* cmd = fCommands.recordDraw(this, gp, info, pipelineIn fo);
368 this->recordTraceMarkersIfNecessary(cmd); 299 this->recordTraceMarkersIfNecessary(cmd);
369 } 300 }
370 301
371 GrTargetCommands::Cmd* GrTargetCommands::recordDraw(
372 GrInOrderDrawBuffer* iodb,
373 const GrGeometryProcessor* gp,
374 const GrDrawTarget::DrawInfo& info,
375 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
376 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
377 this->closeBatch();
378
379 if (!this->setupPipelineAndShouldDraw(iodb, gp, pipelineInfo)) {
380 return NULL;
381 }
382
383 Draw* draw;
384 if (info.isInstanced()) {
385 int instancesConcated = this->concatInstancedDraw(iodb, info);
386 if (info.instanceCount() > instancesConcated) {
387 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
388 draw->fInfo.adjustInstanceCount(-instancesConcated);
389 } else {
390 return NULL;
391 }
392 } else {
393 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
394 }
395
396 return draw;
397 }
398
399 void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch, 302 void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
400 const PipelineInfo& pipelineInfo) { 303 const PipelineInfo& pipelineInfo) {
401 GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(this, batch, pipeline Info); 304 GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(this, batch, pipeline Info);
402 this->recordTraceMarkersIfNecessary(cmd); 305 this->recordTraceMarkersIfNecessary(cmd);
403 } 306 }
404 307
405 GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(
406 GrInOrderDrawBuffer* iodb,
407 GrBatch* batch,
408 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
409 if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) {
410 return NULL;
411 }
412
413 // Check if there is a Batch Draw we can batch with
414 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type() || !fDrawBatch) {
415 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB atchTarget));
416 return fDrawBatch;
417 }
418
419 SkASSERT(&fCmdBuffer.back() == fDrawBatch);
420 if (!fDrawBatch->fBatch->combineIfPossible(batch)) {
421 this->closeBatch();
422 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB atchTarget));
423 }
424
425 return fDrawBatch;
426 }
427
428 void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder , 308 void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder ,
429 const GrPathProcessor* pathProc, 309 const GrPathProcessor* pathProc,
430 const GrPath* path, 310 const GrPath* path,
431 const GrScissorState& scissorState, 311 const GrScissorState& scissorState,
432 const GrStencilSettings& stencilSettings ) { 312 const GrStencilSettings& stencilSettings ) {
433 GrTargetCommands::Cmd* cmd = fCommands.recordStencilPath(this, pipelineBuild er, 313 GrTargetCommands::Cmd* cmd = fCommands.recordStencilPath(this, pipelineBuild er,
434 pathProc, path, sci ssorState, 314 pathProc, path, sci ssorState,
435 stencilSettings); 315 stencilSettings);
436 this->recordTraceMarkersIfNecessary(cmd); 316 this->recordTraceMarkersIfNecessary(cmd);
437 } 317 }
438 318
439 GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath(
440 GrInOrderDrawBuffer* iod b,
441 const GrPipelineBuilder& pipelineBuilder,
442 const GrPathProcessor* p athProc,
443 const GrPath* path,
444 const GrScissorState& sc issorState,
445 const GrStencilSettings& stencilSettings) {
446 this->closeBatch();
447
448 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
449 (path, pipelineBuilder.getRenderT arget()));
450
451 sp->fScissor = scissorState;
452 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
453 sp->fViewMatrix = pathProc->viewMatrix();
454 sp->fStencil = stencilSettings;
455 return sp;
456 }
457
458 void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc, 319 void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
459 const GrPath* path, 320 const GrPath* path,
460 const GrStencilSettings& stencilSettings, 321 const GrStencilSettings& stencilSettings,
461 const PipelineInfo& pipelineInfo) { 322 const PipelineInfo& pipelineInfo) {
462 GrTargetCommands::Cmd* cmd = fCommands.recordDrawPath(this, pathProc, 323 GrTargetCommands::Cmd* cmd = fCommands.recordDrawPath(this, pathProc,
463 path, stencilSettings, 324 path, stencilSettings,
464 pipelineInfo); 325 pipelineInfo);
465 this->recordTraceMarkersIfNecessary(cmd); 326 this->recordTraceMarkersIfNecessary(cmd);
466 } 327 }
467 328
468 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath(
469 GrInOrderDrawBuffer* iodb,
470 const GrPathProcessor* pathPro c,
471 const GrPath* path,
472 const GrStencilSettings& stenc ilSettings,
473 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
474 this->closeBatch();
475
476 // TODO: Only compare the subset of GrPipelineBuilder relevant to path cover ing?
477 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
478 return NULL;
479 }
480 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
481 dp->fStencilSettings = stencilSettings;
482 return dp;
483 }
484
485 void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc, 329 void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
486 const GrPathRange* pathRange, 330 const GrPathRange* pathRange,
487 const void* indices, 331 const void* indices,
488 PathIndexType indexType, 332 PathIndexType indexType,
489 const float transformValues[], 333 const float transformValues[],
490 PathTransformType transformType, 334 PathTransformType transformType,
491 int count, 335 int count,
492 const GrStencilSettings& stencilSettings, 336 const GrStencilSettings& stencilSettings,
493 const PipelineInfo& pipelineInfo) { 337 const PipelineInfo& pipelineInfo) {
494 GrTargetCommands::Cmd* cmd = fCommands.recordDrawPaths(this, pathProc, pathR ange, 338 GrTargetCommands::Cmd* cmd = fCommands.recordDrawPaths(this, pathProc, pathR ange,
495 indices, indexType, t ransformValues, 339 indices, indexType, t ransformValues,
496 transformType, count, 340 transformType, count,
497 stencilSettings, pipe lineInfo); 341 stencilSettings, pipe lineInfo);
498 this->recordTraceMarkersIfNecessary(cmd); 342 this->recordTraceMarkersIfNecessary(cmd);
499 } 343 }
500 344
501 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
502 GrInOrderDrawBuffer* iodb,
503 const GrPathProcessor* pathPro c,
504 const GrPathRange* pathRange,
505 const void* indexValues,
506 GrDrawTarget::PathIndexType in dexType,
507 const float transformValues[],
508 GrDrawTarget::PathTransformTyp e transformType,
509 int count,
510 const GrStencilSettings& stenc ilSettings,
511 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
512 SkASSERT(pathRange);
513 SkASSERT(indexValues);
514 SkASSERT(transformValues);
515 this->closeBatch();
516
517 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
518 return NULL;
519 }
520
521 char* savedIndices;
522 float* savedTransforms;
523
524 iodb->appendIndicesAndTransforms(indexValues, indexType,
525 transformValues, transformType,
526 count, &savedIndices, &savedTransforms);
527
528 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) {
529 // The previous command was also DrawPaths. Try to collapse this call in to the one
530 // before. Note that stenciling all the paths at once, then covering, ma y not be
531 // equivalent to two separate draw calls if there is overlap. Blending w on't work,
532 // and the combined calls may also cancel each other's winding numbers i n some
533 // places. For now the winding numbers are only an issue if the fill is even/odd,
534 // because DrawPaths is currently only used for glyphs, and glyphs in th e same
535 // font tend to all wind in the same direction.
536 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
537 if (pathRange == previous->pathRange() &&
538 indexType == previous->fIndexType &&
539 transformType == previous->fTransformType &&
540 stencilSettings == previous->fStencilSettings &&
541 path_fill_type_is_winding(stencilSettings) &&
542 !pipelineInfo.willBlendWithDst(pathProc)) {
543 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexTy pe);
544 const int xformSize = GrPathRendering::PathTransformSize(transfo rmType);
545 if (&previous->fIndices[previous->fCount*indexBytes] == savedInd ices &&
546 (0 == xformSize ||
547 &previous->fTransforms[previous->fCount*xformSize] == saved Transforms)) {
548 // Fold this DrawPaths call into the one previous.
549 previous->fCount += count;
550 return NULL;
551 }
552 }
553 }
554
555 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange)) ;
556 dp->fIndices = savedIndices;
557 dp->fIndexType = indexType;
558 dp->fTransforms = savedTransforms;
559 dp->fTransformType = transformType;
560 dp->fCount = count;
561 dp->fStencilSettings = stencilSettings;
562 return dp;
563 }
564
565 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, 345 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
566 bool canIgnoreRect, GrRenderTarget* renderTarg et) { 346 bool canIgnoreRect, GrRenderTarget* renderTarg et) {
567 GrTargetCommands::Cmd* cmd = fCommands.recordClear(this, rect, color, 347 GrTargetCommands::Cmd* cmd = fCommands.recordClear(this, rect, color,
568 canIgnoreRect, renderTarg et); 348 canIgnoreRect, renderTarg et);
569 this->recordTraceMarkersIfNecessary(cmd); 349 this->recordTraceMarkersIfNecessary(cmd);
570 } 350 }
571 351
572 GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb,
573 const SkIRect* rect,
574 GrColor color,
575 bool canIgnoreRect,
576 GrRenderTarget* renderTarge t) {
577 SkASSERT(renderTarget);
578 this->closeBatch();
579
580 SkIRect r;
581 if (NULL == rect) {
582 // We could do something smart and remove previous draws and clears to
583 // the current render target. If we get that smart we have to make sure
584 // those draws aren't read before this clear (render-to-texture).
585 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
586 rect = &r;
587 }
588 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
589 GrColorIsPMAssert(color);
590 clr->fColor = color;
591 clr->fRect = *rect;
592 clr->fCanIgnoreRect = canIgnoreRect;
593 return clr;
594 }
595
596 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect, 352 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
597 bool insideClip, 353 bool insideClip,
598 GrRenderTarget* renderTarget) { 354 GrRenderTarget* renderTarget) {
599 GrTargetCommands::Cmd* cmd = fCommands.recordClearStencilClip(this, rect, 355 GrTargetCommands::Cmd* cmd = fCommands.recordClearStencilClip(this, rect,
600 insideClip, re nderTarget); 356 insideClip, re nderTarget);
601 this->recordTraceMarkersIfNecessary(cmd); 357 this->recordTraceMarkersIfNecessary(cmd);
602 } 358 }
603 359
604 GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuf fer* iodb,
605 const SkIRect& r ect,
606 bool insideClip,
607 GrRenderTarget* renderTarget) {
608 SkASSERT(renderTarget);
609 this->closeBatch();
610
611 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli p, (renderTarget));
612 clr->fRect = rect;
613 clr->fInsideClip = insideClip;
614 return clr;
615 }
616
617 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { 360 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
618 if (!this->caps()->discardRenderTargetSupport()) { 361 if (!this->caps()->discardRenderTargetSupport()) {
619 return; 362 return;
620 } 363 }
621 364
622 GrTargetCommands::Cmd* cmd = fCommands.recordDiscard(this, renderTarget); 365 GrTargetCommands::Cmd* cmd = fCommands.recordDiscard(this, renderTarget);
623 this->recordTraceMarkersIfNecessary(cmd); 366 this->recordTraceMarkersIfNecessary(cmd);
624 } 367 }
625 368
626 GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb ,
627 GrRenderTarget* renderTar get) {
628 SkASSERT(renderTarget);
629 this->closeBatch();
630
631 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
632 clr->fColor = GrColor_ILLEGAL;
633 return clr;
634 }
635
636 void GrInOrderDrawBuffer::onReset() { 369 void GrInOrderDrawBuffer::onReset() {
637 fCommands.reset(); 370 fCommands.reset();
638 fPathIndexBuffer.rewind(); 371 fPathIndexBuffer.rewind();
639 fPathTransformBuffer.rewind(); 372 fPathTransformBuffer.rewind();
640 fGpuCmdMarkers.reset(); 373 fGpuCmdMarkers.reset();
641 } 374 }
642 375
643 void GrTargetCommands::reset() {
644 fCmdBuffer.reset();
645 fPrevState = NULL;
646 fDrawBatch = NULL;
647 }
648
649 void GrInOrderDrawBuffer::onFlush() { 376 void GrInOrderDrawBuffer::onFlush() {
650 fCommands.flush(this); 377 fCommands.flush(this);
651 ++fDrawID; 378 ++fDrawID;
652 } 379 }
653 380
654 void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
655 if (fCmdBuffer.empty()) {
656 return;
657 }
658
659 // Updated every time we find a set state cmd to reflect the current state i n the playback
660 // stream.
661 SetState* currentState = NULL;
662
663 // TODO this is temporary while batch is being rolled out
664 this->closeBatch();
665 iodb->getVertexAllocPool()->unmap();
666 iodb->getIndexAllocPool()->unmap();
667 fBatchTarget.preFlush();
668
669 currentState = NULL;
670 CmdBuffer::Iter iter(fCmdBuffer);
671
672 int currCmdMarker = 0;
673
674 GrGpu* gpu = iodb->getGpu();
675
676 int i = 0;
677 while (iter.next()) {
678 i++;
679 GrGpuTraceMarker newMarker("", -1);
680 SkString traceString;
681 if (iter->isTraced()) {
682 traceString = iodb->getCmdString(currCmdMarker);
683 newMarker.fMarker = traceString.c_str();
684 gpu->addGpuTraceMarker(&newMarker);
685 ++currCmdMarker;
686 }
687
688 // TODO temporary hack
689 if (Cmd::kDrawBatch_Cmd == iter->type()) {
690 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
691 fBatchTarget.flushNext(db->fBatch->numberOfDraws());
692 continue;
693 }
694
695 if (Cmd::kSetState_Cmd == iter->type()) {
696 SetState* ss = reinterpret_cast<SetState*>(iter.get());
697
698 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we
699 // will only have GrBatch and we can delete this
700 if (ss->fPrimitiveProcessor) {
701 gpu->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
702 *ss->getPipeline(),
703 ss->fBatchTracker);
704 }
705 currentState = ss;
706 } else {
707 iter->execute(gpu, currentState);
708 }
709
710 if (iter->isTraced()) {
711 gpu->removeGpuTraceMarker(&newMarker);
712 }
713 }
714
715 // TODO see copious notes about hack
716 fBatchTarget.postFlush();
717 }
718
719 void GrTargetCommands::Draw::execute(GrGpu* gpu, const SetState* state) {
720 SkASSERT(state);
721 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state ->fDesc,
722 &state->fBatchTracker);
723 gpu->draw(args, fInfo);
724 }
725
726 void GrTargetCommands::StencilPath::execute(GrGpu* gpu, const SetState*) {
727 GrGpu::StencilPathState state;
728 state.fRenderTarget = fRenderTarget.get();
729 state.fScissor = &fScissor;
730 state.fStencil = &fStencil;
731 state.fUseHWAA = fUseHWAA;
732 state.fViewMatrix = &fViewMatrix;
733
734 gpu->stencilPath(this->path(), state);
735 }
736
737 void GrTargetCommands::DrawPath::execute(GrGpu* gpu, const SetState* state) {
738 SkASSERT(state);
739 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state ->fDesc,
740 &state->fBatchTracker);
741 gpu->drawPath(args, this->path(), fStencilSettings);
742 }
743
744 void GrTargetCommands::DrawPaths::execute(GrGpu* gpu, const SetState* state) {
745 SkASSERT(state);
746 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state ->fDesc,
747 &state->fBatchTracker);
748 gpu->drawPaths(args, this->pathRange(),
749 fIndices, fIndexType,
750 fTransforms, fTransformType,
751 fCount, fStencilSettings);
752 }
753
754 void GrTargetCommands::DrawBatch::execute(GrGpu*, const SetState* state) {
755 SkASSERT(state);
756 fBatch->generateGeometry(fBatchTarget, state->getPipeline());
757 }
758
759 void GrTargetCommands::SetState::execute(GrGpu*, const SetState*) {}
760
761 void GrTargetCommands::Clear::execute(GrGpu* gpu, const SetState*) {
762 if (GrColor_ILLEGAL == fColor) {
763 gpu->discard(this->renderTarget());
764 } else {
765 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
766 }
767 }
768
769 void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) {
770 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
771 }
772
773 void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) {
774 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
775 }
776
777 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, 381 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
778 GrSurface* src, 382 GrSurface* src,
779 const SkIRect& srcRect, 383 const SkIRect& srcRect,
780 const SkIPoint& dstPoint) { 384 const SkIPoint& dstPoint) {
781 GrTargetCommands::Cmd* cmd = fCommands.recordCopySurface(this, dst, src, 385 GrTargetCommands::Cmd* cmd = fCommands.recordCopySurface(this, dst, src,
782 srcRect, dstPoint); 386 srcRect, dstPoint);
783 this->recordTraceMarkersIfNecessary(cmd); 387 this->recordTraceMarkersIfNecessary(cmd);
784 return SkToBool(cmd); 388 return SkToBool(cmd);
785 } 389 }
786 390
787 GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrInOrderDrawBuffer* iodb,
788 GrSurface* dst,
789 GrSurface* src,
790 const SkIRect& srcRec t,
791 const SkIPoint& dstPo int) {
792 if (iodb->getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
793 this->closeBatch();
794 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst , src));
795 cs->fSrcRect = srcRect;
796 cs->fDstPoint = dstPoint;
797 return cs;
798 }
799 return NULL;
800 }
801
802 bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
803 const GrPrimitiveProcessor* pr imProc,
804 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
805 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
806 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation());
807
808 if (ss->getPipeline()->mustSkip()) {
809 fCmdBuffer.pop_back();
810 return false;
811 }
812
813 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
814 ss->getPipeline()->getInitBatchTra cker());
815
816 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
817 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
818 *ss->fPrimitiveProcessor,
819 ss->fBatchTracker) &&
820 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
821 fCmdBuffer.pop_back();
822 } else {
823 fPrevState = ss;
824 iodb->recordTraceMarkersIfNecessary(ss);
825 }
826 return true;
827 }
828
829 bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
830 GrBatch* batch,
831 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
832 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
833 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation());
834
835 if (ss->getPipeline()->mustSkip()) {
836 fCmdBuffer.pop_back();
837 return false;
838 }
839
840 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
841
842 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
843 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
844 fCmdBuffer.pop_back();
845 } else {
846 this->closeBatch();
847 fPrevState = ss;
848 iodb->recordTraceMarkersIfNecessary(ss);
849 }
850 return true;
851 }
852
853 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* c md) { 391 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* c md) {
854 if (!cmd) { 392 if (!cmd) {
855 return; 393 return;
856 } 394 }
857 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); 395 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
858 if (activeTraceMarkers.count() > 0) { 396 if (activeTraceMarkers.count() > 0) {
859 if (cmd->isTraced()) { 397 if (cmd->isTraced()) {
860 fGpuCmdMarkers.back().addSet(activeTraceMarkers); 398 fGpuCmdMarkers.back().addSet(activeTraceMarkers);
861 } else { 399 } else {
862 cmd->makeTraced(); 400 cmd->makeTraced();
863 fGpuCmdMarkers.push_back(activeTraceMarkers); 401 fGpuCmdMarkers.push_back(activeTraceMarkers);
864 } 402 }
865 } 403 }
866 } 404 }
867 405
868 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, 406 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
869 size_t vertexStride, 407 size_t vertexStride,
870 int indexCount) { 408 int indexCount) {
871 fCommands.closeBatch(); 409 fCommands.closeBatch();
872 410
873 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, i ndexCount); 411 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, i ndexCount);
874 } 412 }
OLDNEW
« no previous file with comments | « src/gpu/GrInOrderDrawBuffer.h ('k') | src/gpu/GrTargetCommands.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698