//////////////////////////////////////////////////////////////////////////////// // return true on success; false on failure bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrSoftwarePathRenderer::onDrawPath"); if (nullptr == fContext) { return false; } SkIRect devPathBounds, devClipBounds; if (!get_path_and_clip_bounds(args.fPipelineBuilder, *args.fPath, *args.fViewMatrix, &devPathBounds, &devClipBounds)) { if (args.fPath->isInverseFillType()) { draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColor, *args.fViewMatrix, devClipBounds, devPathBounds); } return true; } SkAutoTUnref<GrTexture> texture( GrSWMaskHelper::DrawPathMaskToTexture(fContext, *args.fPath, *args.fStroke, devPathBounds, args.fAntiAlias, args.fViewMatrix)); if (nullptr == texture) { return false; } GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fTarget, args.fPipelineBuilder, args.fColor, *args.fViewMatrix, devPathBounds); if (args.fPath->isInverseFillType()) { draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColor, *args.fViewMatrix, devClipBounds, devPathBounds); } return true; }
void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(), "GrStencilAndCoverPathRenderer::onStencilPath"); sk_sp<GrPath> p(get_gr_path(fResourceProvider, *args.fShape)); args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fAAType, *args.fViewMatrix, p.get()); }
bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), "GrDashLinePathRenderer::onDrawPath"); bool useHWAA = args.fDrawContext->isUnifiedMultisampled(); GrDashingEffect::AAMode aaMode; if (useHWAA) { // We ignore args.fAntiAlias here and force anti aliasing when using MSAA. Otherwise, // we can wind up with external edges antialiased and internal edges unantialiased. aaMode = GrDashingEffect::AAMode::kCoverageWithMSAA; } else if (args.fAntiAlias) { aaMode = GrDashingEffect::AAMode::kCoverage; } else { aaMode = GrDashingEffect::AAMode::kNone; } SkPoint pts[2]; SkAssertResult(args.fShape->asLine(pts, nullptr)); SkAutoTUnref<GrDrawBatch> batch(GrDashingEffect::CreateDashLineBatch(args.fColor, *args.fViewMatrix, pts, aaMode, args.fShape->style())); if (!batch) { return false; } GrPipelineBuilder pipelineBuilder(*args.fPaint, useHWAA); pipelineBuilder.setUserStencil(args.fUserStencilSettings); args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); return true; }
bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), "GrAADistanceFieldPathRenderer::onDrawPath"); SkASSERT(!args.fDrawContext->isUnifiedMultisampled()); SkASSERT(args.fShape->style().isSimpleFill()); // we've already bailed on inverse filled paths, so this is safe SkASSERT(!args.fShape->isEmpty()); SkASSERT(args.fShape->hasUnstyledKey()); if (!fAtlas) { fAtlas = args.fResourceProvider->createAtlas(kAlpha_8_GrPixelConfig, ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT, NUM_PLOTS_X, NUM_PLOTS_Y, &GrAADistanceFieldPathRenderer::HandleEviction, (void*)this); if (!fAtlas) { return false; } } SkAutoTUnref<GrDrawBatch> batch(new AADistanceFieldPathBatch(args.fPaint->getColor(), *args.fShape, args.fAntiAlias, *args.fViewMatrix, fAtlas, &fShapeCache, &fShapeList, args.fGammaCorrect)); GrPipelineBuilder pipelineBuilder(*args.fPaint); pipelineBuilder.setUserStencil(args.fUserStencilSettings); args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); return true; }
void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrStencilAndCoverPathRenderer::onStencilPath"); SkASSERT(!args.fPath->isInverseFillType()); SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, GrStyle::SimpleFill())); args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fViewMatrix, p, p->getFillType()); }
void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), "GrStencilAndCoverPathRenderer::onStencilPath"); SkASSERT(!args.fIsAA || args.fDrawContext->isStencilBufferMultisampled()); SkPath path; args.fShape->asPath(&path); SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, GrStyle::SimpleFill())); args.fDrawContext->drawContextPriv().stencilPath(*args.fClip, args.fIsAA, *args.fViewMatrix, p); }
bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(), "GrDefaultPathRenderer::onDrawPath"); GrAAType aaType = (AATypeFlags::kNone != args.fAATypeFlags) ? GrAAType::kMSAA : GrAAType::kNone; return this->internalDrawPath( args.fRenderTargetContext, std::move(args.fPaint), aaType, *args.fUserStencilSettings, *args.fClip, *args.fViewMatrix, *args.fShape, false); }
void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(), "GrDefaultPathRenderer::onStencilPath"); SkASSERT(!args.fShape->inverseFilled()); GrPaint paint; paint.setXPFactory(GrDisableColorXPFactory::Get()); auto aaType = (GrAA::kYes == args.fDoStencilMSAA) ? GrAAType::kMSAA : GrAAType::kNone; this->internalDrawPath( args.fRenderTargetContext, std::move(paint), aaType, GrUserStencilSettings::kUnused, *args.fClip, *args.fViewMatrix, *args.fShape, true); }
//////////////////////////////////////////////////////////////////////////////// // return true on success; false on failure bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), "GrSoftwarePathRenderer::onDrawPath"); if (!fTexProvider) { return false; } // We really need to know if the shape will be inverse filled or not bool inverseFilled = false; SkTLazy<GrShape> tmpShape; SkASSERT(!args.fShape->style().applies()) inverseFilled = args.fShape->inverseFilled(); SkIRect devShapeBounds, devClipBounds; if (!get_shape_and_clip_bounds(args.fDrawContext->width(), args.fDrawContext->height(), *args.fClip, *args.fShape, *args.fViewMatrix, &devShapeBounds, &devClipBounds)) { if (inverseFilled) { DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings, *args.fClip, args.fColor, *args.fViewMatrix, devClipBounds, devShapeBounds); } return true; } SkAutoTUnref<GrTexture> texture( GrSWMaskHelper::DrawShapeMaskToTexture(fTexProvider, *args.fShape, devShapeBounds, args.fAntiAlias, args.fViewMatrix)); if (nullptr == texture) { return false; } GrSWMaskHelper::DrawToTargetWithShapeMask(texture, args.fDrawContext, args.fPaint, args.fUserStencilSettings, *args.fClip, args.fColor, *args.fViewMatrix, devShapeBounds); if (inverseFilled) { DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings, *args.fClip, args.fColor, *args.fViewMatrix, devClipBounds, devShapeBounds); } return true; }
bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrDashLinePathRenderer::onDrawPath"); bool msaaIsEnabled = args.fPipelineBuilder->getRenderTarget()->isUnifiedMultisampled(); SkPoint pts[2]; SkAssertResult(args.fPath->isLine(pts)); SkAutoTUnref<GrDrawBatch> batch(GrDashingEffect::CreateDashLineBatch(args.fColor, *args.fViewMatrix, pts, args.fAntiAlias, msaaIsEnabled, *args.fStyle)); if (!batch) { return false; } args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch); return true; }
bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(), "GrStencilAndCoverPathRenderer::onDrawPath"); SkASSERT(!args.fShape->style().strokeRec().isHairlineStyle()); const SkMatrix& viewMatrix = *args.fViewMatrix; sk_sp<GrPath> path(get_gr_path(fResourceProvider, *args.fShape)); if (args.fShape->inverseFilled()) { SkMatrix invert = SkMatrix::I(); SkRect bounds = SkRect::MakeLTRB(0, 0, SkIntToScalar(args.fRenderTargetContext->width()), SkIntToScalar(args.fRenderTargetContext->height())); SkMatrix vmi; // mapRect through persp matrix may not be correct if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) { vmi.mapRect(&bounds); // theoretically could set bloat = 0, instead leave it because of matrix inversion // precision. SkScalar bloat = viewMatrix.getMaxScale() * SK_ScalarHalf; bounds.outset(bloat, bloat); } else { if (!viewMatrix.invert(&invert)) { return false; } } const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : viewMatrix; // fake inverse with a stencil and cover args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fAAType, viewMatrix, path.get()); { static constexpr GrUserStencilSettings kInvertedCoverPass( GrUserStencilSettings::StaticInit< 0x0000, // We know our rect will hit pixels outside the clip and the user bits will // be 0 outside the clip. So we can't just fill where the user bits are 0. We // also need to check that the clip bit is set. GrUserStencilTest::kEqualIfInClip, 0xffff, GrUserStencilOp::kKeep, GrUserStencilOp::kZero, 0xffff>() ); // We have to suppress enabling MSAA for mixed samples or we will get seams due to // coverage modulation along the edge where two triangles making up the rect meet. GrAAType coverAAType = args.fAAType; if (GrAAType::kMixedSamples == coverAAType) { coverAAType = GrAAType::kNone; } args.fRenderTargetContext->addDrawOp(*args.fClip, GrRectOpFactory::MakeNonAAFillWithLocalMatrix( std::move(args.fPaint), viewM, invert, bounds, coverAAType, &kInvertedCoverPass)); } } else { std::unique_ptr<GrDrawOp> op = GrDrawPathOp::Make(viewMatrix, std::move(args.fPaint), args.fAAType, path.get()); args.fRenderTargetContext->addDrawOp(*args.fClip, std::move(op)); } return true; }
bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrStencilAndCoverPathRenderer::onDrawPath"); SkASSERT(!args.fStyle->strokeRec().isHairlineStyle()); const SkPath& path = *args.fPath; GrPipelineBuilder* pipelineBuilder = args.fPipelineBuilder; const SkMatrix& viewMatrix = *args.fViewMatrix; SkASSERT(!pipelineBuilder->hasUserStencilSettings()); if (args.fAntiAlias) { SkASSERT(pipelineBuilder->getRenderTarget()->isStencilBufferMultisampled()); pipelineBuilder->enableState(GrPipelineBuilder::kHWAntialias_Flag); } SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStyle)); if (path.isInverseFillType()) { static constexpr GrUserStencilSettings kInvertedCoverPass( GrUserStencilSettings::StaticInit< 0x0000, // We know our rect will hit pixels outside the clip and the user bits will be 0 // outside the clip. So we can't just fill where the user bits are 0. We also need // to check that the clip bit is set. GrUserStencilTest::kEqualIfInClip, 0xffff, GrUserStencilOp::kKeep, GrUserStencilOp::kZero, 0xffff>() ); pipelineBuilder->setUserStencil(&kInvertedCoverPass); // fake inverse with a stencil and cover args.fTarget->stencilPath(*pipelineBuilder, viewMatrix, p, p->getFillType()); SkMatrix invert = SkMatrix::I(); SkRect bounds = SkRect::MakeLTRB(0, 0, SkIntToScalar(pipelineBuilder->getRenderTarget()->width()), SkIntToScalar(pipelineBuilder->getRenderTarget()->height())); SkMatrix vmi; // mapRect through persp matrix may not be correct if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) { vmi.mapRect(&bounds); // theoretically could set bloat = 0, instead leave it because of matrix inversion // precision. SkScalar bloat = viewMatrix.getMaxScale() * SK_ScalarHalf; bounds.outset(bloat, bloat); } else { if (!viewMatrix.invert(&invert)) { return false; } } const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : viewMatrix; if (pipelineBuilder->getRenderTarget()->hasMixedSamples()) { pipelineBuilder->disableState(GrPipelineBuilder::kHWAntialias_Flag); } SkAutoTUnref<GrDrawBatch> batch( GrRectBatchFactory::CreateNonAAFill(args.fColor, viewM, bounds, nullptr, &invert)); args.fTarget->drawBatch(*pipelineBuilder, batch); } else { static constexpr GrUserStencilSettings kCoverPass( GrUserStencilSettings::StaticInit< 0x0000, GrUserStencilTest::kNotEqual, 0xffff, GrUserStencilOp::kZero, GrUserStencilOp::kKeep, 0xffff>() ); pipelineBuilder->setUserStencil(&kCoverPass); SkAutoTUnref<GrDrawPathBatchBase> batch( GrDrawPathBatch::Create(viewMatrix, args.fColor, p->getFillType(), p)); args.fTarget->drawPathBatch(*pipelineBuilder, batch); } pipelineBuilder->disableUserStencil(); return true; }