| 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 |