diff options
author | george <george@mozilla.com> | 2014-08-29 08:47:55 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-29 08:47:55 -0700 |
commit | 2f26528e59908856e36e88aa3be94d84014e9a58 (patch) | |
tree | a8d2ad9ccd9a38a26139481d1ff74c4d9bbc24c1 /src/core/SkFDot6.h | |
parent | b75b2c05b999e26343e095eabff646705a0091ae (diff) |
Use even rounding for better results when converting from scalar to fdot6
Originally from https://bugzilla.mozilla.org/show_bug.cgi?id=996108, patch by Jeff Muizelaar
R=reed@google.com, reed1
BUG=skia:
Author: george@mozilla.com
Review URL: https://codereview.chromium.org/270263005
Diffstat (limited to 'src/core/SkFDot6.h')
-rw-r--r-- | src/core/SkFDot6.h | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/core/SkFDot6.h b/src/core/SkFDot6.h index 5a0ec57f59..3da753da41 100644 --- a/src/core/SkFDot6.h +++ b/src/core/SkFDot6.h @@ -15,6 +15,28 @@ typedef int32_t SkFDot6; +/* This uses the magic number approach suggested here: + * http://stereopsis.com/sree/fpu2006.html and used in + * _cairo_fixed_from_double. It does banker's rounding + * (i.e. round to nearest even) + */ +inline SkFDot6 SkScalarRoundToFDot6(SkScalar x, int shift = 0) +{ + union { + double fDouble; + int32_t fBits[2]; + } tmp; + int fractionalBits = 6 + shift; + double magic = (1LL << (52 - (fractionalBits))) * 1.5; + + tmp.fDouble = SkScalarToDouble(x) + magic; +#ifdef SK_CPU_BENDIAN + return tmp.fBits[1]; +#else + return tmp.fBits[0]; +#endif +} + #define SK_FDot6One (64) #define SK_FDot6Half (32) |