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

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

Issue 1711963003: Add point spans, but fall back for all cases. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments. Created 4 years, 10 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 | « src/core/SkLinearBitmapPipeline.h ('k') | tests/SkLinearBitmapPipelineTest.cpp » ('j') | 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
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 // If count == 1 use PointListFew instead.
40 SkASSERT(count > 1);
41
42 float dx = length / (count - 1);
43 Sk4f Xs = Sk4f(X(start)) + Sk4f{0.0f, 1.0f, 2.0f, 3.0f} * Sk4f{dx};
44 Sk4f Ys{Y(start)};
45 Sk4f fourDx = {4.0f * dx};
46
47 while (count >= 4) {
48 stage->pointList4(Xs, Ys);
49 Xs = Xs + fourDx;
50 count -= 4;
51 }
52 if (count > 0) {
53 stage->pointListFew(count, Xs, Ys);
54 }
55 }
56
37 template<typename Strategy, typename Next> 57 template<typename Strategy, typename Next>
38 class PointProcessor final : public PointProcessorInterface { 58 class PointProcessor final : public PointProcessorInterface {
39 public: 59 public:
40 template <typename... Args> 60 template <typename... Args>
41 PointProcessor(Next* next, Args&&... args) 61 PointProcessor(Next* next, Args&&... args)
42 : fNext{next} 62 : fNext{next}
43 , fStrategy{std::forward<Args>(args)...}{ } 63 , fStrategy{std::forward<Args>(args)...}{ }
44 64
45 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { 65 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
46 Sk4f newXs = xs; 66 Sk4f newXs = xs;
47 Sk4f newYs = ys; 67 Sk4f newYs = ys;
48 fStrategy.processPoints(&newXs, &newYs); 68 fStrategy.processPoints(&newXs, &newYs);
49 fNext->pointListFew(n, newXs, newYs); 69 fNext->pointListFew(n, newXs, newYs);
50 } 70 }
51 71
52 void pointList4(Sk4fArg xs, Sk4fArg ys) override { 72 void pointList4(Sk4fArg xs, Sk4fArg ys) override {
53 Sk4f newXs = xs; 73 Sk4f newXs = xs;
54 Sk4f newYs = ys; 74 Sk4f newYs = ys;
55 fStrategy.processPoints(&newXs, &newYs); 75 fStrategy.processPoints(&newXs, &newYs);
56 fNext->pointList4(newXs, newYs); 76 fNext->pointList4(newXs, newYs);
57 } 77 }
58 78
79 void pointSpan(SkPoint start, SkScalar length, int count) override {
80 span_fallback(start, length, count, this);
81 }
82
59 private: 83 private:
60 Next* const fNext; 84 Next* const fNext;
61 Strategy fStrategy; 85 Strategy fStrategy;
62 }; 86 };
63 87
64 template<typename Strategy, typename Next> 88 template<typename Strategy, typename Next>
65 class BilerpProcessor final : public BilerpProcessorInterface { 89 class BilerpProcessor final : public BilerpProcessorInterface {
66 public: 90 public:
67 template <typename... Args> 91 template <typename... Args>
68 BilerpProcessor(Next* next, Args&&... args) 92 BilerpProcessor(Next* next, Args&&... args)
(...skipping 14 matching lines...) Expand all
83 fNext->pointList4(newXs, newYs); 107 fNext->pointList4(newXs, newYs);
84 } 108 }
85 109
86 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { 110 void bilerpList(Sk4fArg xs, Sk4fArg ys) override {
87 Sk4f newXs = xs; 111 Sk4f newXs = xs;
88 Sk4f newYs = ys; 112 Sk4f newYs = ys;
89 fStrategy.processPoints(&newXs, &newYs); 113 fStrategy.processPoints(&newXs, &newYs);
90 fNext->bilerpList(newXs, newYs); 114 fNext->bilerpList(newXs, newYs);
91 } 115 }
92 116
117 void pointSpan(SkPoint start, SkScalar length, int count) override {
118 span_fallback(start, length, count, this);
119 }
120
93 private: 121 private:
94 Next* const fNext; 122 Next* const fNext;
95 Strategy fStrategy; 123 Strategy fStrategy;
96 }; 124 };
97 125
98 class SkippedStage final : public BilerpProcessorInterface { 126 class SkippedStage final : public BilerpProcessorInterface {
99 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { 127 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
100 SkFAIL("Skipped stage."); 128 SkFAIL("Skipped stage.");
101 } 129 }
102 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { 130 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override {
103 SkFAIL("Skipped stage."); 131 SkFAIL("Skipped stage.");
104 } 132 }
105 virtual void bilerpList(Sk4fArg xs, Sk4fArg ys) override { 133 void bilerpList(Sk4fArg xs, Sk4fArg ys) override {
134 SkFAIL("Skipped stage.");
135 }
136 void pointSpan(SkPoint start, SkScalar length, int count) override {
106 SkFAIL("Skipped stage."); 137 SkFAIL("Skipped stage.");
107 } 138 }
108 }; 139 };
109 140
110 class TranslateMatrixStrategy { 141 class TranslateMatrixStrategy {
111 public: 142 public:
112 TranslateMatrixStrategy(SkVector offset) 143 TranslateMatrixStrategy(SkVector offset)
113 : fXOffset{X(offset)} 144 : fXOffset{X(offset)}
114 , fYOffset{Y(offset)} { } 145 , fYOffset{Y(offset)} { }
115 void processPoints(Sk4f* xs, Sk4f* ys) { 146 void processPoints(Sk4f* xs, Sk4f* ys) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 void pointList4(Sk4fArg xs, Sk4fArg ys) override { 239 void pointList4(Sk4fArg xs, Sk4fArg ys) override {
209 // px00 px10 px01 px11 240 // px00 px10 px01 px11
210 const Sk4f kXOffsets{-0.5f, 0.5f, -0.5f, 0.5f}, 241 const Sk4f kXOffsets{-0.5f, 0.5f, -0.5f, 0.5f},
211 kYOffsets{-0.5f, -0.5f, 0.5f, 0.5f}; 242 kYOffsets{-0.5f, -0.5f, 0.5f, 0.5f};
212 fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYOffsets); 243 fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYOffsets);
213 fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYOffsets); 244 fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYOffsets);
214 fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYOffsets); 245 fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYOffsets);
215 fNext->bilerpList(Sk4f{xs[3]} + kXOffsets, Sk4f{ys[3]} + kYOffsets); 246 fNext->bilerpList(Sk4f{xs[3]} + kXOffsets, Sk4f{ys[3]} + kYOffsets);
216 } 247 }
217 248
249 void pointSpan(SkPoint start, SkScalar length, int count) override {
250 span_fallback(start, length, count, this);
251 }
252
218 private: 253 private:
219 Next* const fNext; 254 Next* const fNext;
220 }; 255 };
221 256
222 static PointProcessorInterface* choose_filter( 257 static PointProcessorInterface* choose_filter(
223 BilerpProcessorInterface* next, 258 BilerpProcessorInterface* next,
224 SkFilterQuality filterQuailty, 259 SkFilterQuality filterQuailty,
225 SkLinearBitmapPipeline::FilterStage* filterProc) { 260 SkLinearBitmapPipeline::FilterStage* filterProc) {
226 if (SkFilterQuality::kNone_SkFilterQuality == filterQuailty) { 261 if (SkFilterQuality::kNone_SkFilterQuality == filterQuailty) {
227 filterProc->Initialize<SkippedStage>(); 262 filterProc->Initialize<SkippedStage>();
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 fNext->place4Pixels(px0, px1, px2, px3); 483 fNext->place4Pixels(px0, px1, px2, px3);
449 } 484 }
450 485
451 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { 486 void bilerpList(Sk4fArg xs, Sk4fArg ys) override {
452 Sk4f px00, px10, px01, px11; 487 Sk4f px00, px10, px01, px11;
453 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11); 488 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11);
454 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); 489 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11);
455 fNext->placePixel(pixel); 490 fNext->placePixel(pixel);
456 } 491 }
457 492
493 void pointSpan(SkPoint start, SkScalar length, int count) override {
494 span_fallback(start, length, count, this);
495 }
496
458 private: 497 private:
459 PixelPlacerInterface* const fNext; 498 PixelPlacerInterface* const fNext;
460 SourceStrategy fStrategy; 499 SourceStrategy fStrategy;
461 }; 500 };
462 501
463 static BilerpProcessorInterface* choose_pixel_sampler( 502 static BilerpProcessorInterface* choose_pixel_sampler(
464 PixelPlacerInterface* next, 503 PixelPlacerInterface* next,
465 const SkPixmap& srcPixmap, 504 const SkPixmap& srcPixmap,
466 SkLinearBitmapPipeline::SampleStage* sampleStage) { 505 SkLinearBitmapPipeline::SampleStage* sampleStage) {
467 const SkImageInfo& imageInfo = srcPixmap.info(); 506 const SkImageInfo& imageInfo = srcPixmap.info();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 // identity matrix, the matrix stage is skipped, and the tilerStage is the f irst stage. 589 // 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); 590 auto placementStage = choose_pixel_placer(srcImageInfo.alphaType(), &fPixelS tage);
552 auto samplerStage = choose_pixel_sampler(placementStage, srcPixmap, &fSamp leStage); 591 auto samplerStage = choose_pixel_sampler(placementStage, srcPixmap, &fSamp leStage);
553 auto tilerStage = choose_tiler(samplerStage, size, xTile, yTile, &fTileX OrBothStage, 592 auto tilerStage = choose_tiler(samplerStage, size, xTile, yTile, &fTileX OrBothStage,
554 &fTileYStage); 593 &fTileYStage);
555 auto filterStage = choose_filter(tilerStage, filterQuality, &fFilterStage ); 594 auto filterStage = choose_filter(tilerStage, filterQuality, &fFilterStage );
556 fFirstStage = choose_matrix(filterStage, inverse, &fMatrixStage); 595 fFirstStage = choose_matrix(filterStage, inverse, &fMatrixStage);
557 } 596 }
558 597
559 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { 598 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) {
599 SkASSERT(count > 0);
560 fPixelStage->setDestination(dst); 600 fPixelStage->setDestination(dst);
561 601 // 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}; 602 if (count == 1) {
563 Sk4f Ys(y); 603 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f});
564 Sk4f fours{4.0f}; 604 } else {
565 605 // The count and length arguments start out in a precise relation in ord er to keep the
566 while (count >= 4) { 606 // math correct through the different stages. Count is the number of pix el to produce.
567 fFirstStage->pointList4(Xs, Ys); 607 // Since the code samples at pixel centers, length is the distance from the center of the
568 Xs = Xs + fours; 608 // first pixel to the center of the last pixel. This implies that length is count-1.
569 count -= 4; 609 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count);
570 }
571 if (count > 0) {
572 fFirstStage->pointListFew(count, Xs, Ys);
573 } 610 }
574 } 611 }
OLDNEW
« no previous file with comments | « src/core/SkLinearBitmapPipeline.h ('k') | tests/SkLinearBitmapPipelineTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698