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); |
} |