• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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