diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBitmapProcState.cpp | 29 | ||||
-rw-r--r-- | src/core/SkBitmapProcState_shaderproc.h | 83 |
2 files changed, 111 insertions, 1 deletions
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index 7dc9324770..8a677c05be 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -284,6 +284,26 @@ SkASSERT(state.fAlphaScale < 256) #define POSTAMBLE(state) state.fBitmap->getColorTable()->unlock16BitCache() #include "SkBitmapProcState_sample.h" +/////////////////////////////////////////////////////////////////////////////// + +#undef FILTER_PROC +#define FILTER_PROC(x, y, a, b, c, d) Filter_565_Expanded(x, y, a, b, c, d) + +#define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max) +#define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max) +#define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) +#define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) + +#define MAKENAME(suffix) Clamp_S16_D16 ## suffix +#define SRCTYPE uint16_t +#define DSTTYPE uint16_t +#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config) +#define SRC_TO_FILTER(src) src +#define FILTER_TO_DST(c) SkCompact_rgb_16((c) >> 5) +#include "SkBitmapProcState_shaderproc.h" + +/////////////////////////////////////////////////////////////////////////////// + static bool valid_for_filtering(unsigned dimension) { // for filtering, width and height must fit in 14bits, since we use steal // 2 bits from each to store our 4bit subpixel data @@ -295,14 +315,17 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { return false; } const SkMatrix* m; - + bool clamp_clamp; + if (SkShader::kClamp_TileMode == fTileModeX && SkShader::kClamp_TileMode == fTileModeY) { m = &inv; + clamp_clamp = true; } else { fUnitInvMatrix = inv; fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); m = &fUnitInvMatrix; + clamp_clamp = false; } fBitmap = &fOrigBitmap; @@ -463,6 +486,10 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { index >>= 1; // shift away any opaque/alpha distinction fSampleProc16 = gSample16[index]; + // our special-case shaderprocs + if (clamp_clamp && (7 == (index >> 1))) { + fShaderProc16 = Clamp_S16_D16_filter_DX_shaderproc; + } return true; } diff --git a/src/core/SkBitmapProcState_shaderproc.h b/src/core/SkBitmapProcState_shaderproc.h new file mode 100644 index 0000000000..66a6627141 --- /dev/null +++ b/src/core/SkBitmapProcState_shaderproc.h @@ -0,0 +1,83 @@ +#define SCALE_FILTER_NAME MAKENAME(_filter_DX_shaderproc) + +#ifndef PREAMBLE + #define PREAMBLE(state) + #define PREAMBLE_PARAM_X + #define PREAMBLE_PARAM_Y + #define PREAMBLE_ARG_X + #define PREAMBLE_ARG_Y +#endif + + +static void SCALE_FILTER_NAME(const SkBitmapProcState& s, int x, int y, + DSTTYPE* SK_RESTRICT colors, int count) { + SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | + SkMatrix::kScale_Mask)) == 0); + SkASSERT(s.fInvKy == 0); + SkASSERT(count > 0 && colors != NULL); + SkASSERT(s.fDoFilter); + SkDEBUGCODE(CHECKSTATE(s);) + + PREAMBLE(s); + + const unsigned maxX = s.fBitmap->width() - 1; + const SkFixed oneX = s.fFilterOneX; + const SkFixed dx = s.fInvSx; + SkFixed fx; + const SRCTYPE* SK_RESTRICT row0; + const SRCTYPE* SK_RESTRICT row1; + unsigned subY; + + { + SkPoint pt; + s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &pt); + SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1); + const unsigned maxY = s.fBitmap->height() - 1; + // compute our two Y values up front + subY = TILEY_LOW_BITS(fy, maxY); + int y0 = TILEY_PROCF(fy, maxY); + int y1 = TILEY_PROCF((fy + s.fFilterOneY), maxY); + + const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels(); + unsigned rb = s.fBitmap->rowBytes(); + row0 = (const SRCTYPE*)(srcAddr + y0 * rb); + row1 = (const SRCTYPE*)(srcAddr + y1 * rb); + // now initialize fx + fx = SkScalarToFixed(pt.fX) - (oneX >> 1); + } + + do { + unsigned subX = TILEX_LOW_BITS(fx, maxX); + unsigned x0 = TILEX_PROCF(fx, maxX); + unsigned x1 = TILEX_PROCF((fx + oneX), maxX); + + uint32_t c = FILTER_PROC(subX, subY, + SRC_TO_FILTER(row0[x0]), + SRC_TO_FILTER(row0[x1]), + SRC_TO_FILTER(row1[x0]), + SRC_TO_FILTER(row1[x1])); + *colors++ = FILTER_TO_DST(c); + + fx += dx; + } while (--count != 0); +} + +/////////////////////////////////////////////////////////////////////////////// + +#undef MAKENAME +#undef TILEX_PROCF +#undef TILEY_PROCF +#undef TILEX_LOW_BITS +#undef TILEY_LOW_BITS +#ifdef CHECK_FOR_DECAL + #undef CHECK_FOR_DECAL +#endif + +#undef SCALE_FILTER_NAME + +#undef PREAMBLE +#undef PREAMBLE_PARAM_X +#undef PREAMBLE_PARAM_Y +#undef PREAMBLE_ARG_X +#undef PREAMBLE_ARG_Y |