Chromium Code Reviews| Index: src/core/SkLinearBitmapPipeline.cpp |
| diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp |
| index e836746a891ff740d74d7422f08336cff16c214a..9f0c4f810084928ecf067d7f7d9cbdce1fcb26c7 100644 |
| --- a/src/core/SkLinearBitmapPipeline.cpp |
| +++ b/src/core/SkLinearBitmapPipeline.cpp |
| @@ -745,6 +745,13 @@ public: |
| *px3 = this->getPixel(fSrc, bufferLoc[3]); |
| } |
| + void get4Pixels(const uint32_t* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) { |
| + *px0 = this->getPixel(src, index + 0); |
| + *px1 = this->getPixel(src, index + 1); |
| + *px2 = this->getPixel(src, index + 2); |
| + *px3 = this->getPixel(src, index + 3); |
| + } |
| + |
| Sk4f getPixel(const uint32_t* src, int index) { |
| Sk4b bytePixel = Sk4b::Load((uint8_t *)(&src[index])); |
| Sk4f pixel = SkNx_cast<float, uint8_t>(bytePixel); |
| @@ -829,6 +836,77 @@ public: |
| } |
| void pointSpan(Span span) override { |
| + SkASSERT(!span.isEmpty()); |
| + SkPoint start; SkScalar length; int count; |
| + std::tie(start, length, count) = span; |
| + if (length < (count - 1)) { |
| + pointSpanSlowRate(span); |
|
mtklein_C
2016/03/01 18:53:05
Please do a this-> pass.
herb_g
2016/03/01 20:57:06
Done.
|
| + } else if (length == (count - 1)) { |
| + pointSpanUnitRate(span); |
| + } else { |
| + pointSpanFastRate(span); |
| + } |
| + } |
| + |
| + |
| +private: |
| + void pointSpanSlowRate(Span span) { |
|
mtklein_C
2016/03/01 18:53:05
// When moving through source space more slowly th
herb_g
2016/03/01 20:57:06
Done.
|
| + SkPoint start; SkScalar length; int count; |
| + std::tie(start, length, count) = span; |
| + SkScalar x = X(start); |
| + SkFixed fx = SkScalarToFixed(x); |
| + SkScalar dx = length / (count - 1); |
| + SkFixed fdx = SkScalarToFixed(dx); |
| + |
| + const uint32_t* const row = fStrategy.row((int)std::floor(Y(start))); |
|
mtklein_C
2016/03/01 18:53:05
Seems like we can't logically write uint32_t here.
herb_g
2016/03/01 20:57:07
Done.
|
| + SkLinearBitmapPipeline::PixelPlacerInterface* const next = fNext; |
|
mtklein_C
2016/03/01 18:53:06
Just my opinion: I think marking pointers const us
herb_g
2016/03/01 20:57:07
Done.
|
| + int ix = SkFixedFloorToInt(fx); |
| + int prevIX = ix; |
| + Sk4f fpixel = fStrategy.getPixel(row, ix); |
| + auto getNextPixel = [&]() { |
|
mtklein_C
2016/03/01 18:53:05
// As dx gets smaller, we take more and more sampl
herb_g
2016/03/01 20:57:06
Done.
|
| + if (ix != prevIX) { |
| + fpixel = fStrategy.getPixel(row, ix); |
| + prevIX = ix; |
| + } |
| + fx += fdx; |
| + ix = SkFixedFloorToInt(fx); |
| + return fpixel; |
| + }; |
| + while (count >= 4) { |
| + Sk4f px0 = getNextPixel(); |
| + Sk4f px1 = getNextPixel(); |
| + Sk4f px2 = getNextPixel(); |
| + Sk4f px3 = getNextPixel(); |
| + next->place4Pixels(px0, px1, px2, px3); |
| + count -= 4; |
| + } |
| + while (count > 0) { |
| + next->placePixel(getNextPixel()); |
| + count -= 1; |
| + } |
| + } |
| + |
| + void pointSpanUnitRate(Span span) { |
|
mtklein_C
2016/03/01 18:53:05
// We're moving through source space at a rate of
herb_g
2016/03/01 20:57:06
Done.
|
| + SkPoint start; SkScalar length; int count; |
| + std::tie(start, length, count) = span; |
| + const uint32_t* const row = fStrategy.row((int)std::floor(Y(start))); |
| + int ix = SkScalarFloorToInt(X(start)); |
| + SkLinearBitmapPipeline::PixelPlacerInterface* const next = fNext; |
| + while (count >= 4) { |
| + Sk4f px0, px1, px2, px3; |
| + fStrategy.get4Pixels(row, ix, &px0, &px1, &px2, &px3); |
| + next->place4Pixels(px0, px1, px2, px3); |
| + ix += 4; |
| + count -= 4; |
| + } |
| + while (count > 0) { |
| + next->placePixel(fStrategy.getPixel(row, ix)); |
| + ix += 1; |
| + count -= 1; |
| + } |
| + } |
| + |
| + void pointSpanFastRate(Span span) { |
|
mtklein_C
2016/03/01 18:53:06
// We're moving through source space faster than d
herb_g
2016/03/01 20:57:06
Done.
|
| span_fallback(span, this); |
| } |