aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2015-12-15 06:48:48 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-12-15 06:48:48 -0800
commitaed4d32de937a8f2733924eb848cc287e8d04087 (patch)
tree0c7708b50a7459708dc3f9a9613b6900a292d3b5 /src/core
parent11f457e1627be775cfa26d71307dbd6073f9269c (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.cpp6
-rw-r--r--src/core/SkBitmapProcState.h12
-rw-r--r--src/core/SkBitmapProcState_matrix.h12
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;