aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkAlphaRuns.cpp24
-rw-r--r--src/core/SkAntiRun.h10
-rw-r--r--src/core/SkScan_AntiPath.cpp21
3 files changed, 43 insertions, 12 deletions
diff --git a/src/core/SkAlphaRuns.cpp b/src/core/SkAlphaRuns.cpp
index 4125b583fd..a5fc3c9f9f 100644
--- a/src/core/SkAlphaRuns.cpp
+++ b/src/core/SkAlphaRuns.cpp
@@ -16,10 +16,14 @@
*/
#include "SkAntiRun.h"
+#include "SkUtils.h"
void SkAlphaRuns::reset(int width) {
SkASSERT(width > 0);
+#ifdef SK_DEBUG
+ sk_memset16((uint16_t*)fRuns, (uint16_t)(-42), width);
+#endif
fRuns[0] = SkToS16(width);
fRuns[width] = 0;
fAlpha[0] = 0;
@@ -75,13 +79,17 @@ void SkAlphaRuns::Break(int16_t runs[], uint8_t alpha[], int x, int count) {
}
}
-void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
- U8CPU maxValue) {
+int SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
+ U8CPU maxValue, int offsetX) {
SkASSERT(middleCount >= 0);
SkASSERT(x >= 0 && x + (startAlpha != 0) + middleCount + (stopAlpha != 0) <= fWidth);
- int16_t* runs = fRuns;
- uint8_t* alpha = fAlpha;
+ SkASSERT(fRuns[offsetX] >= 0);
+
+ int16_t* runs = fRuns + offsetX;
+ uint8_t* alpha = fAlpha + offsetX;
+ uint8_t* lastAlpha = alpha;
+ x -= offsetX;
if (startAlpha) {
SkAlphaRuns::Break(runs, alpha, x, 1);
@@ -97,6 +105,7 @@ void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
runs += x + 1;
alpha += x + 1;
x = 0;
+ lastAlpha += x; // we don't want the +1
SkDEBUGCODE(this->validate();)
}
@@ -114,13 +123,18 @@ void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
middleCount -= n;
} while (middleCount > 0);
SkDEBUGCODE(this->validate();)
+ lastAlpha = alpha;
}
if (stopAlpha) {
SkAlphaRuns::Break(runs, alpha, x, 1);
- alpha[x] = SkToU8(alpha[x] + stopAlpha);
+ alpha += x;
+ alpha[0] = SkToU8(alpha[0] + stopAlpha);
SkDEBUGCODE(this->validate();)
+ lastAlpha = alpha;
}
+
+ return lastAlpha - fAlpha; // new offsetX
}
#ifdef SK_DEBUG
diff --git a/src/core/SkAntiRun.h b/src/core/SkAntiRun.h
index 89e54819c4..669e5d227a 100644
--- a/src/core/SkAntiRun.h
+++ b/src/core/SkAntiRun.h
@@ -31,7 +31,15 @@ public:
}
void reset(int width);
- void add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue);
+
+ /**
+ * Returns the offsetX value that should be passed on the next call,
+ * assuming we're on the same scanline. If the caller is switching
+ * scanlines, then offsetX should be 0 when this is called.
+ */
+ int add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
+ U8CPU maxValue, int offsetX);
+
SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
SkDEBUGCODE(void dump() const;)
diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp
index b7ce190e9a..98f3b25aea 100644
--- a/src/core/SkScan_AntiPath.cpp
+++ b/src/core/SkScan_AntiPath.cpp
@@ -53,7 +53,7 @@ protected:
int fWidth, fLeft, fSuperLeft;
SkDEBUGCODE(int fCurrX;)
- SkDEBUGCODE(int fCurrY;)
+ int fCurrY;
};
BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
@@ -89,6 +89,7 @@ public:
private:
SkAlphaRuns fRuns;
+ int fOffsetX;
};
SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
@@ -100,6 +101,8 @@ SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
fRuns.fRuns = (int16_t*)sk_malloc_throw((width + 1 + (width + 2)/2) * sizeof(int16_t));
fRuns.fAlpha = (uint8_t*)(fRuns.fRuns + width + 1);
fRuns.reset(width);
+
+ fOffsetX = 0;
}
void SuperBlitter::flush() {
@@ -108,6 +111,7 @@ void SuperBlitter::flush() {
// SkDEBUGCODE(fRuns.dump();)
fRealBlitter->blitAntiH(fLeft, fCurrIY, fRuns.fAlpha, fRuns.fRuns);
fRuns.reset(fWidth);
+ fOffsetX = 0;
}
fCurrIY = -1;
SkDEBUGCODE(fCurrX = -1;)
@@ -134,11 +138,14 @@ void SuperBlitter::blitH(int x, int y, int width) {
}
#ifdef SK_DEBUG
- SkASSERT(y >= fCurrY);
SkASSERT(y != fCurrY || x >= fCurrX);
- fCurrY = y;
#endif
-
+ SkASSERT(y >= fCurrY);
+ if (fCurrY != y) {
+ fOffsetX = 0;
+ fCurrY = y;
+ }
+
if (iy != fCurrIY) { // new scanline
this->flush();
fCurrIY = iy;
@@ -167,8 +174,10 @@ void SuperBlitter::blitH(int x, int y, int width) {
fb = (1 << SHIFT) - fb;
}
}
- fRuns.add(x >> SHIFT, coverage_to_alpha(fb), n, coverage_to_alpha(fe),
- (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT));
+
+ fOffsetX = fRuns.add(x >> SHIFT, coverage_to_alpha(fb), n, coverage_to_alpha(fe),
+ (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT),
+ fOffsetX);
#ifdef SK_DEBUG
fRuns.assertValid(y & MASK, (1 << (8 - SHIFT)));