コード例 #1
0
void GrStencilAndCoverTextContext::drawText(GrContext* context, GrDrawContext* dc,
        const GrClip& clip, const GrPaint& paint,
        const SkPaint& skPaint, const SkMatrix& viewMatrix,
        const SkSurfaceProps& props,
        const char text[], size_t byteLength,
        SkScalar x, SkScalar y, const SkIRect& clipBounds) {
    if (context->abandoned()) {
        return;
    } else if (this->canDraw(skPaint, viewMatrix)) {
        TextRun run(skPaint);
        GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);
        run.setText(text, byteLength, x, y);
        run.draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, props, 0, 0,
                 clipBounds, fFallbackTextContext, skPaint);
        return;
    } else if (fFallbackTextContext->canDraw(skPaint, viewMatrix, props,
               *context->caps()->shaderCaps())) {
        fFallbackTextContext->drawText(context, dc, clip, paint, skPaint, viewMatrix, props, text,
                                       byteLength, x, y, clipBounds);
        return;
    }

    // fall back to drawing as a path
    GrTextUtils::DrawTextAsPath(context, dc, clip, skPaint, viewMatrix, text, byteLength, x, y,
                                clipBounds);
}
コード例 #2
0
ファイル: GrAtlasTextBlob.cpp プロジェクト: jszwedko/skia
void GrAtlasTextBlob::flushCached(GrContext* context,
                                  GrDrawContext* dc,
                                  const SkTextBlob* blob,
                                  const SkSurfaceProps& props,
                                  const GrDistanceFieldAdjustTable* distanceAdjustTable,
                                  const SkPaint& skPaint,
                                  const GrPaint& grPaint,
                                  SkDrawFilter* drawFilter,
                                  const GrClip& clip,
                                  const SkMatrix& viewMatrix,
                                  const SkIRect& clipBounds,
                                  SkScalar x, SkScalar y) {
    // We loop through the runs of the blob, flushing each.  If any run is too large, then we flush
    // it as paths
    GrPipelineBuilder pipelineBuilder(grPaint,  dc->isUnifiedMultisampled());
    pipelineBuilder.setRenderTarget(dc->accessRenderTarget());

    GrColor color = grPaint.getColor();

    SkTextBlobRunIterator it(blob);
    for (int run = 0; !it.done(); it.next(), run++) {
        if (fRuns[run].fDrawAsPaths) {
            this->flushRunAsPaths(context, dc, props, it, clip, skPaint,
                                  drawFilter, viewMatrix, clipBounds, x, y);
            continue;
        }
        this->flushRun(dc, &pipelineBuilder, clip, run, viewMatrix, x, y, color, skPaint, props,
                       distanceAdjustTable, context->getBatchFontCache());
    }

    // Now flush big glyphs
    this->flushBigGlyphs(context, dc, clip, skPaint, viewMatrix, x, y, clipBounds);
}
コード例 #3
0
void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget* rt,
                                              const GrClip& clip,
                                              const GrPaint& paint,
                                              const SkPaint& skPaint,
                                              const SkMatrix& viewMatrix,
                                              const char text[],
                                              size_t byteLength,
                                              SkScalar x, SkScalar y,
                                              const SkIRect& clipBounds) {
    TextRun run(skPaint);
    GrPipelineBuilder pipelineBuilder(paint, rt, clip);
    run.setText(text, byteLength, x, y);
    run.draw(fContext, dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBounds,
             fFallbackTextContext, skPaint);
}
コード例 #4
0
void GrSoftwarePathRenderer::DrawNonAARect(GrDrawContext* drawContext,
                                           const GrPaint& paint,
                                           const GrUserStencilSettings& userStencilSettings,
                                           const GrClip& clip,
                                           const SkMatrix& viewMatrix,
                                           const SkRect& rect,
                                           const SkMatrix& localMatrix) {
    SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(paint.getColor(),
                                                                        viewMatrix, rect,
                                                                        nullptr, &localMatrix));

    GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(paint));
    pipelineBuilder.setUserStencil(&userStencilSettings);

    drawContext->drawBatch(pipelineBuilder, clip, batch);
}
コード例 #5
0
void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarget* rt,
                                                 const GrClip& clip,
                                                 const GrPaint& paint,
                                                 const SkPaint& skPaint,
                                                 const SkMatrix& viewMatrix,
                                                 const char text[],
                                                 size_t byteLength,
                                                 const SkScalar pos[],
                                                 int scalarsPerPosition,
                                                 const SkPoint& offset,
                                                 const SkIRect& clipBounds) {
    TextRun run(skPaint);
    GrPipelineBuilder pipelineBuilder(paint, rt, clip);
    run.setPosText(text, byteLength, pos, scalarsPerPosition, offset);
    run.draw(fContext, dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBounds,
             fFallbackTextContext, skPaint);
}
コード例 #6
0
ファイル: GrAtlasTextBlob.cpp プロジェクト: geekygenius/skia
void GrAtlasTextBlob::flushThrowaway(GrContext* context,
                                     GrDrawContext* dc,
                                     const SkSurfaceProps& props,
                                     const GrDistanceFieldAdjustTable* distanceAdjustTable,
                                     const SkPaint& skPaint,
                                     const GrPaint& grPaint,
                                     const GrClip& clip,
                                     const SkIRect& clipBounds) {
    GrPipelineBuilder pipelineBuilder(grPaint, dc->accessRenderTarget(), clip);

    GrColor color = grPaint.getColor();
    for (int run = 0; run < fRunCount; run++) {
        this->flushRun(dc, &pipelineBuilder, run, color, 0, 0, skPaint, props,
                       distanceAdjustTable, context->getBatchFontCache());
    }

    // Now flush big glyphs
    this->flushBigGlyphs(context, dc, clip, skPaint, 0, 0, clipBounds);
}
コード例 #7
0
ファイル: GrAtlasTextBlob.cpp プロジェクト: jszwedko/skia
void GrAtlasTextBlob::flushThrowaway(GrContext* context,
                                     GrDrawContext* dc,
                                     const SkSurfaceProps& props,
                                     const GrDistanceFieldAdjustTable* distanceAdjustTable,
                                     const SkPaint& skPaint,
                                     const GrPaint& grPaint,
                                     const GrClip& clip,
                                     const SkMatrix& viewMatrix,
                                     const SkIRect& clipBounds,
                                     SkScalar x, SkScalar y) {
    GrPipelineBuilder pipelineBuilder(grPaint,  dc->isUnifiedMultisampled());
    pipelineBuilder.setRenderTarget(dc->accessRenderTarget());

    GrColor color = grPaint.getColor();
    for (int run = 0; run < fRunCount; run++) {
        this->flushRun(dc, &pipelineBuilder, clip, run, viewMatrix, x, y, color, skPaint, props,
                       distanceAdjustTable, context->getBatchFontCache());
    }

    // Now flush big glyphs
    this->flushBigGlyphs(context, dc, clip, skPaint, viewMatrix, x, y, clipBounds);
}
コード例 #8
0
void GrStencilAndCoverTextContext::drawTextBlob(GrContext* context, GrDrawContext* dc,
        const GrClip& clip, const SkPaint& skPaint,
        const SkMatrix& viewMatrix,
        const SkSurfaceProps& props,
        const SkTextBlob* skBlob, SkScalar x, SkScalar y,
        SkDrawFilter* drawFilter,
        const SkIRect& clipBounds) {
    if (context->abandoned()) {
        return;
    }

    if (!this->internalCanDraw(skPaint)) {
        fFallbackTextContext->drawTextBlob(context, dc, clip, skPaint, viewMatrix, props, skBlob,
                                           x, y, drawFilter, clipBounds);
        return;
    }

    if (drawFilter || skPaint.getPathEffect()) {
        // This draw can't be cached.
        this->uncachedDrawTextBlob(context, dc, clip, skPaint, viewMatrix, props, skBlob, x, y,
                                   drawFilter, clipBounds);
        return;
    }

    GrPaint paint;
    if (!SkPaintToGrPaint(context, skPaint, viewMatrix, &paint)) {
        return;
    }

    const TextBlob& blob = this->findOrCreateTextBlob(skBlob, skPaint);
    GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);

    TextBlob::Iter iter(blob);
    for (TextRun* run = iter.get(); run; run = iter.next()) {
        run->draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, props,  x, y,
                  clipBounds, fFallbackTextContext, skPaint);
        run->releaseGlyphCache();
    }
}
コード例 #9
0
ファイル: GrSWMaskHelper.cpp プロジェクト: OwenTan/skia
void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture,
                                               GrDrawContext* drawContext,
                                               const GrPaint& paint,
                                               const GrUserStencilSettings* userStencilSettings,
                                               const GrClip& clip,
                                               const SkMatrix& viewMatrix,
                                               const SkIRect& rect) {
    SkMatrix invert;
    if (!viewMatrix.invert(&invert)) {
        return;
    }

    SkRect dstRect = SkRect::MakeLTRB(SK_Scalar1 * rect.fLeft,
                                      SK_Scalar1 * rect.fTop,
                                      SK_Scalar1 * rect.fRight,
                                      SK_Scalar1 * rect.fBottom);

    // We use device coords to compute the texture coordinates. We take the device coords and apply
    // a translation so that the top-left of the device bounds maps to 0,0, and then a scaling
    // matrix to normalized coords.
    SkMatrix maskMatrix;
    maskMatrix.setIDiv(texture->width(), texture->height());
    maskMatrix.preTranslate(SkIntToScalar(-rect.fLeft), SkIntToScalar(-rect.fTop));

    GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(paint));
    pipelineBuilder.setUserStencil(userStencilSettings);

    pipelineBuilder.addCoverageFragmentProcessor(
                         GrSimpleTextureEffect::Make(texture,
                                                     maskMatrix,
                                                     GrTextureParams::kNone_FilterMode,
                                                     kDevice_GrCoordSet));

    SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(paint.getColor(),
                                                                        SkMatrix::I(),
                                                                        dstRect, nullptr, &invert));
    drawContext->drawBatch(pipelineBuilder, clip, batch);
}
コード例 #10
0
bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext,
                                             const GrPaint& paint,
                                             const GrUserStencilSettings& userStencilSettings,
                                             const GrClip& clip,
                                             const SkMatrix& viewMatrix,
                                             const GrShape& shape,
                                             bool stencilOnly) {
    SkPath path;
    shape.asPath(&path);

    SkScalar hairlineCoverage;
    uint8_t newCoverage = 0xff;
    bool isHairline = false;
    if (IsStrokeHairlineOrEquivalent(shape.style(), viewMatrix, &hairlineCoverage)) {
        newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
        isHairline = true;
    } else {
        SkASSERT(shape.style().isSimpleFill());
    }

    int                          passCount = 0;
    const GrUserStencilSettings* passes[3];
    GrDrawFace                   drawFace[3];
    bool                         reverse = false;
    bool                         lastPassIsBounds;

    if (isHairline) {
        passCount = 1;
        if (stencilOnly) {
            passes[0] = &gDirectToStencil;
        } else {
            passes[0] = &userStencilSettings;
        }
        lastPassIsBounds = false;
        drawFace[0] = GrDrawFace::kBoth;
    } else {
        if (single_pass_shape(shape)) {
            passCount = 1;
            if (stencilOnly) {
                passes[0] = &gDirectToStencil;
            } else {
                passes[0] = &userStencilSettings;
            }
            drawFace[0] = GrDrawFace::kBoth;
            lastPassIsBounds = false;
        } else {
            switch (path.getFillType()) {
                case SkPath::kInverseEvenOdd_FillType:
                    reverse = true;
                    // fallthrough
                case SkPath::kEvenOdd_FillType:
                    passes[0] = &gEOStencilPass;
                    if (stencilOnly) {
                        passCount = 1;
                        lastPassIsBounds = false;
                    } else {
                        passCount = 2;
                        lastPassIsBounds = true;
                        if (reverse) {
                            passes[1] = &gInvEOColorPass;
                        } else {
                            passes[1] = &gEOColorPass;
                        }
                    }
                    drawFace[0] = drawFace[1] = GrDrawFace::kBoth;
                    break;

                case SkPath::kInverseWinding_FillType:
                    reverse = true;
                    // fallthrough
                case SkPath::kWinding_FillType:
                    if (fSeparateStencil) {
                        if (fStencilWrapOps) {
                            passes[0] = &gWindStencilSeparateWithWrap;
                        } else {
                            passes[0] = &gWindStencilSeparateNoWrap;
                        }
                        passCount = 2;
                        drawFace[0] = GrDrawFace::kBoth;
                    } else {
                        if (fStencilWrapOps) {
                            passes[0] = &gWindSingleStencilWithWrapInc;
                            passes[1] = &gWindSingleStencilWithWrapDec;
                        } else {
                            passes[0] = &gWindSingleStencilNoWrapInc;
                            passes[1] = &gWindSingleStencilNoWrapDec;
                        }
                        // which is cw and which is ccw is arbitrary.
                        drawFace[0] = GrDrawFace::kCW;
                        drawFace[1] = GrDrawFace::kCCW;
                        passCount = 3;
                    }
                    if (stencilOnly) {
                        lastPassIsBounds = false;
                        --passCount;
                    } else {
                        lastPassIsBounds = true;
                        drawFace[passCount-1] = GrDrawFace::kBoth;
                        if (reverse) {
                            passes[passCount-1] = &gInvWindColorPass;
                        } else {
                            passes[passCount-1] = &gWindColorPass;
                        }
                    }
                    break;
                default:
                    SkDEBUGFAIL("Unknown path fFill!");
                    return false;
            }
        }
    }

    SkScalar tol = GrPathUtils::kDefaultTolerance;
    SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, path.getBounds());

    SkRect devBounds;
    GetPathDevBounds(path, drawContext->width(), drawContext->height(), viewMatrix, &devBounds);

    for (int p = 0; p < passCount; ++p) {
        if (lastPassIsBounds && (p == passCount-1)) {
            SkRect bounds;
            SkMatrix localMatrix = SkMatrix::I();
            if (reverse) {
                // draw over the dev bounds (which will be the whole dst surface for inv fill).
                bounds = devBounds;
                SkMatrix vmi;
                // mapRect through persp matrix may not be correct
                if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
                    vmi.mapRect(&bounds);
                } else {
                    if (!viewMatrix.invert(&localMatrix)) {
                        return false;
                    }
                }
            } else {
                bounds = path.getBounds();
            }
            const SkMatrix& viewM = (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() :
                                                                               viewMatrix;
            SkAutoTUnref<GrDrawBatch> batch(
                    GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewM, bounds, nullptr,
                                                        &localMatrix));

            SkASSERT(GrDrawFace::kBoth == drawFace[p]);
            GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(paint));
            pipelineBuilder.setDrawFace(drawFace[p]);
            pipelineBuilder.setUserStencil(passes[p]);

            drawContext->drawBatch(pipelineBuilder, clip, batch);
        } else {
            SkAutoTUnref<GrDrawBatch> batch(new DefaultPathBatch(paint.getColor(), path,
                                                                 srcSpaceTol,
                                                                 newCoverage, viewMatrix,
                                                                 isHairline, devBounds));

            GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(paint));
            pipelineBuilder.setDrawFace(drawFace[p]);
            pipelineBuilder.setUserStencil(passes[p]);
            if (passCount > 1) {
                pipelineBuilder.setDisableColorXPFactory();
            }

            drawContext->drawBatch(pipelineBuilder, clip, batch);
        }
    }
    return true;
}
コード例 #11
0
void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
                                                 GrDrawContext* drawContext,
                                                 const GrPaint& grPaint,
                                                 const GrClip& clip,
                                                 const SkMatrix& viewMatrix,
                                                 const SkSurfaceProps& props,
                                                 SkScalar x, SkScalar y,
                                                 const SkIRect& clipBounds,
                                                 GrAtlasTextContext* fallbackTextContext,
                                                 const SkPaint& originalSkPaint) const {
    SkASSERT(fInstanceData);
    SkASSERT(drawContext->isStencilBufferMultisampled() || !grPaint.isAntiAlias());

    if (fInstanceData->count()) {
        static constexpr GrUserStencilSettings kCoverPass(
            GrUserStencilSettings::StaticInit<
                0x0000,
                GrUserStencilTest::kNotEqual, // Stencil pass accounts for clip.
                0xffff,
                GrUserStencilOp::kZero,
                GrUserStencilOp::kKeep,
                0xffff>()
        );

        SkAutoTUnref<GrPathRange> glyphs(this->createGlyphs(ctx));
        if (fLastDrawnGlyphsID != glyphs->uniqueID()) {
            // Either this is the first draw or the glyphs object was purged since last draw.
            glyphs->loadPathsIfNeeded(fInstanceData->indices(), fInstanceData->count());
            fLastDrawnGlyphsID = glyphs->uniqueID();
        }

        // Don't compute a bounding box. For dst copy texture, we'll opt instead for it to just copy
        // the entire dst. Realistically this is a moot point, because any context that supports
        // NV_path_rendering will also support NV_blend_equation_advanced.
        // For clipping we'll just skip any optimizations based on the bounds. This does, however,
        // hurt batching.
        const SkRect bounds = SkRect::MakeIWH(drawContext->width(), drawContext->height());

        SkAutoTUnref<GrDrawBatch> batch(
            GrDrawPathRangeBatch::Create(viewMatrix, fTextRatio, fTextInverseRatio * x,
                                         fTextInverseRatio * y, grPaint.getColor(),
                                         GrPathRendering::kWinding_FillType, glyphs, fInstanceData,
                                         bounds));

        GrPipelineBuilder pipelineBuilder(grPaint);
        pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, grPaint.isAntiAlias());
        pipelineBuilder.setUserStencil(&kCoverPass);

        drawContext->drawBatch(pipelineBuilder, clip, batch);
    }

    if (fFallbackTextBlob) {
        SkPaint fallbackSkPaint(originalSkPaint);
        fStyle.strokeRec().applyToPaint(&fallbackSkPaint);
        if (!fStyle.isSimpleFill()) {
            fallbackSkPaint.setStrokeWidth(fStyle.strokeRec().getWidth() * fTextRatio);
        }

        fallbackTextContext->drawTextBlob(ctx, drawContext, clip, fallbackSkPaint, viewMatrix,
                                          props, fFallbackTextBlob.get(), x, y, nullptr,
                                          clipBounds);
    }
}