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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 } | 84 } |
85 | 85 |
86 /////////////////////////////////////////////////////////////////////////////// | 86 /////////////////////////////////////////////////////////////////////////////// |
87 | 87 |
88 static bool valid_for_filtering(unsigned dimension) { | 88 static bool valid_for_filtering(unsigned dimension) { |
89 // for filtering, width and height must fit in 14bits, since we use steal | 89 // for filtering, width and height must fit in 14bits, since we use steal |
90 // 2 bits from each to store our 4bit subpixel data | 90 // 2 bits from each to store our 4bit subpixel data |
91 return (dimension & ~0x3FFF) == 0; | 91 return (dimension & ~0x3FFF) == 0; |
92 } | 92 } |
93 | 93 |
| 94 static bool effective_matrix_scale_sqrd(const SkMatrix& mat) { |
| 95 SkPoint v1, v2; |
| 96 |
| 97 v1.fX = mat.getScaleX(); |
| 98 v1.fY = mat.getSkewY(); |
| 99 |
| 100 v2.fX = mat.getSkewX(); |
| 101 v2.fY = mat.getScaleY(); |
| 102 |
| 103 return SkMaxScalar(v1.lengthSqd(), v2.lengthSqd()); |
| 104 } |
| 105 |
94 // TODO -- we may want to pass the clip into this function so we only scale | 106 // TODO -- we may want to pass the clip into this function so we only scale |
95 // the portion of the image that we're going to need. This will complicate | 107 // the portion of the image that we're going to need. This will complicate |
96 // the interface to the cache, but might be well worth it. | 108 // the interface to the cache, but might be well worth it. |
97 | 109 |
98 void SkBitmapProcState::possiblyScaleImage() { | 110 void SkBitmapProcState::possiblyScaleImage() { |
99 | 111 |
100 if (fFilterQuality != kHQ_BitmapFilter) { | 112 if (fFilterLevel <= SkPaint::kLow_FilterLevel) { |
| 113 // none or low (bilerp) does not need to look any further |
101 return; | 114 return; |
102 } | 115 } |
103 | 116 |
104 // see if our platform has any specialized convolution code. | 117 // see if our platform has any specialized convolution code. |
105 | 118 |
106 | 119 |
107 // Set up a pointer to a local (instead of storing the structure in the | 120 // Set up a pointer to a local (instead of storing the structure in the |
108 // proc state) to avoid introducing a header dependency; this makes | 121 // proc state) to avoid introducing a header dependency; this makes |
109 // recompiles a lot less painful. | 122 // recompiles a lot less painful. |
110 | 123 |
111 SkConvolutionProcs simd; | 124 SkConvolutionProcs simd; |
112 fConvolutionProcs = &simd; | 125 fConvolutionProcs = &simd; |
113 | 126 |
114 fConvolutionProcs->fExtraHorizontalReads = 0; | 127 fConvolutionProcs->fExtraHorizontalReads = 0; |
115 fConvolutionProcs->fConvolveVertically = NULL; | 128 fConvolutionProcs->fConvolveVertically = NULL; |
116 fConvolutionProcs->fConvolve4RowsHorizontally = NULL; | 129 fConvolutionProcs->fConvolve4RowsHorizontally = NULL; |
117 fConvolutionProcs->fConvolveHorizontally = NULL; | 130 fConvolutionProcs->fConvolveHorizontally = NULL; |
118 fConvolutionProcs->fApplySIMDPadding = NULL; | 131 fConvolutionProcs->fApplySIMDPadding = NULL; |
119 | 132 |
120 this->platformConvolutionProcs(); | 133 this->platformConvolutionProcs(); |
121 | 134 |
122 // STEP 1: Highest quality direct scale? | 135 // STEP 1: Highest quality direct scale? |
123 | 136 |
124 // Check to see if the transformation matrix is simple, and if we're | 137 // Check to see if the transformation matrix is simple, and if we're |
125 // doing high quality scaling. If so, do the bitmap scale here and | 138 // doing high quality scaling. If so, do the bitmap scale here and |
126 // remove the scaling component from the matrix. | 139 // remove the scaling component from the matrix. |
127 | 140 |
128 if (fFilterQuality == kHQ_BitmapFilter && | 141 if (SkPaint::kHigh_FilterLevel == fFilterLevel && |
129 fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Ma
sk) && | 142 fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Ma
sk) && |
130 fOrigBitmap.config() == SkBitmap::kARGB_8888_Config) { | 143 fOrigBitmap.config() == SkBitmap::kARGB_8888_Config) { |
131 | 144 |
132 int dest_width = SkScalarCeilToInt(fOrigBitmap.width() / fInvMatrix.get
ScaleX()); | 145 int dest_width = SkScalarCeilToInt(fOrigBitmap.width() / fInvMatrix.get
ScaleX()); |
133 int dest_height = SkScalarCeilToInt(fOrigBitmap.height() / fInvMatrix.ge
tScaleY()); | 146 int dest_height = SkScalarCeilToInt(fOrigBitmap.height() / fInvMatrix.ge
tScaleY()); |
134 | 147 |
135 // All the criteria are met; let's make a new bitmap. | 148 // All the criteria are met; let's make a new bitmap. |
136 | 149 |
137 fScaledBitmap = SkBitmapScaler::Resize( fOrigBitmap, SkBitmapScaler::RES
IZE_BEST, | 150 fScaledBitmap = SkBitmapScaler::Resize( fOrigBitmap, SkBitmapScaler::RES
IZE_BEST, |
138 dest_width, dest_height, fConvol
utionProcs ); | 151 dest_width, dest_height, fConvol
utionProcs ); |
139 | 152 |
140 fScaledBitmap.lockPixels(); | 153 fScaledBitmap.lockPixels(); |
141 | 154 |
142 fBitmap = &fScaledBitmap; | 155 fBitmap = &fScaledBitmap; |
143 | 156 |
144 // set the inv matrix type to translate-only; | 157 // set the inv matrix type to translate-only; |
145 | 158 |
146 fInvMatrix.setTranslate( 1/fInvMatrix.getScaleX() * fInvMatrix.getTransl
ateX(), | 159 fInvMatrix.setTranslate( 1/fInvMatrix.getScaleX() * fInvMatrix.getTransl
ateX(), |
147 1/fInvMatrix.getScaleY() * fInvMatrix.getTransl
ateY() ); | 160 1/fInvMatrix.getScaleY() * fInvMatrix.getTransl
ateY() ); |
148 | 161 |
149 // no need for any further filtering; we just did it! | 162 // no need for any further filtering; we just did it! |
150 | 163 |
151 fFilterQuality = kNone_BitmapFilter; | 164 fFilterLevel = SkPaint::kNone_FilterLevel; |
152 | 165 |
153 return; | 166 return; |
154 } | 167 } |
155 | 168 |
156 if (!fOrigBitmap.hasMipMap() && fFilterQuality != kNone_BitmapFilter) { | 169 /* |
| 170 * If we get here, the caller has requested either Med or High filter-level |
| 171 * |
| 172 * If High, then our special-case for scale-only did not take, and so we |
| 173 * have to make a choice: |
| 174 * 1. fall back on mipmaps + bilerp |
| 175 * 2. fall back on scanline bicubic filter |
| 176 * For now, we compute the "scale" value from the matrix, and have a |
| 177 * threshold to decide when bicubic is better, and when mips are better. |
| 178 * No doubt a fancier decision tree could be used uere. |
| 179 * |
| 180 * If Medium, then we just try to build a mipmap and select a level, |
| 181 * setting the filter-level to kLow to signal that we just need bilerp |
| 182 * to process the selected level. |
| 183 */ |
157 | 184 |
158 // STEP 2: MIPMAP DOWNSAMPLE? | 185 SkScalar scaleSqd = effective_matrix_scale_sqrd(fInvMatrix); |
159 | 186 |
160 // Check to see if the transformation matrix is scaling *down*. | 187 if (SkPaint::kHigh_FilterLevel == fFilterLevel) { |
161 // If so, automatically build mipmaps. | 188 // Set the limit at 0.25 for the CTM... if the CTM is scaling smaller |
| 189 // than this, then the mipmaps quality may be greater (certainly faster) |
| 190 // so we only keep High quality if the scale is greater than this. |
| 191 // |
| 192 // Since we're dealing with the inverse, we compare against its inverse. |
| 193 const SkScalar bicubicLimit = SkFloatToScalar(4.0f); |
| 194 const SkScalar bicubicLimitSqd = bicubicLimit * bicubicLimit; |
| 195 if (scaleSqd < bicubicLimitSqd) { // use bicubic scanline |
| 196 return; |
| 197 } |
162 | 198 |
163 SkPoint v1, v2; | 199 // else set the filter-level to Medium, since we're scaling down and |
| 200 // want to reqeust mipmaps |
| 201 fFilterLevel = SkPaint::kMedium_FilterLevel; |
| 202 } |
| 203 |
| 204 SkASSERT(SkPaint::kMedium_FilterLevel == fFilterLevel); |
164 | 205 |
165 // conservatively estimate if the matrix is scaling down by seeing | 206 /** |
166 // what its upper left 2x2 portion does to two unit vectors. | 207 * Medium quality means use a mipmap for down-scaling, and just bilper |
167 | 208 * for upscaling. Since we're examining the inverse matrix, we look for |
168 v1.fX = fInvMatrix.getScaleX(); | 209 * a scale > 1 to indicate down scaling by the CTM. |
169 v1.fY = fInvMatrix.getSkewY(); | 210 */ |
170 | 211 if (scaleSqd > SK_Scalar1) { |
171 v2.fX = fInvMatrix.getSkewX(); | 212 if (!fOrigBitmap.hasMipMap()) { |
172 v2.fY = fInvMatrix.getScaleY(); | |
173 | |
174 if (v1.fX * v1.fX + v1.fY * v1.fY > 1 || | |
175 v2.fX * v2.fX + v2.fY * v2.fY > 1) { | |
176 fOrigBitmap.buildMipMap(); | 213 fOrigBitmap.buildMipMap(); |
177 | 214 // build may fail, so we need to check again |
178 // Now that we've built the mipmaps and we know we're downsampling, | 215 } |
179 // downgrade to bilinear interpolation for the mip level. | 216 if (fOrigBitmap.hasMipMap()) { |
180 | 217 int shift = fOrigBitmap.extractMipLevel(&fScaledBitmap, |
181 fFilterQuality = kBilerp_BitmapFilter; | 218 SkScalarToFixed(fInvMatrix.getScaleX()), |
| 219 SkScalarToFixed(fInvMatrix.getSkewY())); |
| 220 if (shift > 0) { |
| 221 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift); |
| 222 fInvMatrix.postScale(scale, scale); |
| 223 fBitmap = &fScaledBitmap; |
| 224 } |
182 } | 225 } |
183 } | 226 } |
184 | 227 |
185 if (fOrigBitmap.hasMipMap()) { | 228 // Now that we've built the mipmaps (if applicable), we set the filter-level |
186 | 229 // bilinear interpolation. |
187 // STEP 3: We've got mipmaps, let's choose the closest level as our rend
er | 230 fFilterLevel = SkPaint::kLow_FilterLevel; |
188 // source and adjust the matrix accordingly. | |
189 | |
190 int shift = fOrigBitmap.extractMipLevel(&fScaledBitmap, | |
191 SkScalarToFixed(fInvMatrix.getSc
aleX()), | |
192 SkScalarToFixed(fInvMatrix.getSk
ewY())); | |
193 | |
194 if (shift > 0) { | |
195 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift); | |
196 fInvMatrix.postScale(scale, scale); | |
197 fBitmap = &fScaledBitmap; | |
198 } | |
199 } | |
200 } | 231 } |
201 | 232 |
202 void SkBitmapProcState::endContext() { | 233 void SkBitmapProcState::endContext() { |
203 SkDELETE(fBitmapFilter); | 234 SkDELETE(fBitmapFilter); |
204 fBitmapFilter = NULL; | 235 fBitmapFilter = NULL; |
205 fScaledBitmap.reset(); | 236 fScaledBitmap.reset(); |
206 } | 237 } |
207 | 238 |
208 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { | 239 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { |
209 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) { | 240 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) { |
210 return false; | 241 return false; |
211 } | 242 } |
212 | 243 |
213 bool trivialMatrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0; | 244 bool trivialMatrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0; |
214 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && | 245 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && |
215 SkShader::kClamp_TileMode == fTileModeY; | 246 SkShader::kClamp_TileMode == fTileModeY; |
216 | 247 |
217 fInvMatrix = inv; | 248 fInvMatrix = inv; |
218 if (!(clampClamp || trivialMatrix)) { | 249 if (!(clampClamp || trivialMatrix)) { |
219 fInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); | 250 fInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); |
220 } | 251 } |
221 | 252 |
222 fBitmap = &fOrigBitmap; | 253 fBitmap = &fOrigBitmap; |
223 | 254 |
224 // initialize our filter quality to the one requested by the caller. | 255 // initialize our filter quality to the one requested by the caller. |
225 // We may downgrade it later if we determine that we either don't need | 256 // We may downgrade it later if we determine that we either don't need |
226 // or can't provide as high a quality filtering as the user requested. | 257 // or can't provide as high a quality filtering as the user requested. |
227 | 258 |
228 fFilterQuality = kNone_BitmapFilter; | 259 fFilterLevel = paint.getFilterLevel(); |
229 if (paint.isFilterBitmap()) { | |
230 if (paint.getFlags() & SkPaint::kHighQualityFilterBitmap_Flag) { | |
231 fFilterQuality = kHQ_BitmapFilter; | |
232 } else { | |
233 fFilterQuality = kBilerp_BitmapFilter; | |
234 } | |
235 } | |
236 | 260 |
237 #ifndef SK_IGNORE_IMAGE_PRESCALE | 261 #ifndef SK_IGNORE_IMAGE_PRESCALE |
238 // possiblyScaleImage will look to see if it can rescale the image as a | 262 // possiblyScaleImage will look to see if it can rescale the image as a |
239 // preprocess; either by scaling up to the target size, or by selecting | 263 // preprocess; either by scaling up to the target size, or by selecting |
240 // a nearby mipmap level. If it does, it will adjust the working | 264 // a nearby mipmap level. If it does, it will adjust the working |
241 // matrix as well as the working bitmap. It may also adjust the filter | 265 // matrix as well as the working bitmap. It may also adjust the filter |
242 // quality to avoid re-filtering an already perfectly scaled image. | 266 // quality to avoid re-filtering an already perfectly scaled image. |
243 | 267 |
244 this->possiblyScaleImage(); | 268 this->possiblyScaleImage(); |
245 #endif | 269 #endif |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 fShaderProc32 = NULL; | 301 fShaderProc32 = NULL; |
278 fShaderProc16 = NULL; | 302 fShaderProc16 = NULL; |
279 fSampleProc32 = NULL; | 303 fSampleProc32 = NULL; |
280 fSampleProc16 = NULL; | 304 fSampleProc16 = NULL; |
281 | 305 |
282 // recompute the triviality of the matrix here because we may have | 306 // recompute the triviality of the matrix here because we may have |
283 // changed it! | 307 // changed it! |
284 | 308 |
285 trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; | 309 trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; |
286 | 310 |
287 if (kHQ_BitmapFilter == fFilterQuality) { | 311 if (SkPaint::kHigh_FilterLevel == fFilterLevel) { |
288 // If this is still set, that means we wanted HQ sampling | 312 // If this is still set, that means we wanted HQ sampling |
289 // but couldn't do it as a preprocess. Let's try to install | 313 // but couldn't do it as a preprocess. Let's try to install |
290 // the scanline version of the HQ sampler. If that process fails, | 314 // the scanline version of the HQ sampler. If that process fails, |
291 // downgrade to bilerp. | 315 // downgrade to bilerp. |
292 | 316 |
293 // NOTE: Might need to be careful here in the future when we want | 317 // NOTE: Might need to be careful here in the future when we want |
294 // to have the platform proc have a shot at this; it's possible that | 318 // to have the platform proc have a shot at this; it's possible that |
295 // the chooseBitmapFilterProc will fail to install a shader but a | 319 // the chooseBitmapFilterProc will fail to install a shader but a |
296 // platform-specific one might succeed, so it might be premature here | 320 // platform-specific one might succeed, so it might be premature here |
297 // to fall back to bilerp. This needs thought. | 321 // to fall back to bilerp. This needs thought. |
298 | 322 |
299 SkASSERT(fInvType > SkMatrix::kTranslate_Mask); | 323 SkASSERT(fInvType > SkMatrix::kTranslate_Mask); |
300 | 324 |
301 fShaderProc32 = this->chooseBitmapFilterProc(); | 325 fShaderProc32 = this->chooseBitmapFilterProc(); |
302 if (!fShaderProc32) { | 326 if (!fShaderProc32) { |
303 fFilterQuality = kBilerp_BitmapFilter; | 327 fFilterLevel = SkPaint::kLow_FilterLevel; |
304 } | 328 } |
305 } | 329 } |
306 | 330 |
307 if (kBilerp_BitmapFilter == fFilterQuality) { | 331 if (SkPaint::kLow_FilterLevel == fFilterLevel) { |
308 // Only try bilerp if the matrix is "interesting" and | 332 // Only try bilerp if the matrix is "interesting" and |
309 // the image has a suitable size. | 333 // the image has a suitable size. |
310 | 334 |
311 if (fInvType <= SkMatrix::kTranslate_Mask || | 335 if (fInvType <= SkMatrix::kTranslate_Mask || |
312 !valid_for_filtering(fBitmap->width() | fBitmap->height())) { | 336 !valid_for_filtering(fBitmap->width() | fBitmap->height())) { |
313 fFilterQuality = kNone_BitmapFilter; | 337 fFilterLevel = SkPaint::kNone_FilterLevel; |
314 } | 338 } |
315 } | 339 } |
316 | 340 |
317 // At this point, we know exactly what kind of sampling the per-scanline | 341 // At this point, we know exactly what kind of sampling the per-scanline |
318 // shader will perform. | 342 // shader will perform. |
319 | 343 |
320 fMatrixProc = this->chooseMatrixProc(trivialMatrix); | 344 fMatrixProc = this->chooseMatrixProc(trivialMatrix); |
321 if (NULL == fMatrixProc) { | 345 if (NULL == fMatrixProc) { |
322 return false; | 346 return false; |
323 } | 347 } |
324 | 348 |
325 /////////////////////////////////////////////////////////////////////// | 349 /////////////////////////////////////////////////////////////////////// |
326 | 350 |
327 // No need to do this if we're doing HQ sampling; if filter quality is | 351 // No need to do this if we're doing HQ sampling; if filter quality is |
328 // still set to HQ by the time we get here, then we must have installed | 352 // still set to HQ by the time we get here, then we must have installed |
329 // the shader proc above and can skip all this. | 353 // the shader proc above and can skip all this. |
330 | 354 |
331 if (fFilterQuality < kHQ_BitmapFilter) { | 355 if (fFilterLevel < SkPaint::kHigh_FilterLevel) { |
332 | 356 |
333 int index = 0; | 357 int index = 0; |
334 if (fAlphaScale < 256) { // note: this distinction is not used for D16 | 358 if (fAlphaScale < 256) { // note: this distinction is not used for D16 |
335 index |= 1; | 359 index |= 1; |
336 } | 360 } |
337 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { | 361 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { |
338 index |= 2; | 362 index |= 2; |
339 } | 363 } |
340 if (fFilterQuality != kNone_BitmapFilter) { | 364 if (fFilterLevel > SkPaint::kNone_FilterLevel) { |
341 index |= 4; | 365 index |= 4; |
342 } | 366 } |
343 // bits 3,4,5 encoding the source bitmap format | 367 // bits 3,4,5 encoding the source bitmap format |
344 switch (fBitmap->config()) { | 368 switch (fBitmap->config()) { |
345 case SkBitmap::kARGB_8888_Config: | 369 case SkBitmap::kARGB_8888_Config: |
346 index |= 0; | 370 index |= 0; |
347 break; | 371 break; |
348 case SkBitmap::kRGB_565_Config: | 372 case SkBitmap::kRGB_565_Config: |
349 index |= 8; | 373 index |= 8; |
350 break; | 374 break; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 return true; | 485 return true; |
462 } | 486 } |
463 | 487 |
464 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, | 488 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, |
465 int x, int y, | 489 int x, int y, |
466 SkPMColor* SK_RESTRICT color
s, | 490 SkPMColor* SK_RESTRICT color
s, |
467 int count) { | 491 int count) { |
468 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); | 492 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); |
469 SkASSERT(s.fInvKy == 0); | 493 SkASSERT(s.fInvKy == 0); |
470 SkASSERT(count > 0 && colors != NULL); | 494 SkASSERT(count > 0 && colors != NULL); |
471 SkASSERT(SkBitmapProcState::kNone_BitmapFilter == s.fFilterQuality); | 495 SkASSERT(SkPaint::kNone_FilterLevel == s.fFilterLevel); |
472 | 496 |
473 const int maxX = s.fBitmap->width() - 1; | 497 const int maxX = s.fBitmap->width() - 1; |
474 const int maxY = s.fBitmap->height() - 1; | 498 const int maxY = s.fBitmap->height() - 1; |
475 int ix = s.fFilterOneX + x; | 499 int ix = s.fFilterOneX + x; |
476 int iy = SkClampMax(s.fFilterOneY + y, maxY); | 500 int iy = SkClampMax(s.fFilterOneY + y, maxY); |
477 #ifdef SK_DEBUG | 501 #ifdef SK_DEBUG |
478 { | 502 { |
479 SkPoint pt; | 503 SkPoint pt; |
480 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, | 504 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, |
481 SkIntToScalar(y) + SK_ScalarHalf, &pt); | 505 SkIntToScalar(y) + SK_ScalarHalf, &pt); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 return x; | 559 return x; |
536 } | 560 } |
537 | 561 |
538 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, | 562 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, |
539 int x, int y, | 563 int x, int y, |
540 SkPMColor* SK_RESTRICT colo
rs, | 564 SkPMColor* SK_RESTRICT colo
rs, |
541 int count) { | 565 int count) { |
542 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); | 566 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); |
543 SkASSERT(s.fInvKy == 0); | 567 SkASSERT(s.fInvKy == 0); |
544 SkASSERT(count > 0 && colors != NULL); | 568 SkASSERT(count > 0 && colors != NULL); |
545 SkASSERT(SkBitmapProcState::kNone_BitmapFilter == s.fFilterQuality); | 569 SkASSERT(SkPaint::kNone_FilterLevel == s.fFilterLevel); |
546 | 570 |
547 const int stopX = s.fBitmap->width(); | 571 const int stopX = s.fBitmap->width(); |
548 const int stopY = s.fBitmap->height(); | 572 const int stopY = s.fBitmap->height(); |
549 int ix = s.fFilterOneX + x; | 573 int ix = s.fFilterOneX + x; |
550 int iy = sk_int_mod(s.fFilterOneY + y, stopY); | 574 int iy = sk_int_mod(s.fFilterOneY + y, stopY); |
551 #ifdef SK_DEBUG | 575 #ifdef SK_DEBUG |
552 { | 576 { |
553 SkPoint pt; | 577 SkPoint pt; |
554 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, | 578 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, |
555 SkIntToScalar(y) + SK_ScalarHalf, &pt); | 579 SkIntToScalar(y) + SK_ScalarHalf, &pt); |
(...skipping 25 matching lines...) Expand all Loading... |
581 int count) { | 605 int count) { |
582 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))
== 0); | 606 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))
== 0); |
583 SkASSERT(s.fInvKy == 0); | 607 SkASSERT(s.fInvKy == 0); |
584 SkASSERT(count > 0 && colors != NULL); | 608 SkASSERT(count > 0 && colors != NULL); |
585 SkASSERT(1 == s.fBitmap->width()); | 609 SkASSERT(1 == s.fBitmap->width()); |
586 | 610 |
587 int iY0; | 611 int iY0; |
588 int iY1 SK_INIT_TO_AVOID_WARNING; | 612 int iY1 SK_INIT_TO_AVOID_WARNING; |
589 int iSubY SK_INIT_TO_AVOID_WARNING; | 613 int iSubY SK_INIT_TO_AVOID_WARNING; |
590 | 614 |
591 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) { | 615 if (SkPaint::kNone_FilterLevel != s.fFilterLevel) { |
592 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); | 616 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); |
593 uint32_t xy[2]; | 617 uint32_t xy[2]; |
594 | 618 |
595 mproc(s, xy, 1, x, y); | 619 mproc(s, xy, 1, x, y); |
596 | 620 |
597 iY0 = xy[0] >> 18; | 621 iY0 = xy[0] >> 18; |
598 iY1 = xy[0] & 0x3FFF; | 622 iY1 = xy[0] & 0x3FFF; |
599 iSubY = (xy[0] >> 14) & 0xF; | 623 iSubY = (xy[0] >> 14) & 0xF; |
600 } else { | 624 } else { |
601 int yTemp; | 625 int yTemp; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 } | 686 } |
663 | 687 |
664 SkASSERT(iY0 == iY2); | 688 SkASSERT(iY0 == iY2); |
665 } | 689 } |
666 #endif | 690 #endif |
667 } | 691 } |
668 | 692 |
669 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0); | 693 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0); |
670 SkPMColor color; | 694 SkPMColor color; |
671 | 695 |
672 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) { | 696 if (SkPaint::kNone_FilterLevel != s.fFilterLevel) { |
673 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1); | 697 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1); |
674 | 698 |
675 if (s.fAlphaScale < 256) { | 699 if (s.fAlphaScale < 256) { |
676 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale); | 700 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale); |
677 } else { | 701 } else { |
678 Filter_32_opaque(iSubY, *row0, *row1, &color); | 702 Filter_32_opaque(iSubY, *row0, *row1, &color); |
679 } | 703 } |
680 } else { | 704 } else { |
681 if (s.fAlphaScale < 256) { | 705 if (s.fAlphaScale < 256) { |
682 color = SkAlphaMulQ(*row0, s.fAlphaScale); | 706 color = SkAlphaMulQ(*row0, s.fAlphaScale); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 | 742 |
719 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { | 743 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { |
720 | 744 |
721 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) { | 745 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) { |
722 return NULL; | 746 return NULL; |
723 } | 747 } |
724 | 748 |
725 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M
ask; | 749 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M
ask; |
726 | 750 |
727 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) { | 751 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) { |
728 if (kNone_BitmapFilter == fFilterQuality && | 752 if (SkPaint::kNone_FilterLevel == fFilterLevel && |
729 fInvType <= SkMatrix::kTranslate_Mask && | 753 fInvType <= SkMatrix::kTranslate_Mask && |
730 !this->setupForTranslate()) { | 754 !this->setupForTranslate()) { |
731 return DoNothing_shaderproc; | 755 return DoNothing_shaderproc; |
732 } | 756 } |
733 return S32_D32_constX_shaderproc; | 757 return S32_D32_constX_shaderproc; |
734 } | 758 } |
735 | 759 |
736 if (fAlphaScale < 256) { | 760 if (fAlphaScale < 256) { |
737 return NULL; | 761 return NULL; |
738 } | 762 } |
739 if (fInvType > SkMatrix::kTranslate_Mask) { | 763 if (fInvType > SkMatrix::kTranslate_Mask) { |
740 return NULL; | 764 return NULL; |
741 } | 765 } |
742 if (fFilterQuality != kNone_BitmapFilter) { | 766 if (SkPaint::kNone_FilterLevel != fFilterLevel) { |
743 return NULL; | 767 return NULL; |
744 } | 768 } |
745 | 769 |
746 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX; | 770 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX; |
747 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY; | 771 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY; |
748 | 772 |
749 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) { | 773 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) { |
750 if (this->setupForTranslate()) { | 774 if (this->setupForTranslate()) { |
751 return Clamp_S32_D32_nofilter_trans_shaderproc; | 775 return Clamp_S32_D32_nofilter_trans_shaderproc; |
752 } | 776 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 SkASSERT(count > 0); | 852 SkASSERT(count > 0); |
829 | 853 |
830 state.fMatrixProc(state, bitmapXY, count, x, y); | 854 state.fMatrixProc(state, bitmapXY, count, x, y); |
831 | 855 |
832 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my); | 856 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my); |
833 | 857 |
834 // There are four formats possible: | 858 // There are four formats possible: |
835 // scale -vs- affine | 859 // scale -vs- affine |
836 // filter -vs- nofilter | 860 // filter -vs- nofilter |
837 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { | 861 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { |
838 proc = state.fFilterQuality != kNone_BitmapFilter ? check_scale_filter :
check_scale_nofilter; | 862 proc = state.fFilterLevel != SkPaint::kNone_FilterLevel ? check_scale_fi
lter : check_scale_nofilter; |
839 } else { | 863 } else { |
840 proc = state.fFilterQuality != kNone_BitmapFilter ? check_affine_filter
: check_affine_nofilter; | 864 proc = state.fFilterLevel != SkPaint::kNone_FilterLevel ? check_affine_f
ilter : check_affine_nofilter; |
841 } | 865 } |
842 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height()); | 866 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height()); |
843 } | 867 } |
844 | 868 |
845 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const { | 869 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const { |
846 return DebugMatrixProc; | 870 return DebugMatrixProc; |
847 } | 871 } |
848 | 872 |
849 #endif | 873 #endif |
850 | 874 |
(...skipping 14 matching lines...) Expand all Loading... |
865 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { | 889 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { |
866 size -= 4; // the shared Y (or YY) coordinate | 890 size -= 4; // the shared Y (or YY) coordinate |
867 if (size < 0) { | 891 if (size < 0) { |
868 size = 0; | 892 size = 0; |
869 } | 893 } |
870 size >>= 1; | 894 size >>= 1; |
871 } else { | 895 } else { |
872 size >>= 2; | 896 size >>= 2; |
873 } | 897 } |
874 | 898 |
875 if (fFilterQuality != kNone_BitmapFilter) { | 899 if (fFilterLevel != SkPaint::kNone_FilterLevel) { |
876 size >>= 1; | 900 size >>= 1; |
877 } | 901 } |
878 | 902 |
879 return size; | 903 return size; |
880 } | 904 } |
OLD | NEW |