OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 "SkLinearBitmapPipeline.h" | 8 #include "SkLinearBitmapPipeline.h" |
9 #include "SkPM4f.h" | 9 #include "SkPM4f.h" |
10 | 10 |
11 #include <algorithm> | 11 #include <algorithm> |
12 #include <cmath> | 12 #include <cmath> |
13 #include <limits> | 13 #include <limits> |
14 #include "SkColor.h" | 14 #include "SkColor.h" |
15 #include "SkSize.h" | 15 #include "SkSize.h" |
16 | 16 |
17 struct X { | 17 struct X { |
18 explicit X(SkScalar val) : fVal{val} { } | 18 explicit X(SkScalar val) : fVal{val} { } |
19 explicit X(SkPoint pt) : fVal{pt.fX} { } | 19 explicit X(SkPoint pt) : fVal{pt.fX} { } |
20 explicit X(SkSize s) : fVal{s.fWidth} { } | 20 explicit X(SkSize s) : fVal{s.fWidth} { } |
21 explicit X(SkISize s) : fVal(s.fWidth) { } | 21 explicit X(SkISize s) : fVal(s.fWidth) { } |
22 operator float () const {return fVal;} | 22 operator float () const {return fVal;} |
23 private: | 23 private: |
24 float fVal; | 24 float fVal; |
25 }; | 25 }; |
26 | 26 |
27 struct Y { | 27 struct Y { |
28 explicit Y(SkScalar val) : fVal{val} { } | 28 explicit Y(SkScalar val) : fVal{val} { } |
29 explicit Y(SkPoint pt) : fVal{pt.fY} { } | 29 explicit Y(SkPoint pt) : fVal{pt.fY} { } |
30 explicit Y(SkSize s) : fVal{s.fHeight} { } | 30 explicit Y(SkSize s) : fVal{s.fHeight} { } |
31 explicit Y(SkISize s) : fVal(s.fHeight) { } | 31 explicit Y(SkISize s) : fVal(s.fHeight) { } |
32 operator float () const {return fVal;} | 32 operator float () const {return fVal;} |
33 private: | 33 private: |
34 float fVal; | 34 float fVal; |
35 }; | 35 }; |
36 | 36 |
37 template <typename Stage> | |
38 void span_fallback(SkPoint start, SkScalar length, int count, Stage* stage) { | |
39 SkASSERT(count > 1); | |
mtklein
2016/02/19 20:54:19
// No point to count == 1... should just use point
herb_g
2016/02/19 22:07:44
Done.
| |
40 | |
41 float dx = length / (count - 1); | |
42 Sk4f Xs = Sk4f(X(start)) + Sk4f{0.0f, 1.0f, 2.0f, 3.0f} * Sk4f{dx}; | |
43 Sk4f Ys{Y(start)}; | |
44 Sk4f fours = {4.0f * dx}; | |
mtklein
2016/02/19 20:54:19
fourDX?
herb_g
2016/02/19 22:07:44
Done.
| |
45 | |
46 while (count >= 4) { | |
47 stage->pointList4(Xs, Ys); | |
48 Xs = Xs + fours; | |
49 count -= 4; | |
50 } | |
51 if (count > 0) { | |
52 stage->pointListFew(count, Xs, Ys); | |
53 } | |
54 } | |
55 | |
37 template<typename Strategy, typename Next> | 56 template<typename Strategy, typename Next> |
38 class PointProcessor final : public PointProcessorInterface { | 57 class PointProcessor final : public PointProcessorInterface { |
39 public: | 58 public: |
40 template <typename... Args> | 59 template <typename... Args> |
41 PointProcessor(Next* next, Args&&... args) | 60 PointProcessor(Next* next, Args&&... args) |
42 : fNext{next} | 61 : fNext{next} |
43 , fStrategy{std::forward<Args>(args)...}{ } | 62 , fStrategy{std::forward<Args>(args)...}{ } |
44 | 63 |
45 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 64 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { |
46 Sk4f newXs = xs; | 65 Sk4f newXs = xs; |
47 Sk4f newYs = ys; | 66 Sk4f newYs = ys; |
48 fStrategy.processPoints(&newXs, &newYs); | 67 fStrategy.processPoints(&newXs, &newYs); |
49 fNext->pointListFew(n, newXs, newYs); | 68 fNext->pointListFew(n, newXs, newYs); |
50 } | 69 } |
51 | 70 |
52 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | 71 void pointList4(Sk4fArg xs, Sk4fArg ys) override { |
53 Sk4f newXs = xs; | 72 Sk4f newXs = xs; |
54 Sk4f newYs = ys; | 73 Sk4f newYs = ys; |
55 fStrategy.processPoints(&newXs, &newYs); | 74 fStrategy.processPoints(&newXs, &newYs); |
56 fNext->pointList4(newXs, newYs); | 75 fNext->pointList4(newXs, newYs); |
57 } | 76 } |
58 | 77 |
78 void pointSpan(SkPoint start, SkScalar length, int count) override { | |
79 span_fallback(start, length, count, this); | |
80 } | |
81 | |
59 private: | 82 private: |
60 Next* const fNext; | 83 Next* const fNext; |
61 Strategy fStrategy; | 84 Strategy fStrategy; |
62 }; | 85 }; |
63 | 86 |
64 template<typename Strategy, typename Next> | 87 template<typename Strategy, typename Next> |
65 class BilerpProcessor final : public BilerpProcessorInterface { | 88 class BilerpProcessor final : public BilerpProcessorInterface { |
66 public: | 89 public: |
67 template <typename... Args> | 90 template <typename... Args> |
68 BilerpProcessor(Next* next, Args&&... args) | 91 BilerpProcessor(Next* next, Args&&... args) |
(...skipping 14 matching lines...) Expand all Loading... | |
83 fNext->pointList4(newXs, newYs); | 106 fNext->pointList4(newXs, newYs); |
84 } | 107 } |
85 | 108 |
86 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | 109 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { |
87 Sk4f newXs = xs; | 110 Sk4f newXs = xs; |
88 Sk4f newYs = ys; | 111 Sk4f newYs = ys; |
89 fStrategy.processPoints(&newXs, &newYs); | 112 fStrategy.processPoints(&newXs, &newYs); |
90 fNext->bilerpList(newXs, newYs); | 113 fNext->bilerpList(newXs, newYs); |
91 } | 114 } |
92 | 115 |
116 void pointSpan(SkPoint start, SkScalar length, int count) override { | |
117 span_fallback(start, length, count, this); | |
118 } | |
119 | |
93 private: | 120 private: |
94 Next* const fNext; | 121 Next* const fNext; |
95 Strategy fStrategy; | 122 Strategy fStrategy; |
96 }; | 123 }; |
97 | 124 |
98 class SkippedStage final : public BilerpProcessorInterface { | 125 class SkippedStage final : public BilerpProcessorInterface { |
99 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 126 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { |
100 SkFAIL("Skipped stage."); | 127 SkFAIL("Skipped stage."); |
101 } | 128 } |
102 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { | 129 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { |
103 SkFAIL("Skipped stage."); | 130 SkFAIL("Skipped stage."); |
104 } | 131 } |
105 virtual void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | 132 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { |
133 SkFAIL("Skipped stage."); | |
134 } | |
135 void pointSpan(SkPoint start, SkScalar length, int count) override { | |
106 SkFAIL("Skipped stage."); | 136 SkFAIL("Skipped stage."); |
107 } | 137 } |
108 }; | 138 }; |
109 | 139 |
110 class TranslateMatrixStrategy { | 140 class TranslateMatrixStrategy { |
111 public: | 141 public: |
112 TranslateMatrixStrategy(SkVector offset) | 142 TranslateMatrixStrategy(SkVector offset) |
113 : fXOffset{X(offset)} | 143 : fXOffset{X(offset)} |
114 , fYOffset{Y(offset)} { } | 144 , fYOffset{Y(offset)} { } |
115 void processPoints(Sk4f* xs, Sk4f* ys) { | 145 void processPoints(Sk4f* xs, Sk4f* ys) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | 238 void pointList4(Sk4fArg xs, Sk4fArg ys) override { |
209 // px00 px10 px01 px11 | 239 // px00 px10 px01 px11 |
210 const Sk4f kXOffsets{-0.5f, 0.5f, -0.5f, 0.5f}, | 240 const Sk4f kXOffsets{-0.5f, 0.5f, -0.5f, 0.5f}, |
211 kYOffsets{-0.5f, -0.5f, 0.5f, 0.5f}; | 241 kYOffsets{-0.5f, -0.5f, 0.5f, 0.5f}; |
212 fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYOffsets); | 242 fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYOffsets); |
213 fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYOffsets); | 243 fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYOffsets); |
214 fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYOffsets); | 244 fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYOffsets); |
215 fNext->bilerpList(Sk4f{xs[3]} + kXOffsets, Sk4f{ys[3]} + kYOffsets); | 245 fNext->bilerpList(Sk4f{xs[3]} + kXOffsets, Sk4f{ys[3]} + kYOffsets); |
216 } | 246 } |
217 | 247 |
248 void pointSpan(SkPoint start, SkScalar length, int count) override { | |
249 span_fallback(start, length, count, this); | |
250 } | |
251 | |
218 private: | 252 private: |
219 Next* const fNext; | 253 Next* const fNext; |
220 }; | 254 }; |
221 | 255 |
222 static PointProcessorInterface* choose_filter( | 256 static PointProcessorInterface* choose_filter( |
223 BilerpProcessorInterface* next, | 257 BilerpProcessorInterface* next, |
224 SkFilterQuality filterQuailty, | 258 SkFilterQuality filterQuailty, |
225 SkLinearBitmapPipeline::FilterStage* filterProc) { | 259 SkLinearBitmapPipeline::FilterStage* filterProc) { |
226 if (SkFilterQuality::kNone_SkFilterQuality == filterQuailty) { | 260 if (SkFilterQuality::kNone_SkFilterQuality == filterQuailty) { |
227 filterProc->Initialize<SkippedStage>(); | 261 filterProc->Initialize<SkippedStage>(); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 fNext->place4Pixels(px0, px1, px2, px3); | 482 fNext->place4Pixels(px0, px1, px2, px3); |
449 } | 483 } |
450 | 484 |
451 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | 485 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { |
452 Sk4f px00, px10, px01, px11; | 486 Sk4f px00, px10, px01, px11; |
453 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11); | 487 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11); |
454 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); | 488 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); |
455 fNext->placePixel(pixel); | 489 fNext->placePixel(pixel); |
456 } | 490 } |
457 | 491 |
492 void pointSpan(SkPoint start, SkScalar length, int count) override { | |
493 span_fallback(start, length, count, this); | |
494 } | |
495 | |
458 private: | 496 private: |
459 PixelPlacerInterface* const fNext; | 497 PixelPlacerInterface* const fNext; |
460 SourceStrategy fStrategy; | 498 SourceStrategy fStrategy; |
461 }; | 499 }; |
462 | 500 |
463 static BilerpProcessorInterface* choose_pixel_sampler( | 501 static BilerpProcessorInterface* choose_pixel_sampler( |
464 PixelPlacerInterface* next, | 502 PixelPlacerInterface* next, |
465 const SkPixmap& srcPixmap, | 503 const SkPixmap& srcPixmap, |
466 SkLinearBitmapPipeline::SampleStage* sampleStage) { | 504 SkLinearBitmapPipeline::SampleStage* sampleStage) { |
467 const SkImageInfo& imageInfo = srcPixmap.info(); | 505 const SkImageInfo& imageInfo = srcPixmap.info(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
550 // identity matrix, the matrix stage is skipped, and the tilerStage is the f irst stage. | 588 // identity matrix, the matrix stage is skipped, and the tilerStage is the f irst stage. |
551 auto placementStage = choose_pixel_placer(srcImageInfo.alphaType(), &fPixelS tage); | 589 auto placementStage = choose_pixel_placer(srcImageInfo.alphaType(), &fPixelS tage); |
552 auto samplerStage = choose_pixel_sampler(placementStage, srcPixmap, &fSamp leStage); | 590 auto samplerStage = choose_pixel_sampler(placementStage, srcPixmap, &fSamp leStage); |
553 auto tilerStage = choose_tiler(samplerStage, size, xTile, yTile, &fTileX OrBothStage, | 591 auto tilerStage = choose_tiler(samplerStage, size, xTile, yTile, &fTileX OrBothStage, |
554 &fTileYStage); | 592 &fTileYStage); |
555 auto filterStage = choose_filter(tilerStage, filterQuality, &fFilterStage ); | 593 auto filterStage = choose_filter(tilerStage, filterQuality, &fFilterStage ); |
556 fFirstStage = choose_matrix(filterStage, inverse, &fMatrixStage); | 594 fFirstStage = choose_matrix(filterStage, inverse, &fMatrixStage); |
557 } | 595 } |
558 | 596 |
559 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { | 597 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { |
598 SkASSERT(count > 0); | |
560 fPixelStage->setDestination(dst); | 599 fPixelStage->setDestination(dst); |
561 | 600 // Adjust points by 0.5, 0.5 to sample from the center of the pixels. |
562 Sk4f Xs = Sk4f(x) + Sk4f{0.5f, 1.5f, 2.5f, 3.5f}; | 601 if (count == 1) { |
563 Sk4f Ys(y); | 602 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f}); |
564 Sk4f fours{4.0f}; | 603 } else { |
565 | 604 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count); |
mtklein
2016/02/19 20:54:19
// Good place for diagrams and an explanation of r
herb_g
2016/02/19 22:07:44
Done.
| |
566 while (count >= 4) { | |
567 fFirstStage->pointList4(Xs, Ys); | |
568 Xs = Xs + fours; | |
569 count -= 4; | |
570 } | |
571 if (count > 0) { | |
572 fFirstStage->pointListFew(count, Xs, Ys); | |
573 } | 605 } |
574 } | 606 } |
OLD | NEW |