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" |
11 #include "GrBatchTarget.h" | 11 #include "GrBatchTarget.h" |
12 #include "GrBatchTest.h" | |
12 #include "GrBufferAllocPool.h" | 13 #include "GrBufferAllocPool.h" |
13 #include "GrGeometryProcessor.h" | 14 #include "GrGeometryProcessor.h" |
14 #include "GrContext.h" | 15 #include "GrContext.h" |
15 #include "GrCoordTransform.h" | 16 #include "GrCoordTransform.h" |
16 #include "GrDefaultGeoProcFactory.h" | 17 #include "GrDefaultGeoProcFactory.h" |
17 #include "GrDrawTarget.h" | 18 #include "GrDrawTarget.h" |
18 #include "GrDrawTargetCaps.h" | 19 #include "GrDrawTargetCaps.h" |
19 #include "GrInvariantOutput.h" | 20 #include "GrInvariantOutput.h" |
20 #include "GrProcessor.h" | 21 #include "GrProcessor.h" |
21 #include "GrStrokeInfo.h" | 22 #include "GrStrokeInfo.h" |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
251 SkMatrix fSrcRotInv; | 252 SkMatrix fSrcRotInv; |
252 SkPoint fPtsRot[2]; | 253 SkPoint fPtsRot[2]; |
253 SkScalar fSrcStrokeWidth; | 254 SkScalar fSrcStrokeWidth; |
254 SkScalar fPhase; | 255 SkScalar fPhase; |
255 SkScalar fIntervals[2]; | 256 SkScalar fIntervals[2]; |
256 SkScalar fParallelScale; | 257 SkScalar fParallelScale; |
257 SkScalar fPerpendicularScale; | 258 SkScalar fPerpendicularScale; |
258 SkDEBUGCODE(SkRect fDevBounds;) | 259 SkDEBUGCODE(SkRect fDevBounds;) |
259 }; | 260 }; |
260 | 261 |
261 static GrBatch* Create(const Geometry& geometry, SkPaint::Cap cap, DashAAMod e aaMode, bool fullDash) { | 262 static GrBatch* Create(const Geometry& geometry, SkPaint::Cap cap, DashAAMod e aaMode, |
263 bool fullDash) { | |
262 return SkNEW_ARGS(DashBatch, (geometry, cap, aaMode, fullDash)); | 264 return SkNEW_ARGS(DashBatch, (geometry, cap, aaMode, fullDash)); |
263 } | 265 } |
264 | 266 |
265 const char* name() const override { return "DashBatch"; } | 267 const char* name() const override { return "DashBatch"; } |
266 | 268 |
267 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 269 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
268 // When this is called on a batch, there is only one geometry bundle | 270 // When this is called on a batch, there is only one geometry bundle |
269 out->setKnownFourComponents(fGeoData[0].fColor); | 271 out->setKnownFourComponents(fGeoData[0].fColor); |
270 } | 272 } |
271 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 273 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 bool fFullDash; | 694 bool fFullDash; |
693 }; | 695 }; |
694 | 696 |
695 static const int kVertsPerDash = 4; | 697 static const int kVertsPerDash = 4; |
696 static const int kIndicesPerDash = 6; | 698 static const int kIndicesPerDash = 6; |
697 | 699 |
698 BatchTracker fBatch; | 700 BatchTracker fBatch; |
699 SkSTArray<1, Geometry, true> fGeoData; | 701 SkSTArray<1, Geometry, true> fGeoData; |
700 }; | 702 }; |
701 | 703 |
702 | 704 static GrBatch* create_batch(GrColor color, const SkMatrix& viewMatrix, const Sk Point pts[2], |
703 bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, | 705 bool useAA, const GrStrokeInfo& strokeInfo, bool ms aaRT) { |
704 GrPipelineBuilder* pipelineBuilder, GrColor c olor, | |
705 const SkMatrix& viewMatrix, const SkPoint pts [2], | |
706 bool useAA, const GrStrokeInfo& strokeInfo) { | |
707 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); | 706 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); |
708 | 707 |
709 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); | 708 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); |
710 | 709 |
711 DashBatch::Geometry geometry; | 710 DashBatch::Geometry geometry; |
712 geometry.fSrcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); | 711 geometry.fSrcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); |
713 | 712 |
714 // the phase should be normalized to be [0, sum of all intervals) | 713 // the phase should be normalized to be [0, sum of all intervals) |
715 SkASSERT(info.fPhase >= 0 && info.fPhase < info.fIntervals[0] + info.fInterv als[1]); | 714 SkASSERT(info.fPhase >= 0 && info.fPhase < info.fIntervals[0] + info.fInterv als[1]); |
716 | 715 |
717 // Rotate the src pts so they are aligned horizontally with pts[0].fX < pts[ 1].fX | 716 // Rotate the src pts so they are aligned horizontally with pts[0].fX < pts[ 1].fX |
718 if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) { | 717 if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) { |
719 SkMatrix rotMatrix; | 718 SkMatrix rotMatrix; |
720 align_to_x_axis(pts, &rotMatrix, geometry.fPtsRot); | 719 align_to_x_axis(pts, &rotMatrix, geometry.fPtsRot); |
721 if(!rotMatrix.invert(&geometry.fSrcRotInv)) { | 720 if(!rotMatrix.invert(&geometry.fSrcRotInv)) { |
722 SkDebugf("Failed to create invertible rotation matrix!\n"); | 721 SkDebugf("Failed to create invertible rotation matrix!\n"); |
723 return false; | 722 return NULL; |
724 } | 723 } |
725 } else { | 724 } else { |
726 geometry.fSrcRotInv.reset(); | 725 geometry.fSrcRotInv.reset(); |
727 memcpy(geometry.fPtsRot, pts, 2 * sizeof(SkPoint)); | 726 memcpy(geometry.fPtsRot, pts, 2 * sizeof(SkPoint)); |
728 } | 727 } |
729 | 728 |
730 // Scale corrections of intervals and stroke from view matrix | 729 // Scale corrections of intervals and stroke from view matrix |
731 calc_dash_scaling(&geometry.fParallelScale, &geometry.fPerpendicularScale, v iewMatrix, | 730 calc_dash_scaling(&geometry.fParallelScale, &geometry.fPerpendicularScale, v iewMatrix, |
732 geometry.fPtsRot); | 731 geometry.fPtsRot); |
733 | 732 |
734 SkScalar offInterval = info.fIntervals[1] * geometry.fParallelScale; | 733 SkScalar offInterval = info.fIntervals[1] * geometry.fParallelScale; |
735 SkScalar strokeWidth = geometry.fSrcStrokeWidth * geometry.fPerpendicularSca le; | 734 SkScalar strokeWidth = geometry.fSrcStrokeWidth * geometry.fPerpendicularSca le; |
736 | 735 |
737 if (SkPaint::kSquare_Cap == cap && 0 != geometry.fSrcStrokeWidth) { | 736 if (SkPaint::kSquare_Cap == cap && 0 != geometry.fSrcStrokeWidth) { |
738 // add cap to on interveal and remove from off interval | 737 // add cap to on interveal and remove from off interval |
739 offInterval -= strokeWidth; | 738 offInterval -= strokeWidth; |
740 } | 739 } |
741 | 740 |
742 DashAAMode aaMode = pipelineBuilder->getRenderTarget()->isMultisampled() ? k MSAA_DashAAMode : | 741 DashAAMode aaMode = msaaRT ? kMSAA_DashAAMode : |
743 useAA ? kEdgeAA_DashAAMode : kBW_DashAAMode; | 742 useAA ? kEdgeAA_DashAAMode : kBW_DashAAMode; |
744 | 743 |
745 // TODO we can do a real rect call if not using fulldash(ie no off interval, not using AA) | 744 // TODO we can do a real rect call if not using fulldash(ie no off interval, not using AA) |
746 bool fullDash = offInterval > 0.f || aaMode != kBW_DashAAMode; | 745 bool fullDash = offInterval > 0.f || aaMode != kBW_DashAAMode; |
747 | 746 |
748 geometry.fColor = color; | 747 geometry.fColor = color; |
749 geometry.fViewMatrix = viewMatrix; | 748 geometry.fViewMatrix = viewMatrix; |
750 geometry.fPhase = info.fPhase; | 749 geometry.fPhase = info.fPhase; |
751 geometry.fIntervals[0] = info.fIntervals[0]; | 750 geometry.fIntervals[0] = info.fIntervals[0]; |
752 geometry.fIntervals[1] = info.fIntervals[1]; | 751 geometry.fIntervals[1] = info.fIntervals[1]; |
753 | 752 |
754 SkAutoTUnref<GrBatch> batch(DashBatch::Create(geometry, cap, aaMode, fullDas h)); | 753 return DashBatch::Create(geometry, cap, aaMode, fullDash); |
754 } | |
755 | |
756 bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, | |
757 GrPipelineBuilder* pipelineBuilder, GrColor c olor, | |
758 const SkMatrix& viewMatrix, const SkPoint pts [2], | |
759 bool useAA, const GrStrokeInfo& strokeInfo) { | |
760 SkAutoTUnref<GrBatch> batch(create_batch(color, viewMatrix, pts, useAA, stro keInfo, | |
761 pipelineBuilder->getRenderTarget()- >isMultisampled())); | |
762 if (!batch) { | |
763 return false; | |
764 } | |
765 | |
755 target->drawBatch(pipelineBuilder, batch); | 766 target->drawBatch(pipelineBuilder, batch); |
756 | |
757 return true; | 767 return true; |
758 } | 768 } |
759 | 769 |
760 ////////////////////////////////////////////////////////////////////////////// | 770 ////////////////////////////////////////////////////////////////////////////// |
761 | 771 |
762 class GLDashingCircleEffect; | 772 class GLDashingCircleEffect; |
763 | 773 |
764 struct DashingCircleBatchTracker { | 774 struct DashingCircleBatchTracker { |
765 GrGPInput fInputColorType; | 775 GrGPInput fInputColorType; |
766 GrColor fColor; | 776 GrColor fColor; |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1273 switch (cap) { | 1283 switch (cap) { |
1274 case kRound_DashCap: | 1284 case kRound_DashCap: |
1275 return DashingCircleEffect::Create(color, dashAAMode, localMatrix); | 1285 return DashingCircleEffect::Create(color, dashAAMode, localMatrix); |
1276 case kNonRound_DashCap: | 1286 case kNonRound_DashCap: |
1277 return DashingLineEffect::Create(color, dashAAMode, localMatrix); | 1287 return DashingLineEffect::Create(color, dashAAMode, localMatrix); |
1278 default: | 1288 default: |
1279 SkFAIL("Unexpected dashed cap."); | 1289 SkFAIL("Unexpected dashed cap."); |
1280 } | 1290 } |
1281 return NULL; | 1291 return NULL; |
1282 } | 1292 } |
1293 | |
1294 //////////////////////////////////////////////////////////////////////////////// ///////////////// | |
1295 | |
1296 #ifdef GR_TEST_UTILS | |
1297 | |
1298 BATCH_TEST_DEFINE(DashBatch) { | |
1299 GrColor color = GrRandomColor(random); | |
1300 SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random); | |
1301 bool useAA = random->nextBool(); | |
1302 bool msaaRT = random->nextBool(); | |
1303 | |
1304 // We can only dash either horizontal or vertical lines | |
1305 SkPoint pts[2]; | |
1306 if (random->nextBool()) { | |
1307 // vertical | |
1308 pts[0].fX = 1.f; | |
1309 pts[0].fY = random->nextF() * 10.f; | |
1310 pts[1].fX = 1.f; | |
1311 pts[1].fY = random->nextF() * 10.f; | |
1312 } else { | |
1313 // horizontal | |
1314 pts[0].fX = random->nextF() * 10.f; | |
1315 pts[0].fY = 1.f; | |
1316 pts[1].fX = random->nextF() * 10.f; | |
1317 pts[1].fY = 1.f; | |
1318 } | |
1319 | |
1320 SkScalar intervals[2]; | |
1321 | |
1322 // We can only dash with the following intervals | |
1323 enum Intervals { | |
1324 kOpenOpen_Intervals , | |
1325 kOpenClose_Intervals, | |
1326 kCloseOpen_Intervals, | |
1327 }; | |
1328 | |
1329 Intervals intervalType = Intervals(random->nextULessThan(kCloseOpen_Interval s + 1)); | |
1330 static const SkScalar kIntervalMin = 0.1f; | |
1331 static const SkScalar kIntervalMax = 10.f; | |
1332 switch (intervalType) { | |
1333 case kOpenOpen_Intervals: | |
1334 intervals[0] = random->nextRangeScalar(kIntervalMin, kIntervalMax); | |
1335 intervals[1] = random->nextRangeScalar(kIntervalMin, kIntervalMax); | |
1336 break; | |
1337 case kOpenClose_Intervals: | |
1338 intervals[0] = 0.f; | |
1339 intervals[1] = random->nextRangeScalar(kIntervalMin, kIntervalMax); | |
1340 break; | |
1341 case kCloseOpen_Intervals: | |
1342 intervals[0] = random->nextRangeScalar(kIntervalMin, kIntervalMax); | |
1343 intervals[1] = 0.f; | |
1344 break; | |
1345 | |
1346 } | |
1347 | |
1348 // phase is 0 < sum (i0, i1) | |
1349 SkScalar phase = random->nextRangeScalar(0, intervals[0] + intervals[1]); | |
1350 | |
1351 SkPaint p; | |
1352 p.setStyle(SkPaint::kStroke_Style); | |
1353 p.setStrokeWidth(SkIntToScalar(1)); | |
1354 | |
1355 if (random->nextBool()) { | |
1356 p.setStrokeCap(SkPaint::kRound_Cap); | |
egdaniel
2015/04/29 18:17:49
Can only do round caps if on interval is 0
| |
1357 } | |
1358 | |
1359 GrStrokeInfo strokeInfo(p); | |
1360 | |
1361 SkPathEffect::DashInfo info; | |
1362 info.fIntervals = intervals; | |
1363 info.fCount = 2; | |
1364 info.fPhase = phase; | |
1365 SkDEBUGCODE(bool success = ) strokeInfo.setDashInfo(info); | |
1366 SkASSERT(success); | |
1367 | |
1368 return create_batch(color, viewMatrix, pts, useAA, strokeInfo, msaaRT); | |
1369 } | |
1370 | |
1371 #endif | |
OLD | NEW |