diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBitmapProcState.cpp | 12 | ||||
-rw-r--r-- | src/core/SkBitmapProcState.h | 39 | ||||
-rw-r--r-- | src/core/SkBitmapProcState_matrix.h | 21 | ||||
-rw-r--r-- | src/core/SkBitmapProcState_matrix_template.h | 20 |
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); |