diff options
author | fmalita <fmalita@chromium.org> | 2015-12-15 06:48:48 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-15 06:48:48 -0800 |
commit | aed4d32de937a8f2733924eb848cc287e8d04087 (patch) | |
tree | 0c7708b50a7459708dc3f9a9613b6900a292d3b5 /src/core | |
parent | 11f457e1627be775cfa26d71307dbd6073f9269c (diff) |
SkBitmapProcState rounding bias
Epsilon bias to keep bitmap sample rounding consistent with geometry
rounding.
Also update the GM to draw an outer border + drop uninteresting
scales in favor of negative scale variants.
BUG=skia:4680,skia:4649
R=reed@google.com,caryclark@google.com,mtklein@google.com
Review URL: https://codereview.chromium.org/1527633002
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBitmapProcState.cpp | 6 | ||||
-rw-r--r-- | src/core/SkBitmapProcState.h | 12 | ||||
-rw-r--r-- | src/core/SkBitmapProcState_matrix.h | 12 |
3 files changed, 24 insertions, 6 deletions
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index 5ec6721436..487bd80402 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -823,10 +823,12 @@ void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const SkBitmapProcState& s, in SkPoint pt; s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &pt); - fx = SkScalarToFractionalInt(pt.fY); + fx = SkScalarToFractionalInt(pt.fY) + + bitmap_sampler_inv_bias(s.fInvMatrix.getScaleY()); const unsigned maxY = s.fPixmap.height() - 1; dstY = SkClampMax(SkFractionalIntToInt(fx), maxY); - fx = SkScalarToFractionalInt(pt.fX); + fx = SkScalarToFractionalInt(pt.fX) + + bitmap_sampler_inv_bias(s.fInvMatrix.getScaleX()); } const SkPMColor* SK_RESTRICT src = s.fPixmap.addr32(0, dstY); diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h index 2ce76bc83e..e6e7a3f393 100644 --- a/src/core/SkBitmapProcState.h +++ b/src/core/SkBitmapProcState.h @@ -12,6 +12,7 @@ #include "SkBitmapController.h" #include "SkBitmapFilter.h" #include "SkBitmapProvider.h" +#include "SkFloatBits.h" #include "SkMatrix.h" #include "SkMipMap.h" #include "SkPaint.h" @@ -24,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 { diff --git a/src/core/SkBitmapProcState_matrix.h b/src/core/SkBitmapProcState_matrix.h index bdab846496..42a5ab6e22 100644 --- a/src/core/SkBitmapProcState_matrix.h +++ b/src/core/SkBitmapProcState_matrix.h @@ -64,12 +64,14 @@ void SCALE_FILTER_NAME(const SkBitmapProcState& s, SkPoint pt; s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &pt); - const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1); + 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 = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1); + fx = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1) + + bitmap_sampler_inv_bias(s.fInvMatrix.getScaleX()); } #ifdef CHECK_FOR_DECAL @@ -102,8 +104,10 @@ void AFFINE_FILTER_NAME(const SkBitmapProcState& s, SkFixed oneX = s.fFilterOneX; SkFixed oneY = s.fFilterOneY; - SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1); - SkFixed fy = SkScalarToFixed(srcPt.fY) - (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; |