465 {
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480 static_assert(sizeof(DrawPass::SortKey) ==
481 SkAlignTo(16 +
sizeof(
void*),
alignof(DrawPass::SortKey)));
482
484
485
486
488
490
491
492
496 if (bufferMgr->hasMappingFailed()) {
497 SKGPU_LOG_W(
"Buffer mapping has already failed; dropping draw pass!");
498 return nullptr;
499 }
500
501 if (!draws->dstCopyBounds().isEmptyNegativeOrNaN() && !dstCopy) {
502 SKGPU_LOG_W(
"Failed to copy destination for reading. Dropping draw pass!");
503 return nullptr;
504 }
505
506 GraphicsPipelineCache pipelineCache;
507
508
510 const ResourceBindingRequirements& bindingReqs =
513 useStorageBuffers ? bindingReqs.fStorageBufferLayout : bindingReqs.fUniformBufferLayout;
514
515 UniformTracker geometryUniformTracker(useStorageBuffers);
516 UniformTracker shadingUniformTracker(useStorageBuffers);
517 TextureBindingTracker textureBindingTracker;
518 GradientBufferTracker gradientBufferTracker;
519
521 PaintParamsKeyBuilder
builder(dict);
522
523
524
525 PipelineDataGatherer gatherer(uniformLayout);
526
527 std::vector<SortKey> keys;
528 keys.reserve(draws->renderStepCount());
529
531
532
533
534 UniquePaintParamsID shaderID;
535 const UniformDataBlock* shadingUniforms = nullptr;
536 const TextureDataBlock* paintTextures = nullptr;
537
538 if (
draw.fPaintParams.has_value()) {
541 ? dstCopy
542 : nullptr;
543 std::tie(shaderID, shadingUniforms, paintTextures) =
545 &gatherer,
547 uniformLayout,
548 draw.fDrawParams.transform(),
549 draw.fPaintParams.value(),
550 draw.fDrawParams.geometry(),
551 curDst,
552 dstCopyOffset,
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 !gradientBufferTracker.writeData(gatherer.gradientBufferData(), bufferMgr)) {
588
589
590 return nullptr;
591 }
592
593
594
595
596
597
598
599
601
602
603 DrawWriter drawWriter(&drawPass->fCommandList, bufferMgr);
606
607 SkASSERT(drawPass->fTarget->isFullyLazy() ||
609 drawPass->fCommandList.setScissor(lastScissor);
610
611
612
613 gradientBufferTracker.bindIfNeeded(&drawPass->fCommandList);
614
615 for (
const SortKey&
key : keys) {
617 const RenderStep& renderStep =
key.renderStep();
618
619 const bool pipelineChange =
key.pipelineIndex() != lastPipeline;
620
621 const bool geomBindingChange = geometryUniformTracker.setCurrentUniforms(
622 key.pipelineIndex(),
key.geometryUniformIndex());
623 const bool shadingBindingChange = shadingUniformTracker.setCurrentUniforms(
624 key.pipelineIndex(),
key.shadingUniformIndex());
625 const bool textureBindingsChange = textureBindingTracker.setCurrentTextureBindings(
626 key.textureBindingIndex());
627 const SkIRect* newScissor =
draw.fDrawParams.clip().scissor() != lastScissor ?
628 &
draw.fDrawParams.clip().scissor() :
nullptr;
629
630 const bool stateChange = geomBindingChange ||
631 shadingBindingChange ||
632 textureBindingsChange ||
634
635
636
637 if (pipelineChange) {
638 drawWriter.newPipelineState(renderStep.primitiveType(),
639 renderStep.vertexStride(),
640 renderStep.instanceStride());
641 } else if (stateChange) {
642 drawWriter.newDynamicState();
643 }
644
645
646 if (pipelineChange) {
647 drawPass->fCommandList.bindGraphicsPipeline(
key.pipelineIndex());
648 lastPipeline =
key.pipelineIndex();
649 }
650 if (stateChange) {
651 if (geomBindingChange) {
653 &drawPass->fCommandList);
654 }
655 if (shadingBindingChange) {
657 }
658 if (textureBindingsChange) {
659 textureBindingTracker.bindTextures(&drawPass->fCommandList);
660 }
661 if (newScissor) {
662 drawPass->fCommandList.setScissor(*newScissor);
663 lastScissor = *newScissor;
664 }
665 }
666
667 UniformCache::Index geometrySsboIndex =
669 ? 0
670 :
key.geometryUniformIndex();
671 UniformCache::Index shadingSsboIndex =
673 ? 0
674 :
key.shadingUniformIndex();
676 renderStep.writeVertices(&drawWriter,
draw.fDrawParams, ssboIndices);
677
678 if (bufferMgr->hasMappingFailed()) {
679 SKGPU_LOG_W(
"Failed to write necessary vertex/instance data for DrawPass, dropping!");
680 return nullptr;
681 }
682 }
683
684 drawWriter.flush();
685
686 drawPass->fBounds = passBounds.roundOut().asSkIRect();
687
688 drawPass->fPipelineDescs = pipelineCache.detach();
689 drawPass->fSamplerDescs = textureBindingTracker.detachSamplers();
690 drawPass->fSampledTextures = textureBindingTracker.detachTextures();
691
692 TRACE_COUNTER1(
"skia.gpu",
"# pipelines", drawPass->fPipelineDescs.size());
693 TRACE_COUNTER1(
"skia.gpu",
"# textures", drawPass->fSampledTextures.size());
694 TRACE_COUNTER1(
"skia.gpu",
"# commands", drawPass->fCommandList.count());
695
696 return drawPass;
697}
static int step(int x, SkScalar min, SkScalar max)
static constexpr Index kInvalidIndex
#define SKGPU_LOG_W(fmt,...)
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
static std::vector< SkPDFIndirectReference > sort(const THashSet< SkPDFIndirectReference > &src)
constexpr uint16_t SkToU16(S x)
static constexpr bool SkToBool(const T &x)
#define TRACE_COUNTER1(category_group, name, value)
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()
static void Draw(SkCanvas *canvas, const SkRect &rect)
PipelineDataCache< UniformDataBlock > UniformDataCache
std::tuple< const UniformDataBlock *, const TextureDataBlock * > ExtractRenderStepData(UniformDataCache *uniformDataCache, TextureDataCache *textureDataCache, PipelineDataGatherer *gatherer, const Layout layout, const RenderStep *step, const DrawParams ¶ms)
std::tuple< UniquePaintParamsID, const UniformDataBlock *, const TextureDataBlock * > ExtractPaintData(Recorder *recorder, PipelineDataGatherer *gatherer, PaintParamsKeyBuilder *builder, const Layout layout, const SkM44 &local2Dev, const PaintParams &p, const Geometry &geometry, sk_sp< TextureProxy > dstTexture, SkIPoint dstOffset, const SkColorInfo &targetColorInfo)
PipelineDataCache< TextureDataBlock > TextureDataCache
static constexpr SkIRect MakeSize(const SkISize &size)
bool contains(int32_t x, int32_t y) const
const SkColorInfo & colorInfo() const
SkISize dimensions() const
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)