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 #ifndef SkLinearBitmapPipeline_sampler_DEFINED | 8 #ifndef SkLinearBitmapPipeline_sampler_DEFINED |
9 #define SkLinearBitmapPipeline_sampler_DEFINED | 9 #define SkLinearBitmapPipeline_sampler_DEFINED |
10 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 // +--------+--------+ | 32 // +--------+--------+ |
33 // | 33 // |
34 // | 34 // |
35 // Given a pixelxy each is multiplied by a different factor derived from the fra
ctional part of x | 35 // Given a pixelxy each is multiplied by a different factor derived from the fra
ctional part of x |
36 // and y: | 36 // and y: |
37 // * px00 -> (1 - x)(1 - y) = 1 - x - y + xy | 37 // * px00 -> (1 - x)(1 - y) = 1 - x - y + xy |
38 // * px10 -> x(1 - y) = x - xy | 38 // * px10 -> x(1 - y) = x - xy |
39 // * px01 -> (1 - x)y = y - xy | 39 // * px01 -> (1 - x)y = y - xy |
40 // * px11 -> xy | 40 // * px11 -> xy |
41 // So x * y is calculated first and then used to calculate all the other factors
. | 41 // So x * y is calculated first and then used to calculate all the other factors
. |
42 static Sk4s VECTORCALL bilerp4(Sk4s xs, Sk4s ys, Sk4f px00, Sk4f px10, | 42 static Sk4s SK_VECTORCALL bilerp4(Sk4s xs, Sk4s ys, Sk4f px00, Sk4f px10, |
43 Sk4f px01, Sk4f px11) { | 43 Sk4f px01, Sk4f px11) { |
44 // Calculate fractional xs and ys. | 44 // Calculate fractional xs and ys. |
45 Sk4s fxs = xs - xs.floor(); | 45 Sk4s fxs = xs - xs.floor(); |
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; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 template <SkColorType colorType, SkGammaType gammaType> | 209 template <SkColorType colorType, SkGammaType gammaType> |
210 class PixelAccessor { | 210 class PixelAccessor { |
211 using Element = typename PixelGetter<colorType, gammaType>::Element; | 211 using Element = typename PixelGetter<colorType, gammaType>::Element; |
212 public: | 212 public: |
213 template <typename... Args> | 213 template <typename... Args> |
214 PixelAccessor(const SkPixmap& srcPixmap, Args&&... args) | 214 PixelAccessor(const SkPixmap& srcPixmap, Args&&... args) |
215 : fSrc{static_cast<const Element*>(srcPixmap.addr())} | 215 : fSrc{static_cast<const Element*>(srcPixmap.addr())} |
216 , fWidth{srcPixmap.rowBytesAsPixels()} | 216 , fWidth{srcPixmap.rowBytesAsPixels()} |
217 , fGetter{srcPixmap, std::move<Args>(args)...} { } | 217 , fGetter{srcPixmap, std::move<Args>(args)...} { } |
218 | 218 |
219 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1,
Sk4f* px2) { | 219 void SK_VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px
1, Sk4f* px2) { |
220 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); | 220 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); |
221 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); | 221 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); |
222 Sk4i bufferLoc = YIs * fWidth + XIs; | 222 Sk4i bufferLoc = YIs * fWidth + XIs; |
223 switch (n) { | 223 switch (n) { |
224 case 3: | 224 case 3: |
225 *px2 = this->getPixelAt(bufferLoc[2]); | 225 *px2 = this->getPixelAt(bufferLoc[2]); |
226 case 2: | 226 case 2: |
227 *px1 = this->getPixelAt(bufferLoc[1]); | 227 *px1 = this->getPixelAt(bufferLoc[1]); |
228 case 1: | 228 case 1: |
229 *px0 = this->getPixelAt(bufferLoc[0]); | 229 *px0 = this->getPixelAt(bufferLoc[0]); |
230 default: | 230 default: |
231 break; | 231 break; |
232 } | 232 } |
233 } | 233 } |
234 | 234 |
235 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2
, Sk4f* px3) { | 235 void SK_VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f*
px2, Sk4f* px3) { |
236 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); | 236 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); |
237 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); | 237 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); |
238 Sk4i bufferLoc = YIs * fWidth + XIs; | 238 Sk4i bufferLoc = YIs * fWidth + XIs; |
239 *px0 = this->getPixelAt(bufferLoc[0]); | 239 *px0 = this->getPixelAt(bufferLoc[0]); |
240 *px1 = this->getPixelAt(bufferLoc[1]); | 240 *px1 = this->getPixelAt(bufferLoc[1]); |
241 *px2 = this->getPixelAt(bufferLoc[2]); | 241 *px2 = this->getPixelAt(bufferLoc[2]); |
242 *px3 = this->getPixelAt(bufferLoc[3]); | 242 *px3 = this->getPixelAt(bufferLoc[3]); |
243 } | 243 } |
244 | 244 |
245 void get4Pixels(const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2,
Sk4f* px3) { | 245 void get4Pixels(const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2,
Sk4f* px3) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 class NearestNeighborSampler : public SkLinearBitmapPipeline::SampleProcessorInt
erface { | 312 class NearestNeighborSampler : public SkLinearBitmapPipeline::SampleProcessorInt
erface { |
313 public: | 313 public: |
314 template<typename... Args> | 314 template<typename... Args> |
315 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next
, Args&& ... args) | 315 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next
, Args&& ... args) |
316 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } | 316 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } |
317 | 317 |
318 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next
, | 318 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next
, |
319 const NearestNeighborSampler& sampler) | 319 const NearestNeighborSampler& sampler) |
320 : fNext{next}, fStrategy{sampler.fStrategy} { } | 320 : fNext{next}, fStrategy{sampler.fStrategy} { } |
321 | 321 |
322 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { | 322 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { |
323 SkASSERT(0 < n && n < 4); | 323 SkASSERT(0 < n && n < 4); |
324 Sk4f px0, px1, px2; | 324 Sk4f px0, px1, px2; |
325 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); | 325 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); |
326 if (n >= 1) fNext->blendPixel(px0); | 326 if (n >= 1) fNext->blendPixel(px0); |
327 if (n >= 2) fNext->blendPixel(px1); | 327 if (n >= 2) fNext->blendPixel(px1); |
328 if (n >= 3) fNext->blendPixel(px2); | 328 if (n >= 3) fNext->blendPixel(px2); |
329 } | 329 } |
330 | 330 |
331 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { | 331 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { |
332 Sk4f px0, px1, px2, px3; | 332 Sk4f px0, px1, px2, px3; |
333 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); | 333 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); |
334 fNext->blend4Pixels(px0, px1, px2, px3); | 334 fNext->blend4Pixels(px0, px1, px2, px3); |
335 } | 335 } |
336 | 336 |
337 void pointSpan(Span span) override { | 337 void pointSpan(Span span) override { |
338 SkASSERT(!span.isEmpty()); | 338 SkASSERT(!span.isEmpty()); |
339 SkPoint start; | 339 SkPoint start; |
340 SkScalar length; | 340 SkScalar length; |
341 int count; | 341 int count; |
342 std::tie(start, length, count) = span; | 342 std::tie(start, length, count) = span; |
343 SkScalar absLength = SkScalarAbs(length); | 343 SkScalar absLength = SkScalarAbs(length); |
344 if (absLength < (count - 1)) { | 344 if (absLength < (count - 1)) { |
345 this->spanSlowRate(span); | 345 this->spanSlowRate(span); |
346 } else if (absLength == (count - 1)) { | 346 } else if (absLength == (count - 1)) { |
347 src_strategy_blend(span, fNext, &fStrategy); | 347 src_strategy_blend(span, fNext, &fStrategy); |
348 } else { | 348 } else { |
349 this->spanFastRate(span); | 349 this->spanFastRate(span); |
350 } | 350 } |
351 } | 351 } |
352 | 352 |
353 void repeatSpan(Span span, int32_t repeatCount) override { | 353 void repeatSpan(Span span, int32_t repeatCount) override { |
354 while (repeatCount > 0) { | 354 while (repeatCount > 0) { |
355 this->pointSpan(span); | 355 this->pointSpan(span); |
356 repeatCount--; | 356 repeatCount--; |
357 } | 357 } |
358 } | 358 } |
359 | 359 |
360 void VECTORCALL bilerpEdge(Sk4s xs, Sk4s ys) override { | 360 void SK_VECTORCALL bilerpEdge(Sk4s xs, Sk4s ys) override { |
361 SkFAIL("Using nearest neighbor sampler, but calling a bilerpEdge."); | 361 SkFAIL("Using nearest neighbor sampler, but calling a bilerpEdge."); |
362 } | 362 } |
363 | 363 |
364 void bilerpSpan(Span span, SkScalar y) override { | 364 void bilerpSpan(Span span, SkScalar y) override { |
365 SkFAIL("Using nearest neighbor sampler, but calling a bilerpSpan."); | 365 SkFAIL("Using nearest neighbor sampler, but calling a bilerpSpan."); |
366 } | 366 } |
367 | 367 |
368 private: | 368 private: |
369 // When moving through source space more slowly than dst space (zoomed in), | 369 // When moving through source space more slowly than dst space (zoomed in), |
370 // we'll be sampling from the same source pixel more than once. | 370 // we'll be sampling from the same source pixel more than once. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 | 446 |
447 // bilerp4() expects xs, ys are the top-lefts of the 2x2 kernel. | 447 // bilerp4() expects xs, ys are the top-lefts of the 2x2 kernel. |
448 Sk4f xs = Sk4f{x} - 0.5f; | 448 Sk4f xs = Sk4f{x} - 0.5f; |
449 Sk4f ys = Sk4f{y} - 0.5f; | 449 Sk4f ys = Sk4f{y} - 0.5f; |
450 Sk4f sampleXs = xs + Sk4f{0.0f, 1.0f, 0.0f, 1.0f}; | 450 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}; | 451 Sk4f sampleYs = ys + Sk4f{0.0f, 0.0f, 1.0f, 1.0f}; |
452 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); | 452 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); |
453 return bilerp4(xs, ys, px00, px10, px01, px11); | 453 return bilerp4(xs, ys, px00, px10, px01, px11); |
454 } | 454 } |
455 | 455 |
456 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { | 456 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { |
457 SkASSERT(0 < n && n < 4); | 457 SkASSERT(0 < n && n < 4); |
458 auto bilerpPixel = [&](int index) { | 458 auto bilerpPixel = [&](int index) { |
459 return this->bilerpNonEdgePixel(xs[index], ys[index]); | 459 return this->bilerpNonEdgePixel(xs[index], ys[index]); |
460 }; | 460 }; |
461 | 461 |
462 if (n >= 1) fNext->blendPixel(bilerpPixel(0)); | 462 if (n >= 1) fNext->blendPixel(bilerpPixel(0)); |
463 if (n >= 2) fNext->blendPixel(bilerpPixel(1)); | 463 if (n >= 2) fNext->blendPixel(bilerpPixel(1)); |
464 if (n >= 3) fNext->blendPixel(bilerpPixel(2)); | 464 if (n >= 3) fNext->blendPixel(bilerpPixel(2)); |
465 } | 465 } |
466 | 466 |
467 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { | 467 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { |
468 auto bilerpPixel = [&](int index) { | 468 auto bilerpPixel = [&](int index) { |
469 return this->bilerpNonEdgePixel(xs[index], ys[index]); | 469 return this->bilerpNonEdgePixel(xs[index], ys[index]); |
470 }; | 470 }; |
471 fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile
rpPixel(3)); | 471 fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile
rpPixel(3)); |
472 } | 472 } |
473 | 473 |
474 void pointSpan(Span span) override { | 474 void pointSpan(Span span) override { |
475 this->bilerpSpan(span, span.startY()); | 475 this->bilerpSpan(span, span.startY()); |
476 } | 476 } |
477 | 477 |
478 void repeatSpan(Span span, int32_t repeatCount) override { | 478 void repeatSpan(Span span, int32_t repeatCount) override { |
479 while (repeatCount > 0) { | 479 while (repeatCount > 0) { |
480 this->pointSpan(span); | 480 this->pointSpan(span); |
481 repeatCount--; | 481 repeatCount--; |
482 } | 482 } |
483 } | 483 } |
484 | 484 |
485 void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) override { | 485 void SK_VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) override { |
486 Sk4f px00, px10, px01, px11; | 486 Sk4f px00, px10, px01, px11; |
487 Sk4f xs = Sk4f{sampleXs[0]}; | 487 Sk4f xs = Sk4f{sampleXs[0]}; |
488 Sk4f ys = Sk4f{sampleYs[0]}; | 488 Sk4f ys = Sk4f{sampleYs[0]}; |
489 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); | 489 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); |
490 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); | 490 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); |
491 fNext->blendPixel(pixel); | 491 fNext->blendPixel(pixel); |
492 } | 492 } |
493 | 493 |
494 void bilerpSpan(Span span, SkScalar y) override { | 494 void bilerpSpan(Span span, SkScalar y) override { |
495 SkASSERT(!span.isEmpty()); | 495 SkASSERT(!span.isEmpty()); |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 } | 801 } |
802 } | 802 } |
803 | 803 |
804 Next* const fNext; | 804 Next* const fNext; |
805 PixelAccessor<colorType, gammaType> fStrategy; | 805 PixelAccessor<colorType, gammaType> fStrategy; |
806 }; | 806 }; |
807 | 807 |
808 } // namespace | 808 } // namespace |
809 | 809 |
810 #endif // SkLinearBitmapPipeline_sampler_DEFINED | 810 #endif // SkLinearBitmapPipeline_sampler_DEFINED |
OLD | NEW |