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

Side by Side Diff: src/core/SkLinearBitmapPipeline_sample.h

Issue 2100323002: Reduce size of LinearBitmapPipeline (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Sync with new SK_VECTORCALL. Created 4 years, 5 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_core.h ('k') | 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 #ifndef SkLinearBitmapPipeline_sampler_DEFINED 8 #ifndef SkLinearBitmapPipeline_sampler_DEFINED
9 #define SkLinearBitmapPipeline_sampler_DEFINED 9 #define SkLinearBitmapPipeline_sampler_DEFINED
10 10
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 Sk4s fys = ys - ys.floor(); 46 Sk4s fys = ys - ys.floor();
47 Sk4s fxys{fxs * fys}; 47 Sk4s fxys{fxs * fys};
48 Sk4f sum = px11 * fxys; 48 Sk4f sum = px11 * fxys;
49 sum = sum + px01 * (fys - fxys); 49 sum = sum + px01 * (fys - fxys);
50 sum = sum + px10 * (fxs - fxys); 50 sum = sum + px10 * (fxs - fxys);
51 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys); 51 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys);
52 return sum; 52 return sum;
53 } 53 }
54 54
55 //////////////////////////////////////////////////////////////////////////////// //////////////////// 55 //////////////////////////////////////////////////////////////////////////////// ////////////////////
56 // PixelGetter is the lowest level interface to the source data. There is a Pixe lGetter for each 56 // PixelGetter is the lowest level interface to the source data. There is a Pixe lConverter for each
57 // of the different SkColorTypes. 57 // of the different SkColorTypes.
58 template <SkColorType, SkGammaType> class PixelGetter; 58 template <SkColorType, SkGammaType> class PixelConverter;
59 59
60 // Alpha handling: 60 // Alpha handling:
61 // The alpha from the paint (tintColor) is used in the blend part of the pipel ine to modulate 61 // The alpha from the paint (tintColor) is used in the blend part of the pipel ine to modulate
62 // the entire bitmap. So, the tint color is given an alpha of 1.0 so that the la ter alpha can 62 // the entire bitmap. So, the tint color is given an alpha of 1.0 so that the la ter alpha can
63 // modulate this color later. 63 // modulate this color later.
64 template <> 64 template <>
65 class PixelGetter<kAlpha_8_SkColorType, kLinear_SkGammaType> { 65 class PixelConverter<kAlpha_8_SkColorType, kLinear_SkGammaType> {
66 public: 66 public:
67 using Element = uint8_t; 67 using Element = uint8_t;
68 PixelGetter(const SkPixmap& srcPixmap, SkColor tintColor) 68 PixelConverter(const SkPixmap& srcPixmap, SkColor tintColor)
69 : fTintColor{set_alpha(Sk4f_from_SkColor(tintColor), 1.0f)} { } 69 : fTintColor{set_alpha(Sk4f_from_SkColor(tintColor), 1.0f)} { }
70 70
71 Sk4f getPixelAt(const uint8_t* src) { 71 Sk4f toSk4f(const Element pixel) const {
72 return fTintColor * (*src * (1.0f/255.0f)); 72 return fTintColor * (pixel * (1.0f/255.0f));
73 } 73 }
74 74
75 private: 75 private:
76 const Sk4f fTintColor; 76 const Sk4f fTintColor;
77 }; 77 };
78 78
79 template <SkGammaType gammaType> 79 template <SkGammaType gammaType>
80 class PixelGetter<kRGB_565_SkColorType, gammaType> { 80 class PixelConverter<kRGB_565_SkColorType, gammaType> {
81 public: 81 public:
82 using Element = uint16_t; 82 using Element = uint16_t;
83 PixelGetter(const SkPixmap& srcPixmap) { } 83 PixelConverter(const SkPixmap& srcPixmap) { }
84 84
85 Sk4f getPixelAt(const uint16_t* src) { 85 Sk4f toSk4f(Element pixel) const {
86 SkPMColor pixel = SkPixel16ToPixel32(*src); 86 SkPMColor pixel32 = SkPixel16ToPixel32(pixel);
87 return gammaType == kSRGB_SkGammaType
88 ? Sk4f_fromS32(pixel32)
89 : Sk4f_fromL32(pixel32);
90 }
91 };
92
93 template <SkGammaType gammaType>
94 class PixelConverter<kARGB_4444_SkColorType, gammaType> {
95 public:
96 using Element = uint16_t;
97 PixelConverter(const SkPixmap& srcPixmap) { }
98
99 Sk4f toSk4f(Element pixel) const {
100 SkPMColor pixel32 = SkPixel4444ToPixel32(pixel);
101 return gammaType == kSRGB_SkGammaType
102 ? Sk4f_fromS32(pixel32)
103 : Sk4f_fromL32(pixel32);
104 }
105 };
106
107 template <SkGammaType gammaType>
108 class PixelConverter<kRGBA_8888_SkColorType, gammaType> {
109 public:
110 using Element = uint32_t;
111 PixelConverter(const SkPixmap& srcPixmap) { }
112
113 Sk4f toSk4f(Element pixel) const {
87 return gammaType == kSRGB_SkGammaType 114 return gammaType == kSRGB_SkGammaType
88 ? Sk4f_fromS32(pixel) 115 ? Sk4f_fromS32(pixel)
89 : Sk4f_fromL32(pixel); 116 : Sk4f_fromL32(pixel);
90 } 117 }
91 }; 118 };
92 119
93 template <SkGammaType gammaType> 120 template <SkGammaType gammaType>
94 class PixelGetter<kARGB_4444_SkColorType, gammaType> { 121 class PixelConverter<kBGRA_8888_SkColorType, gammaType> {
95 public: 122 public:
96 using Element = uint16_t; 123 using Element = uint32_t;
97 PixelGetter(const SkPixmap& srcPixmap) { } 124 PixelConverter(const SkPixmap& srcPixmap) { }
98 125
99 Sk4f getPixelAt(const uint16_t* src) { 126 Sk4f toSk4f(Element pixel) const {
100 SkPMColor pixel = SkPixel4444ToPixel32(*src); 127 return swizzle_rb(
101 return gammaType == kSRGB_SkGammaType 128 gammaType == kSRGB_SkGammaType ? Sk4f_fromS32(pixel) : Sk4f_f romL32(pixel));
102 ? Sk4f_fromS32(pixel)
103 : Sk4f_fromL32(pixel);
104 } 129 }
105 }; 130 };
106 131
107 template <SkGammaType gammaType> 132 template <SkGammaType gammaType>
108 class PixelGetter<kRGBA_8888_SkColorType, gammaType> { 133 class PixelConverter<kIndex_8_SkColorType, gammaType> {
109 public:
110 using Element = uint32_t;
111 PixelGetter(const SkPixmap& srcPixmap) { }
112
113 Sk4f getPixelAt(const uint32_t* src) {
114 return gammaType == kSRGB_SkGammaType
115 ? Sk4f_fromS32(*src)
116 : Sk4f_fromL32(*src);
117 }
118 };
119
120 template <SkGammaType gammaType>
121 class PixelGetter<kBGRA_8888_SkColorType, gammaType> {
122 public:
123 using Element = uint32_t;
124 PixelGetter(const SkPixmap& srcPixmap) { }
125
126 Sk4f getPixelAt(const uint32_t* src) {
127 Sk4f pixel = gammaType == kSRGB_SkGammaType
128 ? Sk4f_fromS32(*src)
129 : Sk4f_fromL32(*src);
130 return swizzle_rb(pixel);
131 }
132 };
133
134 template <SkGammaType gammaType>
135 class PixelGetter<kIndex_8_SkColorType, gammaType> {
136 public: 134 public:
137 using Element = uint8_t; 135 using Element = uint8_t;
138 PixelGetter(const SkPixmap& srcPixmap) { 136 PixelConverter(const SkPixmap& srcPixmap) {
139 SkColorTable* skColorTable = srcPixmap.ctable(); 137 SkColorTable* skColorTable = srcPixmap.ctable();
140 SkASSERT(skColorTable != nullptr); 138 SkASSERT(skColorTable != nullptr);
141 139
142 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get()); 140 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
143 for (int i = 0; i < skColorTable->count(); i++) { 141 for (int i = 0; i < skColorTable->count(); i++) {
144 fColorTable[i] = this->convertPixel((*skColorTable)[i]); 142 fColorTable[i] = this->convertPixel((*skColorTable)[i]);
145 } 143 }
146 } 144 }
147 145
148 PixelGetter(const PixelGetter& strategy) { 146 PixelConverter(const PixelConverter& strategy) {
149 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get()); 147 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
150 // TODO: figure out the count. 148 // TODO: figure out the count.
151 for (int i = 0; i < 256; i++) { 149 for (int i = 0; i < 256; i++) {
152 fColorTable[i] = strategy.fColorTable[i]; 150 fColorTable[i] = strategy.fColorTable[i];
153 } 151 }
154 } 152 }
155 153
156 Sk4f getPixelAt(const uint8_t* src) { 154 Sk4f toSk4f(Element index) const {
157 return fColorTable[*src]; 155 return fColorTable[index];
158 } 156 }
159 157
160 private: 158 private:
161 static const size_t kColorTableSize = sizeof(Sk4f[256]) + 12; 159 static const size_t kColorTableSize = sizeof(Sk4f[256]) + 12;
162 Sk4f convertPixel(SkPMColor pmColor) { 160 Sk4f convertPixel(SkPMColor pmColor) {
163 Sk4f pixel = to_4f(pmColor); 161 Sk4f pixel = to_4f(pmColor);
164 float alpha = get_alpha(pixel); 162 float alpha = get_alpha(pixel);
165 if (alpha != 0.0f) { 163 if (alpha != 0.0f) {
166 float invAlpha = 1.0f / alpha; 164 float invAlpha = 1.0f / alpha;
167 Sk4f normalize = {invAlpha, invAlpha, invAlpha, 1.0f / 255.0f}; 165 Sk4f normalize = {invAlpha, invAlpha, invAlpha, 1.0f / 255.0f};
168 pixel = pixel * normalize; 166 pixel = pixel * normalize;
169 if (gammaType == kSRGB_SkGammaType) { 167 if (gammaType == kSRGB_SkGammaType) {
170 pixel = linear_to_srgb(pixel); 168 pixel = linear_to_srgb(pixel);
171 } 169 }
172 return pixel; 170 return pixel;
173 } else { 171 } else {
174 return Sk4f{0.0f}; 172 return Sk4f{0.0f};
175 } 173 }
176 } 174 }
177 SkAutoMalloc fColorTableStorage{kColorTableSize}; 175 SkAutoMalloc fColorTableStorage{kColorTableSize};
178 Sk4f* fColorTable; 176 Sk4f* fColorTable;
179 }; 177 };
180 178
181 template <SkGammaType gammaType> 179 template <SkGammaType gammaType>
182 class PixelGetter<kGray_8_SkColorType, gammaType> { 180 class PixelConverter<kGray_8_SkColorType, gammaType> {
183 public: 181 public:
184 using Element = uint8_t; 182 using Element = uint8_t;
185 PixelGetter(const SkPixmap& srcPixmap) { } 183 PixelConverter(const SkPixmap& srcPixmap) { }
186 184
187 Sk4f getPixelAt(const uint8_t* src) { 185 Sk4f toSk4f(Element pixel) const {
188 float gray = *src * (1.0f/255.0f); 186 float gray = pixel * (1.0f/255.0f);
189 Sk4f pixel = Sk4f{gray, gray, gray, 1.0f}; 187 Sk4f result = Sk4f{gray, gray, gray, 1.0f};
190 return gammaType == kSRGB_SkGammaType 188 return gammaType == kSRGB_SkGammaType
191 ? srgb_to_linear(pixel) 189 ? srgb_to_linear(result)
192 : pixel; 190 : result;
193 } 191 }
194 }; 192 };
195 193
196 template <> 194 template <>
197 class PixelGetter<kRGBA_F16_SkColorType, kLinear_SkGammaType> { 195 class PixelConverter<kRGBA_F16_SkColorType, kLinear_SkGammaType> {
198 public: 196 public:
199 using Element = uint64_t; 197 using Element = uint64_t;
200 PixelGetter(const SkPixmap& srcPixmap) { } 198 PixelConverter(const SkPixmap& srcPixmap) { }
201 199
202 Sk4f getPixelAt(const uint64_t* src) { 200 Sk4f toSk4f(const Element pixel) const {
203 return SkHalfToFloat_01(*src); 201 return SkHalfToFloat_01(pixel);
204 } 202 }
205 }; 203 };
206 204
205 class PixelAccessorShim {
206 public:
207 explicit PixelAccessorShim(SkLinearBitmapPipeline::PixelAccessorInterface* a ccessor)
208 : fPixelAccessor(accessor) { }
209
210 void SK_VECTORCALL getFewPixels(
211 int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) const {
212 fPixelAccessor->getFewPixels(n, xs, ys, px0, px1, px2);
213 }
214
215 void SK_VECTORCALL get4Pixels(
216 Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) const {
217 fPixelAccessor->get4Pixels(xs, ys, px0, px1, px2, px3);
218 }
219
220 void get4Pixels(
221 const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) const {
222 fPixelAccessor->get4Pixels(src, index, px0, px1, px2, px3);
223 };
224
225 Sk4f getPixelFromRow(const void* row, int index) const {
226 return fPixelAccessor->getPixelFromRow(row, index);
227 }
228
229 Sk4f getPixelAt(int index) const {
230 return fPixelAccessor->getPixelAt(index);
231 }
232
233 const void* row(int y) const {
234 return fPixelAccessor->row(y);
235 }
236
237 private:
238 SkLinearBitmapPipeline::PixelAccessorInterface* const fPixelAccessor;
239 };
240
207 //////////////////////////////////////////////////////////////////////////////// //////////////////// 241 //////////////////////////////////////////////////////////////////////////////// ////////////////////
208 // PixelAccessor handles all the same plumbing for all the PixelGetters. 242 // PixelAccessor handles all the same plumbing for all the PixelGetters.
209 template <SkColorType colorType, SkGammaType gammaType> 243 template <SkColorType colorType, SkGammaType gammaType>
210 class PixelAccessor { 244 class PixelAccessor final : public SkLinearBitmapPipeline::PixelAccessorInterfac e {
211 using Element = typename PixelGetter<colorType, gammaType>::Element; 245 using Element = typename PixelConverter<colorType, gammaType>::Element;
212 public: 246 public:
213 template <typename... Args> 247 template <typename... Args>
214 PixelAccessor(const SkPixmap& srcPixmap, Args&&... args) 248 PixelAccessor(const SkPixmap& srcPixmap, Args&&... args)
215 : fSrc{static_cast<const Element*>(srcPixmap.addr())} 249 : fSrc{static_cast<const Element*>(srcPixmap.addr())}
216 , fWidth{srcPixmap.rowBytesAsPixels()} 250 , fWidth{srcPixmap.rowBytesAsPixels()}
217 , fGetter{srcPixmap, std::move<Args>(args)...} { } 251 , fConverter{srcPixmap, std::move<Args>(args)...} { }
218 252
219 void SK_VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px 1, Sk4f* px2) { 253 void SK_VECTORCALL getFewPixels (
254 int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) const override {
220 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); 255 Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
221 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); 256 Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
222 Sk4i bufferLoc = YIs * fWidth + XIs; 257 Sk4i bufferLoc = YIs * fWidth + XIs;
223 switch (n) { 258 switch (n) {
224 case 3: 259 case 3:
225 *px2 = this->getPixelAt(bufferLoc[2]); 260 *px2 = this->getPixelAt(bufferLoc[2]);
226 case 2: 261 case 2:
227 *px1 = this->getPixelAt(bufferLoc[1]); 262 *px1 = this->getPixelAt(bufferLoc[1]);
228 case 1: 263 case 1:
229 *px0 = this->getPixelAt(bufferLoc[0]); 264 *px0 = this->getPixelAt(bufferLoc[0]);
230 default: 265 default:
231 break; 266 break;
232 } 267 }
233 } 268 }
234 269
235 void SK_VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) { 270 void SK_VECTORCALL get4Pixels(
271 Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) const over ride {
236 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); 272 Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
237 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); 273 Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
238 Sk4i bufferLoc = YIs * fWidth + XIs; 274 Sk4i bufferLoc = YIs * fWidth + XIs;
239 *px0 = this->getPixelAt(bufferLoc[0]); 275 *px0 = this->getPixelAt(bufferLoc[0]);
240 *px1 = this->getPixelAt(bufferLoc[1]); 276 *px1 = this->getPixelAt(bufferLoc[1]);
241 *px2 = this->getPixelAt(bufferLoc[2]); 277 *px2 = this->getPixelAt(bufferLoc[2]);
242 *px3 = this->getPixelAt(bufferLoc[3]); 278 *px3 = this->getPixelAt(bufferLoc[3]);
243 } 279 }
244 280
245 void get4Pixels(const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) { 281 void get4Pixels(
282 const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) const override {
246 *px0 = this->getPixelFromRow(src, index + 0); 283 *px0 = this->getPixelFromRow(src, index + 0);
247 *px1 = this->getPixelFromRow(src, index + 1); 284 *px1 = this->getPixelFromRow(src, index + 1);
248 *px2 = this->getPixelFromRow(src, index + 2); 285 *px2 = this->getPixelFromRow(src, index + 2);
249 *px3 = this->getPixelFromRow(src, index + 3); 286 *px3 = this->getPixelFromRow(src, index + 3);
250 } 287 }
251 288
252 Sk4f getPixelFromRow(const void* row, int index) { 289 Sk4f getPixelFromRow(const void* row, int index) const override {
253 const Element* src = static_cast<const Element*>(row); 290 const Element* src = static_cast<const Element*>(row);
254 return fGetter.getPixelAt(src + index); 291 return fConverter.toSk4f(src[index]);
255 } 292 }
256 293
257 Sk4f getPixelAt(int index) { 294 Sk4f getPixelAt(int index) const override {
258 return this->getPixelFromRow(fSrc, index); 295 return this->getPixelFromRow(fSrc, index);
259 } 296 }
260 297
261 const void* row(int y) const { return fSrc + y * fWidth[0]; } 298 const void* row(int y) const override { return fSrc + y * fWidth; }
262 299
263 private: 300 private:
264 const Element* const fSrc; 301 const Element* const fSrc;
265 const Sk4i fWidth; 302 const int fWidth;
266 PixelGetter<colorType, gammaType> fGetter; 303 PixelConverter<colorType, gammaType> fConverter;
267 }; 304 };
268 305
269 // We're moving through source space at a rate of 1 source pixel per 1 dst pixel . 306 // We're moving through source space at a rate of 1 source pixel per 1 dst pixel .
270 // We'll never re-use pixels, but we can at least load contiguous pixels. 307 // We'll never re-use pixels, but we can at least load contiguous pixels.
271 template <typename Next, typename Strategy> 308 template <typename Next, typename Strategy>
272 static void src_strategy_blend(Span span, Next* next, Strategy* strategy) { 309 static void src_strategy_blend(Span span, Next* next, Strategy* strategy) {
273 SkPoint start; 310 SkPoint start;
274 SkScalar length; 311 SkScalar length;
275 int count; 312 int count;
276 std::tie(start, length, count) = span; 313 std::tie(start, length, count) = span;
(...skipping 24 matching lines...) Expand all
301 338
302 while (count > 0) { 339 while (count > 0) {
303 next->blendPixel(strategy->getPixelFromRow(row, ix)); 340 next->blendPixel(strategy->getPixelFromRow(row, ix));
304 ix -= 1; 341 ix -= 1;
305 count -= 1; 342 count -= 1;
306 } 343 }
307 } 344 }
308 } 345 }
309 346
310 // NearestNeighborSampler - use nearest neighbor filtering to create runs of des tination pixels. 347 // NearestNeighborSampler - use nearest neighbor filtering to create runs of des tination pixels.
311 template<SkColorType colorType, SkGammaType gammaType, typename Next> 348 template<typename Accessor, typename Next>
312 class NearestNeighborSampler : public SkLinearBitmapPipeline::SampleProcessorInt erface { 349 class NearestNeighborSampler : public SkLinearBitmapPipeline::SampleProcessorInt erface {
313 public: 350 public:
314 template<typename... Args> 351 template<typename... Args>
315 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next , Args&& ... args) 352 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next , Args&& ... args)
316 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } 353 : fNext{next}, fAccessor{std::forward<Args>(args)...} { }
317 354
318 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next , 355 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next ,
319 const NearestNeighborSampler& sampler) 356 const NearestNeighborSampler& sampler)
320 : fNext{next}, fStrategy{sampler.fStrategy} { } 357 : fNext{next}, fAccessor{sampler.fAccessor} { }
321 358
322 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { 359 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
323 SkASSERT(0 < n && n < 4); 360 SkASSERT(0 < n && n < 4);
324 Sk4f px0, px1, px2; 361 Sk4f px0, px1, px2;
325 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); 362 fAccessor.getFewPixels(n, xs, ys, &px0, &px1, &px2);
326 if (n >= 1) fNext->blendPixel(px0); 363 if (n >= 1) fNext->blendPixel(px0);
327 if (n >= 2) fNext->blendPixel(px1); 364 if (n >= 2) fNext->blendPixel(px1);
328 if (n >= 3) fNext->blendPixel(px2); 365 if (n >= 3) fNext->blendPixel(px2);
329 } 366 }
330 367
331 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { 368 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
332 Sk4f px0, px1, px2, px3; 369 Sk4f px0, px1, px2, px3;
333 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); 370 fAccessor.get4Pixels(xs, ys, &px0, &px1, &px2, &px3);
334 fNext->blend4Pixels(px0, px1, px2, px3); 371 fNext->blend4Pixels(px0, px1, px2, px3);
335 } 372 }
336 373
337 void pointSpan(Span span) override { 374 void pointSpan(Span span) override {
338 SkASSERT(!span.isEmpty()); 375 SkASSERT(!span.isEmpty());
339 SkPoint start; 376 SkPoint start;
340 SkScalar length; 377 SkScalar length;
341 int count; 378 int count;
342 std::tie(start, length, count) = span; 379 std::tie(start, length, count) = span;
343 SkScalar absLength = SkScalarAbs(length); 380 SkScalar absLength = SkScalarAbs(length);
344 if (absLength < (count - 1)) { 381 if (absLength < (count - 1)) {
345 this->spanSlowRate(span); 382 this->spanSlowRate(span);
346 } else if (absLength == (count - 1)) { 383 } else if (absLength == (count - 1)) {
347 src_strategy_blend(span, fNext, &fStrategy); 384 src_strategy_blend(span, fNext, &fAccessor);
348 } else { 385 } else {
349 this->spanFastRate(span); 386 this->spanFastRate(span);
350 } 387 }
351 } 388 }
352 389
353 void repeatSpan(Span span, int32_t repeatCount) override { 390 void repeatSpan(Span span, int32_t repeatCount) override {
354 while (repeatCount > 0) { 391 while (repeatCount > 0) {
355 this->pointSpan(span); 392 this->pointSpan(span);
356 repeatCount--; 393 repeatCount--;
357 } 394 }
(...skipping 13 matching lines...) Expand all
371 void spanSlowRate(Span span) { 408 void spanSlowRate(Span span) {
372 SkPoint start; 409 SkPoint start;
373 SkScalar length; 410 SkScalar length;
374 int count; 411 int count;
375 std::tie(start, length, count) = span; 412 std::tie(start, length, count) = span;
376 SkScalar x = X(start); 413 SkScalar x = X(start);
377 SkFixed fx = SkScalarToFixed(x); 414 SkFixed fx = SkScalarToFixed(x);
378 SkScalar dx = length / (count - 1); 415 SkScalar dx = length / (count - 1);
379 SkFixed fdx = SkScalarToFixed(dx); 416 SkFixed fdx = SkScalarToFixed(dx);
380 417
381 const void* row = fStrategy.row((int)std::floor(Y(start))); 418 const void* row = fAccessor.row((int)std::floor(Y(start)));
382 Next* next = fNext; 419 Next* next = fNext;
383 420
384 int ix = SkFixedFloorToInt(fx); 421 int ix = SkFixedFloorToInt(fx);
385 int prevIX = ix; 422 int prevIX = ix;
386 Sk4f fpixel = fStrategy.getPixelFromRow(row, ix); 423 Sk4f fpixel = fAccessor.getPixelFromRow(row, ix);
387 424
388 // When dx is less than one, each pixel is used more than once. Using th e fixed point fx 425 // When dx is less than one, each pixel is used more than once. Using th e fixed point fx
389 // allows the code to quickly check that the same pixel is being used. T he code uses this 426 // allows the code to quickly check that the same pixel is being used. T he code uses this
390 // same pixel check to do the sRGB and normalization only once. 427 // same pixel check to do the sRGB and normalization only once.
391 auto getNextPixel = [&]() { 428 auto getNextPixel = [&]() {
392 if (ix != prevIX) { 429 if (ix != prevIX) {
393 fpixel = fStrategy.getPixelFromRow(row, ix); 430 fpixel = fAccessor.getPixelFromRow(row, ix);
394 prevIX = ix; 431 prevIX = ix;
395 } 432 }
396 fx += fdx; 433 fx += fdx;
397 ix = SkFixedFloorToInt(fx); 434 ix = SkFixedFloorToInt(fx);
398 return fpixel; 435 return fpixel;
399 }; 436 };
400 437
401 while (count >= 4) { 438 while (count >= 4) {
402 Sk4f px0 = getNextPixel(); 439 Sk4f px0 = getNextPixel();
403 Sk4f px1 = getNextPixel(); 440 Sk4f px1 = getNextPixel();
404 Sk4f px2 = getNextPixel(); 441 Sk4f px2 = getNextPixel();
405 Sk4f px3 = getNextPixel(); 442 Sk4f px3 = getNextPixel();
406 next->blend4Pixels(px0, px1, px2, px3); 443 next->blend4Pixels(px0, px1, px2, px3);
407 count -= 4; 444 count -= 4;
408 } 445 }
409 while (count > 0) { 446 while (count > 0) {
410 next->blendPixel(getNextPixel()); 447 next->blendPixel(getNextPixel());
411 count -= 1; 448 count -= 1;
412 } 449 }
413 } 450 }
414 451
415 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel. 452 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel.
416 // We'll never re-use pixels, but we can at least load contiguous pixels. 453 // We'll never re-use pixels, but we can at least load contiguous pixels.
417 void spanUnitRate(Span span) { 454 void spanUnitRate(Span span) {
418 src_strategy_blend(span, fNext, &fStrategy); 455 src_strategy_blend(span, fNext, &fAccessor);
419 } 456 }
420 457
421 // We're moving through source space faster than dst (zoomed out), 458 // We're moving through source space faster than dst (zoomed out),
422 // so we'll never reuse a source pixel or be able to do contiguous loads. 459 // so we'll never reuse a source pixel or be able to do contiguous loads.
423 void spanFastRate(Span span) { 460 void spanFastRate(Span span) {
424 span_fallback(span, this); 461 span_fallback(span, this);
425 } 462 }
426 463
427 Next* const fNext; 464 Next* const fNext;
428 PixelAccessor<colorType, gammaType> fStrategy; 465 Accessor fAccessor;
429 }; 466 };
430 467
431 // -- BilerpSampler ------------------------------------------------------------ -------------------- 468 // -- BilerpSampler ------------------------------------------------------------ --------------------
432 // BilerpSampler - use a bilerp filter to create runs of destination pixels. 469 // BilerpSampler - use a bilerp filter to create runs of destination pixels.
433 template<SkColorType colorType, SkGammaType gammaType, typename Next> 470 template<typename Accessor, typename Next>
434 class BilerpSampler : public SkLinearBitmapPipeline::SampleProcessorInterface { 471 class BilerpSampler : public SkLinearBitmapPipeline::SampleProcessorInterface {
435 public: 472 public:
436 template<typename... Args> 473 template<typename... Args>
437 BilerpSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&& ... args) 474 BilerpSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&& ... args)
438 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } 475 : fNext{next}, fAccessor{std::forward<Args>(args)...} { }
439 476
440 BilerpSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, 477 BilerpSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next,
441 const BilerpSampler& sampler) 478 const BilerpSampler& sampler)
442 : fNext{next}, fStrategy{sampler.fStrategy} { } 479 : fNext{next}, fAccessor{sampler.fAccessor} { }
443 480
444 Sk4f bilerpNonEdgePixel(SkScalar x, SkScalar y) { 481 Sk4f bilerpNonEdgePixel(SkScalar x, SkScalar y) {
445 Sk4f px00, px10, px01, px11; 482 Sk4f px00, px10, px01, px11;
446 483
447 // bilerp4() expects xs, ys are the top-lefts of the 2x2 kernel. 484 // bilerp4() expects xs, ys are the top-lefts of the 2x2 kernel.
448 Sk4f xs = Sk4f{x} - 0.5f; 485 Sk4f xs = Sk4f{x} - 0.5f;
449 Sk4f ys = Sk4f{y} - 0.5f; 486 Sk4f ys = Sk4f{y} - 0.5f;
450 Sk4f sampleXs = xs + Sk4f{0.0f, 1.0f, 0.0f, 1.0f}; 487 Sk4f sampleXs = xs + Sk4f{0.0f, 1.0f, 0.0f, 1.0f};
451 Sk4f sampleYs = ys + Sk4f{0.0f, 0.0f, 1.0f, 1.0f}; 488 Sk4f sampleYs = ys + Sk4f{0.0f, 0.0f, 1.0f, 1.0f};
452 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); 489 fAccessor.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11);
453 return bilerp4(xs, ys, px00, px10, px01, px11); 490 return bilerp4(xs, ys, px00, px10, px01, px11);
454 } 491 }
455 492
456 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { 493 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
457 SkASSERT(0 < n && n < 4); 494 SkASSERT(0 < n && n < 4);
458 auto bilerpPixel = [&](int index) { 495 auto bilerpPixel = [&](int index) {
459 return this->bilerpNonEdgePixel(xs[index], ys[index]); 496 return this->bilerpNonEdgePixel(xs[index], ys[index]);
460 }; 497 };
461 498
462 if (n >= 1) fNext->blendPixel(bilerpPixel(0)); 499 if (n >= 1) fNext->blendPixel(bilerpPixel(0));
(...skipping 16 matching lines...) Expand all
479 while (repeatCount > 0) { 516 while (repeatCount > 0) {
480 this->pointSpan(span); 517 this->pointSpan(span);
481 repeatCount--; 518 repeatCount--;
482 } 519 }
483 } 520 }
484 521
485 void SK_VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) override { 522 void SK_VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) override {
486 Sk4f px00, px10, px01, px11; 523 Sk4f px00, px10, px01, px11;
487 Sk4f xs = Sk4f{sampleXs[0]}; 524 Sk4f xs = Sk4f{sampleXs[0]};
488 Sk4f ys = Sk4f{sampleYs[0]}; 525 Sk4f ys = Sk4f{sampleYs[0]};
489 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); 526 fAccessor.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11);
490 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); 527 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11);
491 fNext->blendPixel(pixel); 528 fNext->blendPixel(pixel);
492 } 529 }
493 530
494 void bilerpSpan(Span span, SkScalar y) override { 531 void bilerpSpan(Span span, SkScalar y) override {
495 SkASSERT(!span.isEmpty()); 532 SkASSERT(!span.isEmpty());
496 SkPoint start; 533 SkPoint start;
497 SkScalar length; 534 SkScalar length;
498 int count; 535 int count;
499 std::tie(start, length, count) = span; 536 std::tie(start, length, count) = span;
500 SkScalar absLength = SkScalarAbs(length); 537 SkScalar absLength = SkScalarAbs(length);
501 if (absLength == 0.0f) { 538 if (absLength == 0.0f) {
502 this->spanZeroRate(span, y); 539 this->spanZeroRate(span, y);
503 } else if (absLength < (count - 1)) { 540 } else if (absLength < (count - 1)) {
504 this->spanSlowRate(span, y); 541 this->spanSlowRate(span, y);
505 } else if (absLength == (count - 1)) { 542 } else if (absLength == (count - 1)) {
506 if (std::fmod(span.startX() - 0.5f, 1.0f) == 0.0f) { 543 if (std::fmod(span.startX() - 0.5f, 1.0f) == 0.0f) {
507 if (std::fmod(span.startY() - 0.5f, 1.0f) == 0.0f) { 544 if (std::fmod(span.startY() - 0.5f, 1.0f) == 0.0f) {
508 src_strategy_blend(span, fNext, &fStrategy); 545 src_strategy_blend(span, fNext, &fAccessor);
509 } else { 546 } else {
510 this->spanUnitRateAlignedX(span, y); 547 this->spanUnitRateAlignedX(span, y);
511 } 548 }
512 } else { 549 } else {
513 this->spanUnitRate(span, y); 550 this->spanUnitRate(span, y);
514 } 551 }
515 } else { 552 } else {
516 this->spanFastRate(span, y); 553 this->spanFastRate(span, y);
517 } 554 }
518 } 555 }
519 556
520 private: 557 private:
521 void spanZeroRate(Span span, SkScalar y1) { 558 void spanZeroRate(Span span, SkScalar y1) {
522 SkScalar y0 = span.startY() - 0.5f; 559 SkScalar y0 = span.startY() - 0.5f;
523 y1 += 0.5f; 560 y1 += 0.5f;
524 int iy0 = SkScalarFloorToInt(y0); 561 int iy0 = SkScalarFloorToInt(y0);
525 SkScalar filterY1 = y0 - iy0; 562 SkScalar filterY1 = y0 - iy0;
526 SkScalar filterY0 = 1.0f - filterY1; 563 SkScalar filterY0 = 1.0f - filterY1;
527 int iy1 = SkScalarFloorToInt(y1); 564 int iy1 = SkScalarFloorToInt(y1);
528 int ix = SkScalarFloorToInt(span.startX()); 565 int ix = SkScalarFloorToInt(span.startX());
529 Sk4f pixelY0 = fStrategy.getPixelFromRow(fStrategy.row(iy0), ix); 566 Sk4f pixelY0 = fAccessor.getPixelFromRow(fAccessor.row(iy0), ix);
530 Sk4f pixelY1 = fStrategy.getPixelFromRow(fStrategy.row(iy1), ix); 567 Sk4f pixelY1 = fAccessor.getPixelFromRow(fAccessor.row(iy1), ix);
531 Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1; 568 Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1;
532 int count = span.count(); 569 int count = span.count();
533 while (count >= 4) { 570 while (count >= 4) {
534 fNext->blend4Pixels(filterPixel, filterPixel, filterPixel, filterPix el); 571 fNext->blend4Pixels(filterPixel, filterPixel, filterPixel, filterPix el);
535 count -= 4; 572 count -= 4;
536 } 573 }
537 while (count > 0) { 574 while (count > 0) {
538 fNext->blendPixel(filterPixel); 575 fNext->blendPixel(filterPixel);
539 count -= 1; 576 count -= 1;
540 } 577 }
(...skipping 18 matching lines...) Expand all
559 } 596 }
560 int ix = SkFixedFloorToInt(fx); 597 int ix = SkFixedFloorToInt(fx);
561 int ioldx = ix; 598 int ioldx = ix;
562 Sk4f x{SkFixedToScalar(fx) - ix}; 599 Sk4f x{SkFixedToScalar(fx) - ix};
563 Sk4f dx{SkFixedToScalar(fdx)}; 600 Sk4f dx{SkFixedToScalar(fdx)};
564 SkScalar ry0 = Y(start) - 0.5f; 601 SkScalar ry0 = Y(start) - 0.5f;
565 ry1 += 0.5f; 602 ry1 += 0.5f;
566 SkScalar yFloor = std::floor(ry0); 603 SkScalar yFloor = std::floor(ry0);
567 Sk4f y1 = Sk4f{ry0 - yFloor}; 604 Sk4f y1 = Sk4f{ry0 - yFloor};
568 Sk4f y0 = Sk4f{1.0f} - y1; 605 Sk4f y0 = Sk4f{1.0f} - y1;
569 const void* const row0 = fStrategy.row(SkScalarFloorToInt(ry0)); 606 const void* const row0 = fAccessor.row(SkScalarFloorToInt(ry0));
570 const void* const row1 = fStrategy.row(SkScalarFloorToInt(ry1)); 607 const void* const row1 = fAccessor.row(SkScalarFloorToInt(ry1));
571 Sk4f fpixel00 = y0 * fStrategy.getPixelFromRow(row0, ix); 608 Sk4f fpixel00 = y0 * fAccessor.getPixelFromRow(row0, ix);
572 Sk4f fpixel01 = y1 * fStrategy.getPixelFromRow(row1, ix); 609 Sk4f fpixel01 = y1 * fAccessor.getPixelFromRow(row1, ix);
573 Sk4f fpixel10 = y0 * fStrategy.getPixelFromRow(row0, ix + 1); 610 Sk4f fpixel10 = y0 * fAccessor.getPixelFromRow(row0, ix + 1);
574 Sk4f fpixel11 = y1 * fStrategy.getPixelFromRow(row1, ix + 1); 611 Sk4f fpixel11 = y1 * fAccessor.getPixelFromRow(row1, ix + 1);
575 auto getNextPixel = [&]() { 612 auto getNextPixel = [&]() {
576 if (ix != ioldx) { 613 if (ix != ioldx) {
577 fpixel00 = fpixel10; 614 fpixel00 = fpixel10;
578 fpixel01 = fpixel11; 615 fpixel01 = fpixel11;
579 fpixel10 = y0 * fStrategy.getPixelFromRow(row0, ix + 1); 616 fpixel10 = y0 * fAccessor.getPixelFromRow(row0, ix + 1);
580 fpixel11 = y1 * fStrategy.getPixelFromRow(row1, ix + 1); 617 fpixel11 = y1 * fAccessor.getPixelFromRow(row1, ix + 1);
581 ioldx = ix; 618 ioldx = ix;
582 x = x + xAdjust; 619 x = x + xAdjust;
583 } 620 }
584 621
585 Sk4f x0, x1; 622 Sk4f x0, x1;
586 x0 = Sk4f{1.0f} - x; 623 x0 = Sk4f{1.0f} - x;
587 x1 = x; 624 x1 = x;
588 Sk4f fpixel = x0 * (fpixel00 + fpixel01) + x1 * (fpixel10 + fpixel11 ); 625 Sk4f fpixel = x0 * (fpixel00 + fpixel01) + x1 * (fpixel10 + fpixel11 );
589 fx += fdx; 626 fx += fdx;
590 ix = SkFixedFloorToInt(fx); 627 ix = SkFixedFloorToInt(fx);
(...skipping 20 matching lines...) Expand all
611 648
612 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel. 649 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel.
613 // We'll never re-use pixels, but we can at least load contiguous pixels. 650 // We'll never re-use pixels, but we can at least load contiguous pixels.
614 void spanUnitRate(Span span, SkScalar y1) { 651 void spanUnitRate(Span span, SkScalar y1) {
615 y1 += 0.5f; 652 y1 += 0.5f;
616 SkScalar y0 = span.startY() - 0.5f; 653 SkScalar y0 = span.startY() - 0.5f;
617 int iy0 = SkScalarFloorToInt(y0); 654 int iy0 = SkScalarFloorToInt(y0);
618 SkScalar filterY1 = y0 - iy0; 655 SkScalar filterY1 = y0 - iy0;
619 SkScalar filterY0 = 1.0f - filterY1; 656 SkScalar filterY0 = 1.0f - filterY1;
620 int iy1 = SkScalarFloorToInt(y1); 657 int iy1 = SkScalarFloorToInt(y1);
621 const void* rowY0 = fStrategy.row(iy0); 658 const void* rowY0 = fAccessor.row(iy0);
622 const void* rowY1 = fStrategy.row(iy1); 659 const void* rowY1 = fAccessor.row(iy1);
623 SkScalar x0 = span.startX() - 0.5f; 660 SkScalar x0 = span.startX() - 0.5f;
624 int ix0 = SkScalarFloorToInt(x0); 661 int ix0 = SkScalarFloorToInt(x0);
625 SkScalar filterX1 = x0 - ix0; 662 SkScalar filterX1 = x0 - ix0;
626 SkScalar filterX0 = 1.0f - filterX1; 663 SkScalar filterX0 = 1.0f - filterX1;
627 664
628 auto getPixelY0 = [&]() { 665 auto getPixelY0 = [&]() {
629 Sk4f px = fStrategy.getPixelFromRow(rowY0, ix0); 666 Sk4f px = fAccessor.getPixelFromRow(rowY0, ix0);
630 return px * filterY0; 667 return px * filterY0;
631 }; 668 };
632 669
633 auto getPixelY1 = [&]() { 670 auto getPixelY1 = [&]() {
634 Sk4f px = fStrategy.getPixelFromRow(rowY1, ix0); 671 Sk4f px = fAccessor.getPixelFromRow(rowY1, ix0);
635 return px * filterY1; 672 return px * filterY1;
636 }; 673 };
637 674
638 auto get4PixelsY0 = [&](int ix, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* p x3) { 675 auto get4PixelsY0 = [&](int ix, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* p x3) {
639 fStrategy.get4Pixels(rowY0, ix, px0, px1, px2, px3); 676 fAccessor.get4Pixels(rowY0, ix, px0, px1, px2, px3);
640 *px0 = *px0 * filterY0; 677 *px0 = *px0 * filterY0;
641 *px1 = *px1 * filterY0; 678 *px1 = *px1 * filterY0;
642 *px2 = *px2 * filterY0; 679 *px2 = *px2 * filterY0;
643 *px3 = *px3 * filterY0; 680 *px3 = *px3 * filterY0;
644 }; 681 };
645 682
646 auto get4PixelsY1 = [&](int ix, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* p x3) { 683 auto get4PixelsY1 = [&](int ix, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* p x3) {
647 fStrategy.get4Pixels(rowY1, ix, px0, px1, px2, px3); 684 fAccessor.get4Pixels(rowY1, ix, px0, px1, px2, px3);
648 *px0 = *px0 * filterY1; 685 *px0 = *px0 * filterY1;
649 *px1 = *px1 * filterY1; 686 *px1 = *px1 * filterY1;
650 *px2 = *px2 * filterY1; 687 *px2 = *px2 * filterY1;
651 *px3 = *px3 * filterY1; 688 *px3 = *px3 * filterY1;
652 }; 689 };
653 690
654 auto lerp = [&](Sk4f& pixelX0, Sk4f& pixelX1) { 691 auto lerp = [&](Sk4f& pixelX0, Sk4f& pixelX1) {
655 return pixelX0 * filterX0 + pixelX1 * filterX1; 692 return pixelX0 * filterX0 + pixelX1 * filterX1;
656 }; 693 };
657 694
(...skipping 13 matching lines...) Expand all
671 Sk4f pxS2 = px20 + px21; 708 Sk4f pxS2 = px20 + px21;
672 Sk4f px2 = lerp(pxS1, pxS2); 709 Sk4f px2 = lerp(pxS1, pxS2);
673 Sk4f pxS3 = px30 + px31; 710 Sk4f pxS3 = px30 + px31;
674 Sk4f px3 = lerp(pxS2, pxS3); 711 Sk4f px3 = lerp(pxS2, pxS3);
675 pxB = pxS3; 712 pxB = pxS3;
676 fNext->blend4Pixels(px0, px1, px2, px3); 713 fNext->blend4Pixels(px0, px1, px2, px3);
677 ix0 += 4; 714 ix0 += 4;
678 count -= 4; 715 count -= 4;
679 } 716 }
680 while (count > 0) { 717 while (count > 0) {
681 Sk4f pixelY0 = fStrategy.getPixelFromRow(rowY0, ix0); 718 Sk4f pixelY0 = fAccessor.getPixelFromRow(rowY0, ix0);
682 Sk4f pixelY1 = fStrategy.getPixelFromRow(rowY1, ix0); 719 Sk4f pixelY1 = fAccessor.getPixelFromRow(rowY1, ix0);
683 720
684 fNext->blendPixel(lerp(pixelY0, pixelY1)); 721 fNext->blendPixel(lerp(pixelY0, pixelY1));
685 ix0 += 1; 722 ix0 += 1;
686 count -= 1; 723 count -= 1;
687 } 724 }
688 } else { 725 } else {
689 int count = span.count(); 726 int count = span.count();
690 while (count >= 4) { 727 while (count >= 4) {
691 Sk4f px00, px10, px20, px30; 728 Sk4f px00, px10, px20, px30;
692 get4PixelsY0(ix0 - 3, &px00, &px10, &px20, &px30); 729 get4PixelsY0(ix0 - 3, &px00, &px10, &px20, &px30);
693 Sk4f px01, px11, px21, px31; 730 Sk4f px01, px11, px21, px31;
694 get4PixelsY1(ix0 - 3, &px01, &px11, &px21, &px31); 731 get4PixelsY1(ix0 - 3, &px01, &px11, &px21, &px31);
695 Sk4f pxS3 = px30 + px31; 732 Sk4f pxS3 = px30 + px31;
696 Sk4f px0 = lerp(pxS3, pxB); 733 Sk4f px0 = lerp(pxS3, pxB);
697 Sk4f pxS2 = px20 + px21; 734 Sk4f pxS2 = px20 + px21;
698 Sk4f px1 = lerp(pxS2, pxS3); 735 Sk4f px1 = lerp(pxS2, pxS3);
699 Sk4f pxS1 = px10 + px11; 736 Sk4f pxS1 = px10 + px11;
700 Sk4f px2 = lerp(pxS1, pxS2); 737 Sk4f px2 = lerp(pxS1, pxS2);
701 Sk4f pxS0 = px00 + px01; 738 Sk4f pxS0 = px00 + px01;
702 Sk4f px3 = lerp(pxS0, pxS1); 739 Sk4f px3 = lerp(pxS0, pxS1);
703 pxB = pxS0; 740 pxB = pxS0;
704 fNext->blend4Pixels(px0, px1, px2, px3); 741 fNext->blend4Pixels(px0, px1, px2, px3);
705 ix0 -= 4; 742 ix0 -= 4;
706 count -= 4; 743 count -= 4;
707 } 744 }
708 while (count > 0) { 745 while (count > 0) {
709 Sk4f pixelY0 = fStrategy.getPixelFromRow(rowY0, ix0); 746 Sk4f pixelY0 = fAccessor.getPixelFromRow(rowY0, ix0);
710 Sk4f pixelY1 = fStrategy.getPixelFromRow(rowY1, ix0); 747 Sk4f pixelY1 = fAccessor.getPixelFromRow(rowY1, ix0);
711 748
712 fNext->blendPixel(lerp(pixelY0, pixelY1)); 749 fNext->blendPixel(lerp(pixelY0, pixelY1));
713 ix0 -= 1; 750 ix0 -= 1;
714 count -= 1; 751 count -= 1;
715 } 752 }
716 } 753 }
717 } 754 }
718 755
719 void spanUnitRateAlignedX(Span span, SkScalar y1) { 756 void spanUnitRateAlignedX(Span span, SkScalar y1) {
720 SkScalar y0 = span.startY() - 0.5f; 757 SkScalar y0 = span.startY() - 0.5f;
721 y1 += 0.5f; 758 y1 += 0.5f;
722 int iy0 = SkScalarFloorToInt(y0); 759 int iy0 = SkScalarFloorToInt(y0);
723 SkScalar filterY1 = y0 - iy0; 760 SkScalar filterY1 = y0 - iy0;
724 SkScalar filterY0 = 1.0f - filterY1; 761 SkScalar filterY0 = 1.0f - filterY1;
725 int iy1 = SkScalarFloorToInt(y1); 762 int iy1 = SkScalarFloorToInt(y1);
726 int ix = SkScalarFloorToInt(span.startX()); 763 int ix = SkScalarFloorToInt(span.startX());
727 const void* rowY0 = fStrategy.row(iy0); 764 const void* rowY0 = fAccessor.row(iy0);
728 const void* rowY1 = fStrategy.row(iy1); 765 const void* rowY1 = fAccessor.row(iy1);
729 auto lerp = [&](Sk4f* pixelY0, Sk4f* pixelY1) { 766 auto lerp = [&](Sk4f* pixelY0, Sk4f* pixelY1) {
730 return *pixelY0 * filterY0 + *pixelY1 * filterY1; 767 return *pixelY0 * filterY0 + *pixelY1 * filterY1;
731 }; 768 };
732 769
733 if (span.length() > 0) { 770 if (span.length() > 0) {
734 int count = span.count(); 771 int count = span.count();
735 while (count >= 4) { 772 while (count >= 4) {
736 Sk4f px00, px10, px20, px30; 773 Sk4f px00, px10, px20, px30;
737 fStrategy.get4Pixels(rowY0, ix, &px00, &px10, &px20, &px30); 774 fAccessor.get4Pixels(rowY0, ix, &px00, &px10, &px20, &px30);
738 Sk4f px01, px11, px21, px31; 775 Sk4f px01, px11, px21, px31;
739 fStrategy.get4Pixels(rowY1, ix, &px01, &px11, &px21, &px31); 776 fAccessor.get4Pixels(rowY1, ix, &px01, &px11, &px21, &px31);
740 fNext->blend4Pixels( 777 fNext->blend4Pixels(
741 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21), lerp(&px30, &px31)); 778 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21), lerp(&px30, &px31));
742 ix += 4; 779 ix += 4;
743 count -= 4; 780 count -= 4;
744 } 781 }
745 while (count > 0) { 782 while (count > 0) {
746 Sk4f pixelY0 = fStrategy.getPixelFromRow(rowY0, ix); 783 Sk4f pixelY0 = fAccessor.getPixelFromRow(rowY0, ix);
747 Sk4f pixelY1 = fStrategy.getPixelFromRow(rowY1, ix); 784 Sk4f pixelY1 = fAccessor.getPixelFromRow(rowY1, ix);
748 785
749 fNext->blendPixel(lerp(&pixelY0, &pixelY1)); 786 fNext->blendPixel(lerp(&pixelY0, &pixelY1));
750 ix += 1; 787 ix += 1;
751 count -= 1; 788 count -= 1;
752 } 789 }
753 } else { 790 } else {
754 int count = span.count(); 791 int count = span.count();
755 while (count >= 4) { 792 while (count >= 4) {
756 Sk4f px00, px10, px20, px30; 793 Sk4f px00, px10, px20, px30;
757 fStrategy.get4Pixels(rowY0, ix - 3, &px30, &px20, &px10, &px00); 794 fAccessor.get4Pixels(rowY0, ix - 3, &px30, &px20, &px10, &px00);
758 Sk4f px01, px11, px21, px31; 795 Sk4f px01, px11, px21, px31;
759 fStrategy.get4Pixels(rowY1, ix - 3, &px31, &px21, &px11, &px01); 796 fAccessor.get4Pixels(rowY1, ix - 3, &px31, &px21, &px11, &px01);
760 fNext->blend4Pixels( 797 fNext->blend4Pixels(
761 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21), lerp(&px30, &px31)); 798 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21), lerp(&px30, &px31));
762 ix -= 4; 799 ix -= 4;
763 count -= 4; 800 count -= 4;
764 } 801 }
765 while (count > 0) { 802 while (count > 0) {
766 Sk4f pixelY0 = fStrategy.getPixelFromRow(rowY0, ix); 803 Sk4f pixelY0 = fAccessor.getPixelFromRow(rowY0, ix);
767 Sk4f pixelY1 = fStrategy.getPixelFromRow(rowY1, ix); 804 Sk4f pixelY1 = fAccessor.getPixelFromRow(rowY1, ix);
768 805
769 fNext->blendPixel(lerp(&pixelY0, &pixelY1)); 806 fNext->blendPixel(lerp(&pixelY0, &pixelY1));
770 ix -= 1; 807 ix -= 1;
771 count -= 1; 808 count -= 1;
772 } 809 }
773 } 810 }
774 } 811 }
775 812
776 // We're moving through source space faster than dst (zoomed out), 813 // We're moving through source space faster than dst (zoomed out),
777 // so we'll never reuse a source pixel or be able to do contiguous loads. 814 // so we'll never reuse a source pixel or be able to do contiguous loads.
(...skipping 16 matching lines...) Expand all
794 Sk4f ys = {y - 0.5f, y - 0.5f, y1 + 0.5f, y1 + 0.5f}; 831 Sk4f ys = {y - 0.5f, y - 0.5f, y1 + 0.5f, y1 + 0.5f};
795 while (count > 0) { 832 while (count > 0) {
796 Sk4f xs = Sk4f{-0.5f, 0.5f, -0.5f, 0.5f} + Sk4f{x}; 833 Sk4f xs = Sk4f{-0.5f, 0.5f, -0.5f, 0.5f} + Sk4f{x};
797 this->bilerpEdge(xs, ys); 834 this->bilerpEdge(xs, ys);
798 x += dx; 835 x += dx;
799 count -= 1; 836 count -= 1;
800 } 837 }
801 } 838 }
802 } 839 }
803 840
804 Next* const fNext; 841 Next* const fNext;
805 PixelAccessor<colorType, gammaType> fStrategy; 842 Accessor fAccessor;
806 }; 843 };
807 844
808 } // namespace 845 } // namespace
809 846
810 #endif // SkLinearBitmapPipeline_sampler_DEFINED 847 #endif // SkLinearBitmapPipeline_sampler_DEFINED
OLDNEW
« no previous file with comments | « src/core/SkLinearBitmapPipeline_core.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698