Ejemplo n.º 1
0
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();
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
void GrDrawPathOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
    GrAppliedClip appliedClip = state->detachAppliedClip();
    GrPipeline::FixedDynamicState fixedDynamicState(appliedClip.scissorState().rect());
    GrPipeline pipeline(this->pipelineInitArgs(*state), this->detachProcessors(),
                        std::move(appliedClip));
    sk_sp<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(), this->viewMatrix()));

    GrStencilSettings stencil;
    init_stencil_pass_settings(*state, this->fillType(), &stencil);
    state->gpu()->pathRendering()->drawPath(state->drawOpArgs().renderTarget(),
                                            state->drawOpArgs().origin(),
                                            *pathProc, pipeline, fixedDynamicState, stencil,
                                            fPath.get());
}
Ejemplo n.º 5
0
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.getClipCoverageFragmentProcessor());

    GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAttachment(
                                                drawContext->accessRenderTarget());
    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(),
                                                drawContext->accessRenderTarget(),
                                                path);
    this->recordBatch(batch);
    batch->unref();
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder,
                             GrDrawContext* drawContext,
                             const GrClip& clip,
                             GrDrawBatch* batch) {
    // Setup clip
    GrAppliedClip appliedClip;
    if (!clip.apply(fContext, pipelineBuilder, drawContext, &batch->bounds(), &appliedClip)) {
        return;
    }

    // TODO: this is the only remaining usage of the AutoRestoreFragmentProcessorState - remove it
    GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
    if (appliedClip.getClipCoverageFragmentProcessor()) {
        arfps.set(&pipelineBuilder);
        arfps.addCoverageFragmentProcessor(sk_ref_sp(appliedClip.getClipCoverageFragmentProcessor()));
    }

    GrPipeline::CreateArgs args;
    args.fPipelineBuilder = &pipelineBuilder;
    args.fDrawContext = drawContext;
    args.fCaps = this->caps();
    args.fScissor = &appliedClip.scissorState();
    args.fHasStencilClip = appliedClip.hasStencilClip();
    if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) {
        if (!fResourceProvider->attachStencilAttachment(drawContext->accessRenderTarget())) {
            SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
            return;
        }
    }
    batch->getPipelineOptimizations(&args.fOpts);
    GrScissorState finalScissor;
    if (args.fOpts.fOverrides.fUsePLSDstRead || fClipBatchToBounds) {
        GrGLIRect viewport;
        viewport.fLeft = 0;
        viewport.fBottom = 0;
        viewport.fWidth = drawContext->width();
        viewport.fHeight = drawContext->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(
        sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessors.begin()),
        pipelineBuilder.numColorFragmentProcessors());
    args.fOpts.fCoveragePOI.completeCalculations(
        sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()),
        pipelineBuilder.numCoverageFragmentProcessors());
    if (!this->setupDstReadIfNecessary(pipelineBuilder, drawContext->accessRenderTarget(),
                                       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);
}