Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Unified Diff: src/core/SkLinearBitmapPipeline.cpp

Issue 1743123004: Handle spans in sampling. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkLinearBitmapPipeline.cpp
diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp
index e836746a891ff740d74d7422f08336cff16c214a..236f5bf8768712e13a19096d9b1fd55148229827 100644
--- a/src/core/SkLinearBitmapPipeline.cpp
+++ b/src/core/SkLinearBitmapPipeline.cpp
@@ -745,7 +745,16 @@ public:
*px3 = this->getPixel(fSrc, bufferLoc[3]);
}
- Sk4f getPixel(const uint32_t* src, int index) {
+ void get4Pixels(const void* vsrc, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) {
+ const uint32_t* src = static_cast<const uint32_t*>(vsrc);
+ *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 void* vsrc, int index) {
+ const uint32_t* src = static_cast<const uint32_t*>(vsrc);
Sk4b bytePixel = Sk4b::Load((uint8_t *)(&src[index]));
Sk4f pixel = SkNx_cast<float, uint8_t>(bytePixel);
if (colorOrder == ColorOrder::kBGRA) {
@@ -829,6 +838,89 @@ 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)) {
+ this->pointSpanSlowRate(span);
+ } else if (length == (count - 1)) {
+ this->pointSpanUnitRate(span);
+ } else {
+ this->pointSpanFastRate(span);
+ }
+ }
+
+private:
+ // When moving through source space more slowly than dst space (zoomed in),
+ // we'll be sampling from the same source pixel more than once.
+ void pointSpanSlowRate(Span span) {
+ 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 void* row = fStrategy.row((int)std::floor(Y(start)));
+ SkLinearBitmapPipeline::PixelPlacerInterface* next = fNext;
+
+ int ix = SkFixedFloorToInt(fx);
+ int prevIX = ix;
+ Sk4f fpixel = fStrategy.getPixel(row, ix);
+
+ // When dx is less than one, each pixel is used more than once. Using the fixed point fx
+ // allows the code to quickly check that the same pixel is being used. The code uses this
+ // same pixel check to do the sRGB and normalization only once.
+ auto getNextPixel = [&]() {
+ 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;
+ }
+ }
+
+ // We're moving through source space at a rate of 1 source pixel per 1 dst pixel.
+ // We'll never re-use pixels, but we can at least load contiguous pixels.
+ void pointSpanUnitRate(Span span) {
+ SkPoint start; SkScalar length; int count;
+ std::tie(start, length, count) = span;
+ int ix = SkScalarFloorToInt(X(start));
+ const void* row = fStrategy.row((int)std::floor(Y(start)));
+ SkLinearBitmapPipeline::PixelPlacerInterface* 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;
+ }
+ }
+
+ // We're moving through source space faster than dst (zoomed out),
+ // so we'll never reuse a source pixel or be able to do contiguous loads.
+ void pointSpanFastRate(Span span) {
span_fallback(span, this);
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698