• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
32 class NOFILTER_BITMAP_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader {
33 public:
NOFILTER_BITMAP_SHADER_CLASS(const SkBitmap & src)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 
setContext(const SkBitmap & device,const SkPaint & paint,const SkMatrix & matrix)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 
shadeSpan(int x,int y,SkPMColor dstC[],int count)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 
shadeSpan16(int x,int y,uint16_t dstC[],int count)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     }
294 private:
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