aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBitmapProcState.cpp12
-rw-r--r--src/core/SkBitmapProcState.h39
-rw-r--r--src/core/SkBitmapProcState_matrix.h21
-rw-r--r--src/core/SkBitmapProcState_matrix_template.h20
4 files changed, 48 insertions, 44 deletions
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
index 6ed83002d9..487bd80402 100644
--- a/src/core/SkBitmapProcState.cpp
+++ b/src/core/SkBitmapProcState.cpp
@@ -820,10 +820,15 @@ void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const SkBitmapProcState& s, in
SkFractionalInt fx;
int dstY;
{
- const SkBitmapProcStateAutoMapper mapper(s, x, y);
+ SkPoint pt;
+ s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf,
+ &pt);
+ fx = SkScalarToFractionalInt(pt.fY)
+ + bitmap_sampler_inv_bias(s.fInvMatrix.getScaleY());
const unsigned maxY = s.fPixmap.height() - 1;
- dstY = SkClampMax(SkFixedFloorToInt(mapper.y()), maxY);
- fx = SkFixedToFractionalInt(mapper.x());
+ dstY = SkClampMax(SkFractionalIntToInt(fx), maxY);
+ fx = SkScalarToFractionalInt(pt.fX)
+ + bitmap_sampler_inv_bias(s.fInvMatrix.getScaleX());
}
const SkPMColor* SK_RESTRICT src = s.fPixmap.addr32(0, dstY);
@@ -859,3 +864,4 @@ void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const SkBitmapProcState& s, in
}
}
}
+
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h
index 342da78c05..e6e7a3f393 100644
--- a/src/core/SkBitmapProcState.h
+++ b/src/core/SkBitmapProcState.h
@@ -25,6 +25,17 @@ typedef SkFixed3232 SkFractionalInt;
#define SkFixedToFractionalInt(x) SkFixedToFixed3232(x)
#define SkFractionalIntToInt(x) SkFixed3232ToInt(x)
+// Applying a fixed point (SkFixed, SkFractionalInt) epsilon bias ensures that the inverse-mapped
+// bitmap coordinates are rounded consistently WRT geometry. Note that we only have to do this
+// when the scale is positive - for negative scales we're already rounding in the right direction.
+static inline int bitmap_sampler_inv_bias(SkScalar scale) {
+#ifndef SK_SUPPORT_LEGACY_BITMAP_SAMPLER_BIAS
+ return -(scale > 0);
+#else
+ return 0;
+#endif
+}
+
class SkPaint;
struct SkBitmapProcState {
@@ -201,32 +212,4 @@ void S32_D16_filter_DX(const SkBitmapProcState& s,
void S32_D16_filter_DXDY(const SkBitmapProcState& s,
const uint32_t* xy, int count, uint16_t* colors);
-// Helper class for mapping the middle of pixel (x, y) into SkFixed bitmap space.
-class SkBitmapProcStateAutoMapper {
-public:
- SkBitmapProcStateAutoMapper(const SkBitmapProcState& s, int x, int y) {
- SkPoint pt;
- s.fInvProc(s.fInvMatrix,
- SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &pt);
-
-#ifndef SK_SUPPORT_LEGACY_BITMAP_SAMPLER_BIAS
- // SkFixed epsilon bias to ensure inverse-mapped bitmap coordinates are rounded
- // consistently WRT geometry. Note that we only need the bias for positive scales:
- // for negative scales, the rounding is intrinsically correct.
- fX = SkScalarToFixed(pt.x()) - (s.fInvMatrix.getScaleX() > 0);
- fY = SkScalarToFixed(pt.y()) - (s.fInvMatrix.getScaleY() > 0);
-#else
- fX = SkScalarToFixed(pt.x());
- fY = SkScalarToFixed(pt.y());
-#endif
- }
-
- SkFixed x() const { return fX; }
- SkFixed y() const { return fY; }
-
-private:
- SkFixed fX, fY;
-};
-
#endif
diff --git a/src/core/SkBitmapProcState_matrix.h b/src/core/SkBitmapProcState_matrix.h
index e4212b60fe..42a5ab6e22 100644
--- a/src/core/SkBitmapProcState_matrix.h
+++ b/src/core/SkBitmapProcState_matrix.h
@@ -61,13 +61,17 @@ void SCALE_FILTER_NAME(const SkBitmapProcState& s,
SkFractionalInt fx;
{
- const SkBitmapProcStateAutoMapper mapper(s, x ,y);
- const SkFixed fy = mapper.y() - (s.fFilterOneY >> 1);
+ SkPoint pt;
+ s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &pt);
+ const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1)
+ + bitmap_sampler_inv_bias(s.fInvMatrix.getScaleY());
const unsigned maxY = s.fPixmap.height() - 1;
// compute our two Y values up front
*xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
// now initialize fx
- fx = SkFixedToFractionalInt(mapper.x() - (one >> 1));
+ fx = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1)
+ + bitmap_sampler_inv_bias(s.fInvMatrix.getScaleX());
}
#ifdef CHECK_FOR_DECAL
@@ -93,12 +97,17 @@ void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
SkMatrix::kAffine_Mask)) == 0);
PREAMBLE(s);
- const SkBitmapProcStateAutoMapper mapper(s, x ,y);
+ SkPoint srcPt;
+ s.fInvProc(s.fInvMatrix,
+ SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
SkFixed oneX = s.fFilterOneX;
SkFixed oneY = s.fFilterOneY;
- SkFixed fx = mapper.x() - (oneX >> 1);
- SkFixed fy = mapper.y() - (oneY >> 1);
+ SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1)
+ + bitmap_sampler_inv_bias(s.fInvMatrix.getScaleX());
+ SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1)
+ + bitmap_sampler_inv_bias(s.fInvMatrix.getScaleY());
SkFixed dx = s.fInvSx;
SkFixed dy = s.fInvKy;
unsigned maxX = s.fPixmap.width() - 1;
diff --git a/src/core/SkBitmapProcState_matrix_template.h b/src/core/SkBitmapProcState_matrix_template.h
index 9d639b8a04..468013c30d 100644
--- a/src/core/SkBitmapProcState_matrix_template.h
+++ b/src/core/SkBitmapProcState_matrix_template.h
@@ -22,10 +22,13 @@ void NoFilterProc_Scale(const SkBitmapProcState& s, uint32_t xy[],
const unsigned maxX = s.fPixmap.width() - 1;
SkFractionalInt fx;
{
- const SkBitmapProcStateAutoMapper mapper(s, x ,y);
+ SkPoint pt;
+ s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &pt);
+ fx = SkScalarToFractionalInt(pt.fY);
const unsigned maxY = s.fPixmap.height() - 1;
- *xy++ = TileProc::Y(s, mapper.y(), maxY);
- fx = SkFixedToFractionalInt(mapper.x());
+ *xy++ = TileProc::Y(s, SkFractionalIntToFixed(fx), maxY);
+ fx = SkScalarToFractionalInt(pt.fX);
}
if (0 == maxX) {
@@ -77,9 +80,13 @@ void NoFilterProc_Affine(const SkBitmapProcState& s, uint32_t xy[],
SkMatrix::kScale_Mask |
SkMatrix::kAffine_Mask)) == 0);
- const SkBitmapProcStateAutoMapper mapper(s, x ,y);
- SkFractionalInt fx = SkFixedToFractionalInt(mapper.x());
- SkFractionalInt fy = SkFixedToFractionalInt(mapper.y());
+ SkPoint srcPt;
+ s.fInvProc(s.fInvMatrix,
+ SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+
+ SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX);
+ SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY);
SkFractionalInt dx = s.fInvSxFractionalInt;
SkFractionalInt dy = s.fInvKyFractionalInt;
int maxX = s.fPixmap.width() - 1;
@@ -100,7 +107,6 @@ void NoFilterProc_Persp(const SkBitmapProcState& s, uint32_t* SK_RESTRICT xy,
int maxX = s.fPixmap.width() - 1;
int maxY = s.fPixmap.height() - 1;
- // TODO: inv bias support
SkPerspIter iter(s.fInvMatrix,
SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, count);