diff options
author | 2012-03-27 15:54:28 +0000 | |
---|---|---|
committer | 2012-03-27 15:54:28 +0000 | |
commit | 9fe287bd07baa6d9e890b627c102bba562954f7d (patch) | |
tree | 63501112d1a65fee1387872a2b55ecde52c832be | |
parent | 290e5363bb630be97bcf6777be77a7ca9b04f3c1 (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.cpp | 16 | ||||
-rw-r--r-- | src/core/SkBitmapProcState.cpp | 87 | ||||
-rw-r--r-- | src/core/SkBitmapProcState.h | 34 |
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. |