Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: src/core/SkLinearBitmapPipeline.cpp

Issue 1751943002: Introduce bilerp spans (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698