blob: 15952077013c1dbed80d1643c8ad526794f4815a [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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 */
bsalomon@google.com30085192011-08-19 15:42:31 +00007
bsalomon@google.comffca4002011-02-22 20:34:01 +00008#include "GrPathRenderer.h"
Brian Salomon653f42f2018-07-10 10:07:31 -04009#include "GrCaps.h"
Brian Salomon653f42f2018-07-10 10:07:31 -040010#include "GrPaint.h"
Robert Phillips6f0e02f2019-02-13 11:02:28 -050011#include "GrRecordingContextPriv.h"
Brian Salomon653f42f2018-07-10 10:07:31 -040012#include "GrRenderTargetContext.h"
13#include "GrShape.h"
14#include "GrUserStencilSettings.h"
15#include "SkDrawProcs.h"
bsalomon@google.comffca4002011-02-22 20:34:01 +000016
Brian Salomon653f42f2018-07-10 10:07:31 -040017#ifdef SK_DEBUG
18void GrPathRenderer::StencilPathArgs::validate() const {
19 SkASSERT(fContext);
20 SkASSERT(fRenderTargetContext);
21 SkASSERT(fClipConservativeBounds);
22 SkASSERT(fViewMatrix);
23 SkASSERT(fShape);
24 SkASSERT(fShape->style().isSimpleFill());
Brian Salomon653f42f2018-07-10 10:07:31 -040025 SkPath path;
26 fShape->asPath(&path);
27 SkASSERT(!path.isInverseFillType());
tomhudson@google.comd22b6e42011-06-24 15:53:40 +000028}
Brian Salomon653f42f2018-07-10 10:07:31 -040029#endif
30
31//////////////////////////////////////////////////////////////////////////////
32
33GrPathRenderer::GrPathRenderer() {}
34
35GrPathRenderer::StencilSupport GrPathRenderer::getStencilSupport(const GrShape& shape) const {
36 SkDEBUGCODE(SkPath path;)
37 SkDEBUGCODE(shape.asPath(&path);)
38 SkASSERT(shape.style().isSimpleFill());
39 SkASSERT(!path.isInverseFillType());
40 return this->onGetStencilSupport(shape);
41}
42
43bool GrPathRenderer::drawPath(const DrawPathArgs& args) {
44#ifdef SK_DEBUG
45 args.validate();
46 CanDrawPathArgs canArgs;
Robert Phillips9da87e02019-02-04 13:26:26 -050047 canArgs.fCaps = args.fContext->priv().caps();
Brian Salomon653f42f2018-07-10 10:07:31 -040048 canArgs.fClipConservativeBounds = args.fClipConservativeBounds;
49 canArgs.fViewMatrix = args.fViewMatrix;
50 canArgs.fShape = args.fShape;
Chris Dalton09e56892019-03-13 00:22:01 -060051 canArgs.fAATypeFlags = args.fAATypeFlags;
Greg Danielbe7fc462019-01-03 16:40:42 -050052 canArgs.fTargetIsWrappedVkSecondaryCB = args.fRenderTargetContext->wrapsVkSecondaryCB();
Brian Salomon653f42f2018-07-10 10:07:31 -040053 canArgs.validate();
54
55 canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
Chris Dalton09e56892019-03-13 00:22:01 -060056 if (AATypeFlags::kMixedSampledStencilThenCover & canArgs.fAATypeFlags) {
57 SkASSERT(GrFSAAType::kMixedSamples == args.fRenderTargetContext->fsaaType());
58 }
Brian Salomon653f42f2018-07-10 10:07:31 -040059 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
70bool GrPathRenderer::IsStrokeHairlineOrEquivalent(const GrStyle& style, const SkMatrix& matrix,
Robert Phillips20390c32018-08-17 11:01:03 -040071 SkScalar* outCoverage) {
Brian Salomon653f42f2018-07-10 10:07:31 -040072 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
bsalomon@google.com1dd9baa2013-05-20 16:49:06 +000086
87void GrPathRenderer::GetPathDevBounds(const SkPath& path,
88 int devW, int devH,
89 const SkMatrix& matrix,
90 SkRect* bounds) {
91 if (path.isInverseFillType()) {
92 *bounds = SkRect::MakeWH(SkIntToScalar(devW), SkIntToScalar(devH));
93 return;
94 }
95 *bounds = path.getBounds();
96 matrix.mapRect(bounds);
97}
Brian Salomon653f42f2018-07-10 10:07:31 -040098
99void GrPathRenderer::onStencilPath(const StencilPathArgs& args) {
100 static constexpr GrUserStencilSettings kIncrementStencil(
101 GrUserStencilSettings::StaticInit<
102 0xffff,
103 GrUserStencilTest::kAlways,
104 0xffff,
105 GrUserStencilOp::kReplace,
106 GrUserStencilOp::kReplace,
107 0xffff>()
108 );
109
110 GrPaint paint;
111 DrawPathArgs drawArgs{args.fContext,
112 std::move(paint),
113 &kIncrementStencil,
114 args.fRenderTargetContext,
115 nullptr, // clip
116 args.fClipConservativeBounds,
117 args.fViewMatrix,
118 args.fShape,
Chris Dalton09e56892019-03-13 00:22:01 -0600119 (GrAA::kYes == args.fDoStencilMSAA)
120 ? AATypeFlags::kMSAA
121 : AATypeFlags::kNone,
Brian Salomon653f42f2018-07-10 10:07:31 -0400122 false};
123 this->drawPath(drawArgs);
124}