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

Unified Diff: src/core/SkLinearBitmapPipeline_core.h

Issue 1775963002: Bilerp + mirror + perspective (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments. Created 4 years, 9 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 | « src/core/SkLinearBitmapPipeline.cpp ('k') | src/core/SkLinearBitmapPipeline_matrix.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkLinearBitmapPipeline_core.h
diff --git a/src/core/SkLinearBitmapPipeline_core.h b/src/core/SkLinearBitmapPipeline_core.h
index 0541f3cce5ca45804ecd14abd2ab0baf38517d41..2759f0bb8ccc728472bb68a23d72c8bedf073007 100644
--- a/src/core/SkLinearBitmapPipeline_core.h
+++ b/src/core/SkLinearBitmapPipeline_core.h
@@ -10,6 +10,16 @@
#include <cmath>
+// New bilerp strategy:
+// Pass through on bilerpList4 and bilerpListFew (analogs to pointList), introduce bilerpEdge
+// which takes 4 points. If the sample spans an edge, then break it into a bilerpEdge. Bilerp
+// span then becomes a normal span except in special cases where an extra Y is given. The bilerp
+// need to stay single point calculations until the tile layer.
+// TODO:
+// - edge span predicate.
+// - introduce new point API
+// - Add tile for new api.
+
// Tweak ABI of functions that pass Sk4f by value to pass them via registers.
#if defined(_MSC_VER) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
#define VECTORCALL __vectorcall
@@ -65,12 +75,13 @@ public:
}
bool isEmpty() const { return 0 == fCount; }
+ void clear() { fCount = 0; }
+ int count() const { return fCount; }
SkScalar length() const { return fLength; }
SkScalar startX() const { return X(fStart); }
- SkScalar endX() const { return startX() + length(); }
- void clear() {
- fCount = 0;
- }
+ SkScalar endX() const { return this->startX() + this->length(); }
+ SkScalar startY() const { return Y(fStart); }
+ Span emptySpan() { return Span{{0.0, 0.0}, 0.0f, 0}; }
bool completelyWithin(SkScalar xMin, SkScalar xMax) const {
SkScalar sMin, sMax;
@@ -88,17 +99,14 @@ public:
SkASSERT(dx != 0.0f);
if (this->isEmpty()) {
- return Span{{0.0, 0.0}, 0.0f, 0};
+ return this->emptySpan();
}
int dxSteps = SkScalarFloorToInt((breakX - this->startX()) / dx);
- // Calculate the values for the span to cleave off.
- SkScalar newLength = dxSteps * dx;
-
if (dxSteps < 0) {
// The span is wholly after breakX.
- return Span{{0.0, 0.0}, 0.0f, 0};
+ return this->emptySpan();
} else if (dxSteps >= fCount) {
// The span is wholly before breakX.
Span answer = *this;
@@ -106,6 +114,9 @@ public:
return answer;
}
+ // Calculate the values for the span to cleave off.
+ SkScalar newLength = dxSteps * dx;
+
// If the last (or first if count = 1) sample lands directly on the boundary. Include it
// when dx < 0 and exclude it when dx > 0.
// Reasoning:
@@ -113,15 +124,16 @@ public:
// pixel is after the boundary.
// dx < 0: The sample point on the boundary is part of the current span because the
// entire pixel is before the boundary.
- if (startX() + newLength == breakX && dx > 0) {
- if (dxSteps != 0) {
+ if (this->startX() + newLength == breakX && dx > 0) {
+ if (dxSteps > 0) {
dxSteps -= 1;
newLength -= dx;
} else {
- return Span{{0.0, 0.0}, 0.0f, 0};
+ return this->emptySpan();
}
}
+ // Calculate new span parameters
SkPoint newStart = fStart;
int newCount = dxSteps + 1;
SkASSERT(newCount > 0);
@@ -146,39 +158,6 @@ private:
int fCount;
};
-// BilerpSpans are similar to Spans, but they represent four source samples converting to single
-// destination pixel per count. The pixels for the four samples are collect along two horizontal
-// lines; one starting at {x, y0} and the other starting at {x, y1}. There are two distinct lines
-// to deal with the edge case of the tile mode. For example, y0 may be at the last y position in
-// a tile while y1 would be at the first.
-// The step of a Bilerp (dx) is still length / (count - 1) and the start to the next sample is
-// still dx * count, but the bounds are complicated by the sampling kernel so that the pixels
-// touched are from x to x + length + 1.
-class BilerpSpan {
-public:
- BilerpSpan(SkScalar x, SkScalar y0, SkScalar y1, SkScalar length, int count)
- : fX{x}, fY0{y0}, fY1{y1}, fLength{length}, fCount{count} {
- SkASSERT(count >= 0);
- SkASSERT(std::isfinite(length));
- SkASSERT(std::isfinite(x));
- SkASSERT(std::isfinite(y0));
- SkASSERT(std::isfinite(y1));
- }
-
- operator std::tuple<SkScalar&, SkScalar&, SkScalar&, SkScalar&, int&>() {
- return std::tie(fX, fY0, fY1, fLength, fCount);
- }
-
- bool isEmpty() const { return 0 == fCount; }
-
-private:
- SkScalar fX;
- SkScalar fY0;
- SkScalar fY1;
- SkScalar fLength;
- int fCount;
-};
-
template<typename Stage>
void span_fallback(Span span, Stage* stage) {
SkPoint start;
@@ -206,26 +185,6 @@ void span_fallback(Span span, Stage* stage) {
stage->pointListFew(count, xs, ys);
}
}
-
-template <typename Next>
-void bilerp_span_fallback(BilerpSpan span, Next* next) {
- SkScalar x, y0, y1; SkScalar length; int count;
- std::tie(x, y0, y1, length, count) = span;
-
- SkASSERT(!span.isEmpty());
- float dx = length / (count - 1);
-
- Sk4f xs = Sk4f{x} + Sk4f{0.0f, 1.0f, 0.0f, 1.0f};
- Sk4f ys = Sk4f{y0, y0, y1, y1};
-
- // If count == 1 then dx will be inf or NaN, but that is ok because the resulting addition is
- // never used.
- while (count > 0) {
- next->bilerpList(xs, ys);
- xs = xs + dx;
- count -= 1;
- }
-}
} // namespace
#endif // SkLinearBitmapPipeline_core_DEFINED
« no previous file with comments | « src/core/SkLinearBitmapPipeline.cpp ('k') | src/core/SkLinearBitmapPipeline_matrix.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698