blob: 28c8b1b800058a5846d69076b9db7aab78238d98 [file] [log] [blame]
Chris Dalton0e543092020-11-03 14:09:16 -07001/*
2 * Copyright 2020 Google LLC.
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#ifndef GrStrokeOp_DEFINED
9#define GrStrokeOp_DEFINED
10
11#include "include/core/SkStrokeRec.h"
12#include "include/gpu/GrRecordingContext.h"
13#include "src/gpu/GrSTArenaList.h"
14#include "src/gpu/ops/GrDrawOp.h"
15
16class GrStrokeTessellateShader;
17
18// Base class for ops that render opaque, constant-color strokes by linearizing them into sorted
19// "parametric" and "radial" edges. See GrStrokeTessellateShader.
20class GrStrokeOp : public GrDrawOp {
21protected:
22 // The provided matrix must be a similarity matrix for the time being. This is so we can
23 // bootstrap this Op on top of GrStrokeGeometry with minimal modifications.
24 //
25 // Patches can overlap, so until a stencil technique is implemented, the provided paint must be
26 // a constant blended color.
27 GrStrokeOp(uint32_t classID, GrAAType, const SkMatrix&, const SkStrokeRec&, const SkPath&,
28 GrPaint&&);
29
30 const char* name() const override { return "GrStrokeTessellateOp"; }
31 void visitProxies(const VisitProxyFunc& fn) const override { fProcessors.visitProxies(fn); }
32 FixedFunctionFlags fixedFunctionFlags() const override;
33 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
34 bool hasMixedSampledCoverage, GrClampType) override;
35 CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
36
37 void prePrepareColorProgram(SkArenaAlloc* arena, GrStrokeTessellateShader*,
38 const GrSurfaceProxyView*, GrAppliedClip&&, const
39 GrXferProcessor::DstProxyView&, GrXferBarrierFlags, const GrCaps&);
40
41 static float NumCombinedSegments(float numParametricSegments, float numRadialSegments) {
42 // The first and last edges are shared by both the parametric and radial sets of edges, so
43 // the total number of edges is:
44 //
45 // numCombinedEdges = numParametricEdges + numRadialEdges - 2
46 //
47 // It's also important to differentiate between the number of edges and segments in a strip:
48 //
49 // numCombinedSegments = numCombinedEdges - 1
50 //
51 // So the total number of segments in the combined strip is:
52 //
53 // numCombinedSegments = numParametricEdges + numRadialEdges - 2 - 1
54 // = numParametricSegments + 1 + numRadialSegments + 1 - 2 - 1
55 // = numParametricSegments + numRadialSegments - 1
56 //
57 return numParametricSegments + numRadialSegments - 1;
58 }
59
60 static float NumParametricSegments(float numCombinedSegments, float numRadialSegments) {
61 // numCombinedSegments = numParametricSegments + numRadialSegments - 1.
62 // (See num_combined_segments()).
63 return std::max(numCombinedSegments + 1 - numRadialSegments, 0.f);
64 }
65
66 const GrAAType fAAType;
67 const SkMatrix fViewMatrix;
68 const SkStrokeRec fStroke;
69 // Controls the number of parametric segments the tessellator adds for each curve. The
70 // tessellator will add enough parametric segments so that the center of each one falls within
71 // 1/parametricIntolerance local path units from the true curve.
72 const float fParametricIntolerance;
73 // Controls the number of radial segments the tessellator adds for each curve. The tessellator
74 // will add this number of radial segments for each radian of rotation, in order to guarantee
75 // smoothness.
76 const float fNumRadialSegmentsPerRadian;
77 SkPMColor4f fColor;
78 GrProcessorSet fProcessors;
79
80 GrSTArenaList<SkPath> fPathList;
81 int fTotalCombinedVerbCnt;
82
83 const GrProgramInfo* fColorProgram = nullptr;
84};
85
86#endif