OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkBitmapProcState.h" | 8 #include "SkBitmapProcState.h" |
9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
10 #include "SkFilterProc.h" | 10 #include "SkFilterProc.h" |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 } | 83 } |
84 | 84 |
85 /////////////////////////////////////////////////////////////////////////////// | 85 /////////////////////////////////////////////////////////////////////////////// |
86 | 86 |
87 static bool valid_for_filtering(unsigned dimension) { | 87 static bool valid_for_filtering(unsigned dimension) { |
88 // for filtering, width and height must fit in 14bits, since we use steal | 88 // for filtering, width and height must fit in 14bits, since we use steal |
89 // 2 bits from each to store our 4bit subpixel data | 89 // 2 bits from each to store our 4bit subpixel data |
90 return (dimension & ~0x3FFF) == 0; | 90 return (dimension & ~0x3FFF) == 0; |
91 } | 91 } |
92 | 92 |
93 void SkBitmapProcState::possiblyScaleImage() { | |
94 | |
95 if (fFilterQuality != kHQ_BitmapFilter) { | |
96 return; | |
97 } | |
98 | |
99 // STEP 1: UPSAMPLE? | |
100 | |
101 // Check to see if the transformation matrix is scaling up, and if | |
102 // the matrix is simple, and if we're doing high quality scaling. | |
103 // If so, do the bitmap scale here and remove the scaling component from the matrix. | |
104 | |
105 if (fUnitInvMatrix.getType() == (SkMatrix::kScale_Mask | SkMatrix::kTranslat e_Mask) && | |
106 (fUnitInvMatrix.getScaleX() < 1 || fUnitInvMatrix.getScaleY() < 1) && | |
107 fOrigBitmap.config() == SkBitmap::kARGB_8888_Config) { | |
108 | |
109 // All the criteria are met; let's make a new bitmap. | |
110 fScaledBitmap.setConfig(SkBitmap::kARGB_8888_Config, | |
111 fOrigBitmap.width() / fUnitInvMatrix.getScaleX() , | |
reed1
2013/07/11 20:26:18
This / produces a float (SkScalar). We should use
| |
112 fOrigBitmap.height() / fUnitInvMatrix.getScaleY( )); | |
113 fScaledBitmap.allocPixels(); | |
114 fOrigBitmap.scale(&fScaledBitmap); | |
115 fBitmap = &fScaledBitmap; | |
116 | |
117 // set the inv matrix type to translate-only; | |
118 | |
119 fUnitInvMatrix.setTranslate( 1/fUnitInvMatrix.getScaleX() * fUnitInvMatr ix.getTranslateX(), | |
120 1/fUnitInvMatrix.getScaleY() * fUnitInvMatr ix.getTranslateY() ); | |
121 | |
122 // no need for any further filtering; we just did it! | |
123 | |
124 fFilterQuality = kNone_BitmapFilter; | |
reed1
2013/07/11 20:26:18
Perhaps we should return now, since everything bel
| |
125 } else if (!fOrigBitmap.hasMipMap()) { | |
126 | |
127 // STEP 2: DOWNSAMPLE | |
128 | |
129 // Check to see if the transformation matrix is scaling *down*. | |
130 // If so, automatically build mipmaps. | |
131 | |
132 SkPoint v1, v2; | |
133 | |
134 // conservatively estimate if the matrix is scaling down by seeing | |
135 // what its upper left 2x2 portion does to two unit vectors. | |
136 | |
137 v1.fX = fUnitInvMatrix.getScaleX(); | |
138 v1.fY = fUnitInvMatrix.getSkewY(); | |
139 | |
140 v2.fX = fUnitInvMatrix.getSkewX(); | |
141 v2.fY = fUnitInvMatrix.getScaleY(); | |
142 | |
143 if (v1.fX * v1.fX + v1.fY * v1.fY > 1 || | |
144 v2.fX * v2.fX + v2.fY * v2.fY > 1) { | |
145 fOrigBitmap.buildMipMap(); | |
146 } | |
147 | |
148 // Now that we've built the mipmaps and we know we're downsampling, | |
149 // downgrade to bilinear interpolation for the mip level. | |
150 | |
151 fFilterQuality = kBilerp_BitmapFilter; | |
152 } | |
153 | |
154 if (fOrigBitmap.hasMipMap() && fBitmap == &fOrigBitmap) { | |
155 | |
156 // STEP 3: We've got mipmaps, let's choose the closest level as our rend er | |
157 // source and adjust the matrix accordingly. | |
158 | |
159 int shift = fOrigBitmap.extractMipLevel(&fScaledBitmap, | |
160 SkScalarToFixed(fUnitInvMatrix.g etScaleX()), | |
161 SkScalarToFixed(fUnitInvMatrix.g etSkewY())); | |
162 | |
163 if (shift > 0) { | |
164 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift); | |
165 fUnitInvMatrix.postScale(scale, scale); | |
166 fBitmap = &fScaledBitmap; | |
167 } | |
168 } | |
169 } | |
170 | |
171 void SkBitmapProcState::endContext() { | |
172 SkDELETE(fBitmapFilter); | |
173 } | |
174 | |
93 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { | 175 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { |
94 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) { | 176 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) { |
95 return false; | 177 return false; |
96 } | 178 } |
97 | 179 |
98 const SkMatrix* m; | |
99 bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0; | 180 bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0; |
100 bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX && | 181 bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX && |
101 SkShader::kClamp_TileMode == fTileModeY; | 182 SkShader::kClamp_TileMode == fTileModeY; |
102 | 183 |
103 if (clamp_clamp || trivial_matrix) { | 184 fUnitInvMatrix = inv; |
104 m = &inv; | 185 if (!(clamp_clamp || trivial_matrix)) { |
105 } else { | |
106 fUnitInvMatrix = inv; | |
107 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); | 186 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); |
108 m = &fUnitInvMatrix; | |
109 } | 187 } |
110 | 188 |
111 fBitmap = &fOrigBitmap; | 189 fBitmap = &fOrigBitmap; |
112 if (fOrigBitmap.hasMipMap()) { | 190 |
113 int shift = fOrigBitmap.extractMipLevel(&fMipBitmap, | 191 // initialize our filter quality to the one requested by the caller. |
114 SkScalarToFixed(m->getScaleX()), | 192 // We may downgrade it later if we determine that we either don't need |
115 SkScalarToFixed(m->getSkewY())); | 193 // or can't provide as high a quality filtering as the user requested. |
116 | 194 |
117 if (shift > 0) { | 195 fFilterQuality = kNone_BitmapFilter; |
118 if (m != &fUnitInvMatrix) { | 196 if (paint.isFilterBitmap()) { |
119 fUnitInvMatrix = *m; | 197 if (paint.getFlags() & SkPaint::kHighQualityFilterBitmap_Flag) { |
120 m = &fUnitInvMatrix; | 198 fFilterQuality = kHQ_BitmapFilter; |
121 } | 199 } else { |
122 | 200 fFilterQuality = kBilerp_BitmapFilter; |
123 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift); | |
124 fUnitInvMatrix.postScale(scale, scale); | |
125 | |
126 // now point here instead of fOrigBitmap | |
127 fBitmap = &fMipBitmap; | |
128 } | 201 } |
129 } | 202 } |
130 | 203 |
131 // wack our matrix to exactly no-scale, if we're really close to begin with | 204 // possiblyScaleImage will look to see if it can rescale the image as a |
132 if (matrix_only_scale_translate(*m)) { | 205 // preprocess; either by scaling up to the target size, or by selecting |
206 // a nearby mipmap level. If it does, it will adjust the working | |
207 // matrix as well as the working bitmap. It may also adjust the filter | |
208 // quality to avoid re-filtering an already perfectly scaled image. | |
209 | |
210 possiblyScaleImage(); | |
211 | |
212 // Now that all possible changes to the matrix have taken place, check | |
213 // to see if we're really close to a no-scale matrix. If so, explicitly | |
214 // set it to be so. Subsequent code may inspect this matrix to choose | |
215 // a faster path in this case. | |
216 | |
217 if (matrix_only_scale_translate(fUnitInvMatrix)) { | |
133 SkMatrix forward; | 218 SkMatrix forward; |
134 if (m->invert(&forward)) { | 219 if (fUnitInvMatrix.invert(&forward)) { |
135 if (clamp_clamp ? just_trans_clamp(forward, *fBitmap) | 220 if (clamp_clamp ? just_trans_clamp(forward, *fBitmap) |
136 : just_trans_general(forward)) { | 221 : just_trans_general(forward)) { |
137 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX()); | 222 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX()); |
138 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY()); | 223 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY()); |
139 fUnitInvMatrix.setTranslate(tx, ty); | 224 fUnitInvMatrix.setTranslate(tx, ty); |
140 m = &fUnitInvMatrix; | 225 |
141 // now the following code will sniff m, and decide to take the | |
142 // fast case (since m is purely translate). | |
143 } | 226 } |
144 } | 227 } |
145 } | 228 } |
146 | 229 |
147 // Below this point, we should never refer to the inv parameter, since we | 230 // Below this point, we should never refer to the inv parameter, since we |
148 // may be using a munged version for "our" inverse. | 231 // may be using a munged version for "our" inverse. |
149 | 232 |
150 fInvMatrix = m; | 233 fInvMatrix = &fUnitInvMatrix; |
151 fInvProc = m->getMapXYProc(); | 234 fInvProc = fInvMatrix->getMapXYProc(); |
152 fInvType = m->getType(); | 235 fInvType = fInvMatrix->getType(); |
153 fInvSx = SkScalarToFixed(m->getScaleX()); | 236 fInvSx = SkScalarToFixed(fInvMatrix->getScaleX()); |
154 fInvSxFractionalInt = SkScalarToFractionalInt(m->getScaleX()); | 237 fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix->getScaleX()); |
155 fInvKy = SkScalarToFixed(m->getSkewY()); | 238 fInvKy = SkScalarToFixed(fInvMatrix->getSkewY()); |
156 fInvKyFractionalInt = SkScalarToFractionalInt(m->getSkewY()); | 239 fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix->getSkewY()); |
157 | 240 |
158 fAlphaScale = SkAlpha255To256(paint.getAlpha()); | 241 fAlphaScale = SkAlpha255To256(paint.getAlpha()); |
159 | 242 |
160 // pick-up filtering from the paint, but only if the matrix is | |
161 // more complex than identity/translate (i.e. no need to pay the cost | |
162 // of filtering if we're not scaled etc.). | |
163 // note: we explicitly check inv, since m might be scaled due to unitinv | |
164 // trickery, but we don't want to see that for this test | |
165 fDoFilter = paint.isFilterBitmap() && | |
166 (fInvType > SkMatrix::kTranslate_Mask && | |
167 valid_for_filtering(fBitmap->width() | fBitmap->height())); | |
168 | |
169 fShaderProc32 = NULL; | 243 fShaderProc32 = NULL; |
170 fShaderProc16 = NULL; | 244 fShaderProc16 = NULL; |
171 fSampleProc32 = NULL; | 245 fSampleProc32 = NULL; |
172 fSampleProc16 = NULL; | 246 fSampleProc16 = NULL; |
173 | 247 |
248 if (fFilterQuality == kHQ_BitmapFilter) { | |
reed1
2013/07/11 20:26:18
nit: reverse the sides of the ==
| |
249 // If this is still set, that means we wanted HQ sampling | |
250 // but couldn't do it as a preprocess. Let's try to install | |
251 // the scanline version of the HQ sampler. If that process fails, | |
252 // downgrade to bilerp. | |
253 | |
254 fShaderProc32 = this->chooseBitmapFilterProc(); | |
reed1
2013/07/11 20:26:18
A little tricky (in the future) here, as we will w
| |
255 if (!fShaderProc32) { | |
256 fFilterQuality = kBilerp_BitmapFilter; | |
257 } | |
258 } | |
259 | |
260 if (fFilterQuality == kBilerp_BitmapFilter) { | |
261 // Only try bilerp if the matrix is "interesting" and | |
262 // the image has a suitable size. | |
263 | |
264 if (fInvType < SkMatrix::kTranslate_Mask || | |
265 !valid_for_filtering(fBitmap->width() | fBitmap->height())) { | |
266 fFilterQuality = kNone_BitmapFilter; | |
267 } | |
268 } | |
269 | |
270 // At this point, we know exactly what kind of sampling the per-scanline | |
271 // shader will perform. | |
272 | |
174 fMatrixProc = this->chooseMatrixProc(trivial_matrix); | 273 fMatrixProc = this->chooseMatrixProc(trivial_matrix); |
175 if (NULL == fMatrixProc) { | 274 if (NULL == fMatrixProc) { |
176 return false; | 275 return false; |
177 } | 276 } |
178 | 277 |
179 /////////////////////////////////////////////////////////////////////// | 278 /////////////////////////////////////////////////////////////////////// |
180 | 279 |
181 int index = 0; | 280 // No need to do this if we're doing HQ sampling; if filter quality is |
182 if (fAlphaScale < 256) { // note: this distinction is not used for D16 | 281 // still set to HQ by the time we get here, then we must have installed |
183 index |= 1; | 282 // the shader proc above and can skip all this. |
184 } | |
185 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { | |
186 index |= 2; | |
187 } | |
188 if (fDoFilter) { | |
189 index |= 4; | |
190 } | |
191 // bits 3,4,5 encoding the source bitmap format | |
192 switch (fBitmap->config()) { | |
193 case SkBitmap::kARGB_8888_Config: | |
194 index |= 0; | |
195 break; | |
196 case SkBitmap::kRGB_565_Config: | |
197 index |= 8; | |
198 break; | |
199 case SkBitmap::kIndex8_Config: | |
200 index |= 16; | |
201 break; | |
202 case SkBitmap::kARGB_4444_Config: | |
203 index |= 24; | |
204 break; | |
205 case SkBitmap::kA8_Config: | |
206 index |= 32; | |
207 fPaintPMColor = SkPreMultiplyColor(paint.getColor()); | |
208 break; | |
209 default: | |
210 return false; | |
211 } | |
212 | 283 |
213 #if !SK_ARM_NEON_IS_ALWAYS | 284 if (fFilterQuality < kHQ_BitmapFilter) { |
214 static const SampleProc32 gSkBitmapProcStateSample32[] = { | 285 |
215 S32_opaque_D32_nofilter_DXDY, | 286 int index = 0; |
216 S32_alpha_D32_nofilter_DXDY, | 287 if (fAlphaScale < 256) { // note: this distinction is not used for D16 |
217 S32_opaque_D32_nofilter_DX, | 288 index |= 1; |
218 S32_alpha_D32_nofilter_DX, | 289 } |
219 S32_opaque_D32_filter_DXDY, | 290 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { |
220 S32_alpha_D32_filter_DXDY, | 291 index |= 2; |
221 S32_opaque_D32_filter_DX, | 292 } |
222 S32_alpha_D32_filter_DX, | 293 if (fFilterQuality != kNone_BitmapFilter) { |
294 index |= 4; | |
295 } | |
296 // bits 3,4,5 encoding the source bitmap format | |
297 switch (fBitmap->config()) { | |
298 case SkBitmap::kARGB_8888_Config: | |
299 index |= 0; | |
300 break; | |
301 case SkBitmap::kRGB_565_Config: | |
302 index |= 8; | |
303 break; | |
304 case SkBitmap::kIndex8_Config: | |
305 index |= 16; | |
306 break; | |
307 case SkBitmap::kARGB_4444_Config: | |
308 index |= 24; | |
309 break; | |
310 case SkBitmap::kA8_Config: | |
311 index |= 32; | |
312 fPaintPMColor = SkPreMultiplyColor(paint.getColor()); | |
313 break; | |
314 default: | |
315 return false; | |
316 } | |
223 | 317 |
224 S16_opaque_D32_nofilter_DXDY, | 318 #if !SK_ARM_NEON_IS_ALWAYS |
225 S16_alpha_D32_nofilter_DXDY, | 319 static const SampleProc32 gSkBitmapProcStateSample32[] = { |
226 S16_opaque_D32_nofilter_DX, | 320 S32_opaque_D32_nofilter_DXDY, |
227 S16_alpha_D32_nofilter_DX, | 321 S32_alpha_D32_nofilter_DXDY, |
228 S16_opaque_D32_filter_DXDY, | 322 S32_opaque_D32_nofilter_DX, |
229 S16_alpha_D32_filter_DXDY, | 323 S32_alpha_D32_nofilter_DX, |
230 S16_opaque_D32_filter_DX, | 324 S32_opaque_D32_filter_DXDY, |
231 S16_alpha_D32_filter_DX, | 325 S32_alpha_D32_filter_DXDY, |
326 S32_opaque_D32_filter_DX, | |
327 S32_alpha_D32_filter_DX, | |
232 | 328 |
233 SI8_opaque_D32_nofilter_DXDY, | 329 S16_opaque_D32_nofilter_DXDY, |
234 SI8_alpha_D32_nofilter_DXDY, | 330 S16_alpha_D32_nofilter_DXDY, |
235 SI8_opaque_D32_nofilter_DX, | 331 S16_opaque_D32_nofilter_DX, |
236 SI8_alpha_D32_nofilter_DX, | 332 S16_alpha_D32_nofilter_DX, |
237 SI8_opaque_D32_filter_DXDY, | 333 S16_opaque_D32_filter_DXDY, |
238 SI8_alpha_D32_filter_DXDY, | 334 S16_alpha_D32_filter_DXDY, |
239 SI8_opaque_D32_filter_DX, | 335 S16_opaque_D32_filter_DX, |
240 SI8_alpha_D32_filter_DX, | 336 S16_alpha_D32_filter_DX, |
241 | 337 |
242 S4444_opaque_D32_nofilter_DXDY, | 338 SI8_opaque_D32_nofilter_DXDY, |
243 S4444_alpha_D32_nofilter_DXDY, | 339 SI8_alpha_D32_nofilter_DXDY, |
244 S4444_opaque_D32_nofilter_DX, | 340 SI8_opaque_D32_nofilter_DX, |
245 S4444_alpha_D32_nofilter_DX, | 341 SI8_alpha_D32_nofilter_DX, |
246 S4444_opaque_D32_filter_DXDY, | 342 SI8_opaque_D32_filter_DXDY, |
247 S4444_alpha_D32_filter_DXDY, | 343 SI8_alpha_D32_filter_DXDY, |
248 S4444_opaque_D32_filter_DX, | 344 SI8_opaque_D32_filter_DX, |
249 S4444_alpha_D32_filter_DX, | 345 SI8_alpha_D32_filter_DX, |
250 | 346 |
251 // A8 treats alpha/opaque the same (equally efficient) | 347 S4444_opaque_D32_nofilter_DXDY, |
252 SA8_alpha_D32_nofilter_DXDY, | 348 S4444_alpha_D32_nofilter_DXDY, |
253 SA8_alpha_D32_nofilter_DXDY, | 349 S4444_opaque_D32_nofilter_DX, |
254 SA8_alpha_D32_nofilter_DX, | 350 S4444_alpha_D32_nofilter_DX, |
255 SA8_alpha_D32_nofilter_DX, | 351 S4444_opaque_D32_filter_DXDY, |
256 SA8_alpha_D32_filter_DXDY, | 352 S4444_alpha_D32_filter_DXDY, |
257 SA8_alpha_D32_filter_DXDY, | 353 S4444_opaque_D32_filter_DX, |
258 SA8_alpha_D32_filter_DX, | 354 S4444_alpha_D32_filter_DX, |
259 SA8_alpha_D32_filter_DX | |
260 }; | |
261 | 355 |
262 static const SampleProc16 gSkBitmapProcStateSample16[] = { | 356 // A8 treats alpha/opaque the same (equally efficient) |
263 S32_D16_nofilter_DXDY, | 357 SA8_alpha_D32_nofilter_DXDY, |
264 S32_D16_nofilter_DX, | 358 SA8_alpha_D32_nofilter_DXDY, |
265 S32_D16_filter_DXDY, | 359 SA8_alpha_D32_nofilter_DX, |
266 S32_D16_filter_DX, | 360 SA8_alpha_D32_nofilter_DX, |
361 SA8_alpha_D32_filter_DXDY, | |
362 SA8_alpha_D32_filter_DXDY, | |
363 SA8_alpha_D32_filter_DX, | |
364 SA8_alpha_D32_filter_DX | |
365 }; | |
267 | 366 |
268 S16_D16_nofilter_DXDY, | 367 static const SampleProc16 gSkBitmapProcStateSample16[] = { |
269 S16_D16_nofilter_DX, | 368 S32_D16_nofilter_DXDY, |
270 S16_D16_filter_DXDY, | 369 S32_D16_nofilter_DX, |
271 S16_D16_filter_DX, | 370 S32_D16_filter_DXDY, |
371 S32_D16_filter_DX, | |
272 | 372 |
273 SI8_D16_nofilter_DXDY, | 373 S16_D16_nofilter_DXDY, |
274 SI8_D16_nofilter_DX, | 374 S16_D16_nofilter_DX, |
275 SI8_D16_filter_DXDY, | 375 S16_D16_filter_DXDY, |
276 SI8_D16_filter_DX, | 376 S16_D16_filter_DX, |
277 | 377 |
278 // Don't support 4444 -> 565 | 378 SI8_D16_nofilter_DXDY, |
279 NULL, NULL, NULL, NULL, | 379 SI8_D16_nofilter_DX, |
280 // Don't support A8 -> 565 | 380 SI8_D16_filter_DXDY, |
281 NULL, NULL, NULL, NULL | 381 SI8_D16_filter_DX, |
282 }; | |
283 #endif | |
284 | 382 |
285 fSampleProc32 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample32)[index]; | 383 // Don't support 4444 -> 565 |
286 index >>= 1; // shift away any opaque/alpha distinction | 384 NULL, NULL, NULL, NULL, |
287 fSampleProc16 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample16)[index]; | 385 // Don't support A8 -> 565 |
386 NULL, NULL, NULL, NULL | |
387 }; | |
388 #endif | |
288 | 389 |
289 // our special-case shaderprocs | 390 fSampleProc32 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample32)[index]; |
290 if (SK_ARM_NEON_WRAP(S16_D16_filter_DX) == fSampleProc16) { | 391 index >>= 1; // shift away any opaque/alpha distinction |
291 if (clamp_clamp) { | 392 fSampleProc16 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample16)[index]; |
292 fShaderProc16 = SK_ARM_NEON_WRAP(Clamp_S16_D16_filter_DX_shaderproc) ; | 393 |
293 } else if (SkShader::kRepeat_TileMode == fTileModeX && | 394 // our special-case shaderprocs |
294 SkShader::kRepeat_TileMode == fTileModeY) { | 395 if (SK_ARM_NEON_WRAP(S16_D16_filter_DX) == fSampleProc16) { |
295 fShaderProc16 = SK_ARM_NEON_WRAP(Repeat_S16_D16_filter_DX_shaderproc ); | 396 if (clamp_clamp) { |
397 fShaderProc16 = SK_ARM_NEON_WRAP(Clamp_S16_D16_filter_DX_shaderp roc); | |
398 } else if (SkShader::kRepeat_TileMode == fTileModeX && | |
399 SkShader::kRepeat_TileMode == fTileModeY) { | |
400 fShaderProc16 = SK_ARM_NEON_WRAP(Repeat_S16_D16_filter_DX_shader proc); | |
401 } | |
402 } else if (SK_ARM_NEON_WRAP(SI8_opaque_D32_filter_DX) == fSampleProc32 & & clamp_clamp) { | |
403 fShaderProc32 = SK_ARM_NEON_WRAP(Clamp_SI8_opaque_D32_filter_DX_shad erproc); | |
296 } | 404 } |
297 } else if (SK_ARM_NEON_WRAP(SI8_opaque_D32_filter_DX) == fSampleProc32 && cl amp_clamp) { | |
298 fShaderProc32 = SK_ARM_NEON_WRAP(Clamp_SI8_opaque_D32_filter_DX_shaderpr oc); | |
299 } | |
300 | 405 |
301 if (NULL == fShaderProc32) { | 406 if (NULL == fShaderProc32) { |
302 fShaderProc32 = this->chooseShaderProc32(); | 407 fShaderProc32 = this->chooseShaderProc32(); |
303 } | 408 } |
304 | |
305 if (NULL == fShaderProc32) { | |
306 fShaderProc32 = this->chooseBitmapFilterProc(paint); | |
307 } | 409 } |
308 | 410 |
309 // see if our platform has any accelerated overrides | 411 // see if our platform has any accelerated overrides |
310 this->platformProcs(); | 412 this->platformProcs(); |
311 | 413 |
312 return true; | 414 return true; |
313 } | 415 } |
314 | 416 |
315 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, | 417 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, |
316 int x, int y, | 418 int x, int y, |
317 SkPMColor* SK_RESTRICT color s, | 419 SkPMColor* SK_RESTRICT color s, |
318 int count) { | 420 int count) { |
319 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); | 421 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); |
320 SkASSERT(s.fInvKy == 0); | 422 SkASSERT(s.fInvKy == 0); |
321 SkASSERT(count > 0 && colors != NULL); | 423 SkASSERT(count > 0 && colors != NULL); |
322 SkASSERT(!s.fDoFilter); | 424 SkASSERT(s.fFilterQuality == SkBitmapProcState::kNone_BitmapFilter); |
reed1
2013/07/11 20:26:18
nit: reverse the sides of the ==
| |
323 | 425 |
324 const int maxX = s.fBitmap->width() - 1; | 426 const int maxX = s.fBitmap->width() - 1; |
325 const int maxY = s.fBitmap->height() - 1; | 427 const int maxY = s.fBitmap->height() - 1; |
326 int ix = s.fFilterOneX + x; | 428 int ix = s.fFilterOneX + x; |
327 int iy = SkClampMax(s.fFilterOneY + y, maxY); | 429 int iy = SkClampMax(s.fFilterOneY + y, maxY); |
328 #ifdef SK_DEBUG | 430 #ifdef SK_DEBUG |
329 { | 431 { |
330 SkPoint pt; | 432 SkPoint pt; |
331 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, | 433 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, |
332 SkIntToScalar(y) + SK_ScalarHalf, &pt); | 434 SkIntToScalar(y) + SK_ScalarHalf, &pt); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 return x; | 488 return x; |
387 } | 489 } |
388 | 490 |
389 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, | 491 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, |
390 int x, int y, | 492 int x, int y, |
391 SkPMColor* SK_RESTRICT colo rs, | 493 SkPMColor* SK_RESTRICT colo rs, |
392 int count) { | 494 int count) { |
393 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); | 495 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); |
394 SkASSERT(s.fInvKy == 0); | 496 SkASSERT(s.fInvKy == 0); |
395 SkASSERT(count > 0 && colors != NULL); | 497 SkASSERT(count > 0 && colors != NULL); |
396 SkASSERT(!s.fDoFilter); | 498 SkASSERT(s.fFilterQuality == SkBitmapProcState::kNone_BitmapFilter); |
reed1
2013/07/11 20:26:18
nit: reverse
| |
397 | 499 |
398 const int stopX = s.fBitmap->width(); | 500 const int stopX = s.fBitmap->width(); |
399 const int stopY = s.fBitmap->height(); | 501 const int stopY = s.fBitmap->height(); |
400 int ix = s.fFilterOneX + x; | 502 int ix = s.fFilterOneX + x; |
401 int iy = sk_int_mod(s.fFilterOneY + y, stopY); | 503 int iy = sk_int_mod(s.fFilterOneY + y, stopY); |
402 #ifdef SK_DEBUG | 504 #ifdef SK_DEBUG |
403 { | 505 { |
404 SkPoint pt; | 506 SkPoint pt; |
405 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, | 507 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, |
406 SkIntToScalar(y) + SK_ScalarHalf, &pt); | 508 SkIntToScalar(y) + SK_ScalarHalf, &pt); |
(...skipping 25 matching lines...) Expand all Loading... | |
432 int count) { | 534 int count) { |
433 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0); | 535 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0); |
434 SkASSERT(s.fInvKy == 0); | 536 SkASSERT(s.fInvKy == 0); |
435 SkASSERT(count > 0 && colors != NULL); | 537 SkASSERT(count > 0 && colors != NULL); |
436 SkASSERT(1 == s.fBitmap->width()); | 538 SkASSERT(1 == s.fBitmap->width()); |
437 | 539 |
438 int iY0; | 540 int iY0; |
439 int iY1 SK_INIT_TO_AVOID_WARNING; | 541 int iY1 SK_INIT_TO_AVOID_WARNING; |
440 int iSubY SK_INIT_TO_AVOID_WARNING; | 542 int iSubY SK_INIT_TO_AVOID_WARNING; |
441 | 543 |
442 if (s.fDoFilter) { | 544 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) { |
443 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); | 545 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); |
444 uint32_t xy[2]; | 546 uint32_t xy[2]; |
445 | 547 |
446 mproc(s, xy, 1, x, y); | 548 mproc(s, xy, 1, x, y); |
447 | 549 |
448 iY0 = xy[0] >> 18; | 550 iY0 = xy[0] >> 18; |
449 iY1 = xy[0] & 0x3FFF; | 551 iY1 = xy[0] & 0x3FFF; |
450 iSubY = (xy[0] >> 14) & 0xF; | 552 iSubY = (xy[0] >> 14) & 0xF; |
451 } else { | 553 } else { |
452 int yTemp; | 554 int yTemp; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
513 } | 615 } |
514 | 616 |
515 SkASSERT(iY0 == iY2); | 617 SkASSERT(iY0 == iY2); |
516 } | 618 } |
517 #endif | 619 #endif |
518 } | 620 } |
519 | 621 |
520 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0); | 622 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0); |
521 SkPMColor color; | 623 SkPMColor color; |
522 | 624 |
523 if (s.fDoFilter) { | 625 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) { |
524 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1); | 626 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1); |
525 | 627 |
526 if (s.fAlphaScale < 256) { | 628 if (s.fAlphaScale < 256) { |
527 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale); | 629 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale); |
528 } else { | 630 } else { |
529 Filter_32_opaque(iSubY, *row0, *row1, &color); | 631 Filter_32_opaque(iSubY, *row0, *row1, &color); |
530 } | 632 } |
531 } else { | 633 } else { |
532 if (s.fAlphaScale < 256) { | 634 if (s.fAlphaScale < 256) { |
533 color = SkAlphaMulQ(*row0, s.fAlphaScale); | 635 color = SkAlphaMulQ(*row0, s.fAlphaScale); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
569 | 671 |
570 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { | 672 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { |
571 | 673 |
572 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) { | 674 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) { |
573 return NULL; | 675 return NULL; |
574 } | 676 } |
575 | 677 |
576 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask; | 678 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask; |
577 | 679 |
578 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) { | 680 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) { |
579 if (!fDoFilter && fInvType <= SkMatrix::kTranslate_Mask && !this->setupF orTranslate()) { | 681 if (fFilterQuality == kNone_BitmapFilter && |
682 fInvType <= SkMatrix::kTranslate_Mask && | |
683 !this->setupForTranslate()) { | |
580 return DoNothing_shaderproc; | 684 return DoNothing_shaderproc; |
581 } | 685 } |
582 return S32_D32_constX_shaderproc; | 686 return S32_D32_constX_shaderproc; |
583 } | 687 } |
584 | 688 |
585 if (fAlphaScale < 256) { | 689 if (fAlphaScale < 256) { |
586 return NULL; | 690 return NULL; |
587 } | 691 } |
588 if (fInvType > SkMatrix::kTranslate_Mask) { | 692 if (fInvType > SkMatrix::kTranslate_Mask) { |
589 return NULL; | 693 return NULL; |
590 } | 694 } |
591 if (fDoFilter) { | 695 if (fFilterQuality != kNone_BitmapFilter) { |
592 return NULL; | 696 return NULL; |
593 } | 697 } |
594 | 698 |
595 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX; | 699 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX; |
596 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY; | 700 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY; |
597 | 701 |
598 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) { | 702 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) { |
599 if (this->setupForTranslate()) { | 703 if (this->setupForTranslate()) { |
600 return Clamp_S32_D32_nofilter_trans_shaderproc; | 704 return Clamp_S32_D32_nofilter_trans_shaderproc; |
601 } | 705 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
677 SkASSERT(count > 0); | 781 SkASSERT(count > 0); |
678 | 782 |
679 state.fMatrixProc(state, bitmapXY, count, x, y); | 783 state.fMatrixProc(state, bitmapXY, count, x, y); |
680 | 784 |
681 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my); | 785 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my); |
682 | 786 |
683 // There are four formats possible: | 787 // There are four formats possible: |
684 // scale -vs- affine | 788 // scale -vs- affine |
685 // filter -vs- nofilter | 789 // filter -vs- nofilter |
686 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { | 790 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { |
687 proc = state.fDoFilter ? check_scale_filter : check_scale_nofilter; | 791 proc = state.fFilterQuality != kNone_BitmapFilter ? check_scale_filter : check_scale_nofilter; |
688 } else { | 792 } else { |
689 proc = state.fDoFilter ? check_affine_filter : check_affine_nofilter; | 793 proc = state.fFilterQuality != kNone_BitmapFilter ? check_affine_filter : check_affine_nofilter; |
690 } | 794 } |
691 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height()); | 795 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height()); |
692 } | 796 } |
693 | 797 |
694 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const { | 798 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const { |
695 return DebugMatrixProc; | 799 return DebugMatrixProc; |
696 } | 800 } |
697 | 801 |
698 #endif | 802 #endif |
699 | 803 |
(...skipping 14 matching lines...) Expand all Loading... | |
714 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { | 818 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { |
715 size -= 4; // the shared Y (or YY) coordinate | 819 size -= 4; // the shared Y (or YY) coordinate |
716 if (size < 0) { | 820 if (size < 0) { |
717 size = 0; | 821 size = 0; |
718 } | 822 } |
719 size >>= 1; | 823 size >>= 1; |
720 } else { | 824 } else { |
721 size >>= 2; | 825 size >>= 2; |
722 } | 826 } |
723 | 827 |
724 if (fDoFilter) { | 828 if (fFilterQuality != kNone_BitmapFilter) { |
725 size >>= 1; | 829 size >>= 1; |
726 } | 830 } |
727 | 831 |
728 return size; | 832 return size; |
729 } | 833 } |
OLD | NEW |