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 #include "src/gpu/ganesh/PathRenderer.h"
8
9 #include "include/core/SkMatrix.h"
10 #include "include/core/SkPath.h"
11 #include "include/core/SkRect.h"
12 #include "include/core/SkSize.h"
13 #include "include/gpu/ganesh/GrRecordingContext.h"
14 #include "include/private/gpu/ganesh/GrTypesPriv.h"
15 #include "src/gpu/ganesh/GrPaint.h"
16 #include "src/gpu/ganesh/GrRecordingContextPriv.h"
17 #include "src/gpu/ganesh/GrStyle.h"
18 #include "src/gpu/ganesh/GrUserStencilSettings.h"
19 #include "src/gpu/ganesh/SurfaceDrawContext.h"
20 #include "src/gpu/ganesh/geometry/GrStyledShape.h"
21
22 #include <utility>
23
24 namespace skgpu::ganesh {
25
26 #ifdef SK_DEBUG
validate() const27 void PathRenderer::StencilPathArgs::validate() const {
28 SkASSERT(fContext);
29 SkASSERT(fSurfaceDrawContext);
30 SkASSERT(fClipConservativeBounds);
31 SkASSERT(fViewMatrix);
32 SkASSERT(fShape);
33 SkASSERT(fShape->style().isSimpleFill());
34 SkPath path;
35 fShape->asPath(&path);
36 SkASSERT(!path.isInverseFillType());
37 }
38 #endif
39
40 //////////////////////////////////////////////////////////////////////////////
41
getStencilSupport(const GrStyledShape & shape) const42 PathRenderer::StencilSupport PathRenderer::getStencilSupport(const GrStyledShape& shape) const {
43 SkDEBUGCODE(SkPath path;)
44 SkDEBUGCODE(shape.asPath(&path);)
45 SkASSERT(shape.style().isSimpleFill());
46 SkASSERT(!path.isInverseFillType());
47 return this->onGetStencilSupport(shape);
48 }
49
drawPath(const DrawPathArgs & args)50 bool PathRenderer::drawPath(const DrawPathArgs& args) {
51 #ifdef SK_DEBUG
52 args.validate();
53 CanDrawPathArgs canArgs;
54 canArgs.fCaps = args.fContext->priv().caps();
55 canArgs.fProxy = args.fSurfaceDrawContext->asRenderTargetProxy();
56 canArgs.fClipConservativeBounds = args.fClipConservativeBounds;
57 canArgs.fViewMatrix = args.fViewMatrix;
58 canArgs.fShape = args.fShape;
59 canArgs.fPaint = &args.fPaint;
60 canArgs.fSurfaceProps = &args.fSurfaceDrawContext->surfaceProps();
61 canArgs.fAAType = args.fAAType;
62 canArgs.validate();
63
64 canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
65 SkASSERT(CanDrawPath::kNo != this->canDrawPath(canArgs));
66 if (!args.fUserStencilSettings->isUnused()) {
67 SkPath path;
68 args.fShape->asPath(&path);
69 SkASSERT(args.fShape->style().isSimpleFill());
70 SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fShape));
71 }
72 #endif
73 return this->onDrawPath(args);
74 }
75
GetPathDevBounds(const SkPath & path,SkISize devSize,const SkMatrix & matrix,SkRect * bounds)76 void PathRenderer::GetPathDevBounds(const SkPath& path,
77 SkISize devSize,
78 const SkMatrix& matrix,
79 SkRect* bounds) {
80 if (path.isInverseFillType()) {
81 *bounds = SkRect::Make(devSize);
82 return;
83 }
84 *bounds = path.getBounds();
85 matrix.mapRect(bounds);
86 }
87
onStencilPath(const StencilPathArgs & args)88 void PathRenderer::onStencilPath(const StencilPathArgs& args) {
89 static constexpr GrUserStencilSettings kIncrementStencil(
90 GrUserStencilSettings::StaticInit<
91 0xffff,
92 GrUserStencilTest::kAlways,
93 0xffff,
94 GrUserStencilOp::kReplace,
95 GrUserStencilOp::kReplace,
96 0xffff>()
97 );
98
99 GrPaint paint;
100 DrawPathArgs drawArgs{args.fContext,
101 std::move(paint),
102 &kIncrementStencil,
103 args.fSurfaceDrawContext,
104 nullptr, // clip
105 args.fClipConservativeBounds,
106 args.fViewMatrix,
107 args.fShape,
108 (GrAA::kYes == args.fDoStencilMSAA) ? GrAAType::kMSAA : GrAAType::kNone,
109 false};
110 this->drawPath(drawArgs);
111 }
112
113 } // namespace skgpu::ganesh
114