Пример #1
0
inline void GrGLPathRendering::stencilThenCoverStrokePathInstanced(
        GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
        GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
        GrGLenum transformType, const GrGLfloat *transformValues) {
    if (caps().stencilThenCoverSupport) {
        GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
                                                    reference, mask, coverMode, transformType,
                                                    transformValues));
        return;
    }

    GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
                                       reference, mask, transformType, transformValues));
    GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
                                     coverMode, transformType, transformValues));
}
Пример #2
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);
    }
}