457 {
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472 static_assert(sizeof(DrawPass::SortKey) ==
473 SkAlignTo(16 +
sizeof(
void*),
alignof(DrawPass::SortKey)));
474
476
477
478
480
482
483
484
488 if (bufferMgr->hasMappingFailed()) {
489 SKGPU_LOG_W(
"Buffer mapping has already failed; dropping draw pass!");
490 return nullptr;
491 }
492
493 GraphicsPipelineCache pipelineCache;
494
495
497 const ResourceBindingRequirements& bindingReqs =
501
502 UniformTracker geometryUniformTracker(useStorageBuffers);
503 UniformTracker shadingUniformTracker(useStorageBuffers);
504 TextureBindingTracker textureBindingTracker;
505
507 PaintParamsKeyBuilder
builder(dict);
508
509
510
511 PipelineDataGatherer gatherer(uniformLayout);
512
513
516 if (!draws->dstCopyBounds().isEmptyNegativeOrNaN()) {
518
519 SkIRect dstCopyPixelBounds = draws->dstCopyBounds().makeRoundOut().asSkIRect();
520 dstOffset = dstCopyPixelBounds.
topLeft();
523 if (!dst) {
524 SKGPU_LOG_W(
"Failed to copy destination for reading. Dropping draw pass!");
525 return nullptr;
526 }
527 }
528
529 std::vector<SortKey> keys;
530 keys.reserve(draws->renderStepCount());
531
532 for (
const DrawList::Draw&
draw : draws->fDraws.items()) {
533
534
535
536 UniquePaintParamsID shaderID;
537 const UniformDataBlock* shadingUniforms = nullptr;
538 const TextureDataBlock* paintTextures = nullptr;
539 if (
draw.fPaintParams.has_value()) {
543 : nullptr;
544 std::tie(shaderID, shadingUniforms, paintTextures) =
546 &gatherer,
547 &builder,
548 uniformLayout,
549 draw.fDrawParams.transform(),
550 draw.fPaintParams.value(),
551 curDst,
552 dstOffset,
554 }
555
556 for (
int stepIndex = 0; stepIndex <
draw.fRenderer->numRenderSteps(); ++stepIndex) {
557 const RenderStep*
const step =
draw.fRenderer->steps()[stepIndex];
558 const bool performsShading =
draw.fPaintParams.has_value() &&
step->performsShading();
559
560 GraphicsPipelineCache::Index pipelineIndex = pipelineCache.insert(
563 textureDataCache,
564 &gatherer,
565 uniformLayout,
568
569 UniformCache::Index geomUniformIndex = geometryUniformTracker.trackUniforms(
570 pipelineIndex, geometryUniforms);
571 UniformCache::Index shadingUniformIndex = shadingUniformTracker.trackUniforms(
572 pipelineIndex, performsShading ? shadingUniforms : nullptr);
573 TextureBindingCache::Index textureIndex = textureBindingTracker.trackTextures(
574 performsShading ? paintTextures : nullptr, stepTextures);
575
576 keys.push_back({&
draw, stepIndex, pipelineIndex,
577 geomUniformIndex, shadingUniformIndex, textureIndex});
578 }
579
580 passBounds.join(
draw.fDrawParams.clip().drawBounds());
581 drawPass->fDepthStencilFlags |=
draw.fRenderer->depthStencilFlags();
582 drawPass->fRequiresMSAA |=
draw.fRenderer->requiresMSAA();
583 }
584
585 if (!geometryUniformTracker.writeUniforms(bufferMgr) ||
586 !shadingUniformTracker.writeUniforms(bufferMgr)) {
587
588
589 return nullptr;
590 }
591
592
593
594
595
596
597
598
599 std::sort(keys.begin(), keys.end());
600
601
602 DrawWriter drawWriter(&drawPass->fCommandList, bufferMgr);
603 GraphicsPipelineCache::Index lastPipeline = GraphicsPipelineCache::kInvalidIndex;
605
606 SkASSERT(drawPass->fTarget->isFullyLazy() ||
608 drawPass->fCommandList.setScissor(lastScissor);
609
610 for (
const SortKey&
key : keys) {
611 const DrawList::Draw&
draw =
key.draw();
612 const RenderStep& renderStep =
key.renderStep();
613
614 const bool pipelineChange =
key.pipelineIndex() != lastPipeline;
615
616 const bool geomBindingChange = geometryUniformTracker.setCurrentUniforms(
617 key.pipelineIndex(),
key.geometryUniformIndex());
618 const bool shadingBindingChange = shadingUniformTracker.setCurrentUniforms(
619 key.pipelineIndex(),
key.shadingUniformIndex());
620 const bool textureBindingsChange = textureBindingTracker.setCurrentTextureBindings(
621 key.textureBindingIndex());
622 const SkIRect* newScissor =
draw.fDrawParams.clip().scissor() != lastScissor ?
623 &
draw.fDrawParams.clip().scissor() :
nullptr;
624
625 const bool stateChange = geomBindingChange ||
626 shadingBindingChange ||
627 textureBindingsChange ||
629
630
631
632 if (pipelineChange) {
633 drawWriter.newPipelineState(renderStep.primitiveType(),
634 renderStep.vertexStride(),
635 renderStep.instanceStride());
636 } else if (stateChange) {
637 drawWriter.newDynamicState();
638 }
639
640
641 if (pipelineChange) {
642 drawPass->fCommandList.bindGraphicsPipeline(
key.pipelineIndex());
643 lastPipeline =
key.pipelineIndex();
644 }
645 if (stateChange) {
646 if (geomBindingChange) {
648 &drawPass->fCommandList);
649 }
650 if (shadingBindingChange) {
652 }
653 if (textureBindingsChange) {
654 textureBindingTracker.bindTextures(&drawPass->fCommandList);
655 }
656 if (newScissor) {
657 drawPass->fCommandList.setScissor(*newScissor);
658 lastScissor = *newScissor;
659 }
660 }
661
662 UniformCache::Index geometrySsboIndex =
663 (
key.geometryUniformIndex() == UniformCache::kInvalidIndex)
664 ? 0
665 :
key.geometryUniformIndex();
666 UniformCache::Index shadingSsboIndex =
667 (
key.shadingUniformIndex() == UniformCache::kInvalidIndex)
668 ? 0
669 :
key.shadingUniformIndex();
671 renderStep.writeVertices(&drawWriter,
draw.fDrawParams, ssboIndices);
672
673 if (bufferMgr->hasMappingFailed()) {
674 SKGPU_LOG_W(
"Failed to write necessary vertex/instance data for DrawPass, dropping!");
675 return nullptr;
676 }
677 }
678
679 drawWriter.flush();
680
681 drawPass->fBounds = passBounds.roundOut().asSkIRect();
682
683 drawPass->fPipelineDescs = pipelineCache.detach();
684 drawPass->fSamplerDescs = textureBindingTracker.detachSamplers();
685 drawPass->fSampledTextures = textureBindingTracker.detachTextures();
686
687 TRACE_COUNTER1(
"skia.gpu",
"# pipelines", drawPass->fPipelineDescs.size());
688 TRACE_COUNTER1(
"skia.gpu",
"# textures", drawPass->fSampledTextures.size());
689 TRACE_COUNTER1(
"skia.gpu",
"# commands", drawPass->fCommandList.count());
690
691 return drawPass;
692}
static int step(int x, SkScalar min, SkScalar max)
#define SKGPU_LOG_W(fmt,...)
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
constexpr uint16_t SkToU16(S x)
static constexpr bool SkToBool(const T &x)
#define TRACE_COUNTER1(category_group, name, value)
#define TRACE_EVENT_SCOPE_THREAD
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
const ResourceBindingRequirements & resourceBindingRequirements() const
bool storageBufferPreferred() const
std::array< float, 4 > clearColor() const
std::pair< LoadOp, StoreOp > ops() const
TextureProxy * target() const
const ShaderCodeDictionary * shaderCodeDictionary() const
TextureDataCache * textureDataCache()
const Caps * caps() const
DrawBufferManager * drawBufferManager()
static AI Rect InfiniteInverted()
static UniquePaintParamsID InvalidID()
std::tuple< UniquePaintParamsID, const UniformDataBlock *, const TextureDataBlock * > ExtractPaintData(Recorder *recorder, PipelineDataGatherer *gatherer, PaintParamsKeyBuilder *builder, const Layout layout, const SkM44 &local2Dev, const PaintParams &p, sk_sp< TextureProxy > dstTexture, SkIPoint dstOffset, const SkColorInfo &targetColorInfo)
PipelineDataCache< UniformDataBlock > UniformDataCache
sk_sp< TextureProxy > add_copy_target_task(Recorder *recorder, sk_sp< TextureProxy > target, const SkImageInfo &targetInfo, const SkIPoint &targetOffset)
std::tuple< const UniformDataBlock *, const TextureDataBlock * > ExtractRenderStepData(UniformDataCache *uniformDataCache, TextureDataCache *textureDataCache, PipelineDataGatherer *gatherer, const Layout layout, const RenderStep *step, const DrawParams ¶ms)
PipelineDataCache< TextureDataBlock > TextureDataCache
constexpr SkISize size() const
static constexpr SkIRect MakeSize(const SkISize &size)
constexpr SkIPoint topLeft() const
bool contains(int32_t x, int32_t y) const
const SkColorInfo & colorInfo() const
SkImageInfo makeDimensions(SkISize newSize) const
SkISize dimensions() const
Layout fStorageBufferLayout
#define TRACE_EVENT_INSTANT0(category_group, name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)