inline void GrGLPathRendering::stencilThenCoverFillPathInstanced(
             GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
             GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
             GrGLenum transformType, const GrGLfloat *transformValues) {
    if (caps().stencilThenCoverSupport) {
        GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode,
                                                  mask, coverMode, transformType, transformValues));
        return;
    }
    GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase,
                                     fillMode, mask, transformType, transformValues));
    GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase,
                                   coverMode, transformType, transformValues));
}
Example #2
0
void GrGLPathRendering::onDrawPaths(const GrPipeline& pipeline,
                                    const GrPrimitiveProcessor& primProc,
                                    const GrStencilSettings& stencil, const GrPathRange* pathRange,
                                    const void* indices, PathIndexType indexType,
                                    const float transformValues[], PathTransformType transformType,
                                    int count) {
    SkDEBUGCODE(verify_floats(transformValues, gXformType2ComponentCount[transformType] * count));

    if (!this->gpu()->flushGLState(pipeline, primProc)) {
        return;
    }
    this->flushPathStencilSettings(stencil);
    SkASSERT(!fHWPathStencilSettings.isTwoSided());


    const GrGLPathRange* glPathRange = static_cast<const GrGLPathRange*>(pathRange);

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

    if (glPathRange->shouldStroke()) {
        if (glPathRange->shouldFill()) {
            GL_CALL(StencilFillPathInstanced(
                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
                            fillMode, writeMask, gXformType2GLType[transformType],
                            transformValues));
        }
        GL_CALL(StencilThenCoverStrokePathInstanced(
                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
                            0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                            gXformType2GLType[transformType], transformValues));
    } else {
        GL_CALL(StencilThenCoverFillPathInstanced(
                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
                            fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                            gXformType2GLType[transformType], transformValues));
    }
}
void GrGLPathRendering::onDrawPaths(const DrawPathArgs& args, const GrPathRange* pathRange,
                                    const void* indices, PathIndexType indexType,
                                    const float transformValues[], PathTransformType transformType,
                                    int count) {
    if (!this->gpu()->flushGLState(args)) {
        return;
    }
    this->flushPathStencilSettings(*args.fStencil);
    SkASSERT(!fHWPathStencilSettings.isTwoSided());


    const GrGLPathRange* glPathRange = static_cast<const GrGLPathRange*>(pathRange);

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

    if (glPathRange->shouldStroke()) {
        if (glPathRange->shouldFill()) {
            GL_CALL(StencilFillPathInstanced(
                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
                            fillMode, writeMask, gXformType2GLType[transformType],
                            transformValues));
        }
        GL_CALL(StencilThenCoverStrokePathInstanced(
                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
                            0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                            gXformType2GLType[transformType], transformValues));
    } else {
        GL_CALL(StencilThenCoverFillPathInstanced(
                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
                            fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                            gXformType2GLType[transformType], transformValues));
    }
}
void GrGLPathRendering::drawPaths(const GrPathRange* pathRange,
                                  const void* indices, PathIndexType indexType,
                                  const float transformValues[], PathTransformType transformType,
                                  int count, const GrStencilSettings& stencilSettings) {
    SkASSERT(fGpu->caps()->shaderCaps()->pathRenderingSupport());

    GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();

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

    const SkStrokeRec& stroke = pathRange->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.needToApply()) {
        if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
            GL_CALL(StencilFillPathInstanced(
                            count, gIndexType2GLType[indexType], indices, baseID, fillMode,
                            writeMask, gXformType2GLType[transformType], transformValues));
        }
        this->stencilThenCoverStrokePathInstanced(
                            count, gIndexType2GLType[indexType], indices, baseID,
                            0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                            gXformType2GLType[transformType], transformValues);
    } else {
        this->stencilThenCoverFillPathInstanced(
                            count, gIndexType2GLType[indexType], indices, baseID,
                            fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                            gXformType2GLType[transformType], transformValues);
    }
}
Example #5
0
void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count,
                                  const float transforms[], PathTransformType transformsType,
                                  SkPath::FillType fill) {
    SkASSERT(fGpu->caps()->pathRenderingSupport());
    SkASSERT(NULL != fGpu->drawState()->getRenderTarget());
    SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer());

    GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();

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

    const SkStrokeRec& stroke = pathRange->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(StencilFillPathInstanced(
                                count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
                                writeMask, gXformType2GLType[transformsType],
                                transforms));
            }
            this->stencilThenCoverStrokePathInstanced(
                                count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask,
                                GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                                gXformType2GLType[transformsType], transforms);
        } else {
            this->stencilThenCoverFillPathInstanced(
                                count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask,
                                GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                                gXformType2GLType[transformsType], transforms);
        }
    } else {
        if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
            GL_CALL(StencilFillPathInstanced(
                                count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
                                writeMask, gXformType2GLType[transformsType],
                                transforms));
        }
        if (stroke.needToApply()) {
            GL_CALL(StencilStrokePathInstanced(
                                count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff,
                                writeMask, gXformType2GLType[transformsType],
                                transforms));
        }

        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);
    }
}