aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2016-02-03 05:44:21 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-03 05:44:21 -0800
commit2404f03413bc9b4fa3f556c64642e57507092d8d (patch)
treede08b8a947abd698523fb3712b27edf265cd4d59
parent15691a055db9b68c9b48f589e48d8a85888cf83f (diff)
Use SkBitmapProcStateAutoMapper for filter samplers also
Observation: filter procs are also biased by s.fFilterOne{X,Y} / 2. They all do something along these lines: s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &srcPt); SkFixed fx = SkScalarToFixed(srcPt.fX) - (s.fFilterOneX >> 1); SkFixed fy = SkScalarToFixed(srcPt.fY) - (s.fFilterOneX >> 1); It's trivial to extend SkBitmapProcStateAutoMapper to handle this internally, and convert everyone off explicit mapping. R=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1661613002 CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot Review URL: https://codereview.chromium.org/1661613002
-rw-r--r--src/core/SkBitmapProcState.h20
-rw-r--r--src/core/SkBitmapProcState_matrix.h17
-rw-r--r--src/core/SkBitmapProcState_shaderproc.h8
-rw-r--r--src/opts/SkBitmapProcState_matrix_neon.h17
-rw-r--r--src/opts/SkBitmapProcState_opts_SSE2.cpp18
5 files changed, 34 insertions, 46 deletions
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h
index 0ae8cf2856..fca7dc0a3e 100644
--- a/src/core/SkBitmapProcState.h
+++ b/src/core/SkBitmapProcState.h
@@ -189,7 +189,6 @@ void ClampX_ClampY_nofilter_affine(const SkBitmapProcState& s,
uint32_t xy[], int count, int x, int y);
// Helper class for mapping the middle of pixel (x, y) into SkFractionalInt bitmap space.
-// TODO: filtered version which applies a fFilterOne{X,Y}/2 bias instead of epsilon?
class SkBitmapProcStateAutoMapper {
public:
SkBitmapProcStateAutoMapper(const SkBitmapProcState& s, int x, int y,
@@ -199,12 +198,19 @@ public:
SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &pt);
- // 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.
- // We scale it to persist SkFractionalInt -> SkFixed conversions.
- const SkFixed biasX = (s.fInvMatrix.getScaleX() > 0);
- const SkFixed biasY = (s.fInvMatrix.getScaleY() > 0);
+ SkFixed biasX, biasY;
+ if (s.fFilterLevel == kNone_SkFilterQuality) {
+ // 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.
+ // We scale it to persist SkFractionalInt -> SkFixed conversions.
+ biasX = (s.fInvMatrix.getScaleX() > 0);
+ biasY = (s.fInvMatrix.getScaleY() > 0);
+ } else {
+ biasX = s.fFilterOneX >> 1;
+ biasY = s.fFilterOneY >> 1;
+ }
+
fX = SkScalarToFractionalInt(pt.x()) - SkFixedToFractionalInt(biasX);
fY = SkScalarToFractionalInt(pt.y()) - SkFixedToFractionalInt(biasY);
diff --git a/src/core/SkBitmapProcState_matrix.h b/src/core/SkBitmapProcState_matrix.h
index bdab846496..273a35ba89 100644
--- a/src/core/SkBitmapProcState_matrix.h
+++ b/src/core/SkBitmapProcState_matrix.h
@@ -61,15 +61,13 @@ void SCALE_FILTER_NAME(const SkBitmapProcState& s,
SkFractionalInt fx;
{
- 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 SkBitmapProcStateAutoMapper mapper(s, x, y);
+ const SkFixed fy = SkFractionalIntToFixed(mapper.y());
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 = mapper.x();
}
#ifdef CHECK_FOR_DECAL
@@ -95,15 +93,12 @@ void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
SkMatrix::kAffine_Mask)) == 0);
PREAMBLE(s);
- SkPoint srcPt;
- s.fInvProc(s.fInvMatrix,
- SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ const SkBitmapProcStateAutoMapper mapper(s, x, y);
SkFixed oneX = s.fFilterOneX;
SkFixed oneY = s.fFilterOneY;
- SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1);
- SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1);
+ SkFixed fx = SkFractionalIntToFixed(mapper.x());
+ SkFixed fy = SkFractionalIntToFixed(mapper.y());
SkFixed dx = s.fInvSx;
SkFixed dy = s.fInvKy;
unsigned maxX = s.fPixmap.width() - 1;
diff --git a/src/core/SkBitmapProcState_shaderproc.h b/src/core/SkBitmapProcState_shaderproc.h
index d41ff063e4..1ff2e6bf24 100644
--- a/src/core/SkBitmapProcState_shaderproc.h
+++ b/src/core/SkBitmapProcState_shaderproc.h
@@ -31,10 +31,8 @@ void SCALE_FILTER_NAME(const void* sIn, int x, int y, SkPMColor* SK_RESTRICT col
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 SkBitmapProcStateAutoMapper mapper(s, x, y);
+ SkFixed fy = SkFractionalIntToFixed(mapper.y());
const unsigned maxY = s.fPixmap.height() - 1;
// compute our two Y values up front
subY = TILEY_LOW_BITS(fy, maxY);
@@ -46,7 +44,7 @@ void SCALE_FILTER_NAME(const void* sIn, int x, int y, SkPMColor* SK_RESTRICT col
row0 = (const SRCTYPE*)(srcAddr + y0 * rb);
row1 = (const SRCTYPE*)(srcAddr + y1 * rb);
// now initialize fx
- fx = SkScalarToFixed(pt.fX) - (oneX >> 1);
+ fx = SkFractionalIntToFixed(mapper.x());
}
#ifdef PREAMBLE
diff --git a/src/opts/SkBitmapProcState_matrix_neon.h b/src/opts/SkBitmapProcState_matrix_neon.h
index 4546f70552..df151b275c 100644
--- a/src/opts/SkBitmapProcState_matrix_neon.h
+++ b/src/opts/SkBitmapProcState_matrix_neon.h
@@ -298,15 +298,13 @@ static void SCALE_FILTER_NAME(const SkBitmapProcState& s,
SkFractionalInt fx;
{
- 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 SkBitmapProcStateAutoMapper mapper(s, x, y);
+ const SkFixed fy = SkFractionalIntToFixed(mapper.y());
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 = mapper.x();
}
#ifdef CHECK_FOR_DECAL
@@ -357,15 +355,12 @@ static void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
SkMatrix::kAffine_Mask)) == 0);
PREAMBLE(s);
- SkPoint srcPt;
- s.fInvProc(s.fInvMatrix,
- SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ const SkBitmapProcStateAutoMapper mapper(s, x, y);
SkFixed oneX = s.fFilterOneX;
SkFixed oneY = s.fFilterOneY;
- SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1);
- SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1);
+ SkFixed fx = SkFractionalIntToFixed(mapper.x());
+ SkFixed fy = SkFractionalIntToFixed(mapper.y());
SkFixed dx = s.fInvSx;
SkFixed dy = s.fInvKy;
unsigned maxX = s.fPixmap.width() - 1;
diff --git a/src/opts/SkBitmapProcState_opts_SSE2.cpp b/src/opts/SkBitmapProcState_opts_SSE2.cpp
index b5da8e23fa..cb9a2dbb14 100644
--- a/src/opts/SkBitmapProcState_opts_SSE2.cpp
+++ b/src/opts/SkBitmapProcState_opts_SSE2.cpp
@@ -252,17 +252,14 @@ void ClampX_ClampY_filter_scale_SSE2(const SkBitmapProcState& s, uint32_t xy[],
const unsigned maxX = s.fPixmap.width() - 1;
const SkFixed one = s.fFilterOneX;
const SkFixed dx = s.fInvSx;
- SkFixed fx;
- 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 SkBitmapProcStateAutoMapper mapper(s, x, y);
+ const SkFixed fy = SkFractionalIntToFixed(mapper.y());
const unsigned maxY = s.fPixmap.height() - 1;
// compute our two Y values up front
*xy++ = ClampX_ClampY_pack_filter(fy, maxY, s.fFilterOneY);
// now initialize fx
- fx = SkScalarToFixed(pt.fX) - (one >> 1);
+ SkFixed fx = SkFractionalIntToFixed(mapper.x());
// test if we don't need to apply the tile proc
if (dx > 0 && (unsigned)(fx >> 16) <= maxX &&
@@ -485,15 +482,12 @@ void ClampX_ClampY_nofilter_scale_SSE2(const SkBitmapProcState& s,
*/
void ClampX_ClampY_filter_affine_SSE2(const SkBitmapProcState& s,
uint32_t xy[], int count, int x, int y) {
- SkPoint srcPt;
- s.fInvProc(s.fInvMatrix,
- SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ const SkBitmapProcStateAutoMapper mapper(s, x, y);
SkFixed oneX = s.fFilterOneX;
SkFixed oneY = s.fFilterOneY;
- SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1);
- SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1);
+ SkFixed fx = SkFractionalIntToFixed(mapper.x());
+ SkFixed fy = SkFractionalIntToFixed(mapper.y());
SkFixed dx = s.fInvSx;
SkFixed dy = s.fInvKy;
unsigned maxX = s.fPixmap.width() - 1;