diff options
author | 2016-02-03 05:44:21 -0800 | |
---|---|---|
committer | 2016-02-03 05:44:21 -0800 | |
commit | 2404f03413bc9b4fa3f556c64642e57507092d8d (patch) | |
tree | de08b8a947abd698523fb3712b27edf265cd4d59 | |
parent | 15691a055db9b68c9b48f589e48d8a85888cf83f (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.h | 20 | ||||
-rw-r--r-- | src/core/SkBitmapProcState_matrix.h | 17 | ||||
-rw-r--r-- | src/core/SkBitmapProcState_shaderproc.h | 8 | ||||
-rw-r--r-- | src/opts/SkBitmapProcState_matrix_neon.h | 17 | ||||
-rw-r--r-- | src/opts/SkBitmapProcState_opts_SSE2.cpp | 18 |
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; |