1 /* libs/graphics/sgl/SkBitmapShader16BilerpTemplate.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 #include "SkFilterProc.h" 19 20 class BILERP_BITMAP16_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader { 21 public: BILERP_BITMAP16_SHADER_CLASS(const SkBitmap & src)22 BILERP_BITMAP16_SHADER_CLASS(const SkBitmap& src) 23 : HasSpan16_Sampler_BitmapShader(src, true, 24 SkShader::kClamp_TileMode, 25 SkShader::kClamp_TileMode) 26 { 27 } 28 shadeSpan(int x,int y,SkPMColor dstC[],int count)29 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) 30 { 31 SkASSERT(count > 0); 32 33 U8CPU alpha = this->getPaintAlpha(); 34 35 const SkMatrix& inv = this->getTotalInverse(); 36 const SkBitmap& srcBitmap = this->getSrcBitmap(); 37 unsigned srcMaxX = srcBitmap.width() - 1; 38 unsigned srcMaxY = srcBitmap.height() - 1; 39 unsigned srcRB = srcBitmap.rowBytes(); 40 41 BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap); 42 43 const SkFilterProc* proc_table = SkGetBilinearFilterProcTable(); 44 const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels(); 45 46 if (this->getInverseClass() == kPerspective_MatrixClass) 47 { 48 SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf, 49 SkIntToScalar(y) + SK_ScalarHalf, count); 50 while ((count = iter.next()) != 0) 51 { 52 const SkFixed* srcXY = iter.getXY(); 53 while (--count >= 0) 54 { 55 SkFixed fx = *srcXY++ - SK_FixedHalf; 56 SkFixed fy = *srcXY++ - SK_FixedHalf; 57 int ix = fx >> 16; 58 int iy = fy >> 16; 59 int x = SkClampMax(ix, srcMaxX); 60 int y = SkClampMax(iy, srcMaxY); 61 62 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; 63 64 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + y * srcRB)) + x; 65 if ((unsigned)ix < srcMaxX) 66 p01 += 1; 67 p10 = p00; 68 p11 = p01; 69 if ((unsigned)iy < srcMaxY) 70 { 71 p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); 72 p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); 73 } 74 75 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); 76 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), 77 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), 78 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), 79 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); 80 81 *dstC++ = expanded_rgb16_to_8888(c, alpha); 82 } 83 } 84 } 85 else // linear case 86 { 87 SkFixed fx, fy, dx, dy; 88 89 // now init fx, fy, dx, dy 90 { 91 SkPoint srcPt; 92 this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf, 93 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 94 95 fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf; 96 fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf; 97 98 if (this->getInverseClass() == kFixedStepInX_MatrixClass) 99 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy); 100 else 101 { 102 dx = SkScalarToFixed(inv.getScaleX()); 103 dy = SkScalarToFixed(inv.getSkewY()); 104 } 105 } 106 107 do { 108 int ix = fx >> 16; 109 int iy = fy >> 16; 110 111 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; 112 113 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + 114 SkClampMax(iy, srcMaxY) * srcRB)) + 115 SkClampMax(ix, srcMaxX); 116 if ((unsigned)ix < srcMaxX) 117 p01 += 1; 118 p10 = p00; 119 p11 = p01; 120 if ((unsigned)iy < srcMaxY) 121 { 122 p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); 123 p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); 124 } 125 126 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); 127 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), 128 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), 129 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), 130 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); 131 *dstC++ = expanded_rgb16_to_8888(c, alpha); 132 133 fx += dx; 134 fy += dy; 135 } while (--count != 0); 136 } 137 BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap); 138 } 139 shadeSpan16(int x,int y,uint16_t dstC[],int count)140 virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) 141 { 142 SkASSERT(count > 0); 143 144 const SkMatrix& inv = this->getTotalInverse(); 145 const SkBitmap& srcBitmap = this->getSrcBitmap(); 146 unsigned srcMaxX = srcBitmap.width() - 1; 147 unsigned srcMaxY = srcBitmap.height() - 1; 148 unsigned srcRB = srcBitmap.rowBytes(); 149 150 BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap); 151 152 const SkFilterProc* proc_table = SkGetBilinearFilterProcTable(); 153 const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels(); 154 155 if (this->getInverseClass() == kPerspective_MatrixClass) 156 { 157 SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf, 158 SkIntToScalar(y) + SK_ScalarHalf, count); 159 while ((count = iter.next()) != 0) 160 { 161 const SkFixed* srcXY = iter.getXY(); 162 while (--count >= 0) 163 { 164 SkFixed fx = *srcXY++ - SK_FixedHalf; 165 SkFixed fy = *srcXY++ - SK_FixedHalf; 166 int ix = fx >> 16; 167 int iy = fy >> 16; 168 169 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; 170 171 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + 172 SkClampMax(iy, srcMaxY) * srcRB)) + 173 SkClampMax(ix, srcMaxX); 174 if ((unsigned)ix < srcMaxX) 175 p01 += 1; 176 p10 = p00; 177 p11 = p01; 178 if ((unsigned)iy < srcMaxY) 179 { 180 p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); 181 p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); 182 } 183 184 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); 185 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), 186 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), 187 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), 188 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); 189 *dstC++ = SkCompact_rgb_16(c); 190 } 191 } 192 } 193 else // linear case 194 { 195 SkFixed fx, fy, dx, dy; 196 197 // now init fx, fy, dx, dy 198 { 199 SkPoint srcPt; 200 this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf, 201 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 202 203 fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf; 204 fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf; 205 206 if (this->getInverseClass() == kFixedStepInX_MatrixClass) 207 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy); 208 else 209 { 210 dx = SkScalarToFixed(inv.getScaleX()); 211 dy = SkScalarToFixed(inv.getSkewY()); 212 } 213 } 214 215 do { 216 int ix = fx >> 16; 217 int iy = fy >> 16; 218 219 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; 220 221 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + 222 SkClampMax(iy, srcMaxY) * srcRB)) + 223 SkClampMax(ix, srcMaxX); 224 if ((unsigned)ix < srcMaxX) 225 p01 += 1; 226 p10 = p00; 227 p11 = p01; 228 if ((unsigned)iy < srcMaxY) 229 { 230 p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); 231 p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); 232 } 233 234 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); 235 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), 236 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), 237 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), 238 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); 239 *dstC++ = SkCompact_rgb_16(c); 240 241 fx += dx; 242 fy += dy; 243 } while (--count != 0); 244 } 245 BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap); 246 } 247 }; 248 249 #undef BILERP_BITMAP16_SHADER_CLASS 250 #undef BILERP_BITMAP16_SHADER_TYPE 251 #undef BILERP_BITMAP16_SHADER_PREAMBLE 252 #undef BILERP_BITMAP16_SHADER_PIXEL 253 #undef BILERP_BITMAP16_SHADER_POSTAMBLE 254