add method to compute max count for a given buffer size in the bitmap shader.

fix bug in quad loop of fill_sequential where we were going one quad too far.



git-svn-id: http://skia.googlecode.com/svn/trunk@322 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@android.com 2009-08-14 13:54:37 +00:00
parent a3122b9b1e
commit 4c128c4917
4 changed files with 42 additions and 4 deletions

View File

@ -140,10 +140,10 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
return;
}
uint32_t buffer[BUF_MAX + 1];
uint32_t buffer[BUF_MAX];
SkBitmapProcState::MatrixProc mproc = state.fMatrixProc;
SkBitmapProcState::SampleProc32 sproc = state.fSampleProc32;
int max = fState.fDoFilter ? (BUF_MAX >> 1) : BUF_MAX;
int max = fState.maxCountForBufferSize(sizeof(buffer));
SkASSERT(state.fBitmap->getPixels());
SkASSERT(state.fBitmap->pixelRef() == NULL ||
@ -175,7 +175,7 @@ void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
uint32_t buffer[BUF_MAX];
SkBitmapProcState::MatrixProc mproc = state.fMatrixProc;
SkBitmapProcState::SampleProc16 sproc = state.fSampleProc16;
int max = fState.fDoFilter ? (BUF_MAX >> 1) : BUF_MAX;
int max = fState.maxCountForBufferSize(sizeof(buffer));
SkASSERT(state.fBitmap->getPixels());
SkASSERT(state.fBitmap->pixelRef() == NULL ||

View File

@ -510,3 +510,31 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
return true;
}
///////////////////////////////////////////////////////////////////////////////
/*
The storage requirements for the different matrix procs are as follows,
where each X or Y is 2 bytes, and N is the number of pixels/elements:
scale/translate nofilter Y(4bytes) + N * X
affine/perspective nofilter N * (X Y)
scale/translate filter Y Y + N * (X X)
affine/perspective filter N * (Y Y X X)
*/
int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
int32_t size = static_cast<int32_t>(bufferSize);
int perElemShift;
size &= ~3; // only care about 4-byte aligned chunks
if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
size -= 4; // the shared Y (or YY) coordinate
if (size < 0) {
size = 0;
}
perElemShift = fDoFilter ? 2 : 1;
} else {
perElemShift = fDoFilter ? 3 : 2;
}
return size >> perElemShift;
}

View File

@ -91,6 +91,16 @@ struct SkBitmapProcState {
*/
void platformProcs();
/** Given the size of a buffer, to be used for calling the matrix and
sample procs, this return the maximum count that can be stored in the
buffer, taking into account that filtering and scale-vs-affine affect
this value.
Only valid to call after chooseProcs (setContext) has been called. It is
safe to call this inside the shader's shadeSpan() method.
*/
int maxCountForBufferSize(size_t bufferSize) const;
private:
friend class SkBitmapProcShader;

View File

@ -202,7 +202,7 @@ static void fill_sequential(uint16_t xptr[], int start, int count) {
pattern0 += 0x40004;
*xxptr++ = pattern1;
pattern1 += 0x40004;
} while (--qcount >= 0);
} while (--qcount != 0);
xptr = reinterpret_cast<uint16_t*>(xxptr);
count &= 3;
}