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