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