aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-27 15:54:28 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-27 15:54:28 +0000
commit9fe287bd07baa6d9e890b627c102bba562954f7d (patch)
tree63501112d1a65fee1387872a2b55ecde52c832be
parent290e5363bb630be97bcf6777be77a7ca9b04f3c1 (diff)
add debuggin matrix-proc to validate its output before calling the samplers
Review URL: https://codereview.appspot.com/5901063 git-svn-id: http://skia.googlecode.com/svn/trunk@3505 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/core/SkBitmapProcShader.cpp16
-rw-r--r--src/core/SkBitmapProcState.cpp87
-rw-r--r--src/core/SkBitmapProcState.h34
3 files changed, 120 insertions, 17 deletions
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 32b6f9e29e..e3c46d0ed2 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -161,14 +161,14 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device,
void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
const SkBitmapProcState& state = fState;
- if (state.fShaderProc32) {
- state.fShaderProc32(state, x, y, dstC, count);
+ if (state.getShaderProc32()) {
+ state.getShaderProc32()(state, x, y, dstC, count);
return;
}
uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA];
- SkBitmapProcState::MatrixProc mproc = state.fMatrixProc;
- SkBitmapProcState::SampleProc32 sproc = state.fSampleProc32;
+ SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
+ SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32();
int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
SkASSERT(state.fBitmap->getPixels());
@@ -205,14 +205,14 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
const SkBitmapProcState& state = fState;
- if (state.fShaderProc16) {
- state.fShaderProc16(state, x, y, dstC, count);
+ if (state.getShaderProc16()) {
+ state.getShaderProc16()(state, x, y, dstC, count);
return;
}
uint32_t buffer[BUF_MAX];
- SkBitmapProcState::MatrixProc mproc = state.fMatrixProc;
- SkBitmapProcState::SampleProc16 sproc = state.fSampleProc16;
+ SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
+ SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16();
int max = fState.maxCountForBufferSize(sizeof(buffer));
SkASSERT(state.fBitmap->getPixels());
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
index 75d2791b3b..72958f9aae 100644
--- a/src/core/SkBitmapProcState.cpp
+++ b/src/core/SkBitmapProcState.cpp
@@ -541,6 +541,93 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
}
///////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_DEBUG
+
+static void check_scale_nofilter(uint32_t bitmapXY[], int count,
+ unsigned mx, unsigned my) {
+ unsigned y = *bitmapXY++;
+ SkASSERT(y < my);
+
+ const uint16_t* xptr = reinterpret_cast<const uint16_t*>(bitmapXY);
+ for (int i = 0; i < count; ++i) {
+ SkASSERT(xptr[i] < mx);
+ }
+}
+
+static void check_scale_filter(uint32_t bitmapXY[], int count,
+ unsigned mx, unsigned my) {
+ uint32_t YY = *bitmapXY++;
+ unsigned y0 = YY >> 18;
+ unsigned y1 = YY & 0x3FFF;
+ SkASSERT(y0 < my);
+ SkASSERT(y1 < my);
+
+ for (int i = 0; i < count; ++i) {
+ uint32_t XX = bitmapXY[i];
+ unsigned x0 = XX >> 18;
+ unsigned x1 = XX & 0x3FFF;
+ SkASSERT(x0 < mx);
+ SkASSERT(x1 < mx);
+ }
+}
+
+static void check_affine_nofilter(uint32_t bitmapXY[], int count,
+ unsigned mx, unsigned my) {
+ for (int i = 0; i < count; ++i) {
+ uint32_t XY = bitmapXY[i];
+ unsigned x = XY & 0xFFFF;
+ unsigned y = XY >> 16;
+ SkASSERT(x < mx);
+ SkASSERT(y < my);
+ }
+}
+
+static void check_affine_filter(uint32_t bitmapXY[], int count,
+ unsigned mx, unsigned my) {
+ for (int i = 0; i < count; ++i) {
+ uint32_t YY = *bitmapXY++;
+ unsigned y0 = YY >> 18;
+ unsigned y1 = YY & 0x3FFF;
+ SkASSERT(y0 < my);
+ SkASSERT(y1 < my);
+
+ uint32_t XX = *bitmapXY++;
+ unsigned x0 = XX >> 18;
+ unsigned x1 = XX & 0x3FFF;
+ SkASSERT(x0 < mx);
+ SkASSERT(x1 < mx);
+ }
+}
+
+void SkBitmapProcState::DebugMatrixProc(const SkBitmapProcState& state,
+ uint32_t bitmapXY[], int count,
+ int x, int y) {
+ SkASSERT(bitmapXY);
+ SkASSERT(count > 0);
+
+ state.fMatrixProc(state, bitmapXY, count, x, y);
+
+ void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my);
+
+ // There are four formats possible:
+ // scale -vs- affine
+ // filter -vs- nofilter
+ if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
+ proc = state.fDoFilter ? check_scale_filter : check_scale_nofilter;
+ } else {
+ proc = state.fDoFilter ? check_affine_filter : check_affine_nofilter;
+ }
+ proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height());
+}
+
+SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const {
+ return DebugMatrixProc;
+}
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
/*
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:
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h
index 08c5cdeb80..dc56138db0 100644
--- a/src/core/SkBitmapProcState.h
+++ b/src/core/SkBitmapProcState.h
@@ -58,15 +58,6 @@ struct SkBitmapProcState {
typedef U16CPU (*FixedTileLowBitsProc)(SkFixed, int); // returns 0..0xF
typedef U16CPU (*IntTileProc)(int value, int count); // returns 0..count-1
- // If a shader proc is present, then the corresponding matrix/sample procs
- // are ignored
- ShaderProc32 fShaderProc32; // chooseProcs
- ShaderProc16 fShaderProc16; // chooseProcs
- // These are used if the shaderproc is NULL
- MatrixProc fMatrixProc; // chooseProcs
- SampleProc32 fSampleProc32; // chooseProcs
- SampleProc16 fSampleProc16; // chooseProcs
-
const SkBitmap* fBitmap; // chooseProcs - orig or mip
const SkMatrix* fInvMatrix; // chooseProcs
SkMatrix::MapXYProc fInvProc; // chooseProcs
@@ -117,15 +108,40 @@ struct SkBitmapProcState {
*/
int maxCountForBufferSize(size_t bufferSize) const;
+ // If a shader proc is present, then the corresponding matrix/sample procs
+ // are ignored
+ ShaderProc32 getShaderProc32() const { return fShaderProc32; }
+ ShaderProc16 getShaderProc16() const { return fShaderProc16; }
+
+#ifdef SK_DEBUG
+ MatrixProc getMatrixProc() const;
+#else
+ MatrixProc getMatrixProc() const { return fMatrixProc; }
+#endif
+ SampleProc32 getSampleProc32() const { return fSampleProc32; }
+ SampleProc16 getSampleProc16() const { return fSampleProc16; }
+
private:
friend class SkBitmapProcShader;
+ ShaderProc32 fShaderProc32; // chooseProcs
+ ShaderProc16 fShaderProc16; // chooseProcs
+ // These are used if the shaderproc is NULL
+ MatrixProc fMatrixProc; // chooseProcs
+ SampleProc32 fSampleProc32; // chooseProcs
+ SampleProc16 fSampleProc16; // chooseProcs
+
SkMatrix fUnitInvMatrix; // chooseProcs
SkBitmap fOrigBitmap; // CONSTRUCTOR
SkBitmap fMipBitmap;
MatrixProc chooseMatrixProc(bool trivial_matrix);
bool chooseProcs(const SkMatrix& inv, const SkPaint&);
+
+#ifdef SK_DEBUG
+ static void DebugMatrixProc(const SkBitmapProcState&,
+ uint32_t[], int count, int x, int y);
+#endif
};
/* Macros for packing and unpacking pairs of 16bit values in a 32bit uint.