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
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 44af0cc..7eb8ea1 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -140,10 +140,10 @@
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 @@
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 ||
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
index b999a0c..600b963 100644
--- a/src/core/SkBitmapProcState.cpp
+++ b/src/core/SkBitmapProcState.cpp
@@ -510,3 +510,31 @@
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;
+}
+
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h
index 2790a6c..9db62f0 100644
--- a/src/core/SkBitmapProcState.h
+++ b/src/core/SkBitmapProcState.h
@@ -91,6 +91,16 @@
*/
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;
diff --git a/src/core/SkBitmapProcState_matrixProcs.cpp b/src/core/SkBitmapProcState_matrixProcs.cpp
index cf32d9b..bd924ca 100644
--- a/src/core/SkBitmapProcState_matrixProcs.cpp
+++ b/src/core/SkBitmapProcState_matrixProcs.cpp
@@ -202,7 +202,7 @@
pattern0 += 0x40004;
*xxptr++ = pattern1;
pattern1 += 0x40004;
- } while (--qcount >= 0);
+ } while (--qcount != 0);
xptr = reinterpret_cast<uint16_t*>(xxptr);
count &= 3;
}