SkBitmapProcState_matrixProcs.cpp revision 8a1c16ff38322f0210116fa7293eb8817c7e477e
1#include "SkBitmapProcState.h" 2#include "SkPerspIter.h" 3#include "SkShader.h" 4 5void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); 6void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); 7 8#ifdef SK_CPU_BENDIAN 9 #define PACK_TWO_SHORTS(pri, sec) ((pri) << 16 | (sec)) 10#else 11 #define PACK_TWO_SHORTS(pri, sec) ((pri) | ((sec) << 16)) 12#endif 13 14#ifdef SK_DEBUG 15 static uint32_t pack_two_shorts(U16CPU pri, U16CPU sec) 16 { 17 SkASSERT((uint16_t)pri == pri); 18 SkASSERT((uint16_t)sec == sec); 19 return PACK_TWO_SHORTS(pri, sec); 20 } 21#else 22 #define pack_two_shorts(pri, sec) PACK_TWO_SHORTS(pri, sec) 23#endif 24 25#define MAKENAME(suffix) ClampX_ClampY ## suffix 26#define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max) 27#define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max) 28#define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) 29#define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) 30#define CHECK_FOR_DECAL 31#include "SkBitmapProcState_matrix.h" 32 33#define MAKENAME(suffix) RepeatX_RepeatY ## suffix 34#define TILEX_PROCF(fx, max) (((fx) & 0xFFFF) * ((max) + 1) >> 16) 35#define TILEY_PROCF(fy, max) (((fy) & 0xFFFF) * ((max) + 1) >> 16) 36#define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 37#define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 38#include "SkBitmapProcState_matrix.h" 39 40#define MAKENAME(suffix) GeneralXY ## suffix 41#define PREAMBLE(state) SkBitmapProcState::FixedTileProc tileProcX = (state).fTileProcX; \ 42 SkBitmapProcState::FixedTileProc tileProcY = (state).fTileProcY 43#define PREAMBLE_PARAM_X , SkBitmapProcState::FixedTileProc tileProcX 44#define PREAMBLE_PARAM_Y , SkBitmapProcState::FixedTileProc tileProcY 45#define PREAMBLE_ARG_X , tileProcX 46#define PREAMBLE_ARG_Y , tileProcY 47#define TILEX_PROCF(fx, max) (tileProcX(fx) * ((max) + 1) >> 16) 48#define TILEY_PROCF(fy, max) (tileProcY(fy) * ((max) + 1) >> 16) 49#define TILEX_LOW_BITS(fx, max) ((tileProcX(fx) * ((max) + 1) >> 12) & 0xF) 50#define TILEY_LOW_BITS(fy, max) ((tileProcY(fy) * ((max) + 1) >> 12) & 0xF) 51#include "SkBitmapProcState_matrix.h" 52 53static inline U16CPU fixed_clamp(SkFixed x) 54{ 55#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 56 if (x >> 16) 57 x = 0xFFFF; 58 if (x < 0) 59 x = 0; 60#else 61 if (x >> 16) 62 { 63 if (x < 0) 64 x = 0; 65 else 66 x = 0xFFFF; 67 } 68#endif 69 return x; 70} 71 72static inline U16CPU fixed_repeat(SkFixed x) 73{ 74 return x & 0xFFFF; 75} 76 77static inline U16CPU fixed_mirror(SkFixed x) 78{ 79 SkFixed s = x << 15 >> 31; 80 // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval 81 return (x ^ s) & 0xFFFF; 82} 83 84static SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m) 85{ 86 if (SkShader::kClamp_TileMode == m) 87 return fixed_clamp; 88 if (SkShader::kRepeat_TileMode == m) 89 return fixed_repeat; 90 SkASSERT(SkShader::kMirror_TileMode == m); 91 return fixed_mirror; 92} 93 94SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc() 95{ 96 int index = 0; 97 if (fDoFilter) 98 index = 1; 99 if (fInvType & SkMatrix::kPerspective_Mask) 100 index |= 4; 101 else if (fInvType & SkMatrix::kAffine_Mask) 102 index |= 2; 103 104 if (SkShader::kClamp_TileMode == fTileModeX && 105 SkShader::kClamp_TileMode == fTileModeY) 106 { 107 // clamp gets special version of filterOne 108 fFilterOneX = SK_Fixed1; 109 fFilterOneY = SK_Fixed1; 110 return ClampX_ClampY_Procs[index]; 111 } 112 113 // all remaining procs use this form for filterOne 114 fFilterOneX = SK_Fixed1 / fBitmap->width(); 115 fFilterOneY = SK_Fixed1 / fBitmap->height(); 116 117 if (SkShader::kRepeat_TileMode == fTileModeX && 118 SkShader::kRepeat_TileMode == fTileModeY) 119 { 120 return RepeatX_RepeatY_Procs[index]; 121 } 122 123 // only general needs these procs 124 fTileProcX = choose_tile_proc(fTileModeX); 125 fTileProcY = choose_tile_proc(fTileModeY); 126 return GeneralXY_Procs[index]; 127} 128 129////////////////////////////////////////////////////////////////////////////// 130 131void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) 132{ 133 int i; 134 135 for (i = (count >> 2); i > 0; --i) 136 { 137 *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); 138 fx += dx+dx; 139 *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); 140 fx += dx+dx; 141 } 142 uint16_t* xx = (uint16_t*)dst; 143 144 for (i = (count & 3); i > 0; --i) 145 { 146 *xx++ = SkToU16(fx >> 16); fx += dx; 147 } 148} 149 150void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) 151{ 152 if (count & 1) 153 { 154 SkASSERT((fx >> (16 + 14)) == 0); 155 *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 156 fx += dx; 157 } 158 while ((count -= 2) >= 0) 159 { 160 SkASSERT((fx >> (16 + 14)) == 0); 161 *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 162 fx += dx; 163 164 *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 165 fx += dx; 166 } 167} 168 169/////////////////////////////////// 170 171void repeat_nofilter_identity(uint32_t dst[], int x, int width, int count) 172{ 173 if (x >= width) 174 x %= width; 175 176 int i; 177 uint16_t* xx = (uint16_t*)dst; 178 179 // do the first partial run 180 int n = width - x; 181 if (n > count) 182 n = count; 183 184 count -= n; 185 n += x; 186 for (i = x; i < n; i++) 187 *xx++ = SkToU16(i); 188 189 // do all the full-width runs 190 while ((count -= width) >= 0) 191 for (i = 0; i < width; i++) 192 *xx++ = SkToU16(i); 193 194 // final cleanup run 195 count += width; 196 for (i = 0; i < count; i++) 197 *xx++ = SkToU16(i); 198} 199 200