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

Unified Diff: src/core/SkLinearBitmapPipeline.cpp

Issue 1719333002: tile spans (Closed) Base URL: https://skia.googlesource.com/skia.git@code-organization-speed
Patch Set: After sync 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 02a4bd39f3df869a5d6a75284da472bb636646e2..b61810936bfbaa7505988ea88199a8351cff759b 100644
--- a/src/core/SkLinearBitmapPipeline.cpp
+++ b/src/core/SkLinearBitmapPipeline.cpp
@@ -374,7 +374,50 @@ public:
template <typename Next>
bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) {
- return false;
+ SkScalar xMin = fXMin[0];
mtklein 2016/02/23 15:51:56 It's occurred to me that we should probably be usi
herb_g 2016/02/23 21:10:23 Done.
+ SkScalar xMax = fXMax[0];
+ SkScalar yMin = fYMin[0];
+ SkScalar yMax = fYMax[0];
+ SkScalar x = X(start);
+ SkScalar y = std::min(std::max(yMin, start.fY), yMax);
mtklein 2016/02/23 15:51:56 Weird to write X(start) and start.fY...
herb_g 2016/02/23 21:10:23 Done.
+
mtklein 2016/02/23 15:51:56 Some ideas: - invert the logic so the easy case
herb_g 2016/02/23 21:10:23 I did this a totally different way. Please re-revi
+ int beforeCount = 0;
+ int middleCount = count;
+ int afterCount = 0;
+ if (x < xMin || x + length > xMax) {
+ SkScalar dx = length / (count - 1);
f(malita) 2016/02/23 20:53:48 'count' is the span/pixel count, right - why (coun
f(malita) 2016/02/23 21:04:08 A more general comment re. dx and dst->src mapping
+
+ if (x < xMin) {
+ SkScalar overLength = xMin - x;
+ beforeCount = SkScalarFloorToInt(overLength / dx) + 1;
+ middleCount -= beforeCount;
+ length = length - dx * beforeCount;
+ x = xMin;
+ }
+
+ if (x + length > xMax) {
+ SkScalar overLength = (x + length) - xMax;
+ afterCount = SkScalarFloorToInt(overLength / dx) + 1;
+ middleCount -= afterCount;
+ length = length - dx * afterCount;
+ }
+ auto SendSpan = [&](SkPoint start, SkScalar length, int count) {
f(malita) 2016/02/23 20:53:48 Looks like we only need to capture 'next' here.
herb_g 2016/02/23 21:30:35 This is gone. I made Span handle count == 1.
+ if (count > 0) {
+ if (count == 1) {
+ next->pointListFew(1, Sk4f{X(start)}, Sk4f{Y(start)});
mtklein 2016/02/23 15:51:56 Why can't pointSpan handle count == 1?
herb_g 2016/02/23 21:30:35 There was a NaN problem with the division in a dee
+ } else {
+ next->pointSpan(start, length, count);
+ }
+ }
+ };
+ SendSpan(SkPoint{xMin, y}, 0.0f, beforeCount);
+ SendSpan(SkPoint{x, y}, length, middleCount);
+ SendSpan(SkPoint{xMax - 1, y}, 0.0f, afterCount);
+ } else {
+ next->pointSpan(start, length, count);
+ }
+
+ return true;
}
private:
@@ -386,6 +429,11 @@ private:
template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface>
using Clamp = BilerpProcessor<ClampStrategy, Next>;
+// It would be nice to use fmod, but it uses trunc based rounding where floor rounding is needed.
+static float tile_mod(float l, float base) {
mtklein 2016/02/23 15:51:56 I think you might want to pick a different letter-
herb_g 2016/02/23 21:10:23 Done.
+ return l - std::floor(l / base) * base;
mtklein 2016/02/23 15:51:56 We're getting a little loosey-goosey about SkScala
herb_g 2016/02/23 21:10:23 Done.
+}
+
class RepeatStrategy {
public:
RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { }
@@ -407,7 +455,30 @@ public:
template <typename Next>
bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) {
- return false;
+ SkScalar x = tile_mod(X(start), fXMax[0]);
+ SkScalar y = tile_mod(Y(start), fYMax[0]);
+ SkScalar dx = length / (count - 1);
f(malita) 2016/02/23 20:53:48 Same question re count - 1.
herb_g 2016/02/23 21:30:35 Added much documentation. See if that answers the
+ auto SendSpan = [&](SkPoint start, SkScalar length, int count) {
+ if (count > 0) {
+ if (count == 1) {
+ next->pointListFew(1, Sk4f{X(start)}, Sk4f{Y(start)});
+ } else {
+ next->pointSpan(start, length, count);
+ }
+ }
+ };
+ while (x + length > fXMax[0]) {
mtklein 2016/02/23 15:51:56 Explain how this works?
herb_g 2016/02/23 21:10:23 Done.
+ SkScalar lengthForTile = std::min(fXMax[0] - x, length);
+ int countForTile = SkScalarFloorToInt(lengthForTile / dx);
f(malita) 2016/02/23 20:53:48 I noticed we always pad one to the count in the cl
herb_g 2016/02/23 21:30:35 If the source is 1 pixel wide, then this should ma
+ SkScalar lengthForDx = countForTile * dx;
+ SendSpan({x, y}, lengthForDx, countForTile);
+ length -= lengthForDx;
+ count -= countForTile;
f(malita) 2016/02/23 20:53:48 Looks like we only track count in order to handle
herb_g 2016/02/23 21:30:35 That would mean a bunch of calculation in the comm
+ x = 0;
+ }
+ SendSpan({x, y}, length, count);
+
+ return true;
}
private:
« 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