OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrAAConvexPathRenderer.h" | 9 #include "GrAAConvexPathRenderer.h" |
10 | 10 |
11 #include "GrAAConvexTessellator.h" | 11 #include "GrAAConvexTessellator.h" |
12 #include "GrBatch.h" | 12 #include "GrBatch.h" |
13 #include "GrBatchTarget.h" | 13 #include "GrBatchTarget.h" |
14 #include "GrBatchTest.h" | 14 #include "GrBatchTest.h" |
15 #include "GrCaps.h" | 15 #include "GrCaps.h" |
16 #include "GrContext.h" | 16 #include "GrContext.h" |
17 #include "GrDefaultGeoProcFactory.h" | 17 #include "GrDefaultGeoProcFactory.h" |
18 #include "GrGeometryProcessor.h" | 18 #include "GrGeometryProcessor.h" |
19 #include "GrInvariantOutput.h" | 19 #include "GrInvariantOutput.h" |
20 #include "GrPathUtils.h" | 20 #include "GrPathUtils.h" |
21 #include "GrProcessor.h" | 21 #include "GrProcessor.h" |
22 #include "GrPipelineBuilder.h" | 22 #include "GrPipelineBuilder.h" |
23 #include "GrStrokeInfo.h" | 23 #include "GrStrokeInfo.h" |
24 #include "SkGeometry.h" | 24 #include "SkGeometry.h" |
| 25 #include "SkPathPriv.h" |
25 #include "SkString.h" | 26 #include "SkString.h" |
26 #include "SkTraceEvent.h" | 27 #include "SkTraceEvent.h" |
27 #include "gl/GrGLProcessor.h" | 28 #include "gl/GrGLProcessor.h" |
28 #include "gl/GrGLSL.h" | 29 #include "gl/GrGLSL.h" |
29 #include "gl/GrGLGeometryProcessor.h" | 30 #include "gl/GrGLGeometryProcessor.h" |
30 #include "gl/builders/GrGLProgramBuilder.h" | 31 #include "gl/builders/GrGLProgramBuilder.h" |
31 | 32 |
32 GrAAConvexPathRenderer::GrAAConvexPathRenderer() { | 33 GrAAConvexPathRenderer::GrAAConvexPathRenderer() { |
33 } | 34 } |
34 | 35 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 center.fX = SkScalarMul(center.fX, area); | 110 center.fX = SkScalarMul(center.fX, area); |
110 center.fY = SkScalarMul(center.fY, area); | 111 center.fY = SkScalarMul(center.fY, area); |
111 // undo the translate of p0 to the origin. | 112 // undo the translate of p0 to the origin. |
112 *c = center + p0; | 113 *c = center + p0; |
113 } | 114 } |
114 SkASSERT(!SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY)); | 115 SkASSERT(!SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY)); |
115 } | 116 } |
116 | 117 |
117 static void compute_vectors(SegmentArray* segments, | 118 static void compute_vectors(SegmentArray* segments, |
118 SkPoint* fanPt, | 119 SkPoint* fanPt, |
119 SkPath::Direction dir, | 120 SkPathPriv::FirstDirection dir, |
120 int* vCount, | 121 int* vCount, |
121 int* iCount) { | 122 int* iCount) { |
122 center_of_mass(*segments, fanPt); | 123 center_of_mass(*segments, fanPt); |
123 int count = segments->count(); | 124 int count = segments->count(); |
124 | 125 |
125 // Make the normals point towards the outside | 126 // Make the normals point towards the outside |
126 SkPoint::Side normSide; | 127 SkPoint::Side normSide; |
127 if (dir == SkPath::kCCW_Direction) { | 128 if (dir == SkPathPriv::kCCW_FirstDirection) { |
128 normSide = SkPoint::kRight_Side; | 129 normSide = SkPoint::kRight_Side; |
129 } else { | 130 } else { |
130 normSide = SkPoint::kLeft_Side; | 131 normSide = SkPoint::kLeft_Side; |
131 } | 132 } |
132 | 133 |
133 *vCount = 0; | 134 *vCount = 0; |
134 *iCount = 0; | 135 *iCount = 0; |
135 // compute normals at all points | 136 // compute normals at all points |
136 for (int a = 0; a < count; ++a) { | 137 for (int a = 0; a < count; ++a) { |
137 Segment& sega = (*segments)[a]; | 138 Segment& sega = (*segments)[a]; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 if (SkScalarAbs(data->fLineNormal.dot(pt) + data->fLineC) > kClose)
{ | 206 if (SkScalarAbs(data->fLineNormal.dot(pt) + data->fLineC) > kClose)
{ |
206 data->fStage = DegenerateTestData::kNonDegenerate; | 207 data->fStage = DegenerateTestData::kNonDegenerate; |
207 } | 208 } |
208 case DegenerateTestData::kNonDegenerate: | 209 case DegenerateTestData::kNonDegenerate: |
209 break; | 210 break; |
210 default: | 211 default: |
211 SkFAIL("Unexpected degenerate test stage."); | 212 SkFAIL("Unexpected degenerate test stage."); |
212 } | 213 } |
213 } | 214 } |
214 | 215 |
215 static inline bool get_direction(const SkPath& path, const SkMatrix& m, SkPath::
Direction* dir) { | 216 static inline bool get_direction(const SkPath& path, const SkMatrix& m, |
216 if (!path.cheapComputeDirection(dir)) { | 217 SkPathPriv::FirstDirection* dir) { |
| 218 if (!SkPathPriv::CheapComputeFirstDirection(path, dir)) { |
217 return false; | 219 return false; |
218 } | 220 } |
219 // check whether m reverses the orientation | 221 // check whether m reverses the orientation |
220 SkASSERT(!m.hasPerspective()); | 222 SkASSERT(!m.hasPerspective()); |
221 SkScalar det2x2 = SkScalarMul(m.get(SkMatrix::kMScaleX), m.get(SkMatrix::kMS
caleY)) - | 223 SkScalar det2x2 = SkScalarMul(m.get(SkMatrix::kMScaleX), m.get(SkMatrix::kMS
caleY)) - |
222 SkScalarMul(m.get(SkMatrix::kMSkewX), m.get(SkMatrix::kMSk
ewY)); | 224 SkScalarMul(m.get(SkMatrix::kMSkewX), m.get(SkMatrix::kMSk
ewY)); |
223 if (det2x2 < 0) { | 225 if (det2x2 < 0) { |
224 *dir = SkPath::OppositeDirection(*dir); | 226 *dir = SkPathPriv::OppositeFirstDirection(*dir); |
225 } | 227 } |
226 return true; | 228 return true; |
227 } | 229 } |
228 | 230 |
229 static inline void add_line_to_segment(const SkPoint& pt, | 231 static inline void add_line_to_segment(const SkPoint& pt, |
230 SegmentArray* segments) { | 232 SegmentArray* segments) { |
231 segments->push_back(); | 233 segments->push_back(); |
232 segments->back().fType = Segment::kLine; | 234 segments->back().fType = Segment::kLine; |
233 segments->back().fPts[0] = pt; | 235 segments->back().fPts[0] = pt; |
234 } | 236 } |
235 | 237 |
236 static inline void add_quad_segment(const SkPoint pts[3], | 238 static inline void add_quad_segment(const SkPoint pts[3], |
237 SegmentArray* segments) { | 239 SegmentArray* segments) { |
238 if (pts[0].distanceToSqd(pts[1]) < kCloseSqd || pts[1].distanceToSqd(pts[2])
< kCloseSqd) { | 240 if (pts[0].distanceToSqd(pts[1]) < kCloseSqd || pts[1].distanceToSqd(pts[2])
< kCloseSqd) { |
239 if (pts[0] != pts[2]) { | 241 if (pts[0] != pts[2]) { |
240 add_line_to_segment(pts[2], segments); | 242 add_line_to_segment(pts[2], segments); |
241 } | 243 } |
242 } else { | 244 } else { |
243 segments->push_back(); | 245 segments->push_back(); |
244 segments->back().fType = Segment::kQuad; | 246 segments->back().fType = Segment::kQuad; |
245 segments->back().fPts[0] = pts[1]; | 247 segments->back().fPts[0] = pts[1]; |
246 segments->back().fPts[1] = pts[2]; | 248 segments->back().fPts[1] = pts[2]; |
247 } | 249 } |
248 } | 250 } |
249 | 251 |
250 static inline void add_cubic_segments(const SkPoint pts[4], | 252 static inline void add_cubic_segments(const SkPoint pts[4], |
251 SkPath::Direction dir, | 253 SkPathPriv::FirstDirection dir, |
252 SegmentArray* segments) { | 254 SegmentArray* segments) { |
253 SkSTArray<15, SkPoint, true> quads; | 255 SkSTArray<15, SkPoint, true> quads; |
254 GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, true, dir, &quads); | 256 GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, true, dir, &quads); |
255 int count = quads.count(); | 257 int count = quads.count(); |
256 for (int q = 0; q < count; q += 3) { | 258 for (int q = 0; q < count; q += 3) { |
257 add_quad_segment(&quads[q], segments); | 259 add_quad_segment(&quads[q], segments); |
258 } | 260 } |
259 } | 261 } |
260 | 262 |
261 static bool get_segments(const SkPath& path, | 263 static bool get_segments(const SkPath& path, |
262 const SkMatrix& m, | 264 const SkMatrix& m, |
263 SegmentArray* segments, | 265 SegmentArray* segments, |
264 SkPoint* fanPt, | 266 SkPoint* fanPt, |
265 int* vCount, | 267 int* vCount, |
266 int* iCount) { | 268 int* iCount) { |
267 SkPath::Iter iter(path, true); | 269 SkPath::Iter iter(path, true); |
268 // This renderer over-emphasizes very thin path regions. We use the distance | 270 // This renderer over-emphasizes very thin path regions. We use the distance |
269 // to the path from the sample to compute coverage. Every pixel intersected | 271 // to the path from the sample to compute coverage. Every pixel intersected |
270 // by the path will be hit and the maximum distance is sqrt(2)/2. We don't | 272 // by the path will be hit and the maximum distance is sqrt(2)/2. We don't |
271 // notice that the sample may be close to a very thin area of the path and | 273 // notice that the sample may be close to a very thin area of the path and |
272 // thus should be very light. This is particularly egregious for degenerate | 274 // thus should be very light. This is particularly egregious for degenerate |
273 // line paths. We detect paths that are very close to a line (zero area) and | 275 // line paths. We detect paths that are very close to a line (zero area) and |
274 // draw nothing. | 276 // draw nothing. |
275 DegenerateTestData degenerateData; | 277 DegenerateTestData degenerateData; |
276 SkPath::Direction dir; | 278 SkPathPriv::FirstDirection dir; |
277 // get_direction can fail for some degenerate paths. | 279 // get_direction can fail for some degenerate paths. |
278 if (!get_direction(path, m, &dir)) { | 280 if (!get_direction(path, m, &dir)) { |
279 return false; | 281 return false; |
280 } | 282 } |
281 | 283 |
282 for (;;) { | 284 for (;;) { |
283 SkPoint pts[4]; | 285 SkPoint pts[4]; |
284 SkPath::Verb verb = iter.next(pts); | 286 SkPath::Verb verb = iter.next(pts); |
285 switch (verb) { | 287 switch (verb) { |
286 case SkPath::kMove_Verb: | 288 case SkPath::kMove_Verb: |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 BATCH_TEST_DEFINE(AAConvexPathBatch) { | 1020 BATCH_TEST_DEFINE(AAConvexPathBatch) { |
1019 AAConvexPathBatch::Geometry geometry; | 1021 AAConvexPathBatch::Geometry geometry; |
1020 geometry.fColor = GrRandomColor(random); | 1022 geometry.fColor = GrRandomColor(random); |
1021 geometry.fViewMatrix = GrTest::TestMatrixInvertible(random); | 1023 geometry.fViewMatrix = GrTest::TestMatrixInvertible(random); |
1022 geometry.fPath = GrTest::TestPathConvex(random); | 1024 geometry.fPath = GrTest::TestPathConvex(random); |
1023 | 1025 |
1024 return AAConvexPathBatch::Create(geometry); | 1026 return AAConvexPathBatch::Create(geometry); |
1025 } | 1027 } |
1026 | 1028 |
1027 #endif | 1029 #endif |
OLD | NEW |