Exemple #1
0
void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) {
    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
    SkASSERT(NULL != fGpu->drawState()->getRenderTarget());
    SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer());

    this->flushPathStencilSettings(fill);
    SkASSERT(!fHWPathStencilSettings.isTwoSided());

    const SkStrokeRec& stroke = path->getStroke();

    SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill);

    GrGLenum fillMode =
        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);

    if (nonInvertedFill == fill) {
        if (stroke.needToApply()) {
            if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
                GL_CALL(StencilFillPath(id, fillMode, writeMask));
            }
            this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX);
        } else {
            this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX);
        }
    } else {
        if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
            GL_CALL(StencilFillPath(id, fillMode, writeMask));
        }
        if (stroke.needToApply()) {
            GL_CALL(StencilStrokePath(id, 0xffff, writeMask));
        }

        GrDrawState* drawState = fGpu->drawState();
        GrDrawState::AutoViewMatrixRestore avmr;
        SkRect bounds = SkRect::MakeLTRB(0, 0,
                                         SkIntToScalar(drawState->getRenderTarget()->width()),
                                         SkIntToScalar(drawState->getRenderTarget()->height()));
        SkMatrix vmi;
        // mapRect through persp matrix may not be correct
        if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
            vmi.mapRect(&bounds);
            // theoretically could set bloat = 0, instead leave it because of matrix inversion
            // precision.
            SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
            bounds.outset(bloat, bloat);
        } else {
            avmr.setIdentity(drawState);
        }

        fGpu->drawSimpleRect(bounds);
    }
}
void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath* path) {
    GrGLGpu* gpu = this->gpu();
    SkASSERT(gpu->caps()->shaderCaps()->pathRenderingSupport());
    gpu->flushColorWrite(false);
    gpu->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);

    GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(args.fRenderTarget);
    SkISize size = SkISize::Make(rt->width(), rt->height());
    this->setProjectionMatrix(*args.fViewMatrix, size, rt->origin());
    gpu->flushScissor(*args.fScissor, rt->getViewport(), rt->origin());
    gpu->flushHWAAState(rt, args.fUseHWAA);
    gpu->flushRenderTarget(rt, NULL);

    const GrGLPath* glPath = static_cast<const GrGLPath*>(path);

    this->flushPathStencilSettings(*args.fStencil);
    SkASSERT(!fHWPathStencilSettings.isTwoSided());

    GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(
        fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);

    if (glPath->shouldFill()) {
        GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask));
    }
    if (glPath->shouldStroke()) {
        GL_CALL(StencilStrokePath(glPath->pathID(), 0xffff, writeMask));
    }
}
void GrGLPathRendering::onDrawPath(const GrPrimitiveProcessor& primProc,
                                   const GrPipeline& pipeline,
                                   const GrPipeline::FixedDynamicState& fixedDynamicState,
                                   const GrStencilSettings& stencilPassSettings,
                                   const GrPath* path) {
    if (!this->gpu()->flushGLState(primProc, pipeline, &fixedDynamicState, nullptr, 1, false)) {
        return;
    }
    const GrGLPath* glPath = static_cast<const GrGLPath*>(path);

    this->flushPathStencilSettings(stencilPassSettings);
    SkASSERT(!fHWPathStencilSettings.isTwoSided());

    GrGLenum fillMode =
        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.front().fPassOp);
    GrGLint writeMask = fHWPathStencilSettings.front().fWriteMask;

    if (glPath->shouldStroke()) {
        if (glPath->shouldFill()) {
            GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask));
        }
        GL_CALL(StencilThenCoverStrokePath(glPath->pathID(), 0xffff, writeMask,
                                           GR_GL_BOUNDING_BOX));
    } else {
        GL_CALL(StencilThenCoverFillPath(glPath->pathID(), fillMode, writeMask,
                                         GR_GL_BOUNDING_BOX));
    }
}
inline void GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
                                                     GrGLuint mask, GrGLenum coverMode) {
    if (caps().stencilThenCoverSupport) {
        GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode));
        return;
    }
    GL_CALL(StencilFillPath(path, fillMode, mask));
    GL_CALL(CoverFillPath(path, coverMode));
}
Exemple #5
0
void GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) {
    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
    SkASSERT(NULL != fGpu->drawState()->getRenderTarget());
    SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer());

    this->flushPathStencilSettings(fill);
    SkASSERT(!fHWPathStencilSettings.isTwoSided());

    GrGLenum fillMode =
        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
    GL_CALL(StencilFillPath(id, fillMode, writeMask));
}
void GrGLPathRendering::stencilPath(const GrPath* path, const GrStencilSettings& stencilSettings) {
    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();

    this->flushPathStencilSettings(stencilSettings);
    SkASSERT(!fHWPathStencilSettings.isTwoSided());

    const SkStrokeRec& stroke = path->getStroke();

    GrGLenum fillMode =
        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);

    if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
        GL_CALL(StencilFillPath(id, fillMode, writeMask));
    }
    if (stroke.needToApply()) {
        GL_CALL(StencilStrokePath(id, 0xffff, writeMask));
    }
}
void GrGLPathRendering::onDrawPath(const DrawPathArgs& args, const GrPath* path) {
    if (!this->gpu()->flushGLState(args)) {
        return;
    }
    const GrGLPath* glPath = static_cast<const GrGLPath*>(path);

    this->flushPathStencilSettings(*args.fStencil);
    SkASSERT(!fHWPathStencilSettings.isTwoSided());

    GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(
        fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);

    if (glPath->shouldStroke()) {
        if (glPath->shouldFill()) {
            GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask));
        }
        GL_CALL(StencilThenCoverStrokePath(glPath->pathID(), 0xffff, writeMask,
                                           GR_GL_BOUNDING_BOX));
    } else {
        GL_CALL(StencilThenCoverFillPath(glPath->pathID(), fillMode, writeMask,
                                         GR_GL_BOUNDING_BOX));
    }
}