blob: c8aab20e504b7f76788bbed40de2ced657c2b69f [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/core/SkDrawProcs.h"
9#include "src/gpu/GrCaps.h"
10#include "src/gpu/GrPaint.h"
11#include "src/gpu/GrPathRenderer.h"
12#include "src/gpu/GrRecordingContextPriv.h"
13#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/GrUserStencilSettings.h"
Michael Ludwig2686d692020-04-17 20:21:37 +000015#include "src/gpu/geometry/GrStyledShape.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
Michael Ludwig2686d692020-04-17 20:21:37 +000035GrPathRenderer::StencilSupport GrPathRenderer::getStencilSupport(const GrStyledShape& shape) const {
Brian Salomon653f42f2018-07-10 10:07:31 -040036 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();
Greg Daniel46e366a2019-12-16 14:38:36 -050048 canArgs.fProxy = args.fRenderTargetContext->asRenderTargetProxy();
Brian Salomon653f42f2018-07-10 10:07:31 -040049 canArgs.fClipConservativeBounds = args.fClipConservativeBounds;
50 canArgs.fViewMatrix = args.fViewMatrix;
51 canArgs.fShape = args.fShape;
Ethan Nicholasafe2c902020-04-28 13:55:02 -040052 canArgs.fPaint = &args.fPaint;
Chris Dalton6ce447a2019-06-23 18:07:38 -060053 canArgs.fAAType = args.fAAType;
Greg Danielbe7fc462019-01-03 16:40:42 -050054 canArgs.fTargetIsWrappedVkSecondaryCB = args.fRenderTargetContext->wrapsVkSecondaryCB();
Brian Salomon653f42f2018-07-10 10:07:31 -040055 canArgs.validate();
56
57 canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
Brian Salomon653f42f2018-07-10 10:07:31 -040058 SkASSERT(CanDrawPath::kNo != this->canDrawPath(canArgs));
59 if (!args.fUserStencilSettings->isUnused()) {
60 SkPath path;
61 args.fShape->asPath(&path);
62 SkASSERT(args.fShape->style().isSimpleFill());
63 SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fShape));
64 }
65#endif
66 return this->onDrawPath(args);
67}
68
69bool GrPathRenderer::IsStrokeHairlineOrEquivalent(const GrStyle& style, const SkMatrix& matrix,
Robert Phillips20390c32018-08-17 11:01:03 -040070 SkScalar* outCoverage) {
Brian Salomon653f42f2018-07-10 10:07:31 -040071 if (style.pathEffect()) {
72 return false;
73 }
74 const SkStrokeRec& stroke = style.strokeRec();
75 if (stroke.isHairlineStyle()) {
76 if (outCoverage) {
77 *outCoverage = SK_Scalar1;
78 }
79 return true;
80 }
81 return stroke.getStyle() == SkStrokeRec::kStroke_Style &&
82 SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage);
83}
84
bsalomon@google.com1dd9baa2013-05-20 16:49:06 +000085void GrPathRenderer::GetPathDevBounds(const SkPath& path,
Brian Salomon9f2b86c2019-10-22 10:37:46 -040086 SkISize devSize,
bsalomon@google.com1dd9baa2013-05-20 16:49:06 +000087 const SkMatrix& matrix,
88 SkRect* bounds) {
89 if (path.isInverseFillType()) {
Brian Salomon9f2b86c2019-10-22 10:37:46 -040090 *bounds = SkRect::Make(devSize);
bsalomon@google.com1dd9baa2013-05-20 16:49:06 +000091 return;
92 }
93 *bounds = path.getBounds();
94 matrix.mapRect(bounds);
95}
Brian Salomon653f42f2018-07-10 10:07:31 -040096
97void GrPathRenderer::onStencilPath(const StencilPathArgs& args) {
98 static constexpr GrUserStencilSettings kIncrementStencil(
99 GrUserStencilSettings::StaticInit<
100 0xffff,
101 GrUserStencilTest::kAlways,
102 0xffff,
103 GrUserStencilOp::kReplace,
104 GrUserStencilOp::kReplace,
105 0xffff>()
106 );
107
108 GrPaint paint;
109 DrawPathArgs drawArgs{args.fContext,
110 std::move(paint),
111 &kIncrementStencil,
112 args.fRenderTargetContext,
113 nullptr, // clip
114 args.fClipConservativeBounds,
115 args.fViewMatrix,
116 args.fShape,
Chris Dalton6ce447a2019-06-23 18:07:38 -0600117 (GrAA::kYes == args.fDoStencilMSAA) ? GrAAType::kMSAA : GrAAType::kNone,
Brian Salomon653f42f2018-07-10 10:07:31 -0400118 false};
119 this->drawPath(drawArgs);
120}