Chromium Code Reviews| 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 |