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 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 void clampToSinglePixel(SkPoint pixel) { | 125 void clampToSinglePixel(SkPoint pixel) { |
| 126 fStart = pixel; | 126 fStart = pixel; |
| 127 fLength = 0.0f; | 127 fLength = 0.0f; |
| 128 } | 128 } |
| 129 | 129 |
| 130 private: | 130 private: |
| 131 SkPoint fStart; | 131 SkPoint fStart; |
| 132 SkScalar fLength; | 132 SkScalar fLength; |
| 133 int fCount; | 133 int fCount; |
| 134 }; | 134 }; |
| 135 | |
|
mtklein_C
2016/03/01 16:34:09
Let'd document what a BilerpSpan represents, espec
herb_g
2016/03/01 22:13:58
Done.
| |
| 136 class BilerpSpan { | |
| 137 public: | |
| 138 BilerpSpan(SkScalar x, SkScalar y0, SkScalar y1, SkScalar length, int count) | |
| 139 : fX{x}, fY0{y0}, fY1{y1}, fLength{length}, fCount{count} { | |
| 140 SkASSERT(count >= 0); | |
| 141 SkASSERT(std::isfinite(length)); | |
| 142 } | |
| 143 | |
| 144 operator std::tuple<SkScalar&, SkScalar&, SkScalar&, SkScalar&, int&>() { | |
| 145 return std::tie(fX, fY0, fY1, fLength, fCount); | |
| 146 } | |
| 147 | |
| 148 bool isEmpty() const { return 0 == fCount; } | |
| 149 | |
| 150 private: | |
| 151 SkScalar fX; | |
| 152 SkScalar fY0; | |
| 153 SkScalar fY1; | |
| 154 SkScalar fLength; | |
| 155 int fCount; | |
| 156 }; | |
| 135 } // namespace | 157 } // namespace |
| 136 | 158 |
| 137 class SkLinearBitmapPipeline::PointProcessorInterface { | 159 class SkLinearBitmapPipeline::PointProcessorInterface { |
| 138 public: | 160 public: |
| 139 virtual ~PointProcessorInterface() { } | 161 virtual ~PointProcessorInterface() { } |
| 140 virtual void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) = 0; | 162 virtual void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) = 0; |
| 141 virtual void VECTORCALL pointList4(Sk4s xs, Sk4s ys) = 0; | 163 virtual void VECTORCALL pointList4(Sk4s xs, Sk4s ys) = 0; |
| 142 virtual void pointSpan(Span span) = 0; | 164 virtual void pointSpan(Span span) = 0; |
| 143 }; | 165 }; |
| 144 | 166 |
| 145 class SkLinearBitmapPipeline::BilerpProcessorInterface | 167 class SkLinearBitmapPipeline::BilerpProcessorInterface |
| 146 : public SkLinearBitmapPipeline::PointProcessorInterface { | 168 : public SkLinearBitmapPipeline::PointProcessorInterface { |
| 147 public: | 169 public: |
| 148 // The x's and y's are setup in the following order: | 170 // The x's and y's are setup in the following order: |
| 149 // +--------+--------+ | 171 // +--------+--------+ |
| 150 // | | | | 172 // | | | |
| 151 // | px00 | px10 | | 173 // | px00 | px10 | |
| 152 // | 0 | 1 | | 174 // | 0 | 1 | |
| 153 // +--------+--------+ | 175 // +--------+--------+ |
| 154 // | | | | 176 // | | | |
| 155 // | px01 | px11 | | 177 // | px01 | px11 | |
| 156 // | 2 | 3 | | 178 // | 2 | 3 | |
| 157 // +--------+--------+ | 179 // +--------+--------+ |
| 158 // These pixels coordinates are arranged in the following order in xs and ys : | 180 // These pixels coordinates are arranged in the following order in xs and ys : |
| 159 // px00 px10 px01 px11 | 181 // px00 px10 px01 px11 |
| 160 virtual void VECTORCALL bilerpList(Sk4s xs, Sk4s ys) = 0; | 182 virtual void VECTORCALL bilerpList(Sk4s xs, Sk4s ys) = 0; |
| 183 virtual void bilerpSpan(BilerpSpan span) = 0; | |
| 161 }; | 184 }; |
| 162 | 185 |
| 163 class SkLinearBitmapPipeline::PixelPlacerInterface { | 186 class SkLinearBitmapPipeline::PixelPlacerInterface { |
| 164 public: | 187 public: |
| 165 virtual ~PixelPlacerInterface() { } | 188 virtual ~PixelPlacerInterface() { } |
| 166 virtual void setDestination(SkPM4f* dst) = 0; | 189 virtual void setDestination(SkPM4f* dst) = 0; |
| 167 virtual void VECTORCALL placePixel(Sk4f pixel0) = 0; | 190 virtual void VECTORCALL placePixel(Sk4f pixel0) = 0; |
| 168 virtual void VECTORCALL place4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) = 0 ; | 191 virtual void VECTORCALL place4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) = 0 ; |
| 169 }; | 192 }; |
| 170 | 193 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 190 while (count >= 4) { | 213 while (count >= 4) { |
| 191 stage->pointList4(xs, ys); | 214 stage->pointList4(xs, ys); |
| 192 xs = xs + fourDx; | 215 xs = xs + fourDx; |
| 193 count -= 4; | 216 count -= 4; |
| 194 } | 217 } |
| 195 if (count > 0) { | 218 if (count > 0) { |
| 196 stage->pointListFew(count, xs, ys); | 219 stage->pointListFew(count, xs, ys); |
| 197 } | 220 } |
| 198 } | 221 } |
| 199 | 222 |
| 223 template <typename Next> | |
| 224 void bilerp_span_fallback(BilerpSpan span, Next* next) { | |
| 225 | |
|
mtklein_C
2016/03/01 16:34:09
Stray newline.
herb_g
2016/03/01 22:13:58
Done.
| |
| 226 SkASSERT(!span.isEmpty()); | |
| 227 SkScalar x, y0, y1; SkScalar length; int count; | |
| 228 std::tie(x, y0, y1, length, count) = span; | |
| 229 float dx = length / (count - 1); | |
|
mtklein_C
2016/03/01 16:34:09
Do we not need the usual inf/NaN worries here, or
herb_g
2016/03/01 22:13:58
Done.
| |
| 230 | |
| 231 Sk4f xs = Sk4f{x} + Sk4f{0.0f, 1.0f, 0.0f, 1.0f}; | |
| 232 Sk4f ys = Sk4f{y0, y0, y1, y1}; | |
| 233 | |
| 234 while (count > 0) { | |
| 235 next->bilerpList(xs, ys); | |
| 236 xs = xs + dx; | |
| 237 count -= 1; | |
| 238 } | |
| 239 } | |
| 240 | |
| 200 // PointProcessor uses a strategy to help complete the work of the different sta ges. The strategy | 241 // PointProcessor uses a strategy to help complete the work of the different sta ges. The strategy |
| 201 // must implement the following methods: | 242 // must implement the following methods: |
| 202 // * processPoints(xs, ys) - must mutate the xs and ys for the stage. | 243 // * processPoints(xs, ys) - must mutate the xs and ys for the stage. |
| 203 // * maybeProcessSpan(span, next) - This represents a horizontal series of pixel s | 244 // * maybeProcessSpan(span, next) - This represents a horizontal series of pixel s |
| 204 // to work over. | 245 // to work over. |
| 205 // span - encapsulation of span. | 246 // span - encapsulation of span. |
| 206 // next - a pointer to the next stage. | 247 // next - a pointer to the next stage. |
| 207 // maybeProcessSpan - returns false if it can not process the span and needs t o fallback to | 248 // maybeProcessSpan - returns false if it can not process the span and needs t o fallback to |
| 208 // point lists for processing. | 249 // point lists for processing. |
| 209 template<typename Strategy, typename Next> | 250 template<typename Strategy, typename Next> |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 fNext->bilerpList(xs, ys); | 302 fNext->bilerpList(xs, ys); |
| 262 } | 303 } |
| 263 | 304 |
| 264 void pointSpan(Span span) override { | 305 void pointSpan(Span span) override { |
| 265 SkASSERT(!span.isEmpty()); | 306 SkASSERT(!span.isEmpty()); |
| 266 if (!fStrategy.maybeProcessSpan(span, fNext)) { | 307 if (!fStrategy.maybeProcessSpan(span, fNext)) { |
| 267 span_fallback(span, this); | 308 span_fallback(span, this); |
| 268 } | 309 } |
| 269 } | 310 } |
| 270 | 311 |
| 312 void bilerpSpan(BilerpSpan bSpan) override { | |
| 313 SkASSERT(!bSpan.isEmpty()); | |
| 314 if (!fStrategy.maybeProcessBilerpSpan(bSpan, fNext)) { | |
| 315 bilerp_span_fallback(bSpan, this); | |
| 316 } | |
| 317 } | |
| 318 | |
| 271 private: | 319 private: |
| 272 Next* const fNext; | 320 Next* const fNext; |
| 273 Strategy fStrategy; | 321 Strategy fStrategy; |
| 274 }; | 322 }; |
| 275 | 323 |
| 276 class TranslateMatrixStrategy { | 324 class TranslateMatrixStrategy { |
| 277 public: | 325 public: |
| 278 TranslateMatrixStrategy(SkVector offset) | 326 TranslateMatrixStrategy(SkVector offset) |
| 279 : fXOffset{X(offset)} | 327 : fXOffset{X(offset)} |
| 280 , fYOffset{Y(offset)} { } | 328 , fYOffset{Y(offset)} { } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 fNext->bilerpList(Sk4s{xs[0]} + kXOffsets, Sk4s{ys[0]} + kYOffsets); | 450 fNext->bilerpList(Sk4s{xs[0]} + kXOffsets, Sk4s{ys[0]} + kYOffsets); |
| 403 fNext->bilerpList(Sk4s{xs[1]} + kXOffsets, Sk4s{ys[1]} + kYOffsets); | 451 fNext->bilerpList(Sk4s{xs[1]} + kXOffsets, Sk4s{ys[1]} + kYOffsets); |
| 404 fNext->bilerpList(Sk4s{xs[2]} + kXOffsets, Sk4s{ys[2]} + kYOffsets); | 452 fNext->bilerpList(Sk4s{xs[2]} + kXOffsets, Sk4s{ys[2]} + kYOffsets); |
| 405 fNext->bilerpList(Sk4s{xs[3]} + kXOffsets, Sk4s{ys[3]} + kYOffsets); | 453 fNext->bilerpList(Sk4s{xs[3]} + kXOffsets, Sk4s{ys[3]} + kYOffsets); |
| 406 } | 454 } |
| 407 | 455 |
| 408 void pointSpan(Span span) override { | 456 void pointSpan(Span span) override { |
| 409 SkASSERT(!span.isEmpty()); | 457 SkASSERT(!span.isEmpty()); |
| 410 SkPoint start; SkScalar length; int count; | 458 SkPoint start; SkScalar length; int count; |
| 411 std::tie(start, length, count) = span; | 459 std::tie(start, length, count) = span; |
| 412 float dx = length / (count - 1); | 460 // Adjust the span so that it is in the correct phase with the pixel. |
| 413 | 461 BilerpSpan bSpan{X(start) - 0.5f, Y(start) - 0.5f, Y(start) + 0.5f, leng th, count}; |
| 414 Sk4f Xs = Sk4f{X(start)} + Sk4f{-0.5f, 0.5f, -0.5f, 0.5f}; | 462 fNext->bilerpSpan(bSpan); |
| 415 Sk4f Ys = Sk4f{Y(start)} + Sk4f{-0.5f, -0.5f, 0.5f, 0.5f}; | |
| 416 | |
| 417 Sk4f dXs{dx}; | |
| 418 while (count > 0) { | |
| 419 fNext->bilerpList(Xs, Ys); | |
| 420 Xs = Xs + dXs; | |
| 421 count -= 1; | |
| 422 } | |
| 423 } | 463 } |
| 424 | 464 |
| 425 private: | 465 private: |
| 426 Next* const fNext; | 466 Next* const fNext; |
| 427 }; | 467 }; |
| 428 | 468 |
| 429 static SkLinearBitmapPipeline::PointProcessorInterface* choose_filter( | 469 static SkLinearBitmapPipeline::PointProcessorInterface* choose_filter( |
| 430 SkLinearBitmapPipeline::BilerpProcessorInterface* next, | 470 SkLinearBitmapPipeline::BilerpProcessorInterface* next, |
| 431 SkFilterQuality filterQuailty, | 471 SkFilterQuality filterQuailty, |
| 432 SkLinearBitmapPipeline::FilterStage* filterProc) { | 472 SkLinearBitmapPipeline::FilterStage* filterProc) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 533 next->pointSpan(middle); | 573 next->pointSpan(middle); |
| 534 } | 574 } |
| 535 if (!span.isEmpty()) { | 575 if (!span.isEmpty()) { |
| 536 span.clampToSinglePixel({xMin, y}); | 576 span.clampToSinglePixel({xMin, y}); |
| 537 next->pointSpan(span); | 577 next->pointSpan(span); |
| 538 } | 578 } |
| 539 } | 579 } |
| 540 return true; | 580 return true; |
| 541 } | 581 } |
| 542 | 582 |
| 583 template <typename Next> | |
| 584 bool maybeProcessBilerpSpan(BilerpSpan bSpan, Next* next) { | |
| 585 return false; | |
| 586 } | |
| 587 | |
| 543 private: | 588 private: |
| 544 const Sk4s fXMin{SK_FloatNegativeInfinity}; | 589 const Sk4s fXMin{SK_FloatNegativeInfinity}; |
| 545 const Sk4s fYMin{SK_FloatNegativeInfinity}; | 590 const Sk4s fYMin{SK_FloatNegativeInfinity}; |
| 546 const Sk4s fXMax{SK_FloatInfinity}; | 591 const Sk4s fXMax{SK_FloatInfinity}; |
| 547 const Sk4s fYMax{SK_FloatInfinity}; | 592 const Sk4s fYMax{SK_FloatInfinity}; |
| 548 }; | 593 }; |
| 549 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface> | 594 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface> |
| 550 using Clamp = BilerpProcessor<ClampStrategy, Next>; | 595 using Clamp = BilerpProcessor<ClampStrategy, Next>; |
| 551 | 596 |
| 552 static SkScalar tile_mod(SkScalar x, SkScalar base) { | 597 static SkScalar tile_mod(SkScalar x, SkScalar base) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 636 } | 681 } |
| 637 | 682 |
| 638 // All on a single tile. | 683 // All on a single tile. |
| 639 if (!span.isEmpty()) { | 684 if (!span.isEmpty()) { |
| 640 next->pointSpan(span); | 685 next->pointSpan(span); |
| 641 } | 686 } |
| 642 | 687 |
| 643 return true; | 688 return true; |
| 644 } | 689 } |
| 645 | 690 |
| 691 template <typename Next> | |
| 692 bool maybeProcessBilerpSpan(BilerpSpan bSpan, Next* next) { | |
| 693 return false; | |
| 694 } | |
| 695 | |
| 646 private: | 696 private: |
| 647 const Sk4s fXMax{0.0f}; | 697 const Sk4s fXMax{0.0f}; |
| 648 const Sk4s fXInvMax{0.0f}; | 698 const Sk4s fXInvMax{0.0f}; |
| 649 const Sk4s fYMax{0.0f}; | 699 const Sk4s fYMax{0.0f}; |
| 650 const Sk4s fYInvMax{0.0f}; | 700 const Sk4s fYInvMax{0.0f}; |
| 651 }; | 701 }; |
| 652 | 702 |
| 653 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface> | 703 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface> |
| 654 using Repeat = BilerpProcessor<RepeatStrategy, Next>; | 704 using Repeat = BilerpProcessor<RepeatStrategy, Next>; |
| 655 | 705 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 825 Sk4f px00, px10, px01, px11; | 875 Sk4f px00, px10, px01, px11; |
| 826 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11); | 876 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11); |
| 827 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); | 877 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); |
| 828 fNext->placePixel(pixel); | 878 fNext->placePixel(pixel); |
| 829 } | 879 } |
| 830 | 880 |
| 831 void pointSpan(Span span) override { | 881 void pointSpan(Span span) override { |
| 832 span_fallback(span, this); | 882 span_fallback(span, this); |
| 833 } | 883 } |
| 834 | 884 |
| 885 void bilerpSpan(BilerpSpan span) override { | |
| 886 bilerp_span_fallback(span, this); | |
| 887 } | |
| 888 | |
| 835 private: | 889 private: |
| 836 SkLinearBitmapPipeline::PixelPlacerInterface* const fNext; | 890 SkLinearBitmapPipeline::PixelPlacerInterface* const fNext; |
| 837 SourceStrategy fStrategy; | 891 SourceStrategy fStrategy; |
| 838 }; | 892 }; |
| 839 | 893 |
| 840 using Pixel8888SRGB = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kRGBA>; | 894 using Pixel8888SRGB = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kRGBA>; |
| 841 using Pixel8888LRGB = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kRGBA>; | 895 using Pixel8888LRGB = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kRGBA>; |
| 842 using Pixel8888SBGR = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kBGRA>; | 896 using Pixel8888SBGR = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kBGRA>; |
| 843 using Pixel8888LBGR = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kBGRA>; | 897 using Pixel8888LBGR = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kBGRA>; |
| 844 | 898 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 941 | 995 |
| 942 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { | 996 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { |
| 943 SkASSERT(count > 0); | 997 SkASSERT(count > 0); |
| 944 fPixelStage->setDestination(dst); | 998 fPixelStage->setDestination(dst); |
| 945 // The count and length arguments start out in a precise relation in order t o keep the | 999 // The count and length arguments start out in a precise relation in order t o keep the |
| 946 // math correct through the different stages. Count is the number of pixel t o produce. | 1000 // math correct through the different stages. Count is the number of pixel t o produce. |
| 947 // Since the code samples at pixel centers, length is the distance from the center of the | 1001 // Since the code samples at pixel centers, length is the distance from the center of the |
| 948 // first pixel to the center of the last pixel. This implies that length is count-1. | 1002 // first pixel to the center of the last pixel. This implies that length is count-1. |
| 949 fFirstStage->pointSpan(Span{SkPoint{x + 0.5f, y + 0.5f}, count - 1.0f, count }); | 1003 fFirstStage->pointSpan(Span{SkPoint{x + 0.5f, y + 0.5f}, count - 1.0f, count }); |
| 950 } | 1004 } |
| OLD | NEW |