| 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 #include "SkPM4f.h" | 9 #include "SkPM4f.h" |
| 10 | 10 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 while (count >= 4) { | 47 while (count >= 4) { |
| 48 stage->pointList4(Xs, Ys); | 48 stage->pointList4(Xs, Ys); |
| 49 Xs = Xs + fourDx; | 49 Xs = Xs + fourDx; |
| 50 count -= 4; | 50 count -= 4; |
| 51 } | 51 } |
| 52 if (count > 0) { | 52 if (count > 0) { |
| 53 stage->pointListFew(count, Xs, Ys); | 53 stage->pointListFew(count, Xs, Ys); |
| 54 } | 54 } |
| 55 } | 55 } |
| 56 | 56 |
| 57 // PointProcessor uses a strategy to help complete the work of the different sta
ges. The strategy |
| 58 // must implement the following methods: |
| 59 // * processPoints(xs, ys) - must mutate the xs and ys for the stage. |
| 60 // * maybeProcessSpan(start, length, count) - This represents a horizontal serie
s of pixels |
| 61 // to work over. |
| 62 // start - is the starting pixel. This is in destination space before the matr
ix stage, and in |
| 63 // source space after the matrix stage. |
| 64 // length - is this distance between the first pixel center and the last pixel
center. Like start, |
| 65 // this is in destination space before the matrix stage, and in source
space after. |
| 66 // count - the number of pixels in source space to produce. |
| 67 // next - a pointer to the next stage. |
| 68 // maybeProcessSpan - returns false if it can not process the span and needs t
o fallback to |
| 69 // point lists for processing. |
| 57 template<typename Strategy, typename Next> | 70 template<typename Strategy, typename Next> |
| 58 class PointProcessor final : public PointProcessorInterface { | 71 class PointProcessor final : public PointProcessorInterface { |
| 59 public: | 72 public: |
| 60 template <typename... Args> | 73 template <typename... Args> |
| 61 PointProcessor(Next* next, Args&&... args) | 74 PointProcessor(Next* next, Args&&... args) |
| 62 : fNext{next} | 75 : fNext{next} |
| 63 , fStrategy{std::forward<Args>(args)...}{ } | 76 , fStrategy{std::forward<Args>(args)...}{ } |
| 64 | 77 |
| 65 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 78 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { |
| 66 Sk4f newXs = xs; | 79 Sk4f newXs = xs; |
| 67 Sk4f newYs = ys; | 80 Sk4f newYs = ys; |
| 68 fStrategy.processPoints(&newXs, &newYs); | 81 fStrategy.processPoints(&newXs, &newYs); |
| 69 fNext->pointListFew(n, newXs, newYs); | 82 fNext->pointListFew(n, newXs, newYs); |
| 70 } | 83 } |
| 71 | 84 |
| 72 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | 85 void pointList4(Sk4fArg xs, Sk4fArg ys) override { |
| 73 Sk4f newXs = xs; | 86 Sk4f newXs = xs; |
| 74 Sk4f newYs = ys; | 87 Sk4f newYs = ys; |
| 75 fStrategy.processPoints(&newXs, &newYs); | 88 fStrategy.processPoints(&newXs, &newYs); |
| 76 fNext->pointList4(newXs, newYs); | 89 fNext->pointList4(newXs, newYs); |
| 77 } | 90 } |
| 78 | 91 |
| 79 void pointSpan(SkPoint start, SkScalar length, int count) override { | 92 void pointSpan(SkPoint start, SkScalar length, int count) override { |
| 80 span_fallback(start, length, count, this); | 93 if (!fStrategy.maybeProcessSpan(start, length, count, fNext)) { |
| 94 span_fallback(start, length, count, this); |
| 95 } |
| 81 } | 96 } |
| 82 | 97 |
| 83 private: | 98 private: |
| 84 Next* const fNext; | 99 Next* const fNext; |
| 85 Strategy fStrategy; | 100 Strategy fStrategy; |
| 86 }; | 101 }; |
| 87 | 102 |
| 103 // See PointProcessor for responsibilities of Strategy. |
| 88 template<typename Strategy, typename Next> | 104 template<typename Strategy, typename Next> |
| 89 class BilerpProcessor final : public BilerpProcessorInterface { | 105 class BilerpProcessor final : public BilerpProcessorInterface { |
| 90 public: | 106 public: |
| 91 template <typename... Args> | 107 template <typename... Args> |
| 92 BilerpProcessor(Next* next, Args&&... args) | 108 BilerpProcessor(Next* next, Args&&... args) |
| 93 : fNext{next} | 109 : fNext{next} |
| 94 , fStrategy{std::forward<Args>(args)...}{ } | 110 , fStrategy{std::forward<Args>(args)...}{ } |
| 95 | 111 |
| 96 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 112 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { |
| 97 Sk4f newXs = xs; | 113 Sk4f newXs = xs; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 108 } | 124 } |
| 109 | 125 |
| 110 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | 126 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { |
| 111 Sk4f newXs = xs; | 127 Sk4f newXs = xs; |
| 112 Sk4f newYs = ys; | 128 Sk4f newYs = ys; |
| 113 fStrategy.processPoints(&newXs, &newYs); | 129 fStrategy.processPoints(&newXs, &newYs); |
| 114 fNext->bilerpList(newXs, newYs); | 130 fNext->bilerpList(newXs, newYs); |
| 115 } | 131 } |
| 116 | 132 |
| 117 void pointSpan(SkPoint start, SkScalar length, int count) override { | 133 void pointSpan(SkPoint start, SkScalar length, int count) override { |
| 118 span_fallback(start, length, count, this); | 134 if (!fStrategy.maybeProcessSpan(start, length, count, fNext)) { |
| 135 span_fallback(start, length, count, this); |
| 136 } |
| 119 } | 137 } |
| 120 | 138 |
| 121 private: | 139 private: |
| 122 Next* const fNext; | 140 Next* const fNext; |
| 123 Strategy fStrategy; | 141 Strategy fStrategy; |
| 124 }; | 142 }; |
| 125 | 143 |
| 126 class SkippedStage final : public BilerpProcessorInterface { | 144 class SkippedStage final : public BilerpProcessorInterface { |
| 127 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 145 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { |
| 128 SkFAIL("Skipped stage."); | 146 SkFAIL("Skipped stage."); |
| 129 } | 147 } |
| 130 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { | 148 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { |
| 131 SkFAIL("Skipped stage."); | 149 SkFAIL("Skipped stage."); |
| 132 } | 150 } |
| 133 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | 151 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { |
| 134 SkFAIL("Skipped stage."); | 152 SkFAIL("Skipped stage."); |
| 135 } | 153 } |
| 136 void pointSpan(SkPoint start, SkScalar length, int count) override { | 154 void pointSpan(SkPoint start, SkScalar length, int count) override { |
| 137 SkFAIL("Skipped stage."); | 155 SkFAIL("Skipped stage."); |
| 138 } | 156 } |
| 139 }; | 157 }; |
| 140 | 158 |
| 141 class TranslateMatrixStrategy { | 159 class TranslateMatrixStrategy { |
| 142 public: | 160 public: |
| 143 TranslateMatrixStrategy(SkVector offset) | 161 TranslateMatrixStrategy(SkVector offset) |
| 144 : fXOffset{X(offset)} | 162 : fXOffset{X(offset)} |
| 145 , fYOffset{Y(offset)} { } | 163 , fYOffset{Y(offset)} { } |
| 164 |
| 146 void processPoints(Sk4f* xs, Sk4f* ys) { | 165 void processPoints(Sk4f* xs, Sk4f* ys) { |
| 147 *xs = *xs + fXOffset; | 166 *xs = *xs + fXOffset; |
| 148 *ys = *ys + fYOffset; | 167 *ys = *ys + fYOffset; |
| 149 } | 168 } |
| 150 | 169 |
| 170 template <typename Next> |
| 171 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next)
{ |
| 172 next->pointSpan(start + SkPoint{fXOffset[0], fYOffset[0]}, length, count
); |
| 173 return true; |
| 174 } |
| 175 |
| 151 private: | 176 private: |
| 152 const Sk4f fXOffset, fYOffset; | 177 const Sk4f fXOffset, fYOffset; |
| 153 }; | 178 }; |
| 154 template <typename Next = PointProcessorInterface> | 179 template <typename Next = PointProcessorInterface> |
| 155 using TranslateMatrix = PointProcessor<TranslateMatrixStrategy, Next>; | 180 using TranslateMatrix = PointProcessor<TranslateMatrixStrategy, Next>; |
| 156 | 181 |
| 157 class ScaleMatrixStrategy { | 182 class ScaleMatrixStrategy { |
| 158 public: | 183 public: |
| 159 ScaleMatrixStrategy(SkVector offset, SkVector scale) | 184 ScaleMatrixStrategy(SkVector offset, SkVector scale) |
| 160 : fXOffset{X(offset)}, fYOffset{Y(offset)} | 185 : fXOffset{X(offset)}, fYOffset{Y(offset)} |
| 161 , fXScale{X(scale)}, fYScale{Y(scale)} { } | 186 , fXScale{X(scale)}, fYScale{Y(scale)} { } |
| 162 void processPoints(Sk4f* xs, Sk4f* ys) { | 187 void processPoints(Sk4f* xs, Sk4f* ys) { |
| 163 *xs = *xs * fXScale + fXOffset; | 188 *xs = *xs * fXScale + fXOffset; |
| 164 *ys = *ys * fYScale + fYOffset; | 189 *ys = *ys * fYScale + fYOffset; |
| 165 } | 190 } |
| 166 | 191 |
| 192 template <typename Next> |
| 193 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next)
{ |
| 194 SkPoint newStart = |
| 195 SkPoint{X(start) * fXScale[0] + fXOffset[0], Y(start) * fYScale[0] +
fYOffset[0]}; |
| 196 SkScalar newLength = length * fXScale[0]; |
| 197 next->pointSpan(newStart, newLength, count); |
| 198 return true; |
| 199 } |
| 200 |
| 167 private: | 201 private: |
| 168 const Sk4f fXOffset, fYOffset; | 202 const Sk4f fXOffset, fYOffset; |
| 169 const Sk4f fXScale, fYScale; | 203 const Sk4f fXScale, fYScale; |
| 170 }; | 204 }; |
| 171 template <typename Next = PointProcessorInterface> | 205 template <typename Next = PointProcessorInterface> |
| 172 using ScaleMatrix = PointProcessor<ScaleMatrixStrategy, Next>; | 206 using ScaleMatrix = PointProcessor<ScaleMatrixStrategy, Next>; |
| 173 | 207 |
| 174 class AffineMatrixStrategy { | 208 class AffineMatrixStrategy { |
| 175 public: | 209 public: |
| 176 AffineMatrixStrategy(SkVector offset, SkVector scale, SkVector skew) | 210 AffineMatrixStrategy(SkVector offset, SkVector scale, SkVector skew) |
| 177 : fXOffset{X(offset)}, fYOffset{Y(offset)} | 211 : fXOffset{X(offset)}, fYOffset{Y(offset)} |
| 178 , fXScale{X(scale)}, fYScale{Y(scale)} | 212 , fXScale{X(scale)}, fYScale{Y(scale)} |
| 179 , fXSkew{X(skew)}, fYSkew{Y(skew)} { } | 213 , fXSkew{X(skew)}, fYSkew{Y(skew)} { } |
| 180 void processPoints(Sk4f* xs, Sk4f* ys) { | 214 void processPoints(Sk4f* xs, Sk4f* ys) { |
| 181 Sk4f newXs = fXScale * *xs + fXSkew * *ys + fXOffset; | 215 Sk4f newXs = fXScale * *xs + fXSkew * *ys + fXOffset; |
| 182 Sk4f newYs = fYSkew * *xs + fYScale * *ys + fYOffset; | 216 Sk4f newYs = fYSkew * *xs + fYScale * *ys + fYOffset; |
| 183 | 217 |
| 184 *xs = newXs; | 218 *xs = newXs; |
| 185 *ys = newYs; | 219 *ys = newYs; |
| 186 } | 220 } |
| 187 | 221 |
| 222 template <typename Next> |
| 223 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next)
{ |
| 224 return false; |
| 225 } |
| 226 |
| 188 private: | 227 private: |
| 189 const Sk4f fXOffset, fYOffset; | 228 const Sk4f fXOffset, fYOffset; |
| 190 const Sk4f fXScale, fYScale; | 229 const Sk4f fXScale, fYScale; |
| 191 const Sk4f fXSkew, fYSkew; | 230 const Sk4f fXSkew, fYSkew; |
| 192 }; | 231 }; |
| 193 template <typename Next = PointProcessorInterface> | 232 template <typename Next = PointProcessorInterface> |
| 194 using AffineMatrix = PointProcessor<AffineMatrixStrategy, Next>; | 233 using AffineMatrix = PointProcessor<AffineMatrixStrategy, Next>; |
| 195 | 234 |
| 196 static PointProcessorInterface* choose_matrix( | 235 static PointProcessorInterface* choose_matrix( |
| 197 PointProcessorInterface* next, | 236 PointProcessorInterface* next, |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 : fXMin{0.0f} | 318 : fXMin{0.0f} |
| 280 , fYMin{0.0f} | 319 , fYMin{0.0f} |
| 281 , fXMax{X(max) - 1.0f} | 320 , fXMax{X(max) - 1.0f} |
| 282 , fYMax{Y(max) - 1.0f} { } | 321 , fYMax{Y(max) - 1.0f} { } |
| 283 | 322 |
| 284 void processPoints(Sk4f* xs, Sk4f* ys) { | 323 void processPoints(Sk4f* xs, Sk4f* ys) { |
| 285 *xs = Sk4f::Min(Sk4f::Max(*xs, fXMin), fXMax); | 324 *xs = Sk4f::Min(Sk4f::Max(*xs, fXMin), fXMax); |
| 286 *ys = Sk4f::Min(Sk4f::Max(*ys, fYMin), fYMax); | 325 *ys = Sk4f::Min(Sk4f::Max(*ys, fYMin), fYMax); |
| 287 } | 326 } |
| 288 | 327 |
| 328 template <typename Next> |
| 329 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next)
{ |
| 330 return false; |
| 331 } |
| 332 |
| 289 private: | 333 private: |
| 290 const Sk4f fXMin{SK_FloatNegativeInfinity}; | 334 const Sk4f fXMin{SK_FloatNegativeInfinity}; |
| 291 const Sk4f fYMin{SK_FloatNegativeInfinity}; | 335 const Sk4f fYMin{SK_FloatNegativeInfinity}; |
| 292 const Sk4f fXMax{SK_FloatInfinity}; | 336 const Sk4f fXMax{SK_FloatInfinity}; |
| 293 const Sk4f fYMax{SK_FloatInfinity}; | 337 const Sk4f fYMax{SK_FloatInfinity}; |
| 294 }; | 338 }; |
| 295 template <typename Next = BilerpProcessorInterface> | 339 template <typename Next = BilerpProcessorInterface> |
| 296 using Clamp = BilerpProcessor<ClampStrategy, Next>; | 340 using Clamp = BilerpProcessor<ClampStrategy, Next>; |
| 297 | 341 |
| 298 class RepeatStrategy { | 342 class RepeatStrategy { |
| 299 public: | 343 public: |
| 300 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { } | 344 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { } |
| 301 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { } | 345 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { } |
| 302 RepeatStrategy(SkSize max) | 346 RepeatStrategy(SkSize max) |
| 303 : fXMax{X(max)} | 347 : fXMax{X(max)} |
| 304 , fXInvMax{1.0f / X(max)} | 348 , fXInvMax{1.0f / X(max)} |
| 305 , fYMax{Y(max)} | 349 , fYMax{Y(max)} |
| 306 , fYInvMax{1.0f / Y(max)} { } | 350 , fYInvMax{1.0f / Y(max)} { } |
| 307 | 351 |
| 308 void processPoints(Sk4f* xs, Sk4f* ys) { | 352 void processPoints(Sk4f* xs, Sk4f* ys) { |
| 309 Sk4f divX = (*xs * fXInvMax).floor(); | 353 Sk4f divX = (*xs * fXInvMax).floor(); |
| 310 Sk4f divY = (*ys * fYInvMax).floor(); | 354 Sk4f divY = (*ys * fYInvMax).floor(); |
| 311 Sk4f baseX = (divX * fXMax); | 355 Sk4f baseX = (divX * fXMax); |
| 312 Sk4f baseY = (divY * fYMax); | 356 Sk4f baseY = (divY * fYMax); |
| 313 *xs = *xs - baseX; | 357 *xs = *xs - baseX; |
| 314 *ys = *ys - baseY; | 358 *ys = *ys - baseY; |
| 315 } | 359 } |
| 316 | 360 |
| 361 template <typename Next> |
| 362 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next)
{ |
| 363 return false; |
| 364 } |
| 365 |
| 317 private: | 366 private: |
| 318 const Sk4f fXMax{0.0f}; | 367 const Sk4f fXMax{0.0f}; |
| 319 const Sk4f fXInvMax{0.0f}; | 368 const Sk4f fXInvMax{0.0f}; |
| 320 const Sk4f fYMax{0.0f}; | 369 const Sk4f fYMax{0.0f}; |
| 321 const Sk4f fYInvMax{0.0f}; | 370 const Sk4f fYInvMax{0.0f}; |
| 322 }; | 371 }; |
| 323 | 372 |
| 324 template <typename Next = BilerpProcessorInterface> | 373 template <typename Next = BilerpProcessorInterface> |
| 325 using Repeat = BilerpProcessor<RepeatStrategy, Next>; | 374 using Repeat = BilerpProcessor<RepeatStrategy, Next>; |
| 326 | 375 |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 if (count == 1) { | 651 if (count == 1) { |
| 603 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f}); | 652 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f}); |
| 604 } else { | 653 } else { |
| 605 // The count and length arguments start out in a precise relation in ord
er to keep the | 654 // The count and length arguments start out in a precise relation in ord
er to keep the |
| 606 // math correct through the different stages. Count is the number of pix
el to produce. | 655 // math correct through the different stages. Count is the number of pix
el to produce. |
| 607 // Since the code samples at pixel centers, length is the distance from
the center of the | 656 // Since the code samples at pixel centers, length is the distance from
the center of the |
| 608 // first pixel to the center of the last pixel. This implies that length
is count-1. | 657 // first pixel to the center of the last pixel. This implies that length
is count-1. |
| 609 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count); | 658 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count); |
| 610 } | 659 } |
| 611 } | 660 } |
| OLD | NEW |