OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrDashingEffect.h" | 8 #include "GrDashingEffect.h" |
9 | 9 |
10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "gl/GrGLProcessor.h" | 24 #include "gl/GrGLProcessor.h" |
25 #include "gl/GrGLSL.h" | 25 #include "gl/GrGLSL.h" |
26 #include "gl/builders/GrGLProgramBuilder.h" | 26 #include "gl/builders/GrGLProgramBuilder.h" |
27 | 27 |
28 /////////////////////////////////////////////////////////////////////////////// | 28 /////////////////////////////////////////////////////////////////////////////// |
29 | 29 |
30 // Returns whether or not the gpu can fast path the dash line effect. | 30 // Returns whether or not the gpu can fast path the dash line effect. |
31 static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeI
nfo, | 31 static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeI
nfo, |
32 const GrDrawTarget& target, const GrPipelineBuild
er& pipelineBuilder, | 32 const GrDrawTarget& target, const GrPipelineBuild
er& pipelineBuilder, |
33 const SkMatrix& viewMatrix) { | 33 const SkMatrix& viewMatrix) { |
34 if (pipelineBuilder.getRenderTarget()->isMultisampled()) { | |
35 return false; | |
36 } | |
37 | |
38 // Pts must be either horizontal or vertical in src space | 34 // Pts must be either horizontal or vertical in src space |
39 if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { | 35 if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { |
40 return false; | 36 return false; |
41 } | 37 } |
42 | 38 |
43 // May be able to relax this to include skew. As of now cannot do perspectiv
e | 39 // May be able to relax this to include skew. As of now cannot do perspectiv
e |
44 // because of the non uniform scaling of bloating a rect | 40 // because of the non uniform scaling of bloating a rect |
45 if (!viewMatrix.preservesRightAngles()) { | 41 if (!viewMatrix.preservesRightAngles()) { |
46 return false; | 42 return false; |
47 } | 43 } |
(...skipping 23 matching lines...) Expand all Loading... |
71 SkScalar fIntervalLength; | 67 SkScalar fIntervalLength; |
72 SkRect fRect; | 68 SkRect fRect; |
73 }; | 69 }; |
74 struct DashCircleVertex { | 70 struct DashCircleVertex { |
75 SkPoint fPos; | 71 SkPoint fPos; |
76 SkPoint fDashPos; | 72 SkPoint fDashPos; |
77 SkScalar fIntervalLength; | 73 SkScalar fIntervalLength; |
78 SkScalar fRadius; | 74 SkScalar fRadius; |
79 SkScalar fCenterX; | 75 SkScalar fCenterX; |
80 }; | 76 }; |
| 77 |
| 78 enum DashAAMode { |
| 79 kBW_DashAAMode, |
| 80 kEdgeAA_DashAAMode, |
| 81 kMSAA_DashAAMode, |
| 82 |
| 83 kDashAAModeCount, |
| 84 }; |
81 }; | 85 }; |
82 | 86 |
83 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, | 87 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, |
84 const SkMatrix& viewMatrix, const SkPoint pts[2]) { | 88 const SkMatrix& viewMatrix, const SkPoint pts[2]) { |
85 SkVector vecSrc = pts[1] - pts[0]; | 89 SkVector vecSrc = pts[1] - pts[0]; |
86 SkScalar magSrc = vecSrc.length(); | 90 SkScalar magSrc = vecSrc.length(); |
87 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; | 91 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; |
88 vecSrc.scale(invSrc); | 92 vecSrc.scale(invSrc); |
89 | 93 |
90 SkVector vecSrcPerp; | 94 SkVector vecSrcPerp; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 154 |
151 enum DashCap { | 155 enum DashCap { |
152 kRound_DashCap, | 156 kRound_DashCap, |
153 kNonRound_DashCap, | 157 kNonRound_DashCap, |
154 }; | 158 }; |
155 | 159 |
156 static int kDashVertices = 4; | 160 static int kDashVertices = 4; |
157 | 161 |
158 template <typename T> | 162 template <typename T> |
159 void setup_dashed_rect_common(const SkRect& rect, const SkMatrix& matrix, T* ver
tices, int idx, | 163 void setup_dashed_rect_common(const SkRect& rect, const SkMatrix& matrix, T* ver
tices, int idx, |
160 SkScalar offset, SkScalar bloat, SkScalar len, SkS
calar stroke) { | 164 SkScalar offset, SkScalar bloatX, SkScalar bloatY,
SkScalar len, |
161 SkScalar startDashX = offset - bloat; | 165 SkScalar stroke) { |
162 SkScalar endDashX = offset + len + bloat; | 166 SkScalar startDashX = offset - bloatX; |
163 SkScalar startDashY = -stroke - bloat; | 167 SkScalar endDashX = offset + len + bloatX; |
164 SkScalar endDashY = stroke + bloat; | 168 SkScalar startDashY = -stroke - bloatY; |
| 169 SkScalar endDashY = stroke + bloatY; |
165 vertices[idx].fDashPos = SkPoint::Make(startDashX , startDashY); | 170 vertices[idx].fDashPos = SkPoint::Make(startDashX , startDashY); |
166 vertices[idx + 1].fDashPos = SkPoint::Make(startDashX, endDashY); | 171 vertices[idx + 1].fDashPos = SkPoint::Make(startDashX, endDashY); |
167 vertices[idx + 2].fDashPos = SkPoint::Make(endDashX, endDashY); | 172 vertices[idx + 2].fDashPos = SkPoint::Make(endDashX, endDashY); |
168 vertices[idx + 3].fDashPos = SkPoint::Make(endDashX, startDashY); | 173 vertices[idx + 3].fDashPos = SkPoint::Make(endDashX, startDashY); |
169 | 174 |
170 vertices[idx].fPos = SkPoint::Make(rect.fLeft, rect.fTop); | 175 vertices[idx].fPos = SkPoint::Make(rect.fLeft, rect.fTop); |
171 vertices[idx + 1].fPos = SkPoint::Make(rect.fLeft, rect.fBottom); | 176 vertices[idx + 1].fPos = SkPoint::Make(rect.fLeft, rect.fBottom); |
172 vertices[idx + 2].fPos = SkPoint::Make(rect.fRight, rect.fBottom); | 177 vertices[idx + 2].fPos = SkPoint::Make(rect.fRight, rect.fBottom); |
173 vertices[idx + 3].fPos = SkPoint::Make(rect.fRight, rect.fTop); | 178 vertices[idx + 3].fPos = SkPoint::Make(rect.fRight, rect.fTop); |
174 | 179 |
175 matrix.mapPointsWithStride(&vertices[idx].fPos, sizeof(T), 4); | 180 matrix.mapPointsWithStride(&vertices[idx].fPos, sizeof(T), 4); |
176 } | 181 } |
177 | 182 |
178 static void setup_dashed_rect(const SkRect& rect, void* vertices, int idx, | 183 static void setup_dashed_rect(const SkRect& rect, void* vertices, int idx, |
179 const SkMatrix& matrix, SkScalar offset, SkScalar
bloat, | 184 const SkMatrix& matrix, SkScalar offset, SkScalar
bloatX, |
180 SkScalar len, SkScalar stroke, SkScalar startInter
val, | 185 SkScalar bloatY, SkScalar len, SkScalar stroke, |
181 SkScalar endInterval, SkScalar strokeWidth, DashCa
p cap, | 186 SkScalar startInterval, SkScalar endInterval, SkSc
alar strokeWidth, |
182 const size_t vertexStride) { | 187 DashCap cap, const size_t vertexStride) { |
183 SkScalar intervalLength = startInterval + endInterval; | 188 SkScalar intervalLength = startInterval + endInterval; |
184 | 189 |
185 if (kRound_DashCap == cap) { | 190 if (kRound_DashCap == cap) { |
186 SkASSERT(vertexStride == sizeof(DashCircleVertex)); | 191 SkASSERT(vertexStride == sizeof(DashCircleVertex)); |
187 DashCircleVertex* verts = reinterpret_cast<DashCircleVertex*>(vertices); | 192 DashCircleVertex* verts = reinterpret_cast<DashCircleVertex*>(vertices); |
188 | 193 |
189 setup_dashed_rect_common<DashCircleVertex>(rect, matrix, verts, idx, off
set, bloat, len, | 194 setup_dashed_rect_common<DashCircleVertex>(rect, matrix, verts, idx, off
set, bloatX, |
190 stroke); | 195 bloatY, len, stroke); |
191 | 196 |
192 SkScalar radius = SkScalarHalf(strokeWidth) - 0.5f; | 197 SkScalar radius = SkScalarHalf(strokeWidth) - 0.5f; |
193 SkScalar centerX = SkScalarHalf(endInterval); | 198 SkScalar centerX = SkScalarHalf(endInterval); |
194 | 199 |
195 for (int i = 0; i < kDashVertices; i++) { | 200 for (int i = 0; i < kDashVertices; i++) { |
196 verts[idx + i].fIntervalLength = intervalLength; | 201 verts[idx + i].fIntervalLength = intervalLength; |
197 verts[idx + i].fRadius = radius; | 202 verts[idx + i].fRadius = radius; |
198 verts[idx + i].fCenterX = centerX; | 203 verts[idx + i].fCenterX = centerX; |
199 } | 204 } |
200 | 205 |
201 } else { | 206 } else { |
202 SkASSERT(kNonRound_DashCap == cap && vertexStride == sizeof(DashLineVert
ex)); | 207 SkASSERT(kNonRound_DashCap == cap && vertexStride == sizeof(DashLineVert
ex)); |
203 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(vertices); | 208 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(vertices); |
204 | 209 |
205 setup_dashed_rect_common<DashLineVertex>(rect, matrix, verts, idx, offse
t, bloat, len, | 210 setup_dashed_rect_common<DashLineVertex>(rect, matrix, verts, idx, offse
t, bloatX, |
206 stroke); | 211 bloatY, len, stroke); |
207 | 212 |
208 SkScalar halfOffLen = SkScalarHalf(endInterval); | 213 SkScalar halfOffLen = SkScalarHalf(endInterval); |
209 SkScalar halfStroke = SkScalarHalf(strokeWidth); | 214 SkScalar halfStroke = SkScalarHalf(strokeWidth); |
210 SkRect rectParam; | 215 SkRect rectParam; |
211 rectParam.set(halfOffLen + 0.5f, -halfStroke + 0.5f, | 216 rectParam.set(halfOffLen + 0.5f, -halfStroke + 0.5f, |
212 halfOffLen + startInterval - 0.5f, halfStroke - 0.5f); | 217 halfOffLen + startInterval - 0.5f, halfStroke - 0.5f); |
213 for (int i = 0; i < kDashVertices; i++) { | 218 for (int i = 0; i < kDashVertices; i++) { |
214 verts[idx + i].fIntervalLength = intervalLength; | 219 verts[idx + i].fIntervalLength = intervalLength; |
215 verts[idx + i].fRect = rectParam; | 220 verts[idx + i].fRect = rectParam; |
216 } | 221 } |
(...skipping 10 matching lines...) Expand all Loading... |
227 } | 232 } |
228 | 233 |
229 | 234 |
230 /** | 235 /** |
231 * An GrGeometryProcessor that renders a dashed line. | 236 * An GrGeometryProcessor that renders a dashed line. |
232 * This GrGeometryProcessor is meant for dashed lines that only have a single on
/off interval pair. | 237 * This GrGeometryProcessor is meant for dashed lines that only have a single on
/off interval pair. |
233 * Bounding geometry is rendered and the effect computes coverage based on the f
ragment's | 238 * Bounding geometry is rendered and the effect computes coverage based on the f
ragment's |
234 * position relative to the dashed line. | 239 * position relative to the dashed line. |
235 */ | 240 */ |
236 static GrGeometryProcessor* create_dash_gp(GrColor, | 241 static GrGeometryProcessor* create_dash_gp(GrColor, |
237 GrPrimitiveEdgeType edgeType, | 242 DashAAMode aaMode, |
238 DashCap cap, | 243 DashCap cap, |
239 const SkMatrix& localMatrix); | 244 const SkMatrix& localMatrix); |
240 | 245 |
241 class DashBatch : public GrBatch { | 246 class DashBatch : public GrBatch { |
242 public: | 247 public: |
243 struct Geometry { | 248 struct Geometry { |
244 GrColor fColor; | 249 GrColor fColor; |
245 SkMatrix fViewMatrix; | 250 SkMatrix fViewMatrix; |
246 SkMatrix fSrcRotInv; | 251 SkMatrix fSrcRotInv; |
247 SkPoint fPtsRot[2]; | 252 SkPoint fPtsRot[2]; |
248 SkScalar fSrcStrokeWidth; | 253 SkScalar fSrcStrokeWidth; |
249 SkScalar fPhase; | 254 SkScalar fPhase; |
250 SkScalar fIntervals[2]; | 255 SkScalar fIntervals[2]; |
251 SkScalar fParallelScale; | 256 SkScalar fParallelScale; |
252 SkScalar fPerpendicularScale; | 257 SkScalar fPerpendicularScale; |
253 SkDEBUGCODE(SkRect fDevBounds;) | 258 SkDEBUGCODE(SkRect fDevBounds;) |
254 }; | 259 }; |
255 | 260 |
256 static GrBatch* Create(const Geometry& geometry, SkPaint::Cap cap, bool useA
A, bool fullDash) { | 261 static GrBatch* Create(const Geometry& geometry, SkPaint::Cap cap, DashAAMod
e aaMode, bool fullDash) { |
257 return SkNEW_ARGS(DashBatch, (geometry, cap, useAA, fullDash)); | 262 return SkNEW_ARGS(DashBatch, (geometry, cap, aaMode, fullDash)); |
258 } | 263 } |
259 | 264 |
260 const char* name() const override { return "DashBatch"; } | 265 const char* name() const override { return "DashBatch"; } |
261 | 266 |
262 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 267 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
263 // When this is called on a batch, there is only one geometry bundle | 268 // When this is called on a batch, there is only one geometry bundle |
264 out->setKnownFourComponents(fGeoData[0].fColor); | 269 out->setKnownFourComponents(fGeoData[0].fColor); |
265 } | 270 } |
266 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 271 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
267 out->setUnknownSingleComponent(); | 272 out->setUnknownSingleComponent(); |
(...skipping 12 matching lines...) Expand all Loading... |
280 fBatch.fColor = fGeoData[0].fColor; | 285 fBatch.fColor = fGeoData[0].fColor; |
281 fBatch.fUsesLocalCoords = init.fUsesLocalCoords; | 286 fBatch.fUsesLocalCoords = init.fUsesLocalCoords; |
282 fBatch.fCoverageIgnored = init.fCoverageIgnored; | 287 fBatch.fCoverageIgnored = init.fCoverageIgnored; |
283 } | 288 } |
284 | 289 |
285 struct DashDraw { | 290 struct DashDraw { |
286 SkScalar fStartOffset; | 291 SkScalar fStartOffset; |
287 SkScalar fStrokeWidth; | 292 SkScalar fStrokeWidth; |
288 SkScalar fLineLength; | 293 SkScalar fLineLength; |
289 SkScalar fHalfDevStroke; | 294 SkScalar fHalfDevStroke; |
290 SkScalar fDevBloat; | 295 SkScalar fDevBloatX; |
| 296 SkScalar fDevBloatY; |
291 bool fLineDone; | 297 bool fLineDone; |
292 bool fHasStartRect; | 298 bool fHasStartRect; |
293 bool fHasEndRect; | 299 bool fHasEndRect; |
294 }; | 300 }; |
295 | 301 |
296 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline
) override { | 302 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline
) override { |
297 int instanceCount = fGeoData.count(); | 303 int instanceCount = fGeoData.count(); |
298 | 304 |
299 SkMatrix invert; | 305 SkMatrix invert; |
300 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { | 306 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { |
301 SkDebugf("Failed to invert\n"); | 307 SkDebugf("Failed to invert\n"); |
302 return; | 308 return; |
303 } | 309 } |
304 | 310 |
305 SkPaint::Cap cap = this->cap(); | 311 SkPaint::Cap cap = this->cap(); |
306 | 312 |
307 SkAutoTUnref<const GrGeometryProcessor> gp; | 313 SkAutoTUnref<const GrGeometryProcessor> gp; |
308 | 314 |
309 bool isRoundCap = SkPaint::kRound_Cap == cap; | 315 bool isRoundCap = SkPaint::kRound_Cap == cap; |
310 DashCap capType = isRoundCap ? kRound_DashCap : kNonRound_DashCap; | 316 DashCap capType = isRoundCap ? kRound_DashCap : kNonRound_DashCap; |
311 if (this->fullDash()) { | 317 if (this->fullDash()) { |
312 GrPrimitiveEdgeType edgeType = this->useAA() ? kFillAA_GrProcessorEd
geType : | 318 gp.reset(create_dash_gp(this->color(), this->aaMode(), capType, inve
rt)); |
313 kFillBW_GrProcessorEd
geType; | |
314 gp.reset(create_dash_gp(this->color(), edgeType, capType, invert)); | |
315 } else { | 319 } else { |
316 // Set up the vertex data for the line and start/end dashes | 320 // Set up the vertex data for the line and start/end dashes |
317 gp.reset(GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kP
osition_GPType, | 321 gp.reset(GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kP
osition_GPType, |
318 this->color(), | 322 this->color(), |
319 SkMatrix::I(), | 323 SkMatrix::I(), |
320 invert)); | 324 invert)); |
321 } | 325 } |
322 | 326 |
323 batchTarget->initDraw(gp, pipeline); | 327 batchTarget->initDraw(gp, pipeline); |
324 | 328 |
325 // TODO remove this when batch is everywhere | 329 // TODO remove this when batch is everywhere |
326 GrPipelineInfo init; | 330 GrPipelineInfo init; |
327 init.fColorIgnored = fBatch.fColorIgnored; | 331 init.fColorIgnored = fBatch.fColorIgnored; |
328 init.fOverrideColor = GrColor_ILLEGAL; | 332 init.fOverrideColor = GrColor_ILLEGAL; |
329 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 333 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
330 init.fUsesLocalCoords = this->usesLocalCoords(); | 334 init.fUsesLocalCoords = this->usesLocalCoords(); |
331 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 335 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
332 | 336 |
333 bool useAA = this->useAA(); | 337 // useAA here means Edge AA or MSAA |
| 338 bool useAA = this->aaMode() != kBW_DashAAMode; |
334 bool fullDash = this->fullDash(); | 339 bool fullDash = this->fullDash(); |
335 | 340 |
336 // We do two passes over all of the dashes. First we setup the start, e
nd, and bounds, | 341 // We do two passes over all of the dashes. First we setup the start, e
nd, and bounds, |
337 // rectangles. We preserve all of this work in the rects / draws arrays
below. Then we | 342 // rectangles. We preserve all of this work in the rects / draws arrays
below. Then we |
338 // iterate again over these decomposed dashes to generate vertices | 343 // iterate again over these decomposed dashes to generate vertices |
339 SkSTArray<128, SkRect, true> rects; | 344 SkSTArray<128, SkRect, true> rects; |
340 SkSTArray<128, DashDraw, true> draws; | 345 SkSTArray<128, DashDraw, true> draws; |
341 | 346 |
342 int totalRectCount = 0; | 347 int totalRectCount = 0; |
343 int rectOffset = 0; | 348 int rectOffset = 0; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 args.fPhase = 0; | 442 args.fPhase = 0; |
438 } | 443 } |
439 | 444 |
440 // Change the dashing info from src space into device space | 445 // Change the dashing info from src space into device space |
441 SkScalar* devIntervals = args.fIntervals; | 446 SkScalar* devIntervals = args.fIntervals; |
442 devIntervals[0] = args.fIntervals[0] * args.fParallelScale; | 447 devIntervals[0] = args.fIntervals[0] * args.fParallelScale; |
443 devIntervals[1] = args.fIntervals[1] * args.fParallelScale; | 448 devIntervals[1] = args.fIntervals[1] * args.fParallelScale; |
444 SkScalar devPhase = args.fPhase * args.fParallelScale; | 449 SkScalar devPhase = args.fPhase * args.fParallelScale; |
445 SkScalar strokeWidth = args.fSrcStrokeWidth * args.fPerpendicularSca
le; | 450 SkScalar strokeWidth = args.fSrcStrokeWidth * args.fPerpendicularSca
le; |
446 | 451 |
447 if ((strokeWidth < 1.f && !useAA) || 0.f == strokeWidth) { | 452 if ((strokeWidth < 1.f && useAA) || 0.f == strokeWidth) { |
448 strokeWidth = 1.f; | 453 strokeWidth = 1.f; |
449 } | 454 } |
450 | 455 |
451 SkScalar halfDevStroke = strokeWidth * 0.5f; | 456 SkScalar halfDevStroke = strokeWidth * 0.5f; |
452 | 457 |
453 if (SkPaint::kSquare_Cap == cap && 0 != args.fSrcStrokeWidth) { | 458 if (SkPaint::kSquare_Cap == cap && 0 != args.fSrcStrokeWidth) { |
454 // add cap to on interval and remove from off interval | 459 // add cap to on interval and remove from off interval |
455 devIntervals[0] += strokeWidth; | 460 devIntervals[0] += strokeWidth; |
456 devIntervals[1] -= strokeWidth; | 461 devIntervals[1] -= strokeWidth; |
457 } | 462 } |
458 SkScalar startOffset = devIntervals[1] * 0.5f + devPhase; | 463 SkScalar startOffset = devIntervals[1] * 0.5f + devPhase; |
459 | 464 |
460 SkScalar bloatX = useAA ? 0.5f / args.fParallelScale : 0.f; | 465 // For EdgeAA, we bloat in X & Y for both square and round caps. |
461 SkScalar bloatY = useAA ? 0.5f / args.fPerpendicularScale : 0.f; | 466 // For MSAA, we don't bloat at all for square caps, and bloat in Y o
nly for round caps. |
| 467 SkScalar devBloatX = this->aaMode() == kEdgeAA_DashAAMode ? 0.5f : 0
.0f; |
| 468 SkScalar devBloatY = (SkPaint::kRound_Cap == cap && this->aaMode() =
= kMSAA_DashAAMode) |
| 469 ? 0.5f : devBloatX; |
462 | 470 |
463 SkScalar devBloat = useAA ? 0.5f : 0.f; | 471 SkScalar bloatX = devBloatX / args.fParallelScale; |
| 472 SkScalar bloatY = devBloatY / args.fPerpendicularScale; |
464 | 473 |
465 if (devIntervals[1] <= 0.f && useAA) { | 474 if (devIntervals[1] <= 0.f && useAA) { |
466 // Case when we end up drawing a solid AA rect | 475 // Case when we end up drawing a solid AA rect |
467 // Reset the start rect to draw this single solid rect | 476 // Reset the start rect to draw this single solid rect |
468 // but it requires to upload a new intervals uniform so we can m
imic | 477 // but it requires to upload a new intervals uniform so we can m
imic |
469 // one giant dash | 478 // one giant dash |
470 args.fPtsRot[0].fX -= hasStartRect ? startAdj : 0; | 479 args.fPtsRot[0].fX -= hasStartRect ? startAdj : 0; |
471 args.fPtsRot[1].fX += hasEndRect ? endAdj : 0; | 480 args.fPtsRot[1].fX += hasEndRect ? endAdj : 0; |
472 startRect.set(args.fPtsRot, 2); | 481 startRect.set(args.fPtsRot, 2); |
473 startRect.outset(strokeAdj, halfSrcStroke); | 482 startRect.outset(strokeAdj, halfSrcStroke); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 SkASSERT(useAA); // so that we know bloatX and bloatY have been
set | 521 SkASSERT(useAA); // so that we know bloatX and bloatY have been
set |
513 startRect.outset(bloatX, bloatY); | 522 startRect.outset(bloatX, bloatY); |
514 } | 523 } |
515 | 524 |
516 if (hasEndRect) { | 525 if (hasEndRect) { |
517 SkASSERT(useAA); // so that we know bloatX and bloatY have been
set | 526 SkASSERT(useAA); // so that we know bloatX and bloatY have been
set |
518 endRect.outset(bloatX, bloatY); | 527 endRect.outset(bloatX, bloatY); |
519 } | 528 } |
520 | 529 |
521 draw.fStartOffset = startOffset; | 530 draw.fStartOffset = startOffset; |
522 draw.fDevBloat = devBloat; | 531 draw.fDevBloatX = devBloatX; |
| 532 draw.fDevBloatY = devBloatY; |
523 draw.fHalfDevStroke = halfDevStroke; | 533 draw.fHalfDevStroke = halfDevStroke; |
524 draw.fStrokeWidth = strokeWidth; | 534 draw.fStrokeWidth = strokeWidth; |
525 draw.fHasStartRect = hasStartRect; | 535 draw.fHasStartRect = hasStartRect; |
526 draw.fLineDone = lineDone; | 536 draw.fLineDone = lineDone; |
527 draw.fHasEndRect = hasEndRect; | 537 draw.fHasEndRect = hasEndRect; |
528 } | 538 } |
529 | 539 |
530 const GrVertexBuffer* vertexBuffer; | 540 const GrVertexBuffer* vertexBuffer; |
531 int firstVertex; | 541 int firstVertex; |
532 | 542 |
533 size_t vertexStride = gp->getVertexStride(); | 543 size_t vertexStride = gp->getVertexStride(); |
534 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | 544 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
535 totalRectCount * k
VertsPerDash, | 545 totalRectCount * k
VertsPerDash, |
536 &vertexBuffer, | 546 &vertexBuffer, |
537 &firstVertex); | 547 &firstVertex); |
538 | 548 |
539 if (!vertices || !batchTarget->quadIndexBuffer()) { | 549 if (!vertices || !batchTarget->quadIndexBuffer()) { |
540 SkDebugf("Could not allocate buffers\n"); | 550 SkDebugf("Could not allocate buffers\n"); |
541 return; | 551 return; |
542 } | 552 } |
543 | 553 |
544 int curVIdx = 0; | 554 int curVIdx = 0; |
545 int rectIndex = 0; | 555 int rectIndex = 0; |
546 for (int i = 0; i < instanceCount; i++) { | 556 for (int i = 0; i < instanceCount; i++) { |
547 Geometry& args = fGeoData[i]; | 557 Geometry& args = fGeoData[i]; |
548 | 558 |
549 if (!draws[i].fLineDone) { | 559 if (!draws[i].fLineDone) { |
550 if (fullDash) { | 560 if (fullDash) { |
551 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.
fSrcRotInv, | 561 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.
fSrcRotInv, |
552 draws[i].fStartOffset, draws[i].fDevBloat, | 562 draws[i].fStartOffset, draws[i].fDevBloatX
, |
553 draws[i].fLineLength, draws[i].fHalfDevStr
oke, | 563 draws[i].fDevBloatY, draws[i].fLineLength, |
554 args.fIntervals[0], args.fIntervals[1], dr
aws[i].fStrokeWidth, | 564 draws[i].fHalfDevStroke, args.fIntervals[0
], |
| 565 args.fIntervals[1], draws[i].fStrokeWidth, |
555 capType, gp->getVertexStride()); | 566 capType, gp->getVertexStride()); |
556 } else { | 567 } else { |
557 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); | 568 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); |
558 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); | 569 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); |
559 setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRo
tInv, verts); | 570 setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRo
tInv, verts); |
560 } | 571 } |
561 curVIdx += 4; | 572 curVIdx += 4; |
562 } | 573 } |
563 rectIndex++; | 574 rectIndex++; |
564 | 575 |
565 if (draws[i].fHasStartRect) { | 576 if (draws[i].fHasStartRect) { |
566 if (fullDash) { | 577 if (fullDash) { |
567 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.
fSrcRotInv, | 578 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.
fSrcRotInv, |
568 draws[i].fStartOffset, draws[i].fDevBloat,
args.fIntervals[0], | 579 draws[i].fStartOffset, draws[i].fDevBloatX
, |
| 580 draws[i].fDevBloatY, args.fIntervals[0], |
569 draws[i].fHalfDevStroke, args.fIntervals[0
], | 581 draws[i].fHalfDevStroke, args.fIntervals[0
], |
570 args.fIntervals[1], draws[i].fStrokeWidth,
capType, | 582 args.fIntervals[1], draws[i].fStrokeWidth,
capType, |
571 gp->getVertexStride()); | 583 gp->getVertexStride()); |
572 } else { | 584 } else { |
573 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); | 585 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); |
574 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); | 586 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); |
575 setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRo
tInv, verts); | 587 setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRo
tInv, verts); |
576 } | 588 } |
577 | 589 |
578 curVIdx += 4; | 590 curVIdx += 4; |
579 } | 591 } |
580 rectIndex++; | 592 rectIndex++; |
581 | 593 |
582 if (draws[i].fHasEndRect) { | 594 if (draws[i].fHasEndRect) { |
583 if (fullDash) { | 595 if (fullDash) { |
584 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.
fSrcRotInv, | 596 setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.
fSrcRotInv, |
585 draws[i].fStartOffset, draws[i].fDevBloat,
args.fIntervals[0], | 597 draws[i].fStartOffset, draws[i].fDevBloatX
, |
| 598 draws[i].fDevBloatY, args.fIntervals[0], |
586 draws[i].fHalfDevStroke, args.fIntervals[0
], | 599 draws[i].fHalfDevStroke, args.fIntervals[0
], |
587 args.fIntervals[1], draws[i].fStrokeWidth,
capType, | 600 args.fIntervals[1], draws[i].fStrokeWidth,
capType, |
588 gp->getVertexStride()); | 601 gp->getVertexStride()); |
589 } else { | 602 } else { |
590 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); | 603 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); |
591 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); | 604 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); |
592 setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRo
tInv, verts); | 605 setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRo
tInv, verts); |
593 } | 606 } |
594 curVIdx += 4; | 607 curVIdx += 4; |
595 } | 608 } |
(...skipping 21 matching lines...) Expand all Loading... |
617 batchTarget->draw(drawInfo); | 630 batchTarget->draw(drawInfo); |
618 | 631 |
619 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | 632 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
620 totalRectCount -= drawInfo.instanceCount(); | 633 totalRectCount -= drawInfo.instanceCount(); |
621 } | 634 } |
622 } | 635 } |
623 | 636 |
624 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 637 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
625 | 638 |
626 private: | 639 private: |
627 DashBatch(const Geometry& geometry, SkPaint::Cap cap, bool useAA, bool fullD
ash) { | 640 DashBatch(const Geometry& geometry, SkPaint::Cap cap, DashAAMode aaMode, boo
l fullDash) { |
628 this->initClassID<DashBatch>(); | 641 this->initClassID<DashBatch>(); |
629 fGeoData.push_back(geometry); | 642 fGeoData.push_back(geometry); |
630 | 643 |
631 fBatch.fUseAA = useAA; | 644 fBatch.fAAMode = aaMode; |
632 fBatch.fCap = cap; | 645 fBatch.fCap = cap; |
633 fBatch.fFullDash = fullDash; | 646 fBatch.fFullDash = fullDash; |
634 } | 647 } |
635 | 648 |
636 bool onCombineIfPossible(GrBatch* t) override { | 649 bool onCombineIfPossible(GrBatch* t) override { |
637 DashBatch* that = t->cast<DashBatch>(); | 650 DashBatch* that = t->cast<DashBatch>(); |
638 | 651 |
639 if (this->useAA() != that->useAA()) { | 652 if (this->aaMode() != that->aaMode()) { |
640 return false; | 653 return false; |
641 } | 654 } |
642 | 655 |
643 if (this->fullDash() != that->fullDash()) { | 656 if (this->fullDash() != that->fullDash()) { |
644 return false; | 657 return false; |
645 } | 658 } |
646 | 659 |
647 if (this->cap() != that->cap()) { | 660 if (this->cap() != that->cap()) { |
648 return false; | 661 return false; |
649 } | 662 } |
650 | 663 |
651 // TODO vertex color | 664 // TODO vertex color |
652 if (this->color() != that->color()) { | 665 if (this->color() != that->color()) { |
653 return false; | 666 return false; |
654 } | 667 } |
655 | 668 |
656 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | 669 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); |
657 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { | 670 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { |
658 return false; | 671 return false; |
659 } | 672 } |
660 | 673 |
661 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | 674 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; |
662 return true; | 675 return true; |
663 } | 676 } |
664 | 677 |
665 GrColor color() const { return fBatch.fColor; } | 678 GrColor color() const { return fBatch.fColor; } |
666 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 679 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
667 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | 680 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
668 bool useAA() const { return fBatch.fUseAA; } | 681 DashAAMode aaMode() const { return fBatch.fAAMode; } |
669 bool fullDash() const { return fBatch.fFullDash; } | 682 bool fullDash() const { return fBatch.fFullDash; } |
670 SkPaint::Cap cap() const { return fBatch.fCap; } | 683 SkPaint::Cap cap() const { return fBatch.fCap; } |
671 | 684 |
672 struct BatchTracker { | 685 struct BatchTracker { |
673 GrColor fColor; | 686 GrColor fColor; |
674 bool fUsesLocalCoords; | 687 bool fUsesLocalCoords; |
675 bool fColorIgnored; | 688 bool fColorIgnored; |
676 bool fCoverageIgnored; | 689 bool fCoverageIgnored; |
677 SkPaint::Cap fCap; | 690 SkPaint::Cap fCap; |
678 bool fUseAA; | 691 DashAAMode fAAMode; |
679 bool fFullDash; | 692 bool fFullDash; |
680 }; | 693 }; |
681 | 694 |
682 static const int kVertsPerDash = 4; | 695 static const int kVertsPerDash = 4; |
683 static const int kIndicesPerDash = 6; | 696 static const int kIndicesPerDash = 6; |
684 | 697 |
685 BatchTracker fBatch; | 698 BatchTracker fBatch; |
686 SkSTArray<1, Geometry, true> fGeoData; | 699 SkSTArray<1, Geometry, true> fGeoData; |
687 }; | 700 }; |
688 | 701 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 geometry.fPtsRot); | 736 geometry.fPtsRot); |
724 | 737 |
725 SkScalar offInterval = info.fIntervals[1] * geometry.fParallelScale; | 738 SkScalar offInterval = info.fIntervals[1] * geometry.fParallelScale; |
726 SkScalar strokeWidth = geometry.fSrcStrokeWidth * geometry.fPerpendicularSca
le; | 739 SkScalar strokeWidth = geometry.fSrcStrokeWidth * geometry.fPerpendicularSca
le; |
727 | 740 |
728 if (SkPaint::kSquare_Cap == cap && 0 != geometry.fSrcStrokeWidth) { | 741 if (SkPaint::kSquare_Cap == cap && 0 != geometry.fSrcStrokeWidth) { |
729 // add cap to on interveal and remove from off interval | 742 // add cap to on interveal and remove from off interval |
730 offInterval -= strokeWidth; | 743 offInterval -= strokeWidth; |
731 } | 744 } |
732 | 745 |
733 bool useAA = paint.isAntiAlias(); | 746 DashAAMode aaMode = pipelineBuilder->getRenderTarget()->isMultisampled() ? k
MSAA_DashAAMode : |
| 747 paint.isAntiAlias() ? kEdgeAA_DashAAMode : |
| 748 kBW_DashAAMode; |
| 749 |
734 // TODO we can do a real rect call if not using fulldash(ie no off interval,
not using AA) | 750 // TODO we can do a real rect call if not using fulldash(ie no off interval,
not using AA) |
735 bool fullDash = offInterval > 0.f || useAA; | 751 bool fullDash = offInterval > 0.f || aaMode != kBW_DashAAMode; |
736 | 752 |
737 geometry.fColor = color; | 753 geometry.fColor = color; |
738 geometry.fViewMatrix = viewMatrix; | 754 geometry.fViewMatrix = viewMatrix; |
739 geometry.fPhase = info.fPhase; | 755 geometry.fPhase = info.fPhase; |
740 geometry.fIntervals[0] = info.fIntervals[0]; | 756 geometry.fIntervals[0] = info.fIntervals[0]; |
741 geometry.fIntervals[1] = info.fIntervals[1]; | 757 geometry.fIntervals[1] = info.fIntervals[1]; |
742 | 758 |
743 SkAutoTUnref<GrBatch> batch(DashBatch::Create(geometry, cap, useAA, fullDash
)); | 759 SkAutoTUnref<GrBatch> batch(DashBatch::Create(geometry, cap, aaMode, fullDas
h)); |
744 target->drawBatch(pipelineBuilder, batch); | 760 target->drawBatch(pipelineBuilder, batch); |
745 | 761 |
746 return true; | 762 return true; |
747 } | 763 } |
748 | 764 |
749 ////////////////////////////////////////////////////////////////////////////// | 765 ////////////////////////////////////////////////////////////////////////////// |
750 | 766 |
751 class GLDashingCircleEffect; | 767 class GLDashingCircleEffect; |
752 | 768 |
753 struct DashingCircleBatchTracker { | 769 struct DashingCircleBatchTracker { |
754 GrGPInput fInputColorType; | 770 GrGPInput fInputColorType; |
755 GrColor fColor; | 771 GrColor fColor; |
756 bool fUsesLocalCoords; | 772 bool fUsesLocalCoords; |
757 }; | 773 }; |
758 | 774 |
759 /* | 775 /* |
760 * This effect will draw a dotted line (defined as a dashed lined with round cap
s and no on | 776 * This effect will draw a dotted line (defined as a dashed lined with round cap
s and no on |
761 * interval). The radius of the dots is given by the strokeWidth and the spacing
by the DashInfo. | 777 * interval). The radius of the dots is given by the strokeWidth and the spacing
by the DashInfo. |
762 * Both of the previous two parameters are in device space. This effect also req
uires the setting of | 778 * Both of the previous two parameters are in device space. This effect also req
uires the setting of |
763 * a vec2 vertex attribute for the the four corners of the bounding rect. This a
ttribute is the | 779 * a vec2 vertex attribute for the the four corners of the bounding rect. This a
ttribute is the |
764 * "dash position" of each vertex. In other words it is the vertex coords (in de
vice space) if we | 780 * "dash position" of each vertex. In other words it is the vertex coords (in de
vice space) if we |
765 * transform the line to be horizontal, with the start of line at the origin the
n shifted to the | 781 * transform the line to be horizontal, with the start of line at the origin the
n shifted to the |
766 * right by half the off interval. The line then goes in the positive x directio
n. | 782 * right by half the off interval. The line then goes in the positive x directio
n. |
767 */ | 783 */ |
768 class DashingCircleEffect : public GrGeometryProcessor { | 784 class DashingCircleEffect : public GrGeometryProcessor { |
769 public: | 785 public: |
770 typedef SkPathEffect::DashInfo DashInfo; | 786 typedef SkPathEffect::DashInfo DashInfo; |
771 | 787 |
772 static GrGeometryProcessor* Create(GrColor, | 788 static GrGeometryProcessor* Create(GrColor, |
773 GrPrimitiveEdgeType edgeType, | 789 DashAAMode aaMode, |
774 const SkMatrix& localMatrix); | 790 const SkMatrix& localMatrix); |
775 | 791 |
776 virtual ~DashingCircleEffect(); | 792 virtual ~DashingCircleEffect(); |
777 | 793 |
778 const char* name() const override { return "DashingCircleEffect"; } | 794 const char* name() const override { return "DashingCircleEffect"; } |
779 | 795 |
780 const Attribute* inPosition() const { return fInPosition; } | 796 const Attribute* inPosition() const { return fInPosition; } |
781 | 797 |
782 const Attribute* inDashParams() const { return fInDashParams; } | 798 const Attribute* inDashParams() const { return fInDashParams; } |
783 | 799 |
784 const Attribute* inCircleParams() const { return fInCircleParams; } | 800 const Attribute* inCircleParams() const { return fInCircleParams; } |
785 | 801 |
786 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } | 802 DashAAMode aaMode() const { return fAAMode; } |
787 | 803 |
788 virtual void getGLProcessorKey(const GrBatchTracker&, | 804 virtual void getGLProcessorKey(const GrBatchTracker&, |
789 const GrGLCaps&, | 805 const GrGLCaps&, |
790 GrProcessorKeyBuilder* b) const override; | 806 GrProcessorKeyBuilder* b) const override; |
791 | 807 |
792 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker&, | 808 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker&, |
793 const GrGLCaps&) const over
ride; | 809 const GrGLCaps&) const over
ride; |
794 | 810 |
795 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const
override; | 811 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const
override; |
796 | 812 |
797 bool onCanMakeEqual(const GrBatchTracker&, | 813 bool onCanMakeEqual(const GrBatchTracker&, |
798 const GrGeometryProcessor&, | 814 const GrGeometryProcessor&, |
799 const GrBatchTracker&) const override; | 815 const GrBatchTracker&) const override; |
800 | 816 |
801 private: | 817 private: |
802 DashingCircleEffect(GrColor, GrPrimitiveEdgeType edgeType, const SkMatrix& l
ocalMatrix); | 818 DashingCircleEffect(GrColor, DashAAMode aaMode, const SkMatrix& localMatrix)
; |
803 | 819 |
804 bool onIsEqual(const GrGeometryProcessor& other) const override; | 820 bool onIsEqual(const GrGeometryProcessor& other) const override; |
805 | 821 |
806 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override; | 822 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override; |
807 | 823 |
808 GrPrimitiveEdgeType fEdgeType; | 824 DashAAMode fAAMode; |
809 const Attribute* fInPosition; | 825 const Attribute* fInPosition; |
810 const Attribute* fInDashParams; | 826 const Attribute* fInDashParams; |
811 const Attribute* fInCircleParams; | 827 const Attribute* fInCircleParams; |
812 | 828 |
813 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 829 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
814 | 830 |
815 typedef GrGeometryProcessor INHERITED; | 831 typedef GrGeometryProcessor INHERITED; |
816 }; | 832 }; |
817 | 833 |
818 ////////////////////////////////////////////////////////////////////////////// | 834 ////////////////////////////////////////////////////////////////////////////// |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 873 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
858 | 874 |
859 // emit attributes | 875 // emit attributes |
860 vsBuilder->emitAttributes(dce); | 876 vsBuilder->emitAttributes(dce); |
861 | 877 |
862 // XY are dashPos, Z is dashInterval | 878 // XY are dashPos, Z is dashInterval |
863 GrGLVertToFrag dashParams(kVec3f_GrSLType); | 879 GrGLVertToFrag dashParams(kVec3f_GrSLType); |
864 args.fPB->addVarying("DashParam", &dashParams); | 880 args.fPB->addVarying("DashParam", &dashParams); |
865 vsBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->f
Name); | 881 vsBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->f
Name); |
866 | 882 |
867 // xy, refer to circle radius - 0.5, z refers to cicles center x coord | 883 // x refers to circle radius - 0.5, y refers to cicle's center x coord |
868 GrGLVertToFrag circleParams(kVec2f_GrSLType); | 884 GrGLVertToFrag circleParams(kVec2f_GrSLType); |
869 args.fPB->addVarying("CircleParams", &circleParams); | 885 args.fPB->addVarying("CircleParams", &circleParams); |
870 vsBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams(
)->fName); | 886 vsBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams(
)->fName); |
871 | 887 |
872 // Setup pass through color | 888 // Setup pass through color |
873 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU
LL, &fColorUniform); | 889 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU
LL, &fColorUniform); |
874 | 890 |
875 // Setup position | 891 // Setup position |
876 this->setupPosition(pb, gpArgs, dce.inPosition()->fName, dce.viewMatrix()); | 892 this->setupPosition(pb, gpArgs, dce.inPosition()->fName, dce.viewMatrix()); |
877 | 893 |
878 // emit transforms | 894 // emit transforms |
879 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dce.inPosition()->fName
, dce.localMatrix(), | 895 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dce.inPosition()->fName
, dce.localMatrix(), |
880 args.fTransformsIn, args.fTransformsOut); | 896 args.fTransformsIn, args.fTransformsOut); |
881 | 897 |
882 // transforms all points so that we can compare them to our test circle | 898 // transforms all points so that we can compare them to our test circle |
883 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 899 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
884 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", | 900 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", |
885 dashParams.fsIn(), dashParams.fsIn(), dashParams.fsIn
(), | 901 dashParams.fsIn(), dashParams.fsIn(), dashParams.fsIn
(), |
886 dashParams.fsIn()); | 902 dashParams.fsIn()); |
887 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", dashPa
rams.fsIn()); | 903 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", dashPa
rams.fsIn()); |
888 fsBuilder->codeAppendf("vec2 center = vec2(%s.y, 0.0);", circleParams.fsIn()
); | 904 fsBuilder->codeAppendf("vec2 center = vec2(%s.y, 0.0);", circleParams.fsIn()
); |
889 fsBuilder->codeAppend("float dist = length(center - fragPosShifted);"); | 905 fsBuilder->codeAppend("float dist = length(center - fragPosShifted);"); |
890 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { | 906 if (dce.aaMode() != kBW_DashAAMode) { |
891 fsBuilder->codeAppendf("float diff = dist - %s.x;", circleParams.fsIn())
; | 907 fsBuilder->codeAppendf("float diff = dist - %s.x;", circleParams.fsIn())
; |
892 fsBuilder->codeAppend("diff = 1.0 - diff;"); | 908 fsBuilder->codeAppend("diff = 1.0 - diff;"); |
893 fsBuilder->codeAppend("float alpha = clamp(diff, 0.0, 1.0);"); | 909 fsBuilder->codeAppend("float alpha = clamp(diff, 0.0, 1.0);"); |
894 } else { | 910 } else { |
895 fsBuilder->codeAppendf("float alpha = 1.0;"); | 911 fsBuilder->codeAppendf("float alpha = 1.0;"); |
896 fsBuilder->codeAppendf("alpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;", circl
eParams.fsIn()); | 912 fsBuilder->codeAppendf("alpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;", circl
eParams.fsIn()); |
897 } | 913 } |
898 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); | 914 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
899 } | 915 } |
900 | 916 |
(...skipping 13 matching lines...) Expand all Loading... |
914 | 930 |
915 void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp, | 931 void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp, |
916 const GrBatchTracker& bt, | 932 const GrBatchTracker& bt, |
917 const GrGLCaps&, | 933 const GrGLCaps&, |
918 GrProcessorKeyBuilder* b) { | 934 GrProcessorKeyBuilder* b) { |
919 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>(
); | 935 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>(
); |
920 const DashingCircleEffect& dce = gp.cast<DashingCircleEffect>(); | 936 const DashingCircleEffect& dce = gp.cast<DashingCircleEffect>(); |
921 uint32_t key = 0; | 937 uint32_t key = 0; |
922 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0
x0; | 938 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0
x0; |
923 key |= ComputePosKey(gp.viewMatrix()) << 1; | 939 key |= ComputePosKey(gp.viewMatrix()) << 1; |
924 key |= dce.getEdgeType() << 8; | 940 key |= dce.aaMode() << 8; |
925 b->add32(key << 16 | local.fInputColorType); | 941 b->add32(key << 16 | local.fInputColorType); |
926 } | 942 } |
927 | 943 |
928 ////////////////////////////////////////////////////////////////////////////// | 944 ////////////////////////////////////////////////////////////////////////////// |
929 | 945 |
930 GrGeometryProcessor* DashingCircleEffect::Create(GrColor color, | 946 GrGeometryProcessor* DashingCircleEffect::Create(GrColor color, |
931 GrPrimitiveEdgeType edgeType, | 947 DashAAMode aaMode, |
932 const SkMatrix& localMatrix) { | 948 const SkMatrix& localMatrix) { |
933 return SkNEW_ARGS(DashingCircleEffect, (color, edgeType, localMatrix)); | 949 return SkNEW_ARGS(DashingCircleEffect, (color, aaMode, localMatrix)); |
934 } | 950 } |
935 | 951 |
936 DashingCircleEffect::~DashingCircleEffect() {} | 952 DashingCircleEffect::~DashingCircleEffect() {} |
937 | 953 |
938 void DashingCircleEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* ou
t) const { | 954 void DashingCircleEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* ou
t) const { |
939 out->setUnknownSingleComponent(); | 955 out->setUnknownSingleComponent(); |
940 } | 956 } |
941 | 957 |
942 void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt, | 958 void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt, |
943 const GrGLCaps& caps, | 959 const GrGLCaps& caps, |
944 GrProcessorKeyBuilder* b) const { | 960 GrProcessorKeyBuilder* b) const { |
945 GLDashingCircleEffect::GenKey(*this, bt, caps, b); | 961 GLDashingCircleEffect::GenKey(*this, bt, caps, b); |
946 } | 962 } |
947 | 963 |
948 GrGLPrimitiveProcessor* DashingCircleEffect::createGLInstance(const GrBatchTrack
er& bt, | 964 GrGLPrimitiveProcessor* DashingCircleEffect::createGLInstance(const GrBatchTrack
er& bt, |
949 const GrGLCaps&) c
onst { | 965 const GrGLCaps&) c
onst { |
950 return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt)); | 966 return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt)); |
951 } | 967 } |
952 | 968 |
953 DashingCircleEffect::DashingCircleEffect(GrColor color, | 969 DashingCircleEffect::DashingCircleEffect(GrColor color, |
954 GrPrimitiveEdgeType edgeType, | 970 DashAAMode aaMode, |
955 const SkMatrix& localMatrix) | 971 const SkMatrix& localMatrix) |
956 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) { | 972 : INHERITED(color, SkMatrix::I(), localMatrix), fAAMode(aaMode) { |
957 this->initClassID<DashingCircleEffect>(); | 973 this->initClassID<DashingCircleEffect>(); |
958 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); | 974 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); |
959 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe
rtexAttribType)); | 975 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe
rtexAttribType)); |
960 fInCircleParams = &this->addVertexAttrib(Attribute("inCircleParams", | 976 fInCircleParams = &this->addVertexAttrib(Attribute("inCircleParams", |
961 kVec2f_GrVertexAttribType
)); | 977 kVec2f_GrVertexAttribType
)); |
962 } | 978 } |
963 | 979 |
964 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const { | 980 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const { |
965 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); | 981 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); |
966 return fEdgeType == dce.fEdgeType; | 982 return fAAMode == dce.fAAMode; |
967 } | 983 } |
968 | 984 |
969 void DashingCircleEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineI
nfo& init) const { | 985 void DashingCircleEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineI
nfo& init) const { |
970 DashingCircleBatchTracker* local = bt->cast<DashingCircleBatchTracker>(); | 986 DashingCircleBatchTracker* local = bt->cast<DashingCircleBatchTracker>(); |
971 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in
it, false); | 987 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in
it, false); |
972 local->fUsesLocalCoords = init.fUsesLocalCoords; | 988 local->fUsesLocalCoords = init.fUsesLocalCoords; |
973 } | 989 } |
974 | 990 |
975 bool DashingCircleEffect::onCanMakeEqual(const GrBatchTracker& m, | 991 bool DashingCircleEffect::onCanMakeEqual(const GrBatchTracker& m, |
976 const GrGeometryProcessor& that, | 992 const GrGeometryProcessor& that, |
977 const GrBatchTracker& t) const { | 993 const GrBatchTracker& t) const { |
978 const DashingCircleBatchTracker& mine = m.cast<DashingCircleBatchTracker>(); | 994 const DashingCircleBatchTracker& mine = m.cast<DashingCircleBatchTracker>(); |
979 const DashingCircleBatchTracker& theirs = t.cast<DashingCircleBatchTracker>(
); | 995 const DashingCircleBatchTracker& theirs = t.cast<DashingCircleBatchTracker>(
); |
980 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, | 996 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, |
981 that, theirs.fUsesLocalCoords) && | 997 that, theirs.fUsesLocalCoords) && |
982 CanCombineOutput(mine.fInputColorType, mine.fColor, | 998 CanCombineOutput(mine.fInputColorType, mine.fColor, |
983 theirs.fInputColorType, theirs.fColor); | 999 theirs.fInputColorType, theirs.fColor); |
984 } | 1000 } |
985 | 1001 |
986 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect); | 1002 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect); |
987 | 1003 |
988 GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random, | 1004 GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random, |
989 GrContext*, | 1005 GrContext*, |
990 const GrDrawTargetCaps& cap
s, | 1006 const GrDrawTargetCaps& cap
s, |
991 GrTexture*[]) { | 1007 GrTexture*[]) { |
992 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->next
ULessThan( | 1008 DashAAMode aaMode = static_cast<DashAAMode>(random->nextULessThan(kDashAAMod
eCount)); |
993 kGrProcessorEdgeTypeCnt)); | |
994 return DashingCircleEffect::Create(GrRandomColor(random), | 1009 return DashingCircleEffect::Create(GrRandomColor(random), |
995 edgeType, GrProcessorUnitTest::TestMatrix
(random)); | 1010 aaMode, GrProcessorUnitTest::TestMatrix(ra
ndom)); |
996 } | 1011 } |
997 | 1012 |
998 ////////////////////////////////////////////////////////////////////////////// | 1013 ////////////////////////////////////////////////////////////////////////////// |
999 | 1014 |
1000 class GLDashingLineEffect; | 1015 class GLDashingLineEffect; |
1001 | 1016 |
1002 struct DashingLineBatchTracker { | 1017 struct DashingLineBatchTracker { |
1003 GrGPInput fInputColorType; | 1018 GrGPInput fInputColorType; |
1004 GrColor fColor; | 1019 GrColor fColor; |
1005 bool fUsesLocalCoords; | 1020 bool fUsesLocalCoords; |
1006 }; | 1021 }; |
1007 | 1022 |
1008 /* | 1023 /* |
1009 * This effect will draw a dashed line. The width of the dash is given by the st
rokeWidth and the | 1024 * This effect will draw a dashed line. The width of the dash is given by the st
rokeWidth and the |
1010 * length and spacing by the DashInfo. Both of the previous two parameters are i
n device space. | 1025 * length and spacing by the DashInfo. Both of the previous two parameters are i
n device space. |
1011 * This effect also requires the setting of a vec2 vertex attribute for the the
four corners of the | 1026 * This effect also requires the setting of a vec2 vertex attribute for the the
four corners of the |
1012 * bounding rect. This attribute is the "dash position" of each vertex. In other
words it is the | 1027 * bounding rect. This attribute is the "dash position" of each vertex. In other
words it is the |
1013 * vertex coords (in device space) if we transform the line to be horizontal, wi
th the start of | 1028 * vertex coords (in device space) if we transform the line to be horizontal, wi
th the start of |
1014 * line at the origin then shifted to the right by half the off interval. The li
ne then goes in the | 1029 * line at the origin then shifted to the right by half the off interval. The li
ne then goes in the |
1015 * positive x direction. | 1030 * positive x direction. |
1016 */ | 1031 */ |
1017 class DashingLineEffect : public GrGeometryProcessor { | 1032 class DashingLineEffect : public GrGeometryProcessor { |
1018 public: | 1033 public: |
1019 typedef SkPathEffect::DashInfo DashInfo; | 1034 typedef SkPathEffect::DashInfo DashInfo; |
1020 | 1035 |
1021 static GrGeometryProcessor* Create(GrColor, | 1036 static GrGeometryProcessor* Create(GrColor, |
1022 GrPrimitiveEdgeType edgeType, | 1037 DashAAMode aaMode, |
1023 const SkMatrix& localMatrix); | 1038 const SkMatrix& localMatrix); |
1024 | 1039 |
1025 virtual ~DashingLineEffect(); | 1040 virtual ~DashingLineEffect(); |
1026 | 1041 |
1027 const char* name() const override { return "DashingEffect"; } | 1042 const char* name() const override { return "DashingEffect"; } |
1028 | 1043 |
1029 const Attribute* inPosition() const { return fInPosition; } | 1044 const Attribute* inPosition() const { return fInPosition; } |
1030 | 1045 |
1031 const Attribute* inDashParams() const { return fInDashParams; } | 1046 const Attribute* inDashParams() const { return fInDashParams; } |
1032 | 1047 |
1033 const Attribute* inRectParams() const { return fInRectParams; } | 1048 const Attribute* inRectParams() const { return fInRectParams; } |
1034 | 1049 |
1035 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } | 1050 DashAAMode aaMode() const { return fAAMode; } |
1036 | 1051 |
1037 virtual void getGLProcessorKey(const GrBatchTracker& bt, | 1052 virtual void getGLProcessorKey(const GrBatchTracker& bt, |
1038 const GrGLCaps& caps, | 1053 const GrGLCaps& caps, |
1039 GrProcessorKeyBuilder* b) const override; | 1054 GrProcessorKeyBuilder* b) const override; |
1040 | 1055 |
1041 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, | 1056 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, |
1042 const GrGLCaps&) const over
ride; | 1057 const GrGLCaps&) const over
ride; |
1043 | 1058 |
1044 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const
override; | 1059 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const
override; |
1045 | 1060 |
1046 bool onCanMakeEqual(const GrBatchTracker&, | 1061 bool onCanMakeEqual(const GrBatchTracker&, |
1047 const GrGeometryProcessor&, | 1062 const GrGeometryProcessor&, |
1048 const GrBatchTracker&) const override; | 1063 const GrBatchTracker&) const override; |
1049 | 1064 |
1050 private: | 1065 private: |
1051 DashingLineEffect(GrColor, GrPrimitiveEdgeType edgeType, const SkMatrix& loc
alMatrix); | 1066 DashingLineEffect(GrColor, DashAAMode aaMode, const SkMatrix& localMatrix); |
1052 | 1067 |
1053 bool onIsEqual(const GrGeometryProcessor& other) const override; | 1068 bool onIsEqual(const GrGeometryProcessor& other) const override; |
1054 | 1069 |
1055 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override; | 1070 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override; |
1056 | 1071 |
1057 GrPrimitiveEdgeType fEdgeType; | 1072 DashAAMode fAAMode; |
1058 const Attribute* fInPosition; | 1073 const Attribute* fInPosition; |
1059 const Attribute* fInDashParams; | 1074 const Attribute* fInDashParams; |
1060 const Attribute* fInRectParams; | 1075 const Attribute* fInRectParams; |
1061 | 1076 |
1062 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 1077 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
1063 | 1078 |
1064 typedef GrGeometryProcessor INHERITED; | 1079 typedef GrGeometryProcessor INHERITED; |
1065 }; | 1080 }; |
1066 | 1081 |
1067 ////////////////////////////////////////////////////////////////////////////// | 1082 ////////////////////////////////////////////////////////////////////////////// |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 // emit transforms | 1137 // emit transforms |
1123 this->emitTransforms(args.fPB, gpArgs->fPositionVar, de.inPosition()->fName,
de.localMatrix(), | 1138 this->emitTransforms(args.fPB, gpArgs->fPositionVar, de.inPosition()->fName,
de.localMatrix(), |
1124 args.fTransformsIn, args.fTransformsOut); | 1139 args.fTransformsIn, args.fTransformsOut); |
1125 | 1140 |
1126 // transforms all points so that we can compare them to our test rect | 1141 // transforms all points so that we can compare them to our test rect |
1127 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 1142 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
1128 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", | 1143 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", |
1129 inDashParams.fsIn(), inDashParams.fsIn(), inDashParam
s.fsIn(), | 1144 inDashParams.fsIn(), inDashParams.fsIn(), inDashParam
s.fsIn(), |
1130 inDashParams.fsIn()); | 1145 inDashParams.fsIn()); |
1131 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", inDash
Params.fsIn()); | 1146 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", inDash
Params.fsIn()); |
1132 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { | 1147 if (de.aaMode() == kEdgeAA_DashAAMode) { |
1133 // The amount of coverage removed in x and y by the edges is computed as
a pair of negative | 1148 // The amount of coverage removed in x and y by the edges is computed as
a pair of negative |
1134 // numbers, xSub and ySub. | 1149 // numbers, xSub and ySub. |
1135 fsBuilder->codeAppend("float xSub, ySub;"); | 1150 fsBuilder->codeAppend("float xSub, ySub;"); |
1136 fsBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRe
ctParams.fsIn()); | 1151 fsBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRe
ctParams.fsIn()); |
1137 fsBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inR
ectParams.fsIn()); | 1152 fsBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inR
ectParams.fsIn()); |
1138 fsBuilder->codeAppendf("ySub = min(fragPosShifted.y - %s.y, 0.0);", inRe
ctParams.fsIn()); | 1153 fsBuilder->codeAppendf("ySub = min(fragPosShifted.y - %s.y, 0.0);", inRe
ctParams.fsIn()); |
1139 fsBuilder->codeAppendf("ySub += min(%s.w - fragPosShifted.y, 0.0);", inR
ectParams.fsIn()); | 1154 fsBuilder->codeAppendf("ySub += min(%s.w - fragPosShifted.y, 0.0);", inR
ectParams.fsIn()); |
1140 // Now compute coverage in x and y and multiply them to get the fraction
of the pixel | 1155 // Now compute coverage in x and y and multiply them to get the fraction
of the pixel |
1141 // covered. | 1156 // covered. |
1142 fsBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0)) * (1.0 + m
ax(ySub, -1.0));"); | 1157 fsBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0)) * (1.0 + m
ax(ySub, -1.0));"); |
| 1158 } else if (de.aaMode() == kMSAA_DashAAMode) { |
| 1159 // For MSAA, we don't modulate the alpha by the Y distance, since MSAA c
overage will handle |
| 1160 // AA on the the top and bottom edges. The shader is only responsible fo
r intra-dash alpha. |
| 1161 fsBuilder->codeAppend("float xSub;"); |
| 1162 fsBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRe
ctParams.fsIn()); |
| 1163 fsBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inR
ectParams.fsIn()); |
| 1164 // Now compute coverage in x to get the fraction of the pixel covered. |
| 1165 fsBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0));"); |
1143 } else { | 1166 } else { |
1144 // Assuming the bounding geometry is tight so no need to check y values | 1167 // Assuming the bounding geometry is tight so no need to check y values |
1145 fsBuilder->codeAppendf("float alpha = 1.0;"); | 1168 fsBuilder->codeAppendf("float alpha = 1.0;"); |
1146 fsBuilder->codeAppendf("alpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0
: 0.0;", | 1169 fsBuilder->codeAppendf("alpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0
: 0.0;", |
1147 inRectParams.fsIn()); | 1170 inRectParams.fsIn()); |
1148 fsBuilder->codeAppendf("alpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0
: 0.0;", | 1171 fsBuilder->codeAppendf("alpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0
: 0.0;", |
1149 inRectParams.fsIn()); | 1172 inRectParams.fsIn()); |
1150 } | 1173 } |
1151 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); | 1174 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
1152 } | 1175 } |
(...skipping 14 matching lines...) Expand all Loading... |
1167 | 1190 |
1168 void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp, | 1191 void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp, |
1169 const GrBatchTracker& bt, | 1192 const GrBatchTracker& bt, |
1170 const GrGLCaps&, | 1193 const GrGLCaps&, |
1171 GrProcessorKeyBuilder* b) { | 1194 GrProcessorKeyBuilder* b) { |
1172 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); | 1195 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); |
1173 const DashingLineEffect& de = gp.cast<DashingLineEffect>(); | 1196 const DashingLineEffect& de = gp.cast<DashingLineEffect>(); |
1174 uint32_t key = 0; | 1197 uint32_t key = 0; |
1175 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0
x0; | 1198 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0
x0; |
1176 key |= ComputePosKey(gp.viewMatrix()) << 1; | 1199 key |= ComputePosKey(gp.viewMatrix()) << 1; |
1177 key |= de.getEdgeType() << 8; | 1200 key |= de.aaMode() << 8; |
1178 b->add32(key << 16 | local.fInputColorType); | 1201 b->add32(key << 16 | local.fInputColorType); |
1179 } | 1202 } |
1180 | 1203 |
1181 ////////////////////////////////////////////////////////////////////////////// | 1204 ////////////////////////////////////////////////////////////////////////////// |
1182 | 1205 |
1183 GrGeometryProcessor* DashingLineEffect::Create(GrColor color, | 1206 GrGeometryProcessor* DashingLineEffect::Create(GrColor color, |
1184 GrPrimitiveEdgeType edgeType, | 1207 DashAAMode aaMode, |
1185 const SkMatrix& localMatrix) { | 1208 const SkMatrix& localMatrix) { |
1186 return SkNEW_ARGS(DashingLineEffect, (color, edgeType, localMatrix)); | 1209 return SkNEW_ARGS(DashingLineEffect, (color, aaMode, localMatrix)); |
1187 } | 1210 } |
1188 | 1211 |
1189 DashingLineEffect::~DashingLineEffect() {} | 1212 DashingLineEffect::~DashingLineEffect() {} |
1190 | 1213 |
1191 void DashingLineEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out)
const { | 1214 void DashingLineEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out)
const { |
1192 out->setUnknownSingleComponent(); | 1215 out->setUnknownSingleComponent(); |
1193 } | 1216 } |
1194 | 1217 |
1195 void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt, | 1218 void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt, |
1196 const GrGLCaps& caps, | 1219 const GrGLCaps& caps, |
1197 GrProcessorKeyBuilder* b) const { | 1220 GrProcessorKeyBuilder* b) const { |
1198 GLDashingLineEffect::GenKey(*this, bt, caps, b); | 1221 GLDashingLineEffect::GenKey(*this, bt, caps, b); |
1199 } | 1222 } |
1200 | 1223 |
1201 GrGLPrimitiveProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker
& bt, | 1224 GrGLPrimitiveProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker
& bt, |
1202 const GrGLCaps&) con
st { | 1225 const GrGLCaps&) con
st { |
1203 return SkNEW_ARGS(GLDashingLineEffect, (*this, bt)); | 1226 return SkNEW_ARGS(GLDashingLineEffect, (*this, bt)); |
1204 } | 1227 } |
1205 | 1228 |
1206 DashingLineEffect::DashingLineEffect(GrColor color, | 1229 DashingLineEffect::DashingLineEffect(GrColor color, |
1207 GrPrimitiveEdgeType edgeType, | 1230 DashAAMode aaMode, |
1208 const SkMatrix& localMatrix) | 1231 const SkMatrix& localMatrix) |
1209 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) { | 1232 : INHERITED(color, SkMatrix::I(), localMatrix), fAAMode(aaMode) { |
1210 this->initClassID<DashingLineEffect>(); | 1233 this->initClassID<DashingLineEffect>(); |
1211 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); | 1234 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); |
1212 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe
rtexAttribType)); | 1235 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe
rtexAttribType)); |
1213 fInRectParams = &this->addVertexAttrib(Attribute("inRect", kVec4f_GrVertexAt
tribType)); | 1236 fInRectParams = &this->addVertexAttrib(Attribute("inRect", kVec4f_GrVertexAt
tribType)); |
1214 } | 1237 } |
1215 | 1238 |
1216 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const { | 1239 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const { |
1217 const DashingLineEffect& de = other.cast<DashingLineEffect>(); | 1240 const DashingLineEffect& de = other.cast<DashingLineEffect>(); |
1218 return fEdgeType == de.fEdgeType; | 1241 return fAAMode == de.fAAMode; |
1219 } | 1242 } |
1220 | 1243 |
1221 void DashingLineEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInf
o& init) const { | 1244 void DashingLineEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInf
o& init) const { |
1222 DashingLineBatchTracker* local = bt->cast<DashingLineBatchTracker>(); | 1245 DashingLineBatchTracker* local = bt->cast<DashingLineBatchTracker>(); |
1223 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in
it, false); | 1246 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in
it, false); |
1224 local->fUsesLocalCoords = init.fUsesLocalCoords; | 1247 local->fUsesLocalCoords = init.fUsesLocalCoords; |
1225 } | 1248 } |
1226 | 1249 |
1227 bool DashingLineEffect::onCanMakeEqual(const GrBatchTracker& m, | 1250 bool DashingLineEffect::onCanMakeEqual(const GrBatchTracker& m, |
1228 const GrGeometryProcessor& that, | 1251 const GrGeometryProcessor& that, |
1229 const GrBatchTracker& t) const { | 1252 const GrBatchTracker& t) const { |
1230 const DashingLineBatchTracker& mine = m.cast<DashingLineBatchTracker>(); | 1253 const DashingLineBatchTracker& mine = m.cast<DashingLineBatchTracker>(); |
1231 const DashingLineBatchTracker& theirs = t.cast<DashingLineBatchTracker>(); | 1254 const DashingLineBatchTracker& theirs = t.cast<DashingLineBatchTracker>(); |
1232 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, | 1255 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, |
1233 that, theirs.fUsesLocalCoords) && | 1256 that, theirs.fUsesLocalCoords) && |
1234 CanCombineOutput(mine.fInputColorType, mine.fColor, | 1257 CanCombineOutput(mine.fInputColorType, mine.fColor, |
1235 theirs.fInputColorType, theirs.fColor); | 1258 theirs.fInputColorType, theirs.fColor); |
1236 } | 1259 } |
1237 | 1260 |
1238 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect); | 1261 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect); |
1239 | 1262 |
1240 GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, | 1263 GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, |
1241 GrContext*, | 1264 GrContext*, |
1242 const GrDrawTargetCaps& caps, | 1265 const GrDrawTargetCaps& caps, |
1243 GrTexture*[]) { | 1266 GrTexture*[]) { |
1244 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->next
ULessThan( | 1267 DashAAMode aaMode = static_cast<DashAAMode>(random->nextULessThan(kDashAAMod
eCount)); |
1245 kGrProcessorEdgeTypeCnt)); | |
1246 | |
1247 return DashingLineEffect::Create(GrRandomColor(random), | 1268 return DashingLineEffect::Create(GrRandomColor(random), |
1248 edgeType, GrProcessorUnitTest::TestMatrix(r
andom)); | 1269 aaMode, GrProcessorUnitTest::TestMatrix(ran
dom)); |
1249 } | 1270 } |
1250 | 1271 |
1251 ////////////////////////////////////////////////////////////////////////////// | 1272 ////////////////////////////////////////////////////////////////////////////// |
1252 | 1273 |
1253 static GrGeometryProcessor* create_dash_gp(GrColor color, | 1274 static GrGeometryProcessor* create_dash_gp(GrColor color, |
1254 GrPrimitiveEdgeType edgeType, | 1275 DashAAMode dashAAMode, |
1255 DashCap cap, | 1276 DashCap cap, |
1256 const SkMatrix& localMatrix) { | 1277 const SkMatrix& localMatrix) { |
1257 switch (cap) { | 1278 switch (cap) { |
1258 case kRound_DashCap: | 1279 case kRound_DashCap: |
1259 return DashingCircleEffect::Create(color, edgeType, localMatrix); | 1280 return DashingCircleEffect::Create(color, dashAAMode, localMatrix); |
1260 case kNonRound_DashCap: | 1281 case kNonRound_DashCap: |
1261 return DashingLineEffect::Create(color, edgeType, localMatrix); | 1282 return DashingLineEffect::Create(color, dashAAMode, localMatrix); |
1262 default: | 1283 default: |
1263 SkFAIL("Unexpected dashed cap."); | 1284 SkFAIL("Unexpected dashed cap."); |
1264 } | 1285 } |
1265 return NULL; | 1286 return NULL; |
1266 } | 1287 } |
OLD | NEW |