1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkBitmapProcState_matrix.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,303 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2011 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 +#include "SkMath.h" 1.13 +#include "SkMathPriv.h" 1.14 + 1.15 +#define SCALE_NOFILTER_NAME MAKENAME(_nofilter_scale) 1.16 +#define SCALE_FILTER_NAME MAKENAME(_filter_scale) 1.17 +#define AFFINE_NOFILTER_NAME MAKENAME(_nofilter_affine) 1.18 +#define AFFINE_FILTER_NAME MAKENAME(_filter_affine) 1.19 +#define PERSP_NOFILTER_NAME MAKENAME(_nofilter_persp) 1.20 +#define PERSP_FILTER_NAME MAKENAME(_filter_persp) 1.21 + 1.22 +#define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x) 1.23 +#define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y) 1.24 + 1.25 +#ifndef PREAMBLE 1.26 + #define PREAMBLE(state) 1.27 + #define PREAMBLE_PARAM_X 1.28 + #define PREAMBLE_PARAM_Y 1.29 + #define PREAMBLE_ARG_X 1.30 + #define PREAMBLE_ARG_Y 1.31 +#endif 1.32 + 1.33 +// declare functions externally to suppress warnings. 1.34 +void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, 1.35 + uint32_t xy[], int count, int x, int y); 1.36 +void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s, 1.37 + uint32_t xy[], int count, int x, int y); 1.38 +void PERSP_NOFILTER_NAME(const SkBitmapProcState& s, 1.39 + uint32_t* SK_RESTRICT xy, 1.40 + int count, int x, int y); 1.41 +void SCALE_FILTER_NAME(const SkBitmapProcState& s, 1.42 + uint32_t xy[], int count, int x, int y); 1.43 +void AFFINE_FILTER_NAME(const SkBitmapProcState& s, 1.44 + uint32_t xy[], int count, int x, int y); 1.45 +void PERSP_FILTER_NAME(const SkBitmapProcState& s, 1.46 + uint32_t* SK_RESTRICT xy, int count, 1.47 + int x, int y); 1.48 + 1.49 +void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, 1.50 + uint32_t xy[], int count, int x, int y) { 1.51 + SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 1.52 + SkMatrix::kScale_Mask)) == 0); 1.53 + 1.54 + PREAMBLE(s); 1.55 + // we store y, x, x, x, x, x 1.56 + 1.57 + const unsigned maxX = s.fBitmap->width() - 1; 1.58 + SkFractionalInt fx; 1.59 + { 1.60 + SkPoint pt; 1.61 + s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 1.62 + SkIntToScalar(y) + SK_ScalarHalf, &pt); 1.63 + fx = SkScalarToFractionalInt(pt.fY); 1.64 + const unsigned maxY = s.fBitmap->height() - 1; 1.65 + *xy++ = TILEY_PROCF(SkFractionalIntToFixed(fx), maxY); 1.66 + fx = SkScalarToFractionalInt(pt.fX); 1.67 + } 1.68 + 1.69 + if (0 == maxX) { 1.70 + // all of the following X values must be 0 1.71 + memset(xy, 0, count * sizeof(uint16_t)); 1.72 + return; 1.73 + } 1.74 + 1.75 + const SkFractionalInt dx = s.fInvSxFractionalInt; 1.76 + 1.77 +#ifdef CHECK_FOR_DECAL 1.78 + if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { 1.79 + decal_nofilter_scale(xy, SkFractionalIntToFixed(fx), 1.80 + SkFractionalIntToFixed(dx), count); 1.81 + } else 1.82 +#endif 1.83 + { 1.84 + int i; 1.85 + for (i = (count >> 2); i > 0; --i) { 1.86 + unsigned a, b; 1.87 + a = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; 1.88 + b = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; 1.89 +#ifdef SK_CPU_BENDIAN 1.90 + *xy++ = (a << 16) | b; 1.91 +#else 1.92 + *xy++ = (b << 16) | a; 1.93 +#endif 1.94 + a = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; 1.95 + b = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; 1.96 +#ifdef SK_CPU_BENDIAN 1.97 + *xy++ = (a << 16) | b; 1.98 +#else 1.99 + *xy++ = (b << 16) | a; 1.100 +#endif 1.101 + } 1.102 + uint16_t* xx = (uint16_t*)xy; 1.103 + for (i = (count & 3); i > 0; --i) { 1.104 + *xx++ = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; 1.105 + } 1.106 + } 1.107 +} 1.108 + 1.109 +// note: we could special-case on a matrix which is skewed in X but not Y. 1.110 +// this would require a more general setup thatn SCALE does, but could use 1.111 +// SCALE's inner loop that only looks at dx 1.112 + 1.113 +void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s, 1.114 + uint32_t xy[], int count, int x, int y) { 1.115 + SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); 1.116 + SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 1.117 + SkMatrix::kScale_Mask | 1.118 + SkMatrix::kAffine_Mask)) == 0); 1.119 + 1.120 + PREAMBLE(s); 1.121 + SkPoint srcPt; 1.122 + s.fInvProc(s.fInvMatrix, 1.123 + SkIntToScalar(x) + SK_ScalarHalf, 1.124 + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 1.125 + 1.126 + SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX); 1.127 + SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY); 1.128 + SkFractionalInt dx = s.fInvSxFractionalInt; 1.129 + SkFractionalInt dy = s.fInvKyFractionalInt; 1.130 + int maxX = s.fBitmap->width() - 1; 1.131 + int maxY = s.fBitmap->height() - 1; 1.132 + 1.133 + for (int i = count; i > 0; --i) { 1.134 + *xy++ = (TILEY_PROCF(SkFractionalIntToFixed(fy), maxY) << 16) | 1.135 + TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); 1.136 + fx += dx; fy += dy; 1.137 + } 1.138 +} 1.139 + 1.140 +void PERSP_NOFILTER_NAME(const SkBitmapProcState& s, 1.141 + uint32_t* SK_RESTRICT xy, 1.142 + int count, int x, int y) { 1.143 + SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); 1.144 + 1.145 + PREAMBLE(s); 1.146 + int maxX = s.fBitmap->width() - 1; 1.147 + int maxY = s.fBitmap->height() - 1; 1.148 + 1.149 + SkPerspIter iter(s.fInvMatrix, 1.150 + SkIntToScalar(x) + SK_ScalarHalf, 1.151 + SkIntToScalar(y) + SK_ScalarHalf, count); 1.152 + 1.153 + while ((count = iter.next()) != 0) { 1.154 + const SkFixed* SK_RESTRICT srcXY = iter.getXY(); 1.155 + while (--count >= 0) { 1.156 + *xy++ = (TILEY_PROCF(srcXY[1], maxY) << 16) | 1.157 + TILEX_PROCF(srcXY[0], maxX); 1.158 + srcXY += 2; 1.159 + } 1.160 + } 1.161 +} 1.162 + 1.163 +////////////////////////////////////////////////////////////////////////////// 1.164 + 1.165 +static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max, 1.166 + SkFixed one PREAMBLE_PARAM_Y) { 1.167 + unsigned i = TILEY_PROCF(f, max); 1.168 + i = (i << 4) | TILEY_LOW_BITS(f, max); 1.169 + return (i << 14) | (TILEY_PROCF((f + one), max)); 1.170 +} 1.171 + 1.172 +static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max, 1.173 + SkFixed one PREAMBLE_PARAM_X) { 1.174 + unsigned i = TILEX_PROCF(f, max); 1.175 + i = (i << 4) | TILEX_LOW_BITS(f, max); 1.176 + return (i << 14) | (TILEX_PROCF((f + one), max)); 1.177 +} 1.178 + 1.179 +void SCALE_FILTER_NAME(const SkBitmapProcState& s, 1.180 + uint32_t xy[], int count, int x, int y) { 1.181 + SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 1.182 + SkMatrix::kScale_Mask)) == 0); 1.183 + SkASSERT(s.fInvKy == 0); 1.184 + 1.185 + PREAMBLE(s); 1.186 + 1.187 + const unsigned maxX = s.fBitmap->width() - 1; 1.188 + const SkFixed one = s.fFilterOneX; 1.189 + const SkFractionalInt dx = s.fInvSxFractionalInt; 1.190 + SkFractionalInt fx; 1.191 + 1.192 + { 1.193 + SkPoint pt; 1.194 + s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 1.195 + SkIntToScalar(y) + SK_ScalarHalf, &pt); 1.196 + const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1); 1.197 + const unsigned maxY = s.fBitmap->height() - 1; 1.198 + // compute our two Y values up front 1.199 + *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y); 1.200 + // now initialize fx 1.201 + fx = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1); 1.202 + } 1.203 + 1.204 +#ifdef CHECK_FOR_DECAL 1.205 + if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { 1.206 + decal_filter_scale(xy, SkFractionalIntToFixed(fx), 1.207 + SkFractionalIntToFixed(dx), count); 1.208 + } else 1.209 +#endif 1.210 + { 1.211 + do { 1.212 + SkFixed fixedFx = SkFractionalIntToFixed(fx); 1.213 + *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X); 1.214 + fx += dx; 1.215 + } while (--count != 0); 1.216 + } 1.217 +} 1.218 + 1.219 +void AFFINE_FILTER_NAME(const SkBitmapProcState& s, 1.220 + uint32_t xy[], int count, int x, int y) { 1.221 + SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); 1.222 + SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 1.223 + SkMatrix::kScale_Mask | 1.224 + SkMatrix::kAffine_Mask)) == 0); 1.225 + 1.226 + PREAMBLE(s); 1.227 + SkPoint srcPt; 1.228 + s.fInvProc(s.fInvMatrix, 1.229 + SkIntToScalar(x) + SK_ScalarHalf, 1.230 + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 1.231 + 1.232 + SkFixed oneX = s.fFilterOneX; 1.233 + SkFixed oneY = s.fFilterOneY; 1.234 + SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1); 1.235 + SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1); 1.236 + SkFixed dx = s.fInvSx; 1.237 + SkFixed dy = s.fInvKy; 1.238 + unsigned maxX = s.fBitmap->width() - 1; 1.239 + unsigned maxY = s.fBitmap->height() - 1; 1.240 + 1.241 + do { 1.242 + *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y); 1.243 + fy += dy; 1.244 + *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X); 1.245 + fx += dx; 1.246 + } while (--count != 0); 1.247 +} 1.248 + 1.249 +void PERSP_FILTER_NAME(const SkBitmapProcState& s, 1.250 + uint32_t* SK_RESTRICT xy, int count, 1.251 + int x, int y) { 1.252 + SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); 1.253 + 1.254 + PREAMBLE(s); 1.255 + unsigned maxX = s.fBitmap->width() - 1; 1.256 + unsigned maxY = s.fBitmap->height() - 1; 1.257 + SkFixed oneX = s.fFilterOneX; 1.258 + SkFixed oneY = s.fFilterOneY; 1.259 + 1.260 + SkPerspIter iter(s.fInvMatrix, 1.261 + SkIntToScalar(x) + SK_ScalarHalf, 1.262 + SkIntToScalar(y) + SK_ScalarHalf, count); 1.263 + 1.264 + while ((count = iter.next()) != 0) { 1.265 + const SkFixed* SK_RESTRICT srcXY = iter.getXY(); 1.266 + do { 1.267 + *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY, 1.268 + oneY PREAMBLE_ARG_Y); 1.269 + *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX, 1.270 + oneX PREAMBLE_ARG_X); 1.271 + srcXY += 2; 1.272 + } while (--count != 0); 1.273 + } 1.274 +} 1.275 + 1.276 +static SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = { 1.277 + SCALE_NOFILTER_NAME, 1.278 + SCALE_FILTER_NAME, 1.279 + AFFINE_NOFILTER_NAME, 1.280 + AFFINE_FILTER_NAME, 1.281 + PERSP_NOFILTER_NAME, 1.282 + PERSP_FILTER_NAME 1.283 +}; 1.284 + 1.285 +#undef MAKENAME 1.286 +#undef TILEX_PROCF 1.287 +#undef TILEY_PROCF 1.288 +#ifdef CHECK_FOR_DECAL 1.289 + #undef CHECK_FOR_DECAL 1.290 +#endif 1.291 + 1.292 +#undef SCALE_NOFILTER_NAME 1.293 +#undef SCALE_FILTER_NAME 1.294 +#undef AFFINE_NOFILTER_NAME 1.295 +#undef AFFINE_FILTER_NAME 1.296 +#undef PERSP_NOFILTER_NAME 1.297 +#undef PERSP_FILTER_NAME 1.298 + 1.299 +#undef PREAMBLE 1.300 +#undef PREAMBLE_PARAM_X 1.301 +#undef PREAMBLE_PARAM_Y 1.302 +#undef PREAMBLE_ARG_X 1.303 +#undef PREAMBLE_ARG_Y 1.304 + 1.305 +#undef TILEX_LOW_BITS 1.306 +#undef TILEY_LOW_BITS