1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 11 #ifndef NOFILTER_BITMAP_SHADER_PREAMBLE 12 #define NOFILTER_BITMAP_SHADER_PREAMBLE(bitmap, rb) 13 #endif 14 #ifndef NOFILTER_BITMAP_SHADER_POSTAMBLE 15 #define NOFILTER_BITMAP_SHADER_POSTAMBLE(bitmap) 16 #endif 17 #ifndef NOFILTER_BITMAP_SHADER_PREAMBLE16 18 #define NOFILTER_BITMAP_SHADER_PREAMBLE16(bitmap, rb) 19 #endif 20 #ifndef NOFILTER_BITMAP_SHADER_POSTAMBLE16 21 #define NOFILTER_BITMAP_SHADER_POSTAMBLE16(bitmap) 22 #endif 23 24 class NOFILTER_BITMAP_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader { 25 public: 26 NOFILTER_BITMAP_SHADER_CLASS(const SkBitmap& src) 27 : HasSpan16_Sampler_BitmapShader(src, false, 28 NOFILTER_BITMAP_SHADER_TILEMODE, 29 NOFILTER_BITMAP_SHADER_TILEMODE) 30 { 31 } 32 33 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix) 34 { 35 if (!this->INHERITED::setContext(device, paint, matrix)) 36 return false; 37 38 #ifdef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE 39 this->computeUnitInverse(); 40 #endif 41 return true; 42 } 43 44 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) 45 { 46 SkASSERT(count > 0); 47 48 #ifdef NOFILTER_BITMAP_SHADER_SPRITEPROC32 49 if ((this->getTotalInverse().getType() & ~SkMatrix::kTranslate_Mask) == 0) 50 { 51 NOFILTER_BITMAP_SHADER_SPRITEPROC32(this, x, y, dstC, count); 52 return; 53 } 54 #endif 55 56 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); 57 #ifdef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE 58 const SkMatrix& inv = this->getUnitInverse(); 59 SkMatrix::MapPtProc invProc = this->getUnitInverseProc(); 60 #else 61 const SkMatrix& inv = this->getTotalInverse(); 62 SkMatrix::MapPtProc invProc = this->getInverseMapPtProc(); 63 #endif 64 const SkBitmap& srcBitmap = this->getSrcBitmap(); 65 unsigned srcMaxX = srcBitmap.width() - 1; 66 unsigned srcMaxY = srcBitmap.height() - 1; 67 unsigned srcRB = srcBitmap.rowBytes(); 68 SkFixed fx, fy, dx, dy; 69 70 const NOFILTER_BITMAP_SHADER_TYPE* srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)srcBitmap.getPixels(); 71 NOFILTER_BITMAP_SHADER_PREAMBLE(srcBitmap, srcRB); 72 73 if (this->getInverseClass() == kPerspective_MatrixClass) 74 { 75 SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf, 76 SkIntToScalar(y) + SK_ScalarHalf, count); 77 while ((count = iter.next()) != 0) 78 { 79 const SkFixed* srcXY = iter.getXY(); 80 81 /* Do I need this? 82 #ifndef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE 83 fx >>= level; 84 fy >>= level; 85 #endif 86 */ 87 if (256 == scale) 88 { 89 while (--count >= 0) 90 { 91 fx = *srcXY++; 92 fy = *srcXY++; 93 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX); 94 unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY); 95 *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB); 96 } 97 } 98 else 99 { 100 while (--count >= 0) 101 { 102 fx = *srcXY++; 103 fy = *srcXY++; 104 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX); 105 unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY); 106 uint32_t c = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB); 107 *dstC++ = SkAlphaMulQ(c, scale); 108 } 109 } 110 } 111 return; 112 } 113 114 // now init fx, fy, dx, dy 115 { 116 SkPoint srcPt; 117 invProc(inv, SkIntToScalar(x) + SK_ScalarHalf, 118 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 119 120 fx = SkScalarToFixed(srcPt.fX); 121 fy = SkScalarToFixed(srcPt.fY); 122 123 if (this->getInverseClass() == kFixedStepInX_MatrixClass) 124 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy); 125 else 126 { 127 dx = SkScalarToFixed(inv.getScaleX()); 128 dy = SkScalarToFixed(inv.getSkewY()); 129 } 130 } 131 132 #ifndef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE 133 { int level = this->getMipLevel() >> 16; 134 fx >>= level; 135 fy >>= level; 136 dx >>= level; 137 dy >>= level; 138 } 139 #endif 140 141 if (dy == 0) 142 { 143 int y_index = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY); 144 // SkDEBUGF(("fy = %g, srcMaxY = %d, y_index = %d\n", SkFixedToFloat(fy), srcMaxY, y_index)); 145 srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)((const char*)srcPixels + y_index * srcRB); 146 if (scale == 256) 147 while (--count >= 0) 148 { 149 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX); 150 fx += dx; 151 *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_X(srcPixels, x); 152 } 153 else 154 while (--count >= 0) 155 { 156 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX); 157 SkPMColor c = NOFILTER_BITMAP_SHADER_SAMPLE_X(srcPixels, x); 158 fx += dx; 159 *dstC++ = SkAlphaMulQ(c, scale); 160 } 161 } 162 else // dy != 0 163 { 164 if (scale == 256) 165 while (--count >= 0) 166 { 167 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX); 168 unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY); 169 fx += dx; 170 fy += dy; 171 *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB); 172 } 173 else 174 while (--count >= 0) 175 { 176 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX); 177 unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY); 178 SkPMColor c = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB); 179 fx += dx; 180 fy += dy; 181 *dstC++ = SkAlphaMulQ(c, scale); 182 } 183 } 184 185 NOFILTER_BITMAP_SHADER_POSTAMBLE(srcBitmap); 186 } 187 188 virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) 189 { 190 SkASSERT(count > 0); 191 SkASSERT(this->getFlags() & SkShader::kHasSpan16_Flag); 192 193 #ifdef NOFILTER_BITMAP_SHADER_SPRITEPROC16 194 if ((this->getTotalInverse().getType() & ~SkMatrix::kTranslate_Mask) == 0) 195 { 196 NOFILTER_BITMAP_SHADER_SPRITEPROC16(this, x, y, dstC, count); 197 return; 198 } 199 #endif 200 201 #ifdef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE 202 const SkMatrix& inv = this->getUnitInverse(); 203 SkMatrix::MapPtProc invProc = this->getUnitInverseProc(); 204 #else 205 const SkMatrix& inv = this->getTotalInverse(); 206 SkMatrix::MapPtProc invProc = this->getInverseMapPtProc(); 207 #endif 208 const SkBitmap& srcBitmap = this->getSrcBitmap(); 209 unsigned srcMaxX = srcBitmap.width() - 1; 210 unsigned srcMaxY = srcBitmap.height() - 1; 211 unsigned srcRB = srcBitmap.rowBytes(); 212 SkFixed fx, fy, dx, dy; 213 214 const NOFILTER_BITMAP_SHADER_TYPE* srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)srcBitmap.getPixels(); 215 NOFILTER_BITMAP_SHADER_PREAMBLE16(srcBitmap, srcRB); 216 217 if (this->getInverseClass() == kPerspective_MatrixClass) 218 { 219 SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf, 220 SkIntToScalar(y) + SK_ScalarHalf, count); 221 while ((count = iter.next()) != 0) 222 { 223 const SkFixed* srcXY = iter.getXY(); 224 225 while (--count >= 0) 226 { 227 fx = *srcXY++; 228 fy = *srcXY++; 229 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX); 230 unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY); 231 *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY16(srcPixels, x, y, srcRB); 232 } 233 } 234 return; 235 } 236 237 // now init fx, fy, dx, dy 238 { 239 SkPoint srcPt; 240 invProc(inv, SkIntToScalar(x) + SK_ScalarHalf, 241 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 242 243 fx = SkScalarToFixed(srcPt.fX); 244 fy = SkScalarToFixed(srcPt.fY); 245 246 if (this->getInverseClass() == kFixedStepInX_MatrixClass) 247 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy); 248 else 249 { 250 dx = SkScalarToFixed(inv.getScaleX()); 251 dy = SkScalarToFixed(inv.getSkewY()); 252 } 253 } 254 255 #ifndef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE 256 { int level = this->getMipLevel() >> 16; 257 fx >>= level; 258 fy >>= level; 259 dx >>= level; 260 dy >>= level; 261 } 262 #endif 263 264 if (dy == 0) 265 { 266 srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)((const char*)srcPixels + NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY) * srcRB); 267 do { 268 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX); 269 fx += dx; 270 *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_X16(srcPixels, x); 271 } while (--count != 0); 272 } 273 else // dy != 0 274 { 275 do { 276 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX); 277 unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY); 278 fx += dx; 279 fy += dy; 280 *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY16(srcPixels, x, y, srcRB); 281 } while (--count != 0); 282 } 283 284 NOFILTER_BITMAP_SHADER_POSTAMBLE16(srcBitmap); 285 } 286 private: 287 typedef HasSpan16_Sampler_BitmapShader INHERITED; 288 }; 289 290 #undef NOFILTER_BITMAP_SHADER_CLASS 291 #undef NOFILTER_BITMAP_SHADER_TYPE 292 #undef NOFILTER_BITMAP_SHADER_PREAMBLE 293 #undef NOFILTER_BITMAP_SHADER_POSTAMBLE 294 #undef NOFILTER_BITMAP_SHADER_SAMPLE_X //(x) 295 #undef NOFILTER_BITMAP_SHADER_SAMPLE_XY //(x, y, rowBytes) 296 #undef NOFILTER_BITMAP_SHADER_TILEMODE 297 #undef NOFILTER_BITMAP_SHADER_TILEPROC 298 299 #undef NOFILTER_BITMAP_SHADER_PREAMBLE16 300 #undef NOFILTER_BITMAP_SHADER_POSTAMBLE16 301 #undef NOFILTER_BITMAP_SHADER_SAMPLE_X16 //(x) 302 #undef NOFILTER_BITMAP_SHADER_SAMPLE_XY16 //(x, y, rowBytes) 303 304 #undef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE 305 #undef NOFILTER_BITMAP_SHADER_SPRITEPROC16 306 #undef NOFILTER_BITMAP_SHADER_SPRITEPROC32 307