Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* NEON optimized code (C) COPYRIGHT 2009 Motorola |
michael@0 | 2 | * |
michael@0 | 3 | * Use of this source code is governed by a BSD-style license that can be |
michael@0 | 4 | * found in the LICENSE file. |
michael@0 | 5 | */ |
michael@0 | 6 | |
michael@0 | 7 | #include "SkBitmapProcState.h" |
michael@0 | 8 | #include "SkPerspIter.h" |
michael@0 | 9 | #include "SkShader.h" |
michael@0 | 10 | #include "SkUtils.h" |
michael@0 | 11 | #include "SkUtilsArm.h" |
michael@0 | 12 | #include "SkBitmapProcState_utils.h" |
michael@0 | 13 | |
michael@0 | 14 | /* returns 0...(n-1) given any x (positive or negative). |
michael@0 | 15 | |
michael@0 | 16 | As an example, if n (which is always positive) is 5... |
michael@0 | 17 | |
michael@0 | 18 | x: -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 |
michael@0 | 19 | returns: 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 |
michael@0 | 20 | */ |
michael@0 | 21 | static inline int sk_int_mod(int x, int n) { |
michael@0 | 22 | SkASSERT(n > 0); |
michael@0 | 23 | if ((unsigned)x >= (unsigned)n) { |
michael@0 | 24 | if (x < 0) { |
michael@0 | 25 | x = n + ~(~x % n); |
michael@0 | 26 | } else { |
michael@0 | 27 | x = x % n; |
michael@0 | 28 | } |
michael@0 | 29 | } |
michael@0 | 30 | return x; |
michael@0 | 31 | } |
michael@0 | 32 | |
michael@0 | 33 | void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); |
michael@0 | 34 | void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); |
michael@0 | 35 | |
michael@0 | 36 | // Compile neon code paths if needed |
michael@0 | 37 | #if !SK_ARM_NEON_IS_NONE |
michael@0 | 38 | |
michael@0 | 39 | // These are defined in src/opts/SkBitmapProcState_matrixProcs_neon.cpp |
michael@0 | 40 | extern const SkBitmapProcState::MatrixProc ClampX_ClampY_Procs_neon[]; |
michael@0 | 41 | extern const SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs_neon[]; |
michael@0 | 42 | |
michael@0 | 43 | #endif // !SK_ARM_NEON_IS_NONE |
michael@0 | 44 | |
michael@0 | 45 | // Compile non-neon code path if needed |
michael@0 | 46 | #if !SK_ARM_NEON_IS_ALWAYS |
michael@0 | 47 | #define MAKENAME(suffix) ClampX_ClampY ## suffix |
michael@0 | 48 | #define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max) |
michael@0 | 49 | #define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max) |
michael@0 | 50 | #define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) |
michael@0 | 51 | #define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) |
michael@0 | 52 | #define CHECK_FOR_DECAL |
michael@0 | 53 | #include "SkBitmapProcState_matrix.h" |
michael@0 | 54 | |
michael@0 | 55 | #define MAKENAME(suffix) RepeatX_RepeatY ## suffix |
michael@0 | 56 | #define TILEX_PROCF(fx, max) SK_USHIFT16(((fx) & 0xFFFF) * ((max) + 1)) |
michael@0 | 57 | #define TILEY_PROCF(fy, max) SK_USHIFT16(((fy) & 0xFFFF) * ((max) + 1)) |
michael@0 | 58 | #define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) |
michael@0 | 59 | #define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) |
michael@0 | 60 | #include "SkBitmapProcState_matrix.h" |
michael@0 | 61 | #endif |
michael@0 | 62 | |
michael@0 | 63 | #define MAKENAME(suffix) GeneralXY ## suffix |
michael@0 | 64 | #define PREAMBLE(state) SkBitmapProcState::FixedTileProc tileProcX = (state).fTileProcX; (void) tileProcX; \ |
michael@0 | 65 | SkBitmapProcState::FixedTileProc tileProcY = (state).fTileProcY; (void) tileProcY; \ |
michael@0 | 66 | SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcX = (state).fTileLowBitsProcX; (void) tileLowBitsProcX; \ |
michael@0 | 67 | SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcY = (state).fTileLowBitsProcY; (void) tileLowBitsProcY |
michael@0 | 68 | #define PREAMBLE_PARAM_X , SkBitmapProcState::FixedTileProc tileProcX, SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcX |
michael@0 | 69 | #define PREAMBLE_PARAM_Y , SkBitmapProcState::FixedTileProc tileProcY, SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcY |
michael@0 | 70 | #define PREAMBLE_ARG_X , tileProcX, tileLowBitsProcX |
michael@0 | 71 | #define PREAMBLE_ARG_Y , tileProcY, tileLowBitsProcY |
michael@0 | 72 | #define TILEX_PROCF(fx, max) SK_USHIFT16(tileProcX(fx) * ((max) + 1)) |
michael@0 | 73 | #define TILEY_PROCF(fy, max) SK_USHIFT16(tileProcY(fy) * ((max) + 1)) |
michael@0 | 74 | #define TILEX_LOW_BITS(fx, max) tileLowBitsProcX(fx, (max) + 1) |
michael@0 | 75 | #define TILEY_LOW_BITS(fy, max) tileLowBitsProcY(fy, (max) + 1) |
michael@0 | 76 | #include "SkBitmapProcState_matrix.h" |
michael@0 | 77 | |
michael@0 | 78 | static inline U16CPU fixed_clamp(SkFixed x) |
michael@0 | 79 | { |
michael@0 | 80 | if (x < 0) { |
michael@0 | 81 | x = 0; |
michael@0 | 82 | } |
michael@0 | 83 | if (x >> 16) { |
michael@0 | 84 | x = 0xFFFF; |
michael@0 | 85 | } |
michael@0 | 86 | return x; |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | static inline U16CPU fixed_repeat(SkFixed x) |
michael@0 | 90 | { |
michael@0 | 91 | return x & 0xFFFF; |
michael@0 | 92 | } |
michael@0 | 93 | |
michael@0 | 94 | // Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly. |
michael@0 | 95 | // See http://code.google.com/p/skia/issues/detail?id=472 |
michael@0 | 96 | #if defined(_MSC_VER) && (_MSC_VER >= 1600) |
michael@0 | 97 | #pragma optimize("", off) |
michael@0 | 98 | #endif |
michael@0 | 99 | |
michael@0 | 100 | static inline U16CPU fixed_mirror(SkFixed x) |
michael@0 | 101 | { |
michael@0 | 102 | SkFixed s = x << 15 >> 31; |
michael@0 | 103 | // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval |
michael@0 | 104 | return (x ^ s) & 0xFFFF; |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | #if defined(_MSC_VER) && (_MSC_VER >= 1600) |
michael@0 | 108 | #pragma optimize("", on) |
michael@0 | 109 | #endif |
michael@0 | 110 | |
michael@0 | 111 | static SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m) |
michael@0 | 112 | { |
michael@0 | 113 | if (SkShader::kClamp_TileMode == m) |
michael@0 | 114 | return fixed_clamp; |
michael@0 | 115 | if (SkShader::kRepeat_TileMode == m) |
michael@0 | 116 | return fixed_repeat; |
michael@0 | 117 | SkASSERT(SkShader::kMirror_TileMode == m); |
michael@0 | 118 | return fixed_mirror; |
michael@0 | 119 | } |
michael@0 | 120 | |
michael@0 | 121 | static inline U16CPU fixed_clamp_lowbits(SkFixed x, int) { |
michael@0 | 122 | return (x >> 12) & 0xF; |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | static inline U16CPU fixed_repeat_or_mirrow_lowbits(SkFixed x, int scale) { |
michael@0 | 126 | return ((x * scale) >> 12) & 0xF; |
michael@0 | 127 | } |
michael@0 | 128 | |
michael@0 | 129 | static SkBitmapProcState::FixedTileLowBitsProc choose_tile_lowbits_proc(unsigned m) { |
michael@0 | 130 | if (SkShader::kClamp_TileMode == m) { |
michael@0 | 131 | return fixed_clamp_lowbits; |
michael@0 | 132 | } else { |
michael@0 | 133 | SkASSERT(SkShader::kMirror_TileMode == m || |
michael@0 | 134 | SkShader::kRepeat_TileMode == m); |
michael@0 | 135 | // mirror and repeat have the same behavior for the low bits. |
michael@0 | 136 | return fixed_repeat_or_mirrow_lowbits; |
michael@0 | 137 | } |
michael@0 | 138 | } |
michael@0 | 139 | |
michael@0 | 140 | static inline U16CPU int_clamp(int x, int n) { |
michael@0 | 141 | if (x >= n) { |
michael@0 | 142 | x = n - 1; |
michael@0 | 143 | } |
michael@0 | 144 | if (x < 0) { |
michael@0 | 145 | x = 0; |
michael@0 | 146 | } |
michael@0 | 147 | return x; |
michael@0 | 148 | } |
michael@0 | 149 | |
michael@0 | 150 | static inline U16CPU int_repeat(int x, int n) { |
michael@0 | 151 | return sk_int_mod(x, n); |
michael@0 | 152 | } |
michael@0 | 153 | |
michael@0 | 154 | static inline U16CPU int_mirror(int x, int n) { |
michael@0 | 155 | x = sk_int_mod(x, 2 * n); |
michael@0 | 156 | if (x >= n) { |
michael@0 | 157 | x = n + ~(x - n); |
michael@0 | 158 | } |
michael@0 | 159 | return x; |
michael@0 | 160 | } |
michael@0 | 161 | |
michael@0 | 162 | #if 0 |
michael@0 | 163 | static void test_int_tileprocs() { |
michael@0 | 164 | for (int i = -8; i <= 8; i++) { |
michael@0 | 165 | SkDebugf(" int_mirror(%2d, 3) = %d\n", i, int_mirror(i, 3)); |
michael@0 | 166 | } |
michael@0 | 167 | } |
michael@0 | 168 | #endif |
michael@0 | 169 | |
michael@0 | 170 | static SkBitmapProcState::IntTileProc choose_int_tile_proc(unsigned tm) { |
michael@0 | 171 | if (SkShader::kClamp_TileMode == tm) |
michael@0 | 172 | return int_clamp; |
michael@0 | 173 | if (SkShader::kRepeat_TileMode == tm) |
michael@0 | 174 | return int_repeat; |
michael@0 | 175 | SkASSERT(SkShader::kMirror_TileMode == tm); |
michael@0 | 176 | return int_mirror; |
michael@0 | 177 | } |
michael@0 | 178 | |
michael@0 | 179 | ////////////////////////////////////////////////////////////////////////////// |
michael@0 | 180 | |
michael@0 | 181 | void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) |
michael@0 | 182 | { |
michael@0 | 183 | int i; |
michael@0 | 184 | |
michael@0 | 185 | for (i = (count >> 2); i > 0; --i) |
michael@0 | 186 | { |
michael@0 | 187 | *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); |
michael@0 | 188 | fx += dx+dx; |
michael@0 | 189 | *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); |
michael@0 | 190 | fx += dx+dx; |
michael@0 | 191 | } |
michael@0 | 192 | count &= 3; |
michael@0 | 193 | |
michael@0 | 194 | uint16_t* xx = (uint16_t*)dst; |
michael@0 | 195 | for (i = count; i > 0; --i) { |
michael@0 | 196 | *xx++ = SkToU16(fx >> 16); fx += dx; |
michael@0 | 197 | } |
michael@0 | 198 | } |
michael@0 | 199 | |
michael@0 | 200 | void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) |
michael@0 | 201 | { |
michael@0 | 202 | |
michael@0 | 203 | |
michael@0 | 204 | if (count & 1) |
michael@0 | 205 | { |
michael@0 | 206 | SkASSERT((fx >> (16 + 14)) == 0); |
michael@0 | 207 | *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); |
michael@0 | 208 | fx += dx; |
michael@0 | 209 | } |
michael@0 | 210 | while ((count -= 2) >= 0) |
michael@0 | 211 | { |
michael@0 | 212 | SkASSERT((fx >> (16 + 14)) == 0); |
michael@0 | 213 | *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); |
michael@0 | 214 | fx += dx; |
michael@0 | 215 | |
michael@0 | 216 | *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); |
michael@0 | 217 | fx += dx; |
michael@0 | 218 | } |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | /////////////////////////////////////////////////////////////////////////////// |
michael@0 | 222 | // stores the same as SCALE, but is cheaper to compute. Also since there is no |
michael@0 | 223 | // scale, we don't need/have a FILTER version |
michael@0 | 224 | |
michael@0 | 225 | static void fill_sequential(uint16_t xptr[], int start, int count) { |
michael@0 | 226 | #if 1 |
michael@0 | 227 | if (reinterpret_cast<intptr_t>(xptr) & 0x2) { |
michael@0 | 228 | *xptr++ = start++; |
michael@0 | 229 | count -= 1; |
michael@0 | 230 | } |
michael@0 | 231 | if (count > 3) { |
michael@0 | 232 | uint32_t* xxptr = reinterpret_cast<uint32_t*>(xptr); |
michael@0 | 233 | uint32_t pattern0 = PACK_TWO_SHORTS(start + 0, start + 1); |
michael@0 | 234 | uint32_t pattern1 = PACK_TWO_SHORTS(start + 2, start + 3); |
michael@0 | 235 | start += count & ~3; |
michael@0 | 236 | int qcount = count >> 2; |
michael@0 | 237 | do { |
michael@0 | 238 | *xxptr++ = pattern0; |
michael@0 | 239 | pattern0 += 0x40004; |
michael@0 | 240 | *xxptr++ = pattern1; |
michael@0 | 241 | pattern1 += 0x40004; |
michael@0 | 242 | } while (--qcount != 0); |
michael@0 | 243 | xptr = reinterpret_cast<uint16_t*>(xxptr); |
michael@0 | 244 | count &= 3; |
michael@0 | 245 | } |
michael@0 | 246 | while (--count >= 0) { |
michael@0 | 247 | *xptr++ = start++; |
michael@0 | 248 | } |
michael@0 | 249 | #else |
michael@0 | 250 | for (int i = 0; i < count; i++) { |
michael@0 | 251 | *xptr++ = start++; |
michael@0 | 252 | } |
michael@0 | 253 | #endif |
michael@0 | 254 | } |
michael@0 | 255 | |
michael@0 | 256 | static int nofilter_trans_preamble(const SkBitmapProcState& s, uint32_t** xy, |
michael@0 | 257 | int x, int y) { |
michael@0 | 258 | SkPoint pt; |
michael@0 | 259 | s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, |
michael@0 | 260 | SkIntToScalar(y) + SK_ScalarHalf, &pt); |
michael@0 | 261 | **xy = s.fIntTileProcY(SkScalarToFixed(pt.fY) >> 16, |
michael@0 | 262 | s.fBitmap->height()); |
michael@0 | 263 | *xy += 1; // bump the ptr |
michael@0 | 264 | // return our starting X position |
michael@0 | 265 | return SkScalarToFixed(pt.fX) >> 16; |
michael@0 | 266 | } |
michael@0 | 267 | |
michael@0 | 268 | static void clampx_nofilter_trans(const SkBitmapProcState& s, |
michael@0 | 269 | uint32_t xy[], int count, int x, int y) { |
michael@0 | 270 | SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); |
michael@0 | 271 | |
michael@0 | 272 | int xpos = nofilter_trans_preamble(s, &xy, x, y); |
michael@0 | 273 | const int width = s.fBitmap->width(); |
michael@0 | 274 | if (1 == width) { |
michael@0 | 275 | // all of the following X values must be 0 |
michael@0 | 276 | memset(xy, 0, count * sizeof(uint16_t)); |
michael@0 | 277 | return; |
michael@0 | 278 | } |
michael@0 | 279 | |
michael@0 | 280 | uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); |
michael@0 | 281 | int n; |
michael@0 | 282 | |
michael@0 | 283 | // fill before 0 as needed |
michael@0 | 284 | if (xpos < 0) { |
michael@0 | 285 | n = -xpos; |
michael@0 | 286 | if (n > count) { |
michael@0 | 287 | n = count; |
michael@0 | 288 | } |
michael@0 | 289 | memset(xptr, 0, n * sizeof(uint16_t)); |
michael@0 | 290 | count -= n; |
michael@0 | 291 | if (0 == count) { |
michael@0 | 292 | return; |
michael@0 | 293 | } |
michael@0 | 294 | xptr += n; |
michael@0 | 295 | xpos = 0; |
michael@0 | 296 | } |
michael@0 | 297 | |
michael@0 | 298 | // fill in 0..width-1 if needed |
michael@0 | 299 | if (xpos < width) { |
michael@0 | 300 | n = width - xpos; |
michael@0 | 301 | if (n > count) { |
michael@0 | 302 | n = count; |
michael@0 | 303 | } |
michael@0 | 304 | fill_sequential(xptr, xpos, n); |
michael@0 | 305 | count -= n; |
michael@0 | 306 | if (0 == count) { |
michael@0 | 307 | return; |
michael@0 | 308 | } |
michael@0 | 309 | xptr += n; |
michael@0 | 310 | } |
michael@0 | 311 | |
michael@0 | 312 | // fill the remaining with the max value |
michael@0 | 313 | sk_memset16(xptr, width - 1, count); |
michael@0 | 314 | } |
michael@0 | 315 | |
michael@0 | 316 | static void repeatx_nofilter_trans(const SkBitmapProcState& s, |
michael@0 | 317 | uint32_t xy[], int count, int x, int y) { |
michael@0 | 318 | SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); |
michael@0 | 319 | |
michael@0 | 320 | int xpos = nofilter_trans_preamble(s, &xy, x, y); |
michael@0 | 321 | const int width = s.fBitmap->width(); |
michael@0 | 322 | if (1 == width) { |
michael@0 | 323 | // all of the following X values must be 0 |
michael@0 | 324 | memset(xy, 0, count * sizeof(uint16_t)); |
michael@0 | 325 | return; |
michael@0 | 326 | } |
michael@0 | 327 | |
michael@0 | 328 | uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); |
michael@0 | 329 | int start = sk_int_mod(xpos, width); |
michael@0 | 330 | int n = width - start; |
michael@0 | 331 | if (n > count) { |
michael@0 | 332 | n = count; |
michael@0 | 333 | } |
michael@0 | 334 | fill_sequential(xptr, start, n); |
michael@0 | 335 | xptr += n; |
michael@0 | 336 | count -= n; |
michael@0 | 337 | |
michael@0 | 338 | while (count >= width) { |
michael@0 | 339 | fill_sequential(xptr, 0, width); |
michael@0 | 340 | xptr += width; |
michael@0 | 341 | count -= width; |
michael@0 | 342 | } |
michael@0 | 343 | |
michael@0 | 344 | if (count > 0) { |
michael@0 | 345 | fill_sequential(xptr, 0, count); |
michael@0 | 346 | } |
michael@0 | 347 | } |
michael@0 | 348 | |
michael@0 | 349 | static void fill_backwards(uint16_t xptr[], int pos, int count) { |
michael@0 | 350 | for (int i = 0; i < count; i++) { |
michael@0 | 351 | SkASSERT(pos >= 0); |
michael@0 | 352 | xptr[i] = pos--; |
michael@0 | 353 | } |
michael@0 | 354 | } |
michael@0 | 355 | |
michael@0 | 356 | static void mirrorx_nofilter_trans(const SkBitmapProcState& s, |
michael@0 | 357 | uint32_t xy[], int count, int x, int y) { |
michael@0 | 358 | SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); |
michael@0 | 359 | |
michael@0 | 360 | int xpos = nofilter_trans_preamble(s, &xy, x, y); |
michael@0 | 361 | const int width = s.fBitmap->width(); |
michael@0 | 362 | if (1 == width) { |
michael@0 | 363 | // all of the following X values must be 0 |
michael@0 | 364 | memset(xy, 0, count * sizeof(uint16_t)); |
michael@0 | 365 | return; |
michael@0 | 366 | } |
michael@0 | 367 | |
michael@0 | 368 | uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); |
michael@0 | 369 | // need to know our start, and our initial phase (forward or backward) |
michael@0 | 370 | bool forward; |
michael@0 | 371 | int n; |
michael@0 | 372 | int start = sk_int_mod(xpos, 2 * width); |
michael@0 | 373 | if (start >= width) { |
michael@0 | 374 | start = width + ~(start - width); |
michael@0 | 375 | forward = false; |
michael@0 | 376 | n = start + 1; // [start .. 0] |
michael@0 | 377 | } else { |
michael@0 | 378 | forward = true; |
michael@0 | 379 | n = width - start; // [start .. width) |
michael@0 | 380 | } |
michael@0 | 381 | if (n > count) { |
michael@0 | 382 | n = count; |
michael@0 | 383 | } |
michael@0 | 384 | if (forward) { |
michael@0 | 385 | fill_sequential(xptr, start, n); |
michael@0 | 386 | } else { |
michael@0 | 387 | fill_backwards(xptr, start, n); |
michael@0 | 388 | } |
michael@0 | 389 | forward = !forward; |
michael@0 | 390 | xptr += n; |
michael@0 | 391 | count -= n; |
michael@0 | 392 | |
michael@0 | 393 | while (count >= width) { |
michael@0 | 394 | if (forward) { |
michael@0 | 395 | fill_sequential(xptr, 0, width); |
michael@0 | 396 | } else { |
michael@0 | 397 | fill_backwards(xptr, width - 1, width); |
michael@0 | 398 | } |
michael@0 | 399 | forward = !forward; |
michael@0 | 400 | xptr += width; |
michael@0 | 401 | count -= width; |
michael@0 | 402 | } |
michael@0 | 403 | |
michael@0 | 404 | if (count > 0) { |
michael@0 | 405 | if (forward) { |
michael@0 | 406 | fill_sequential(xptr, 0, count); |
michael@0 | 407 | } else { |
michael@0 | 408 | fill_backwards(xptr, width - 1, count); |
michael@0 | 409 | } |
michael@0 | 410 | } |
michael@0 | 411 | } |
michael@0 | 412 | |
michael@0 | 413 | /////////////////////////////////////////////////////////////////////////////// |
michael@0 | 414 | |
michael@0 | 415 | SkBitmapProcState::MatrixProc |
michael@0 | 416 | SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { |
michael@0 | 417 | // test_int_tileprocs(); |
michael@0 | 418 | // check for our special case when there is no scale/affine/perspective |
michael@0 | 419 | if (trivial_matrix) { |
michael@0 | 420 | SkASSERT(SkPaint::kNone_FilterLevel == fFilterLevel); |
michael@0 | 421 | fIntTileProcY = choose_int_tile_proc(fTileModeY); |
michael@0 | 422 | switch (fTileModeX) { |
michael@0 | 423 | case SkShader::kClamp_TileMode: |
michael@0 | 424 | return clampx_nofilter_trans; |
michael@0 | 425 | case SkShader::kRepeat_TileMode: |
michael@0 | 426 | return repeatx_nofilter_trans; |
michael@0 | 427 | case SkShader::kMirror_TileMode: |
michael@0 | 428 | return mirrorx_nofilter_trans; |
michael@0 | 429 | } |
michael@0 | 430 | } |
michael@0 | 431 | |
michael@0 | 432 | int index = 0; |
michael@0 | 433 | if (fFilterLevel != SkPaint::kNone_FilterLevel) { |
michael@0 | 434 | index = 1; |
michael@0 | 435 | } |
michael@0 | 436 | if (fInvType & SkMatrix::kPerspective_Mask) { |
michael@0 | 437 | index += 4; |
michael@0 | 438 | } else if (fInvType & SkMatrix::kAffine_Mask) { |
michael@0 | 439 | index += 2; |
michael@0 | 440 | } |
michael@0 | 441 | |
michael@0 | 442 | if (SkShader::kClamp_TileMode == fTileModeX && |
michael@0 | 443 | SkShader::kClamp_TileMode == fTileModeY) |
michael@0 | 444 | { |
michael@0 | 445 | // clamp gets special version of filterOne |
michael@0 | 446 | fFilterOneX = SK_Fixed1; |
michael@0 | 447 | fFilterOneY = SK_Fixed1; |
michael@0 | 448 | return SK_ARM_NEON_WRAP(ClampX_ClampY_Procs)[index]; |
michael@0 | 449 | } |
michael@0 | 450 | |
michael@0 | 451 | // all remaining procs use this form for filterOne |
michael@0 | 452 | fFilterOneX = SK_Fixed1 / fBitmap->width(); |
michael@0 | 453 | fFilterOneY = SK_Fixed1 / fBitmap->height(); |
michael@0 | 454 | |
michael@0 | 455 | if (SkShader::kRepeat_TileMode == fTileModeX && |
michael@0 | 456 | SkShader::kRepeat_TileMode == fTileModeY) |
michael@0 | 457 | { |
michael@0 | 458 | return SK_ARM_NEON_WRAP(RepeatX_RepeatY_Procs)[index]; |
michael@0 | 459 | } |
michael@0 | 460 | |
michael@0 | 461 | fTileProcX = choose_tile_proc(fTileModeX); |
michael@0 | 462 | fTileProcY = choose_tile_proc(fTileModeY); |
michael@0 | 463 | fTileLowBitsProcX = choose_tile_lowbits_proc(fTileModeX); |
michael@0 | 464 | fTileLowBitsProcY = choose_tile_lowbits_proc(fTileModeY); |
michael@0 | 465 | return GeneralXY_Procs[index]; |
michael@0 | 466 | } |