blob: 72b84d5a77aca919250ba106810aec3be91856e9 [file] [log] [blame]
Chris Dalton419a94d2017-08-28 10:24:22 -06001/*
2 * Copyright 2017 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#ifndef GrGrCCPRGeometry_DEFINED
9#define GrGrCCPRGeometry_DEFINED
10
Chris Daltonc1e59632017-09-05 00:30:07 -060011#include "SkNx.h"
12#include "SkPoint.h"
13#include "SkTArray.h"
Chris Dalton419a94d2017-08-28 10:24:22 -060014
Chris Daltonc1e59632017-09-05 00:30:07 -060015struct SkDCubic;
16enum class SkCubicType;
Chris Dalton419a94d2017-08-28 10:24:22 -060017
Chris Daltonc1e59632017-09-05 00:30:07 -060018/**
19 * This class chops device-space contours up into a series of segments that CCPR knows how to
20 * render. (See GrCCPRGeometry::Verb.)
Chris Dalton419a94d2017-08-28 10:24:22 -060021 *
22 * NOTE: This must be done in device space, since an affine transformation can change whether a
23 * curve is monotonic.
Chris Dalton419a94d2017-08-28 10:24:22 -060024 */
Chris Daltonc1e59632017-09-05 00:30:07 -060025class GrCCPRGeometry {
26public:
27 // These are the verbs that CCPR knows how to draw. If a path has any segments that don't map to
28 // this list, then they are chopped into smaller ones that do. A list of these comprise a
29 // compact representation of what can later be expanded into GPU instance data.
30 enum class Verb : uint8_t {
31 kBeginPath, // Included only for caller convenience.
32 kBeginContour,
33 kLineTo,
34 kMonotonicQuadraticTo, // Monotonic relative to the vector between its endpoints [P2 - P0].
35 kConvexSerpentineTo,
36 kConvexLoopTo,
37 kEndClosedContour, // endPt == startPt.
38 kEndOpenContour // endPt != startPt.
39 };
40
41 // These tallies track numbers of CCPR primitives are required to draw a contour.
42 struct PrimitiveTallies {
43 int fTriangles; // Number of triangles in the contour's fan.
44 int fQuadratics;
45 int fSerpentines;
46 int fLoops;
47
48 void operator+=(const PrimitiveTallies&);
49 PrimitiveTallies operator-(const PrimitiveTallies&) const;
50 };
51
52 GrCCPRGeometry(int numSkPoints = 0, int numSkVerbs = 0)
53 : fPoints(numSkPoints * 3) // Reserve for a 3x expansion in points and verbs.
54 , fVerbs(numSkVerbs * 3) {}
55
56 const SkTArray<SkPoint, true>& points() const { SkASSERT(!fBuildingContour); return fPoints; }
57 const SkTArray<Verb, true>& verbs() const { SkASSERT(!fBuildingContour); return fVerbs; }
58
59 void reset() {
60 SkASSERT(!fBuildingContour);
61 fPoints.reset();
62 fVerbs.reset();
63 }
64
65 // This is included in case the caller needs to discard previously added contours. It is up to
66 // the caller to track counts and ensure we don't pop back into the middle of a different
67 // contour.
68 void resize_back(int numPoints, int numVerbs) {
69 SkASSERT(!fBuildingContour);
70 fPoints.resize_back(numPoints);
71 fVerbs.resize_back(numVerbs);
72 SkASSERT(fVerbs.empty() || fVerbs.back() == Verb::kEndOpenContour ||
73 fVerbs.back() == Verb::kEndClosedContour);
74 }
75
76 void beginPath();
77 void beginContour(const SkPoint& devPt);
78 void lineTo(const SkPoint& devPt);
79 void quadraticTo(const SkPoint& devP1, const SkPoint& devP2);
80 void cubicTo(const SkPoint& devP1, const SkPoint& devP2, const SkPoint& devP3);
81 PrimitiveTallies endContour(); // Returns the numbers of primitives needed to draw the contour.
82
83private:
84 inline void appendMonotonicQuadratic(const Sk2f& p1, const Sk2f& p2);
85 inline void appendConvexCubic(SkCubicType, const SkDCubic&);
86
87 // Transient state used while building a contour.
88 SkPoint fCurrAnchorPoint;
89 SkPoint fCurrFanPoint;
90 PrimitiveTallies fCurrContourTallies;
91 SkDEBUGCODE(bool fBuildingContour = false);
92
93 // TODO: These points could eventually be written directly to block-allocated GPU buffers.
94 SkSTArray<128, SkPoint, true> fPoints;
95 SkSTArray<128, Verb, true> fVerbs;
96};
97
98inline void GrCCPRGeometry::PrimitiveTallies::operator+=(const PrimitiveTallies& b) {
99 fTriangles += b.fTriangles;
100 fQuadratics += b.fQuadratics;
101 fSerpentines += b.fSerpentines;
102 fLoops += b.fLoops;
103}
104
105GrCCPRGeometry::PrimitiveTallies
106inline GrCCPRGeometry::PrimitiveTallies::operator-(const PrimitiveTallies& b) const {
107 return {fTriangles - b.fTriangles,
108 fQuadratics - b.fQuadratics,
109 fSerpentines - b.fSerpentines,
110 fLoops - b.fLoops};
111}
Chris Dalton419a94d2017-08-28 10:24:22 -0600112
113#endif