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

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

Issue 1705203002: Add bilerp filtering. (Closed) Base URL: https://skia.googlesource.com/skia.git@fp-simple-linear-20160217
Patch Set: Redo bilerp. 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 9
10 struct X { 10 struct X {
11 explicit X(SkScalar val) : fVal{val} { } 11 explicit X(SkScalar val) : fVal{val} { }
12 explicit X(SkPoint pt) : fVal{pt.fX} { } 12 explicit X(SkPoint pt) : fVal{pt.fX} { }
13 explicit X(SkSize s) : fVal{s.fWidth} { } 13 explicit X(SkSize s) : fVal{s.fWidth} { }
14 explicit X(SkISize s) : fVal(s.fWidth) { } 14 explicit X(SkISize s) : fVal(s.fWidth) { }
15 operator float () const {return fVal;} 15 operator float () const {return fVal;}
16 private: 16 private:
17 float fVal; 17 float fVal;
18 }; 18 };
19 19
20 struct Y { 20 struct Y {
21 explicit Y(SkScalar val) : fVal{val} { } 21 explicit Y(SkScalar val) : fVal{val} { }
22 explicit Y(SkPoint pt) : fVal{pt.fY} { } 22 explicit Y(SkPoint pt) : fVal{pt.fY} { }
23 explicit Y(SkSize s) : fVal{s.fHeight} { } 23 explicit Y(SkSize s) : fVal{s.fHeight} { }
24 explicit Y(SkISize s) : fVal(s.fHeight) { } 24 explicit Y(SkISize s) : fVal(s.fHeight) { }
25
26 operator float () const {return fVal;} 25 operator float () const {return fVal;}
27 private: 26 private:
28 float fVal; 27 float fVal;
29 }; 28 };
30 29
31 template<typename Strategy, typename Next> 30 template<typename Strategy, typename Next>
32 class PointProcessor : public PointProcessorInterface { 31 class PointProcessor final : public PointProcessorInterface {
33 public: 32 public:
34 template <typename... Args> 33 template <typename... Args>
35 PointProcessor(Next* next, Args&&... args) 34 PointProcessor(Next* next, Args&&... args)
36 : fNext{next} 35 : fNext{next}
37 , fStrategy{std::forward<Args>(args)...}{ } 36 , fStrategy{std::forward<Args>(args)...}{ }
38 37
39 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { 38 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
40 Sk4f newXs = xs; 39 Sk4f newXs = xs;
41 Sk4f newYs = ys; 40 Sk4f newYs = ys;
42 fStrategy.processPoints(&newXs, &newYs); 41 fStrategy.processPoints(&newXs, &newYs);
43 fNext->pointListFew(n, newXs, newYs); 42 fNext->pointListFew(n, newXs, newYs);
44 } 43 }
45 44
46 void pointList4(Sk4fArg xs, Sk4fArg ys) override { 45 void pointList4(Sk4fArg xs, Sk4fArg ys) override {
47 Sk4f newXs = xs; 46 Sk4f newXs = xs;
48 Sk4f newYs = ys; 47 Sk4f newYs = ys;
49 fStrategy.processPoints(&newXs, &newYs); 48 fStrategy.processPoints(&newXs, &newYs);
50 fNext->pointList4(newXs, newYs); 49 fNext->pointList4(newXs, newYs);
51 } 50 }
52 51
53 private: 52 private:
54 Next* const fNext; 53 Next* const fNext;
55 Strategy fStrategy; 54 Strategy fStrategy;
56 }; 55 };
57 56
58 class SkippedStage final : public PointProcessorInterface { 57 template<typename Strategy, typename Next>
58 class BilerpProcessor final : public BilerpProcessorInterface {
59 public:
60 template <typename... Args>
61 BilerpProcessor(Next* next, Args&&... args)
62 : fNext{next}
63 , fStrategy{std::forward<Args>(args)...}{ }
64
59 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { 65 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
60 SkFAIL("Abort tiler."); 66 Sk4f newXs = xs;
67 Sk4f newYs = ys;
68 fStrategy.processPoints(&newXs, &newYs);
69 fNext->pointListFew(n, newXs, newYs);
70 }
71
72 void pointList4(Sk4fArg xs, Sk4fArg ys) override {
73 Sk4f newXs = xs;
74 Sk4f newYs = ys;
75 fStrategy.processPoints(&newXs, &newYs);
76 fNext->pointList4(newXs, newYs);
77 }
78
79 void bilerpList(Sk4fArg xs, Sk4fArg ys) override {
80 Sk4f newXs = xs;
81 Sk4f newYs = ys;
82 fStrategy.processPoints(&newXs, &newYs);
83 fNext->bilerpList(newXs, newYs);
84 }
85
86 private:
87 Next* const fNext;
88 Strategy fStrategy;
89 };
90
91 class SkippedStage final : public BilerpProcessorInterface {
92 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
93 SkFAIL("Skipped stage.");
61 } 94 }
62 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { 95 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override {
63 SkFAIL("Abort point processor."); 96 SkFAIL("Skipped stage.");
97 }
98 virtual void bilerpList(Sk4fArg xs, Sk4fArg ys) override {
99 SkFAIL("Skipped stage.");
64 } 100 }
65 }; 101 };
66 102
67 class TranslateMatrixStrategy { 103 class TranslateMatrixStrategy {
68 public: 104 public:
69 TranslateMatrixStrategy(SkVector offset) 105 TranslateMatrixStrategy(SkVector offset)
70 : fXOffset{X(offset)} 106 : fXOffset{X(offset)}
71 , fYOffset{Y(offset)} { } 107 , fYOffset{Y(offset)} { }
72 void processPoints(Sk4f* xs, Sk4f* ys) { 108 void processPoints(Sk4f* xs, Sk4f* ys) {
73 *xs = *xs + fXOffset; 109 *xs = *xs + fXOffset;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 matrixProc->Initialize<TranslateMatrix<>>( 176 matrixProc->Initialize<TranslateMatrix<>>(
141 next, 177 next,
142 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}); 178 SkVector{inverse.getTranslateX(), inverse.getTranslateY()});
143 } else { 179 } else {
144 matrixProc->Initialize<SkippedStage>(); 180 matrixProc->Initialize<SkippedStage>();
145 return next; 181 return next;
146 } 182 }
147 return matrixProc->get(); 183 return matrixProc->get();
148 } 184 }
149 185
186 template <typename Next = BilerpProcessorInterface>
187 class ExpandBilerp final : public PointProcessorInterface {
188 public:
189 ExpandBilerp(Next* next) : fNext{next} { }
190
191 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
192 SkASSERT(0 < n && n < 4);
193 // px00 px10 px01 px11
194 const Sk4f kXOffsets{0.0f, 1.0f, 0.0f, 1.0f},
195 kYOffsets{0.0f, 0.0f, 1.0f, 1.0f};
196 if (n >= 1) fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYO ffsets);
197 if (n >= 2) fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYO ffsets);
198 if (n >= 3) fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYO ffsets);
199 }
200
201 void pointList4(Sk4fArg xs, Sk4fArg ys) override {
202 // px00 px10 px01 px11
203 const Sk4f kXOffsets{0.0f, 1.0f, 0.0f, 1.0f},
204 kYOffsets{0.0f, 0.0f, 1.0f, 1.0f};
205 fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYOffsets);
206 fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYOffsets);
207 fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYOffsets);
208 fNext->bilerpList(Sk4f{xs[3]} + kXOffsets, Sk4f{ys[3]} + kYOffsets);
209 }
210
211 private:
212 Next* const fNext;
213 };
214
215 static PointProcessorInterface* choose_filter(
216 BilerpProcessorInterface* next,
217 SkFilterQuality filterQuailty,
218 SkLinearBitmapPipeline::FilterStage* filterProc) {
219 if (SkFilterQuality::kNone_SkFilterQuality == filterQuailty) {
220 filterProc->Initialize<SkippedStage>();
221 return next;
222 } else {
223 filterProc->Initialize<ExpandBilerp<>>(next);
224 return filterProc->get();
225 }
226 }
227
150 class ClampStrategy { 228 class ClampStrategy {
151 public: 229 public:
152 ClampStrategy(X max) 230 ClampStrategy(X max)
153 : fXMin{0.0f} 231 : fXMin{0.0f}
154 , fXMax{max - 1.0f} { } 232 , fXMax{max - 1.0f} { }
155 ClampStrategy(Y max) 233 ClampStrategy(Y max)
156 : fYMin{0.0f} 234 : fYMin{0.0f}
157 , fYMax{max - 1.0f} { } 235 , fYMax{max - 1.0f} { }
158 ClampStrategy(SkSize max) 236 ClampStrategy(SkSize max)
159 : fXMin{0.0f} 237 : fXMin{0.0f}
160 , fYMin{0.0f} 238 , fYMin{0.0f}
161 , fXMax{X(max) - 1.0f} 239 , fXMax{X(max) - 1.0f}
162 , fYMax{Y(max) - 1.0f} { } 240 , fYMax{Y(max) - 1.0f} { }
163 241
164 void processPoints(Sk4f* xs, Sk4f* ys) { 242 void processPoints(Sk4f* xs, Sk4f* ys) {
165 *xs = Sk4f::Min(Sk4f::Max(*xs, fXMin), fXMax); 243 *xs = Sk4f::Min(Sk4f::Max(*xs, fXMin), fXMax);
166 *ys = Sk4f::Min(Sk4f::Max(*ys, fYMin), fYMax); 244 *ys = Sk4f::Min(Sk4f::Max(*ys, fYMin), fYMax);
167 } 245 }
168 246
169 private: 247 private:
170 const Sk4f fXMin{SK_FloatNegativeInfinity}; 248 const Sk4f fXMin{SK_FloatNegativeInfinity};
171 const Sk4f fYMin{SK_FloatNegativeInfinity}; 249 const Sk4f fYMin{SK_FloatNegativeInfinity};
172 const Sk4f fXMax{SK_FloatInfinity}; 250 const Sk4f fXMax{SK_FloatInfinity};
173 const Sk4f fYMax{SK_FloatInfinity}; 251 const Sk4f fYMax{SK_FloatInfinity};
174 }; 252 };
175 template <typename Next = PointProcessorInterface> 253 template <typename Next = BilerpProcessorInterface>
176 using Clamp = PointProcessor<ClampStrategy, Next>; 254 using Clamp = BilerpProcessor<ClampStrategy, Next>;
177 255
178 class RepeatStrategy { 256 class RepeatStrategy {
179 public: 257 public:
180 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { } 258 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { }
181 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { } 259 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { }
182 RepeatStrategy(SkSize max) 260 RepeatStrategy(SkSize max)
183 : fXMax{X(max)} 261 : fXMax{X(max)}
184 , fXInvMax{1.0f / X(max)} 262 , fXInvMax{1.0f / X(max)}
185 , fYMax{Y(max)} 263 , fYMax{Y(max)}
186 , fYInvMax{1.0f / Y(max)} { } 264 , fYInvMax{1.0f / Y(max)} { }
187 265
188 void processPoints(Sk4f* xs, Sk4f* ys) { 266 void processPoints(Sk4f* xs, Sk4f* ys) {
189 Sk4f divX = (*xs * fXInvMax).floor(); 267 Sk4f divX = (*xs * fXInvMax).floor();
190 Sk4f divY = (*ys * fYInvMax).floor(); 268 Sk4f divY = (*ys * fYInvMax).floor();
191 Sk4f baseX = (divX * fXMax); 269 Sk4f baseX = (divX * fXMax);
192 Sk4f baseY = (divY * fYMax); 270 Sk4f baseY = (divY * fYMax);
193 *xs = *xs - baseX; 271 *xs = *xs - baseX;
194 *ys = *ys - baseY; 272 *ys = *ys - baseY;
195 } 273 }
196 274
197 private: 275 private:
198 const Sk4f fXMax{0.0f}; 276 const Sk4f fXMax{0.0f};
199 const Sk4f fXInvMax{0.0f}; 277 const Sk4f fXInvMax{0.0f};
200 const Sk4f fYMax{0.0f}; 278 const Sk4f fYMax{0.0f};
201 const Sk4f fYInvMax{0.0f}; 279 const Sk4f fYInvMax{0.0f};
202 }; 280 };
203 281
204 template <typename Next = PointProcessorInterface> 282 template <typename Next = BilerpProcessorInterface>
205 using Repeat = PointProcessor<RepeatStrategy, Next>; 283 using Repeat = BilerpProcessor<RepeatStrategy, Next>;
206 284
207 static PointProcessorInterface* choose_tiler( 285 static BilerpProcessorInterface* choose_tiler(
208 PointProcessorInterface* next, 286 BilerpProcessorInterface* next,
209 SkSize dimensions, 287 SkSize dimensions,
210 SkShader::TileMode xMode, 288 SkShader::TileMode xMode,
211 SkShader::TileMode yMode, 289 SkShader::TileMode yMode,
212 SkLinearBitmapPipeline::TileStage* tileProcXOrBoth, 290 SkLinearBitmapPipeline::TileStage* tileProcXOrBoth,
213 SkLinearBitmapPipeline::TileStage* tileProcY) { 291 SkLinearBitmapPipeline::TileStage* tileProcY) {
214 if (xMode == yMode) { 292 if (xMode == yMode) {
215 switch (xMode) { 293 switch (xMode) {
216 case SkShader::kClamp_TileMode: 294 case SkShader::kClamp_TileMode:
217 tileProcXOrBoth->Initialize<Clamp<>>(next, dimensions); 295 tileProcXOrBoth->Initialize<Clamp<>>(next, dimensions);
218 break; 296 break;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 pixel = pixel * Sk4f{1.0f/255.0f}; 378 pixel = pixel * Sk4f{1.0f/255.0f};
301 if (colorProfile == kSRGB_SkColorProfileType) { 379 if (colorProfile == kSRGB_SkColorProfileType) {
302 pixel = sRGBFast::sRGBToLinear(pixel); 380 pixel = sRGBFast::sRGBToLinear(pixel);
303 } 381 }
304 return pixel; 382 return pixel;
305 } 383 }
306 const uint32_t* const fSrc; 384 const uint32_t* const fSrc;
307 const Sk4i fWidth; 385 const Sk4i fWidth;
308 }; 386 };
309 387
388 // Explaination of the math:
389 // 1 - x x
390 // +--------+--------+
391 // | | |
392 // 1 - y | px00 | px10 |
393 // | | |
394 // +--------+--------+
395 // | | |
396 // y | px01 | px11 |
397 // | | |
398 // +--------+--------+
399 //
400 //
401 // Given a pixelxy each is multiplied by a different factor derived from the fra ctional part of x
402 // and y:
403 // * px00 -> (1 - x)(1 - y) = 1 - x - y + xy
404 // * px10 -> x(1 - y) = x - xy
405 // * px01 -> (1 - x)y = y - xy
406 // * px11 -> xy
407 // So x * y is calculated first and then used to calculate all the other factors .
mtklein 2016/02/17 23:46:55 This is beautiful. Nominated for favorite code sn
herb_g 2016/02/18 03:49:06 Acknowledged.
408 static Sk4f bilerp4(Sk4fArg xs, Sk4fArg ys, Sk4fArg px00, Sk4fArg px10,
409 Sk4fArg px01, Sk4fArg px11) {
410 // Calculate fractional xs and ys.
411 Sk4f fxs = xs - xs.floor();
412 Sk4f fys = ys - ys.floor();
413 Sk4f fxys{fxs * fys};
414 Sk4f sum = px11 * fxys;
415 sum = sum + px01 * (fys - fxys);
416 sum = sum + px10 * (fxs - fxys);
417 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys);
418 return sum;
419 }
420
310 template <typename SourceStrategy> 421 template <typename SourceStrategy>
311 class Sampler final : public PointProcessorInterface { 422 class Sampler final : public BilerpProcessorInterface {
312 public: 423 public:
313 template <typename... Args> 424 template <typename... Args>
314 Sampler(PixelPlacerInterface* next, Args&&... args) 425 Sampler(PixelPlacerInterface* next, Args&&... args)
315 : fNext{next} 426 : fNext{next}
316 , fStrategy{std::forward<Args>(args)...} { } 427 , fStrategy{std::forward<Args>(args)...} { }
317 428
318 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { 429 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
319 SkASSERT(0 < n && n < 4); 430 SkASSERT(0 < n && n < 4);
320 Sk4f px0, px1, px2; 431 Sk4f px0, px1, px2;
321 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); 432 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2);
322 if (n >= 1) fNext->placePixel(px0); 433 if (n >= 1) fNext->placePixel(px0);
323 if (n >= 2) fNext->placePixel(px1); 434 if (n >= 2) fNext->placePixel(px1);
324 if (n >= 3) fNext->placePixel(px2); 435 if (n >= 3) fNext->placePixel(px2);
325 } 436 }
326 437
327 void pointList4(Sk4fArg xs, Sk4fArg ys) override { 438 void pointList4(Sk4fArg xs, Sk4fArg ys) override {
328 Sk4f px0, px1, px2, px3; 439 Sk4f px0, px1, px2, px3;
329 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); 440 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3);
330 fNext->place4Pixels(px0, px1, px2, px3); 441 fNext->place4Pixels(px0, px1, px2, px3);
331 } 442 }
332 443
444 void bilerpList(Sk4fArg xs, Sk4fArg ys) override {
445 Sk4f px00, px10, px01, px11;
446 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11);
447 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11);
448 fNext->placePixel(pixel);
449 }
450
333 private: 451 private:
334 PixelPlacerInterface* const fNext; 452 PixelPlacerInterface* const fNext;
335 SourceStrategy fStrategy; 453 SourceStrategy fStrategy;
336 }; 454 };
337 455
338 static PointProcessorInterface* choose_pixel_sampler( 456 static BilerpProcessorInterface* choose_pixel_sampler(
339 PixelPlacerInterface* next, 457 PixelPlacerInterface* next,
340 const SkImageInfo& imageInfo, 458 const SkImageInfo& imageInfo,
341 const void* imageData, 459 const void* imageData,
342 SkLinearBitmapPipeline::SampleStage* sampleStage) { 460 SkLinearBitmapPipeline::SampleStage* sampleStage) {
343 switch (imageInfo.colorType()) { 461 switch (imageInfo.colorType()) {
344 case kRGBA_8888_SkColorType: 462 case kRGBA_8888_SkColorType:
345 case kBGRA_8888_SkColorType: 463 case kBGRA_8888_SkColorType:
346 if (kN32_SkColorType == imageInfo.colorType()) { 464 if (kN32_SkColorType == imageInfo.colorType()) {
347 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { 465 if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
348 sampleStage->Initialize<Sampler<Passthrough8888<kSRGB_SkColo rProfileType>>>( 466 sampleStage->Initialize<Sampler<Passthrough8888<kSRGB_SkColo rProfileType>>>(
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 placerStage->Initialize<PlaceFPPixel<kUnpremul_SkAlphaType>>(); 526 placerStage->Initialize<PlaceFPPixel<kUnpremul_SkAlphaType>>();
409 } else { 527 } else {
410 // kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType 528 // kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType
411 placerStage->Initialize<PlaceFPPixel<kPremul_SkAlphaType>>(); 529 placerStage->Initialize<PlaceFPPixel<kPremul_SkAlphaType>>();
412 } 530 }
413 return placerStage->get(); 531 return placerStage->get();
414 } 532 }
415 533
416 SkLinearBitmapPipeline::SkLinearBitmapPipeline( 534 SkLinearBitmapPipeline::SkLinearBitmapPipeline(
417 const SkMatrix& inverse, 535 const SkMatrix& inverse,
536 SkFilterQuality filterQuality,
418 SkShader::TileMode xTile, SkShader::TileMode yTile, 537 SkShader::TileMode xTile, SkShader::TileMode yTile,
419 const SkImageInfo& srcImageInfo, 538 const SkImageInfo& srcImageInfo,
420 const void* srcImageData) { 539 const void* srcImageData) {
421 SkSize size; 540 SkSize size;
422 size = srcImageInfo.dimensions(); 541 size = srcImageInfo.dimensions();
423 542
424 // As the stages are built, the chooser function may skip a stage. For examp le, with the 543 // As the stages are built, the chooser function may skip a stage. For examp le, with the
425 // identity matrix, the matrix stage is skipped, and the tilerStage is the f irst stage. 544 // identity matrix, the matrix stage is skipped, and the tilerStage is the f irst stage.
426 auto placementStage = choose_pixel_placer(srcImageInfo.alphaType(), &fPixelS tage); 545 auto placementStage = choose_pixel_placer(srcImageInfo.alphaType(), &fPixelS tage);
427 auto samplerStage = choose_pixel_sampler(placementStage, srcImageInfo, 546 auto samplerStage = choose_pixel_sampler(placementStage, srcImageInfo,
428 srcImageData, &fSampleStage); 547 srcImageData, &fSampleStage);
429 auto tilerStage = choose_tiler(samplerStage, size, xTile, yTile, &fTileX OrBothStage, 548 auto tilerStage = choose_tiler(samplerStage, size, xTile, yTile, &fTileX OrBothStage,
430 &fTileYStage); 549 &fTileYStage);
431 fFirstStage = choose_matrix(tilerStage, inverse, &fMatrixStage); 550 auto filterStage = choose_filter(tilerStage, filterQuality, &fFilterStage );
551 fFirstStage = choose_matrix(filterStage, inverse, &fMatrixStage);
432 } 552 }
433 553
434 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { 554 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) {
435 fPixelStage->setDestination(dst); 555 fPixelStage->setDestination(dst);
436 556
437 Sk4f Xs = Sk4f(x) + Sk4f{0.5f, 1.5f, 2.5f, 3.5f}; 557 Sk4f Xs = Sk4f(x) + Sk4f{0.5f, 1.5f, 2.5f, 3.5f};
438 Sk4f Ys(y); 558 Sk4f Ys(y);
439 Sk4f fours{4.0f}; 559 Sk4f fours{4.0f};
440 560
441 while (count >= 4) { 561 while (count >= 4) {
442 fFirstStage->pointList4(Xs, Ys); 562 fFirstStage->pointList4(Xs, Ys);
443 Xs = Xs + fours; 563 Xs = Xs + fours;
444 count -= 4; 564 count -= 4;
445 } 565 }
446 if (count > 0) { 566 if (count > 0) {
447 fFirstStage->pointListFew(count, Xs, Ys); 567 fFirstStage->pointListFew(count, Xs, Ys);
448 } 568 }
449 } 569 }
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