aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkBitmapProcState.cpp29
-rw-r--r--src/core/SkBitmapProcState_shaderproc.h83
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