git-svn-id: http://skia.googlecode.com/svn/trunk@2784 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2011-12-01 21:47:26 +00:00
Родитель f974a5d782
Коммит a89c77b5ca
4 изменённых файлов: 57 добавлений и 72 удалений

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

@ -24,23 +24,16 @@ class SkBlitter {
public:
virtual ~SkBlitter();
/// Blit a horizontal run of opaque pixels.
/// Blit a horizontal run of pixels.
virtual void blitH(int x, int y, int width);
/// Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
/// zero-terminated run-length encoding of spans of constant alpha values.
virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
const int16_t runs[]);
/** Blit a vertical run of pixels with a constant alpha value.
Subclasses may require all blits to be performed in scanline order
and redefine blitV() to cause a runtime error.
*/
/// Blit a vertical run of pixels with a constant alpha value.
virtual void blitV(int x, int y, int height, SkAlpha alpha);
/// Blit an opaque rectangle.
/// Blit a solid rectangle.
virtual void blitRect(int x, int y, int width, int height);
/// Blit a rectangle with one antialiased column on the left,
/// width opaque pixels, and one antialiased column on the right.
virtual void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha);
/// Blit a pattern of pixels defined by a rectangle-clipped mask;
/// typically used for text.
virtual void blitMask(const SkMask&, const SkIRect& clip);

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

@ -930,36 +930,7 @@ public:
SkASSERT(fBounds.contains(x + width - 1, y + height - 1));
this->addRun(x, y, 0xFF, width);
// we assume the rect must be all we'll see for these scanlines
// so we ensure our row goes all the way to our right
this->flushRowH(fCurrRow);
y -= fBounds.fTop;
SkASSERT(y == fCurrRow->fY);
fCurrRow->fY = y + height - 1;
}
void addAntiRectRun(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) {
SkASSERT(fBounds.contains(x + width - 1, y + height - 1));
SkASSERT(width >= 0);
// Conceptually we're always adding 3 runs, but we should
// merge or omit them if possible.
if (leftAlpha == 0xFF) {
width++;
} else if (leftAlpha > 0) {
this->addRun(x++, y, leftAlpha, 1);
}
if (rightAlpha == 0xFF) {
width++;
}
this->addRun(x, y, 0xFF, width);
if (rightAlpha > 0 && rightAlpha < 255) {
this->addRun(x + width, y, rightAlpha, 1);
}
// we assume the rect must be all we'll see for these scanlines
// we assum the rect must be all we'll see for these scanlines
// so we ensure our row goes all the way to our right
this->flushRowH(fCurrRow);
@ -1142,7 +1113,6 @@ public:
}
}
// Must evaluate clips in scan-line order, so can't allow blitV()
virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE
{ unexpected(); }
@ -1151,12 +1121,6 @@ public:
fBuilder->addRectRun(x, y, width, height);
}
virtual void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE {
this->recordMinY(y);
fBuilder->addAntiRectRun(x, y, width, height, leftAlpha, rightAlpha);
}
virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE
{ unexpected(); }

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

@ -52,16 +52,6 @@ void SkBlitter::blitRect(int x, int y, int width, int height) {
}
}
/// Default implementation doesn't check for any easy optimizations
/// such as alpha == 0 or 255; also uses blitV(), which some subclasses
/// may not support.
void SkBlitter::blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) {
this->blitV(x, y, height, leftAlpha);
this->blitRect(x + 1, y, width, height);
this->blitV(x + width - 1, y, height, rightAlpha);
}
//////////////////////////////////////////////////////////////////////////////
static inline void bits_to_runs(SkBlitter* blitter, int x, int y,
@ -128,8 +118,7 @@ void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
int rite_mask = 0xFF << (8 - (rite_edge & 7));
int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
// check for empty right mask, so we don't read off the end
// (or go slower than we need to)
// check for empty right mask, so we don't read off the end (or go slower than we need to)
if (rite_mask == 0) {
SkASSERT(full_runs >= 0);
full_runs -= 1;
@ -139,8 +128,8 @@ void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
full_runs -= 1;
}
// Back up manually so we can keep in sync with our byte-aligned
// src; have cx reflect our actual starting x-coord.
// back up manually so we can keep in sync with our byte-aligned src
// have cx reflect our actual starting x-coord
cx -= left_edge & 7;
if (full_runs < 0) {
@ -152,8 +141,7 @@ void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
}
} else {
while (--height >= 0) {
bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2,
rite_mask);
bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask);
bits += mask_rowBytes;
cy += 1;
}

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

@ -219,7 +219,42 @@ void SuperBlitter::blitH(int x, int y, int width) {
#endif
}
// All parameters are in supersampled space.
static void set_left_rite_runs(SkAlphaRuns& runs, int ileft, U8CPU leftA,
int n, U8CPU riteA) {
SkASSERT(leftA <= 0xFF);
SkASSERT(riteA <= 0xFF);
int16_t* run = runs.fRuns;
uint8_t* aa = runs.fAlpha;
if (ileft > 0) {
run[0] = ileft;
aa[0] = 0;
run += ileft;
aa += ileft;
}
SkASSERT(leftA < 0xFF);
if (leftA > 0) {
*run++ = 1;
*aa++ = leftA;
}
if (n > 0) {
run[0] = n;
aa[0] = 0xFF;
run += n;
aa += n;
}
SkASSERT(riteA < 0xFF);
if (riteA > 0) {
*run++ = 1;
*aa++ = riteA;
}
run[0] = 0;
}
void SuperBlitter::blitRect(int x, int y, int width, int height) {
SkASSERT(width > 0);
SkASSERT(height > 0);
@ -240,7 +275,6 @@ void SuperBlitter::blitRect(int x, int y, int width, int height) {
int stop_y = (y + height) >> SHIFT;
int count = stop_y - start_y;
if (count > 0) {
y += count << SHIFT;
height -= count << SHIFT;
@ -284,9 +318,19 @@ void SuperBlitter::blitRect(int x, int y, int width, int height) {
const int coverageR = coverage_to_alpha(xrite) << SHIFT;
SkASSERT(n + (coverageR != 0) <= fWidth);
fRealBlitter->blitAntiRect(ileft + fLeft, start_y, n, count,
coverageL > 0 ? coverageL : 255,
coverageR > 0 ? coverageR : 255);
for (int i = start_y; i < stop_y; ++i) {
// note: we should only need to call set_left_rite once, but
// our clipping blitters sometimes modify runs/alpha in-place,
// so for now we reset fRuns each time :(
//
// TODO:
// - don't modify in-place, or at least tell us when you're going to
// - pass height down to blitAntiH (blitAntiHV) so that aaclip and
// other can take advantage of the vertical-repeat explicitly
//
set_left_rite_runs(fRuns, ileft, coverageL, n, coverageR);
fRealBlitter->blitAntiH(fLeft, i, fRuns.fAlpha, fRuns.fRuns);
}
// preamble for our next call to blitH()
fCurrIY = stop_y - 1;
@ -316,10 +360,6 @@ public:
virtual void blitH(int x, int y, int width) SK_OVERRIDE;
// TODO: blitAntiRect() if we ever have performance problems -
// but the gains aren't expected to be nearly as large as for
// SuperBlitter.
static bool CanHandleRect(const SkIRect& bounds) {
#ifdef FORCE_RLE
return false;