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 "GrPathRenderer.h"
9 #include "GrCaps.h"
10 #include "GrContextPriv.h"
11 #include "GrPaint.h"
12 #include "GrRenderTargetContext.h"
13 #include "GrShape.h"
14 #include "GrUserStencilSettings.h"
15 #include "SkDrawProcs.h"
16
17 #ifdef SK_DEBUG
validate() const18 void GrPathRenderer::StencilPathArgs::validate() const {
19 SkASSERT(fContext);
20 SkASSERT(fRenderTargetContext);
21 SkASSERT(fClipConservativeBounds);
22 SkASSERT(fViewMatrix);
23 SkASSERT(fShape);
24 SkASSERT(fShape->style().isSimpleFill());
25 SkASSERT(GrAAType::kCoverage != fAAType);
26 SkPath path;
27 fShape->asPath(&path);
28 SkASSERT(!path.isInverseFillType());
29 }
30 #endif
31
32 //////////////////////////////////////////////////////////////////////////////
33
GrPathRenderer()34 GrPathRenderer::GrPathRenderer() {}
35
getStencilSupport(const GrShape & shape) const36 GrPathRenderer::StencilSupport GrPathRenderer::getStencilSupport(const GrShape& 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
drawPath(const DrawPathArgs & args)44 bool GrPathRenderer::drawPath(const DrawPathArgs& args) {
45 #ifdef SK_DEBUG
46 args.validate();
47 CanDrawPathArgs canArgs;
48 canArgs.fCaps = args.fContext->contextPriv().caps();
49 canArgs.fClipConservativeBounds = args.fClipConservativeBounds;
50 canArgs.fViewMatrix = args.fViewMatrix;
51 canArgs.fShape = args.fShape;
52 canArgs.fAAType = args.fAAType;
53 canArgs.fTargetIsWrappedVkSecondaryCB = args.fRenderTargetContext->wrapsVkSecondaryCB();
54 canArgs.validate();
55
56 canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
57 SkASSERT(!(canArgs.fAAType == GrAAType::kMSAA &&
58 GrFSAAType::kUnifiedMSAA != args.fRenderTargetContext->fsaaType()));
59 SkASSERT(!(canArgs.fAAType == GrAAType::kMixedSamples &&
60 GrFSAAType::kMixedSamples != args.fRenderTargetContext->fsaaType()));
61 SkASSERT(CanDrawPath::kNo != this->canDrawPath(canArgs));
62 if (!args.fUserStencilSettings->isUnused()) {
63 SkPath path;
64 args.fShape->asPath(&path);
65 SkASSERT(args.fShape->style().isSimpleFill());
66 SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fShape));
67 }
68 #endif
69 return this->onDrawPath(args);
70 }
71
IsStrokeHairlineOrEquivalent(const GrStyle & style,const SkMatrix & matrix,SkScalar * outCoverage)72 bool GrPathRenderer::IsStrokeHairlineOrEquivalent(const GrStyle& style, const SkMatrix& matrix,
73 SkScalar* outCoverage) {
74 if (style.pathEffect()) {
75 return false;
76 }
77 const SkStrokeRec& stroke = style.strokeRec();
78 if (stroke.isHairlineStyle()) {
79 if (outCoverage) {
80 *outCoverage = SK_Scalar1;
81 }
82 return true;
83 }
84 return stroke.getStyle() == SkStrokeRec::kStroke_Style &&
85 SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage);
86 }
87
88
GetPathDevBounds(const SkPath & path,int devW,int devH,const SkMatrix & matrix,SkRect * bounds)89 void GrPathRenderer::GetPathDevBounds(const SkPath& path,
90 int devW, int devH,
91 const SkMatrix& matrix,
92 SkRect* bounds) {
93 if (path.isInverseFillType()) {
94 *bounds = SkRect::MakeWH(SkIntToScalar(devW), SkIntToScalar(devH));
95 return;
96 }
97 *bounds = path.getBounds();
98 matrix.mapRect(bounds);
99 }
100
onStencilPath(const StencilPathArgs & args)101 void GrPathRenderer::onStencilPath(const StencilPathArgs& args) {
102 static constexpr GrUserStencilSettings kIncrementStencil(
103 GrUserStencilSettings::StaticInit<
104 0xffff,
105 GrUserStencilTest::kAlways,
106 0xffff,
107 GrUserStencilOp::kReplace,
108 GrUserStencilOp::kReplace,
109 0xffff>()
110 );
111
112 GrPaint paint;
113 DrawPathArgs drawArgs{args.fContext,
114 std::move(paint),
115 &kIncrementStencil,
116 args.fRenderTargetContext,
117 nullptr, // clip
118 args.fClipConservativeBounds,
119 args.fViewMatrix,
120 args.fShape,
121 args.fAAType,
122 false};
123 this->drawPath(drawArgs);
124 }
125