1 | /* |
2 | * Copyright 2011 Google Inc. |
3 | * |
4 | * Use of this source code is governed by a BSD-style license that can be |
5 | * found in the LICENSE file. |
6 | */ |
7 | |
8 | #include "include/gpu/GrRecordingContext.h" |
9 | #include "src/core/SkDrawProcs.h" |
10 | #include "src/gpu/GrCaps.h" |
11 | #include "src/gpu/GrPaint.h" |
12 | #include "src/gpu/GrPathRenderer.h" |
13 | #include "src/gpu/GrRecordingContextPriv.h" |
14 | #include "src/gpu/GrRenderTargetContext.h" |
15 | #include "src/gpu/GrUserStencilSettings.h" |
16 | #include "src/gpu/geometry/GrStyledShape.h" |
17 | |
18 | #ifdef SK_DEBUG |
19 | void GrPathRenderer::StencilPathArgs::validate() const { |
20 | SkASSERT(fContext); |
21 | SkASSERT(fRenderTargetContext); |
22 | SkASSERT(fClipConservativeBounds); |
23 | SkASSERT(fViewMatrix); |
24 | SkASSERT(fShape); |
25 | SkASSERT(fShape->style().isSimpleFill()); |
26 | SkPath path; |
27 | fShape->asPath(&path); |
28 | SkASSERT(!path.isInverseFillType()); |
29 | } |
30 | #endif |
31 | |
32 | ////////////////////////////////////////////////////////////////////////////// |
33 | |
34 | GrPathRenderer::GrPathRenderer() {} |
35 | |
36 | GrPathRenderer::StencilSupport GrPathRenderer::getStencilSupport(const GrStyledShape& shape) const { |
37 | SkDEBUGCODE(SkPath path;) |
38 | SkDEBUGCODE(shape.asPath(&path);) |
39 | SkASSERT(shape.style().isSimpleFill()); |
40 | SkASSERT(!path.isInverseFillType()); |
41 | return this->onGetStencilSupport(shape); |
42 | } |
43 | |
44 | bool GrPathRenderer::drawPath(const DrawPathArgs& args) { |
45 | #ifdef SK_DEBUG |
46 | args.validate(); |
47 | CanDrawPathArgs canArgs; |
48 | canArgs.fCaps = args.fContext->priv().caps(); |
49 | canArgs.fProxy = args.fRenderTargetContext->asRenderTargetProxy(); |
50 | canArgs.fClipConservativeBounds = args.fClipConservativeBounds; |
51 | canArgs.fViewMatrix = args.fViewMatrix; |
52 | canArgs.fShape = args.fShape; |
53 | canArgs.fPaint = &args.fPaint; |
54 | canArgs.fAAType = args.fAAType; |
55 | canArgs.fTargetIsWrappedVkSecondaryCB = args.fRenderTargetContext->wrapsVkSecondaryCB(); |
56 | canArgs.validate(); |
57 | |
58 | canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused(); |
59 | SkASSERT(CanDrawPath::kNo != this->canDrawPath(canArgs)); |
60 | if (!args.fUserStencilSettings->isUnused()) { |
61 | SkPath path; |
62 | args.fShape->asPath(&path); |
63 | SkASSERT(args.fShape->style().isSimpleFill()); |
64 | SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fShape)); |
65 | } |
66 | #endif |
67 | return this->onDrawPath(args); |
68 | } |
69 | |
70 | bool GrPathRenderer::IsStrokeHairlineOrEquivalent(const GrStyle& style, const SkMatrix& matrix, |
71 | SkScalar* outCoverage) { |
72 | if (style.pathEffect()) { |
73 | return false; |
74 | } |
75 | const SkStrokeRec& stroke = style.strokeRec(); |
76 | if (stroke.isHairlineStyle()) { |
77 | if (outCoverage) { |
78 | *outCoverage = SK_Scalar1; |
79 | } |
80 | return true; |
81 | } |
82 | return stroke.getStyle() == SkStrokeRec::kStroke_Style && |
83 | SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage); |
84 | } |
85 | |
86 | void GrPathRenderer::GetPathDevBounds(const SkPath& path, |
87 | SkISize devSize, |
88 | const SkMatrix& matrix, |
89 | SkRect* bounds) { |
90 | if (path.isInverseFillType()) { |
91 | *bounds = SkRect::Make(devSize); |
92 | return; |
93 | } |
94 | *bounds = path.getBounds(); |
95 | matrix.mapRect(bounds); |
96 | } |
97 | |
98 | void GrPathRenderer::onStencilPath(const StencilPathArgs& args) { |
99 | static constexpr GrUserStencilSettings kIncrementStencil( |
100 | GrUserStencilSettings::StaticInit< |
101 | 0xffff, |
102 | GrUserStencilTest::kAlways, |
103 | 0xffff, |
104 | GrUserStencilOp::kReplace, |
105 | GrUserStencilOp::kReplace, |
106 | 0xffff>() |
107 | ); |
108 | |
109 | GrPaint paint; |
110 | DrawPathArgs drawArgs{args.fContext, |
111 | std::move(paint), |
112 | &kIncrementStencil, |
113 | args.fRenderTargetContext, |
114 | nullptr, // clip |
115 | args.fClipConservativeBounds, |
116 | args.fViewMatrix, |
117 | args.fShape, |
118 | (GrAA::kYes == args.fDoStencilMSAA) ? GrAAType::kMSAA : GrAAType::kNone, |
119 | false}; |
120 | this->drawPath(drawArgs); |
121 | } |
122 | |