void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawPathBatchBase* batch) { // This looks like drawBatch() but there is an added wrinkle that stencil settings get inserted // after setting up clipping but before onDrawBatch(). TODO: Figure out a better model for // handling stencil settings WRT interactions between pipeline(builder), clipmaskmanager, and // batches. SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); GrPipelineBuilder::AutoRestoreStencil ars; GrAppliedClip clip; if (!fClipMaskManager->setupClipping(pipelineBuilder, &ars, &batch->bounds(), &clip)) { return; } GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; if (clip.clipCoverageFragmentProcessor()) { arfps.set(&pipelineBuilder); arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor()); } // Ensure the render target has a stencil buffer and get the stencil settings. GrStencilSettings stencilSettings; GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt); this->getPathStencilSettingsForFilltype(batch->fillType(), sb, &stencilSettings); batch->setStencilSettings(stencilSettings); GrPipeline::CreateArgs args; if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState(), batch)) { return; } this->recordBatch(batch); }
void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, const SkMatrix& viewMatrix, const GrPath* path, GrPathRendering::FillType fill) { // TODO: extract portions of checkDraw that are relevant to path stenciling. SkASSERT(path); SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); // Setup clip GrPipelineBuilder::AutoRestoreStencil ars; GrAppliedClip clip; if (!fClipMaskManager->setupClipping(pipelineBuilder, &ars, nullptr, &clip)) { return; } GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; if (clip.clipCoverageFragmentProcessor()) { arfps.set(&pipelineBuilder); arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor()); } // set stencil settings for path GrStencilSettings stencilSettings; GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt); this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings); GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, pipelineBuilder.isHWAntialias(), stencilSettings, clip.scissorState(), pipelineBuilder.getRenderTarget(), path); this->recordBatch(batch); batch->unref(); }
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBatch* batch) { // Setup clip GrPipelineBuilder::AutoRestoreStencil ars; GrAppliedClip clip; if (!fClipMaskManager->setupClipping(pipelineBuilder, &ars, &batch->bounds(), &clip)) { return; } GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; if (clip.clipCoverageFragmentProcessor()) { arfps.set(&pipelineBuilder); arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor()); } GrPipeline::CreateArgs args; if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState(), batch)) { return; } #ifdef ENABLE_MDB SkASSERT(fRenderTarget); batch->pipeline()->addDependenciesTo(fRenderTarget); #endif this->recordBatch(batch); }
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBatch* batch) { // Setup clip GrScissorState scissorState; GrPipelineBuilder::AutoRestoreStencil ars; GrAppliedClip clip; if (!fClipMaskManager->setupClipping(pipelineBuilder, &ars, &scissorState, &batch->bounds(), &clip)) { return; } GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; if (clip.clipCoverageFragmentProcessor()) { arfps.set(&pipelineBuilder); arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor()); } GrPipeline::CreateArgs args; if (!this->installPipelineInDrawBatch(&pipelineBuilder, &scissorState, batch)) { return; } this->recordBatch(batch); }
void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, GrDrawContext* drawContext, const GrClip& clip, const SkMatrix& viewMatrix, const GrPath* path, GrPathRendering::FillType fill) { // TODO: extract portions of checkDraw that are relevant to path stenciling. SkASSERT(path); SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); // Setup clip GrAppliedClip appliedClip; if (!clip.apply(fContext, pipelineBuilder, drawContext, nullptr, &appliedClip)) { return; } // TODO: respect fClipBatchToBounds if we ever start computing bounds here. // Coverage AA does not make sense when rendering to the stencil buffer. The caller should never // attempt this in a situation that would require coverage AA. SkASSERT(!appliedClip.clipCoverageFragmentProcessor()); GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAttachment(rt); if (!stencilAttachment) { SkDebugf("ERROR creating stencil attachment. Draw skipped.\n"); return; } GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, pipelineBuilder.isHWAntialias(), fill, appliedClip.hasStencilClip(), stencilAttachment->bits(), appliedClip.scissorState(), pipelineBuilder.getRenderTarget(), path); this->recordBatch(batch); batch->unref(); }
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, const GrClip& clip, GrDrawBatch* batch) { // Setup clip GrAppliedClip appliedClip; if (!clip.apply(fClipMaskManager, pipelineBuilder, &batch->bounds(), &appliedClip)) { return; } GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; if (appliedClip.clipCoverageFragmentProcessor()) { arfps.set(&pipelineBuilder); arfps.addCoverageFragmentProcessor(appliedClip.clipCoverageFragmentProcessor()); } GrPipeline::CreateArgs args; args.fPipelineBuilder = &pipelineBuilder; args.fCaps = this->caps(); args.fScissor = &appliedClip.scissorState(); args.fHasStencilClip = appliedClip.hasStencilClip(); if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) { if (!fResourceProvider->attachStencilAttachment(pipelineBuilder.getRenderTarget())) { SkDebugf("ERROR creating stencil attachment. Draw skipped.\n"); return; } } batch->getPipelineOptimizations(&args.fOpts); GrScissorState finalScissor; if (args.fOpts.fOverrides.fUsePLSDstRead || fClipBatchToBounds) { GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); GrGLIRect viewport; viewport.fLeft = 0; viewport.fBottom = 0; viewport.fWidth = rt->width(); viewport.fHeight = rt->height(); SkIRect ibounds; ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewport.fLeft, viewport.fWidth); ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport.fBottom, viewport.fHeight); ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewport.fLeft, viewport.fWidth); ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), viewport.fBottom, viewport.fHeight); if (appliedClip.scissorState().enabled()) { const SkIRect& scissorRect = appliedClip.scissorState().rect(); if (!ibounds.intersect(scissorRect)) { return; } } finalScissor.set(ibounds); args.fScissor = &finalScissor; } args.fOpts.fColorPOI.completeCalculations(pipelineBuilder.fColorFragmentProcessors.begin(), pipelineBuilder.numColorFragmentProcessors()); args.fOpts.fCoveragePOI.completeCalculations( pipelineBuilder.fCoverageFragmentProcessors.begin(), pipelineBuilder.numCoverageFragmentProcessors()); if (!this->setupDstReadIfNecessary(pipelineBuilder, clip, args.fOpts, &args.fDstTexture, batch->bounds())) { return; } if (!batch->installPipeline(args)) { return; } #ifdef ENABLE_MDB SkASSERT(fRenderTarget); batch->pipeline()->addDependenciesTo(fRenderTarget); #endif this->recordBatch(batch); }