1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkMath.h" 9#include "SkMathPriv.h" 10 11#define SCALE_FILTER_NAME MAKENAME(_filter_scale) 12#define AFFINE_FILTER_NAME MAKENAME(_filter_affine) 13#define PERSP_FILTER_NAME MAKENAME(_filter_persp) 14 15#define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x) 16#define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y) 17 18#ifndef PREAMBLE 19 #define PREAMBLE(state) 20 #define PREAMBLE_PARAM_X 21 #define PREAMBLE_PARAM_Y 22 #define PREAMBLE_ARG_X 23 #define PREAMBLE_ARG_Y 24#endif 25 26// declare functions externally to suppress warnings. 27void SCALE_FILTER_NAME(const SkBitmapProcState& s, 28 uint32_t xy[], int count, int x, int y); 29void AFFINE_FILTER_NAME(const SkBitmapProcState& s, 30 uint32_t xy[], int count, int x, int y); 31void PERSP_FILTER_NAME(const SkBitmapProcState& s, 32 uint32_t* SK_RESTRICT xy, int count, 33 int x, int y); 34 35static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max, 36 SkFixed one PREAMBLE_PARAM_Y) { 37 unsigned i = TILEY_PROCF(f, max); 38 i = (i << 4) | EXTRACT_LOW_BITS(f, max); 39 return (i << 14) | (TILEY_PROCF((f + one), max)); 40} 41 42static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max, 43 SkFixed one PREAMBLE_PARAM_X) { 44 unsigned i = TILEX_PROCF(f, max); 45 i = (i << 4) | EXTRACT_LOW_BITS(f, max); 46 return (i << 14) | (TILEX_PROCF((f + one), max)); 47} 48 49void SCALE_FILTER_NAME(const SkBitmapProcState& s, 50 uint32_t xy[], int count, int x, int y) { 51 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 52 SkMatrix::kScale_Mask)) == 0); 53 SkASSERT(s.fInvKy == 0); 54 55 PREAMBLE(s); 56 57 const unsigned maxX = s.fPixmap.width() - 1; 58 const SkFixed one = s.fFilterOneX; 59 const SkFractionalInt dx = s.fInvSxFractionalInt; 60 SkFractionalInt fx; 61 62 { 63 const SkBitmapProcStateAutoMapper mapper(s, x, y); 64 const SkFixed fy = mapper.fixedY(); 65 const unsigned maxY = s.fPixmap.height() - 1; 66 // compute our two Y values up front 67 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y); 68 // now initialize fx 69 fx = mapper.fractionalIntX(); 70 } 71 72#ifdef CHECK_FOR_DECAL 73 const SkFixed fixedFx = SkFractionalIntToFixed(fx); 74 const SkFixed fixedDx = SkFractionalIntToFixed(dx); 75 if (can_truncate_to_fixed_for_decal(fixedFx, fixedDx, count, maxX)) { 76 decal_filter_scale(xy, fixedFx, fixedDx, count); 77 } else 78#endif 79 { 80 do { 81 SkFixed fixedFx = SkFractionalIntToFixed(fx); 82 *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X); 83 fx += dx; 84 } while (--count != 0); 85 } 86} 87 88void AFFINE_FILTER_NAME(const SkBitmapProcState& s, 89 uint32_t xy[], int count, int x, int y) { 90 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); 91 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 92 SkMatrix::kScale_Mask | 93 SkMatrix::kAffine_Mask)) == 0); 94 95 PREAMBLE(s); 96 const SkBitmapProcStateAutoMapper mapper(s, x, y); 97 98 SkFixed oneX = s.fFilterOneX; 99 SkFixed oneY = s.fFilterOneY; 100 SkFixed fx = mapper.fixedX(); 101 SkFixed fy = mapper.fixedY(); 102 SkFixed dx = s.fInvSx; 103 SkFixed dy = s.fInvKy; 104 unsigned maxX = s.fPixmap.width() - 1; 105 unsigned maxY = s.fPixmap.height() - 1; 106 107 do { 108 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y); 109 fy += dy; 110 *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X); 111 fx += dx; 112 } while (--count != 0); 113} 114 115void PERSP_FILTER_NAME(const SkBitmapProcState& s, 116 uint32_t* SK_RESTRICT xy, int count, 117 int x, int y) { 118 SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); 119 120 PREAMBLE(s); 121 unsigned maxX = s.fPixmap.width() - 1; 122 unsigned maxY = s.fPixmap.height() - 1; 123 SkFixed oneX = s.fFilterOneX; 124 SkFixed oneY = s.fFilterOneY; 125 126 SkPerspIter iter(s.fInvMatrix, 127 SkIntToScalar(x) + SK_ScalarHalf, 128 SkIntToScalar(y) + SK_ScalarHalf, count); 129 130 while ((count = iter.next()) != 0) { 131 const SkFixed* SK_RESTRICT srcXY = iter.getXY(); 132 do { 133 *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY, 134 oneY PREAMBLE_ARG_Y); 135 *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX, 136 oneX PREAMBLE_ARG_X); 137 srcXY += 2; 138 } while (--count != 0); 139 } 140} 141 142#undef MAKENAME 143#undef TILEX_PROCF 144#undef TILEY_PROCF 145#ifdef CHECK_FOR_DECAL 146 #undef CHECK_FOR_DECAL 147#endif 148 149#undef SCALE_FILTER_NAME 150#undef AFFINE_FILTER_NAME 151#undef PERSP_FILTER_NAME 152 153#undef PREAMBLE 154#undef PREAMBLE_PARAM_X 155#undef PREAMBLE_PARAM_Y 156#undef PREAMBLE_ARG_X 157#undef PREAMBLE_ARG_Y 158 159#undef EXTRACT_LOW_BITS 160