Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkLinearBitmapPipeline.h" | 8 #include "SkLinearBitmapPipeline.h" |
| 9 | 9 |
| 10 struct X { | 10 struct X { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 Sk4f newYs = ys; | 48 Sk4f newYs = ys; |
| 49 fStrategy.processPoints(&newXs, &newYs); | 49 fStrategy.processPoints(&newXs, &newYs); |
| 50 fNext->pointList4(newXs, newYs); | 50 fNext->pointList4(newXs, newYs); |
| 51 } | 51 } |
| 52 | 52 |
| 53 private: | 53 private: |
| 54 Next* const fNext; | 54 Next* const fNext; |
| 55 Strategy fStrategy; | 55 Strategy fStrategy; |
| 56 }; | 56 }; |
| 57 | 57 |
| 58 class SkippedStage final : public PointProcessorInterface { | 58 template<typename Strategy, typename Next> |
| 59 class BilerpProcessor : public BilerpProcessorInterface { | |
|
mtklein
2016/02/17 20:25:09
final (and PointProcessor too)?
herb_g
2016/02/17 23:40:43
Done.
| |
| 60 public: | |
| 61 template <typename... Args> | |
| 62 BilerpProcessor(Next* next, Args&&... args) | |
| 63 : fNext{next} | |
| 64 , fStrategy{std::forward<Args>(args)...}{ } | |
| 65 | |
| 59 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 66 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { |
| 60 SkFAIL("Abort tiler."); | 67 Sk4f newXs = xs; |
|
mtklein
2016/02/17 20:25:09
This is so sad. :(
herb_g
2016/02/17 23:40:44
Acknowledged.
| |
| 68 Sk4f newYs = ys; | |
| 69 fStrategy.processPoints(&newXs, &newYs); | |
| 70 fNext->pointListFew(n, newXs, newYs); | |
| 71 } | |
| 72 | |
| 73 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | |
| 74 Sk4f newXs = xs; | |
| 75 Sk4f newYs = ys; | |
| 76 fStrategy.processPoints(&newXs, &newYs); | |
| 77 fNext->pointList4(newXs, newYs); | |
| 78 } | |
| 79 | |
| 80 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | |
| 81 Sk4f newXs = xs; | |
| 82 Sk4f newYs = ys; | |
| 83 fStrategy.processPoints(&newXs, &newYs); | |
| 84 fNext->bilerpList(newXs, newYs); | |
| 85 } | |
| 86 | |
| 87 private: | |
| 88 Next* const fNext; | |
| 89 Strategy fStrategy; | |
| 90 }; | |
| 91 | |
| 92 class SkippedStage final : public BilerpProcessorInterface { | |
| 93 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | |
| 94 SkFAIL("Skipped stage."); | |
| 61 } | 95 } |
| 62 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { | 96 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { |
| 63 SkFAIL("Abort point processor."); | 97 SkFAIL("Skipped stage."); |
| 98 } | |
| 99 virtual void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | |
|
mtklein
2016/02/17 20:25:09
I think override's plenty.
herb_g
2016/02/17 23:40:44
Done.
| |
| 100 SkFAIL("Skipped stage."); | |
| 64 } | 101 } |
| 65 }; | 102 }; |
| 66 | 103 |
| 67 class TranslateMatrixStrategy { | 104 class TranslateMatrixStrategy { |
| 68 public: | 105 public: |
| 69 TranslateMatrixStrategy(SkVector offset) | 106 TranslateMatrixStrategy(SkVector offset) |
| 70 : fXOffset{X(offset)} | 107 : fXOffset{X(offset)} |
| 71 , fYOffset{Y(offset)} { } | 108 , fYOffset{Y(offset)} { } |
| 72 void processPoints(Sk4f* xs, Sk4f* ys) { | 109 void processPoints(Sk4f* xs, Sk4f* ys) { |
| 73 *xs = *xs + fXOffset; | 110 *xs = *xs + fXOffset; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 matrixProc->Initialize<TranslateMatrix<>>( | 177 matrixProc->Initialize<TranslateMatrix<>>( |
| 141 next, | 178 next, |
| 142 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}); | 179 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}); |
| 143 } else { | 180 } else { |
| 144 matrixProc->Initialize<SkippedStage>(); | 181 matrixProc->Initialize<SkippedStage>(); |
| 145 return next; | 182 return next; |
| 146 } | 183 } |
| 147 return matrixProc->get(); | 184 return matrixProc->get(); |
| 148 } | 185 } |
| 149 | 186 |
| 187 template <typename Next = BilerpProcessorInterface> | |
| 188 class ExpandBilerp final : public PointProcessorInterface { | |
| 189 public: | |
| 190 ExpandBilerp(Next* next) : fNext{next} { } | |
| 191 | |
| 192 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | |
| 193 SkASSERT(n > 0 && n <= 4); | |
|
mtklein
2016/02/17 20:25:09
This seems awkward. It's a bug if we call pointLi
herb_g
2016/02/17 23:40:43
Done.
| |
| 194 if (n >= 1) fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYO ffsets); | |
| 195 if (n >= 2) fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYO ffsets); | |
| 196 if (n >= 3) fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYO ffsets); | |
| 197 if (n == 4) fNext->bilerpList(Sk4f{xs[3]} + kXOffsets, Sk4f{ys[3]} + kYO ffsets); | |
| 198 } | |
| 199 | |
| 200 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | |
| 201 pointListFew(4, xs, ys); | |
|
mtklein
2016/02/17 20:25:09
self calls usually have a this->
herb_g
2016/02/17 23:40:44
Removed
| |
| 202 } | |
|
mtklein
2016/02/17 20:25:09
Is this why we distinguish PointProcessor and Bile
herb_g
2016/02/17 23:40:44
There is no sensible bilerp here or at the matrix
| |
| 203 | |
| 204 private: | |
| 205 static const Sk4f kXOffsets; | |
| 206 static const Sk4f kYOffsets; | |
| 207 Next* const fNext; | |
| 208 }; | |
| 209 | |
| 210 template <typename Next> | |
| 211 const Sk4f ExpandBilerp<Next>::kXOffsets = {0.0f, 1.0f, 0.0f, 1.0f}; | |
|
mtklein
2016/02/17 20:25:09
This is all sort of awkward and boilerplate-y.
Le
herb_g
2016/02/17 23:40:43
Done.
| |
| 212 template <typename Next> | |
| 213 const Sk4f ExpandBilerp<Next>::kYOffsets = {0.0f, 0.0f, 1.0f, 1.0f}; | |
| 214 | |
| 215 static PointProcessorInterface* choose_filter( | |
| 216 BilerpProcessorInterface* next, | |
| 217 SkFilterQuality filterQuailty, | |
| 218 SkLinearBitmapPipeline::FilterStage* filterProc) { | |
| 219 if (filterQuailty >= SkFilterQuality::kLow_SkFilterQuality) { | |
|
mtklein
2016/02/17 20:25:09
Might wanna write as:
none -> skipped
else -
herb_g
2016/02/17 23:40:43
Done.
| |
| 220 filterProc->Initialize<ExpandBilerp<>>(next); | |
| 221 return filterProc->get(); | |
| 222 } else { | |
| 223 filterProc->Initialize<SkippedStage>(); | |
| 224 return next; | |
| 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 Loading... | |
| 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 inline Sk4f bilerp4(SkPoint pt, Sk4f pixel00, Sk4f pixel01, | |
|
mtklein
2016/02/17 20:25:09
It's a good habit to get into writing static on al
herb_g
2016/02/17 23:40:44
Done.
| |
| 389 Sk4f pixel10, Sk4f pixel11) { | |
| 390 Sk4f Xs{X(pt) - std::floor(X(pt))}; | |
|
mtklein
2016/02/17 20:25:09
If we're using std:: stuff, might want to consider
herb_g
2016/02/17 23:40:43
Redid whole function.
| |
| 391 Sk4f Ys{Y(pt) - std::floor(Y(pt))}; | |
| 392 Sk4f XYs{Xs * Ys}; | |
| 393 Sk4f sum = pixel11 * XYs; | |
| 394 sum = sum + pixel01 * (Xs - XYs); | |
| 395 sum = sum + pixel10 * (Ys - XYs); | |
| 396 sum = sum + pixel00 * (Sk4f{1.0f} - Xs - Ys + XYs); | |
|
mtklein
2016/02/17 20:25:09
This would be a really great place for an ASCII ar
herb_g
2016/02/17 23:40:43
Done.
| |
| 397 return sum; | |
| 398 } | |
| 399 | |
| 310 template <typename SourceStrategy> | 400 template <typename SourceStrategy> |
| 311 class Sampler final : public PointProcessorInterface { | 401 class Sampler final : public BilerpProcessorInterface { |
| 312 public: | 402 public: |
| 313 template <typename... Args> | 403 template <typename... Args> |
| 314 Sampler(PixelPlacerInterface* next, Args&&... args) | 404 Sampler(PixelPlacerInterface* next, Args&&... args) |
| 315 : fNext{next} | 405 : fNext{next} |
| 316 , fStrategy{std::forward<Args>(args)...} { } | 406 , fStrategy{std::forward<Args>(args)...} { } |
| 317 | 407 |
| 318 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 408 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { |
| 319 SkASSERT(0 < n && n < 4); | 409 SkASSERT(0 < n && n < 4); |
| 320 Sk4f px0, px1, px2; | 410 Sk4f px0, px1, px2; |
| 321 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); | 411 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); |
| 322 if (n >= 1) fNext->placePixel(px0); | 412 if (n >= 1) fNext->placePixel(px0); |
| 323 if (n >= 2) fNext->placePixel(px1); | 413 if (n >= 2) fNext->placePixel(px1); |
| 324 if (n >= 3) fNext->placePixel(px2); | 414 if (n >= 3) fNext->placePixel(px2); |
| 325 } | 415 } |
| 326 | 416 |
| 327 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | 417 void pointList4(Sk4fArg xs, Sk4fArg ys) override { |
| 328 Sk4f px0, px1, px2, px3; | 418 Sk4f px0, px1, px2, px3; |
| 329 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); | 419 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); |
| 330 fNext->place4Pixels(px0, px1, px2, px3); | 420 fNext->place4Pixels(px0, px1, px2, px3); |
| 331 } | 421 } |
| 332 | 422 |
| 423 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | |
| 424 SkPoint referencePoint{xs[0], ys[0]}; | |
|
mtklein
2016/02/17 20:25:09
Do these all have the same fractional parts? I'm
herb_g
2016/02/17 23:40:43
Done.
| |
| 425 Sk4f px0, px1, px2, px3; | |
| 426 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); | |
| 427 Sk4f pixel = bilerp4(referencePoint, px0, px1, px2, px3); | |
| 428 fNext->placePixel(pixel); | |
| 429 } | |
| 430 | |
| 333 private: | 431 private: |
| 334 PixelPlacerInterface* const fNext; | 432 PixelPlacerInterface* const fNext; |
| 335 SourceStrategy fStrategy; | 433 SourceStrategy fStrategy; |
| 336 }; | 434 }; |
| 337 | 435 |
| 338 static PointProcessorInterface* choose_pixel_sampler( | 436 static BilerpProcessorInterface* choose_pixel_sampler( |
| 339 PixelPlacerInterface* next, | 437 PixelPlacerInterface* next, |
| 340 const SkImageInfo& imageInfo, | 438 const SkImageInfo& imageInfo, |
| 341 const void* imageData, | 439 const void* imageData, |
| 342 SkLinearBitmapPipeline::SampleStage* sampleStage) { | 440 SkLinearBitmapPipeline::SampleStage* sampleStage) { |
| 343 switch (imageInfo.colorType()) { | 441 switch (imageInfo.colorType()) { |
| 344 case kRGBA_8888_SkColorType: | 442 case kRGBA_8888_SkColorType: |
| 345 case kBGRA_8888_SkColorType: | 443 case kBGRA_8888_SkColorType: |
| 346 if (kN32_SkColorType == imageInfo.colorType()) { | 444 if (kN32_SkColorType == imageInfo.colorType()) { |
| 347 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { | 445 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { |
| 348 sampleStage->Initialize<Sampler<Passthrough8888<kSRGB_SkColo rProfileType>>>( | 446 sampleStage->Initialize<Sampler<Passthrough8888<kSRGB_SkColo rProfileType>>>( |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 placerStage->Initialize<PlaceFPPixel<kUnpremul_SkAlphaType>>(); | 506 placerStage->Initialize<PlaceFPPixel<kUnpremul_SkAlphaType>>(); |
| 409 } else { | 507 } else { |
| 410 // kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType | 508 // kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType |
| 411 placerStage->Initialize<PlaceFPPixel<kPremul_SkAlphaType>>(); | 509 placerStage->Initialize<PlaceFPPixel<kPremul_SkAlphaType>>(); |
| 412 } | 510 } |
| 413 return placerStage->get(); | 511 return placerStage->get(); |
| 414 } | 512 } |
| 415 | 513 |
| 416 SkLinearBitmapPipeline::SkLinearBitmapPipeline( | 514 SkLinearBitmapPipeline::SkLinearBitmapPipeline( |
| 417 const SkMatrix& inverse, | 515 const SkMatrix& inverse, |
| 516 SkFilterQuality filterQuality, | |
| 418 SkShader::TileMode xTile, SkShader::TileMode yTile, | 517 SkShader::TileMode xTile, SkShader::TileMode yTile, |
| 419 const SkImageInfo& srcImageInfo, | 518 const SkImageInfo& srcImageInfo, |
| 420 const void* srcImageData) { | 519 const void* srcImageData) { |
| 421 SkSize size; | 520 SkSize size; |
| 422 size = srcImageInfo.dimensions(); | 521 size = srcImageInfo.dimensions(); |
| 423 | 522 |
| 424 // As the stages are built, the chooser function may skip a stage. For examp le, with the | 523 // 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. | 524 // 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); | 525 auto placementStage = choose_pixel_placer(srcImageInfo.alphaType(), &fPixelS tage); |
| 427 auto samplerStage = choose_pixel_sampler(placementStage, srcImageInfo, | 526 auto samplerStage = choose_pixel_sampler(placementStage, srcImageInfo, |
| 428 srcImageData, &fSampleStage); | 527 srcImageData, &fSampleStage); |
| 429 auto tilerStage = choose_tiler(samplerStage, size, xTile, yTile, &fTileX OrBothStage, | 528 auto tilerStage = choose_tiler(samplerStage, size, xTile, yTile, &fTileX OrBothStage, |
| 430 &fTileYStage); | 529 &fTileYStage); |
| 431 fFirstStage = choose_matrix(tilerStage, inverse, &fMatrixStage); | 530 auto filterStage = choose_filter(tilerStage, filterQuality, &fFilterStage ); |
| 531 fFirstStage = choose_matrix(filterStage, inverse, &fMatrixStage); | |
| 432 } | 532 } |
| 433 | 533 |
| 434 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { | 534 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { |
| 435 fPixelStage->setDestination(dst); | 535 fPixelStage->setDestination(dst); |
| 436 | 536 |
| 437 Sk4f Xs = Sk4f(x) + Sk4f{0.5f, 1.5f, 2.5f, 3.5f}; | 537 Sk4f Xs = Sk4f(x) + Sk4f{0.5f, 1.5f, 2.5f, 3.5f}; |
| 438 Sk4f Ys(y); | 538 Sk4f Ys(y); |
| 439 Sk4f fours{4.0f}; | 539 Sk4f fours{4.0f}; |
| 440 | 540 |
| 441 while (count >= 4) { | 541 while (count >= 4) { |
| 442 fFirstStage->pointList4(Xs, Ys); | 542 fFirstStage->pointList4(Xs, Ys); |
| 443 Xs = Xs + fours; | 543 Xs = Xs + fours; |
| 444 count -= 4; | 544 count -= 4; |
| 445 } | 545 } |
| 446 if (count > 0) { | 546 if (count > 0) { |
| 447 fFirstStage->pointListFew(count, Xs, Ys); | 547 fFirstStage->pointListFew(count, Xs, Ys); |
| 448 } | 548 } |
| 449 } | 549 } |
| OLD | NEW |