remember previous x-offset when we re-enter the runs array. speeds up paths

with lots of x-transitions in a single scanline



git-svn-id: http://skia.googlecode.com/svn/trunk@1456 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2011-05-31 19:18:02 +00:00
Родитель 9405e55c37
Коммит fa57ae7d1e
3 изменённых файлов: 43 добавлений и 12 удалений

Просмотреть файл

@ -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

Просмотреть файл

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

Просмотреть файл

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