Chromium Code Reviews| 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 // TODO -- we may want to pass the clip into this function so we only scale | |
| 94 // the portion of the image that we're going to need. This will complicate | |
| 95 // the interface to the cache, but might be well worth it. | |
| 96 | |
| 97 void SkBitmapProcState::possiblyScaleImage() { | |
| 98 | |
| 99 if (fFilterQuality != kHQ_BitmapFilter) { | |
| 100 return; | |
| 101 } | |
| 102 | |
| 103 // STEP 1: UPSAMPLE? | |
| 104 | |
| 105 // Check to see if the transformation matrix is scaling up, and if | |
| 106 // the matrix is simple, and if we're doing high quality scaling. | |
| 107 // If so, do the bitmap scale here and remove the scaling component from the matrix. | |
| 108 | |
| 109 if (fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Ma sk) && | |
| 110 (fInvMatrix.getScaleX() < 1 || fInvMatrix.getScaleY() < 1) && | |
| 111 fOrigBitmap.config() == SkBitmap::kARGB_8888_Config) { | |
| 112 | |
| 113 // All the criteria are met; let's make a new bitmap. | |
|
robertphillips
2013/07/12 19:42:31
How does all this work out when the scaled width &
humper
2013/07/12 21:12:03
Fractional widths are (currently) getting rounded
| |
| 114 fScaledBitmap.setConfig(SkBitmap::kARGB_8888_Config, | |
| 115 (int)(fOrigBitmap.width() / fInvMatrix.getScaleX ()), | |
| 116 (int)(fOrigBitmap.height() / fInvMatrix.getScale Y())); | |
| 117 fScaledBitmap.allocPixels(); | |
| 118 fOrigBitmap.scale(&fScaledBitmap); | |
| 119 fBitmap = &fScaledBitmap; | |
| 120 | |
| 121 // set the inv matrix type to translate-only; | |
| 122 | |
| 123 fInvMatrix.setTranslate( 1/fInvMatrix.getScaleX() * fInvMatrix.getTransl ateX(), | |
|
robertphillips
2013/07/12 19:42:31
align with above
humper
2013/07/12 21:12:03
Done.
| |
| 124 1/fInvMatrix.getScaleY() * fInvMatrix.getTr anslateY() ); | |
| 125 | |
| 126 // no need for any further filtering; we just did it! | |
| 127 | |
| 128 fFilterQuality = kNone_BitmapFilter; | |
| 129 | |
| 130 return; | |
| 131 } | |
| 132 | |
| 133 if (!fOrigBitmap.hasMipMap()) { | |
| 134 | |
| 135 // STEP 2: DOWNSAMPLE | |
| 136 | |
| 137 // Check to see if the transformation matrix is scaling *down*. | |
| 138 // If so, automatically build mipmaps. | |
| 139 | |
| 140 SkPoint v1, v2; | |
| 141 | |
| 142 // conservatively estimate if the matrix is scaling down by seeing | |
| 143 // what its upper left 2x2 portion does to two unit vectors. | |
| 144 | |
| 145 v1.fX = fInvMatrix.getScaleX(); | |
| 146 v1.fY = fInvMatrix.getSkewY(); | |
| 147 | |
| 148 v2.fX = fInvMatrix.getSkewX(); | |
| 149 v2.fY = fInvMatrix.getScaleY(); | |
| 150 | |
| 151 if (v1.fX * v1.fX + v1.fY * v1.fY > 1 || | |
| 152 v2.fX * v2.fX + v2.fY * v2.fY > 1) { | |
| 153 fOrigBitmap.buildMipMap(); | |
| 154 | |
| 155 // Now that we've built the mipmaps and we know we're downsampling, | |
| 156 // downgrade to bilinear interpolation for the mip level. | |
| 157 | |
| 158 fFilterQuality = kBilerp_BitmapFilter; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 if (fOrigBitmap.hasMipMap()) { | |
| 163 | |
| 164 // STEP 3: We've got mipmaps, let's choose the closest level as our rend er | |
| 165 // source and adjust the matrix accordingly. | |
| 166 | |
| 167 int shift = fOrigBitmap.extractMipLevel(&fScaledBitmap, | |
| 168 SkScalarToFixed(fInvMatrix.getSc aleX()), | |
| 169 SkScalarToFixed(fInvMatrix.getSk ewY())); | |
| 170 | |
| 171 if (shift > 0) { | |
| 172 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift); | |
| 173 fInvMatrix.postScale(scale, scale); | |
| 174 fBitmap = &fScaledBitmap; | |
| 175 } | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 void SkBitmapProcState::endContext() { | |
| 180 SkDELETE(fBitmapFilter); | |
| 181 } | |
| 182 | |
| 93 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { | 183 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { |
| 94 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) { | 184 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) { |
| 95 return false; | 185 return false; |
| 96 } | 186 } |
| 97 | 187 |
|
robertphillips
2013/07/12 19:42:31
trivialMatrix
humper
2013/07/12 21:12:03
Done.
| |
| 98 const SkMatrix* m; | |
| 99 bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0; | 188 bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0; |
|
robertphillips
2013/07/12 19:42:31
clampClamp
humper
2013/07/12 21:12:03
Done.
| |
| 100 bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX && | 189 bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX && |
| 101 SkShader::kClamp_TileMode == fTileModeY; | 190 SkShader::kClamp_TileMode == fTileModeY; |
| 102 | 191 |
| 103 if (clamp_clamp || trivial_matrix) { | 192 fInvMatrix = inv; |
| 104 m = &inv; | 193 if (!(clamp_clamp || trivial_matrix)) { |
| 105 } else { | 194 fInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); |
| 106 fUnitInvMatrix = inv; | |
| 107 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); | |
| 108 m = &fUnitInvMatrix; | |
| 109 } | 195 } |
| 110 | 196 |
| 111 fBitmap = &fOrigBitmap; | 197 fBitmap = &fOrigBitmap; |
| 112 if (fOrigBitmap.hasMipMap()) { | 198 |
| 113 int shift = fOrigBitmap.extractMipLevel(&fMipBitmap, | 199 // initialize our filter quality to the one requested by the caller. |
| 114 SkScalarToFixed(m->getScaleX()), | 200 // We may downgrade it later if we determine that we either don't need |
| 115 SkScalarToFixed(m->getSkewY())); | 201 // or can't provide as high a quality filtering as the user requested. |
| 116 | 202 |
| 117 if (shift > 0) { | 203 fFilterQuality = kNone_BitmapFilter; |
| 118 if (m != &fUnitInvMatrix) { | 204 if (paint.isFilterBitmap()) { |
| 119 fUnitInvMatrix = *m; | 205 if (paint.getFlags() & SkPaint::kHighQualityFilterBitmap_Flag) { |
| 120 m = &fUnitInvMatrix; | 206 fFilterQuality = kHQ_BitmapFilter; |
| 121 } | 207 } else { |
| 122 | 208 fFilterQuality = kBilerp_BitmapFilter; |
| 123 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift); | 209 } |
| 124 fUnitInvMatrix.postScale(scale, scale); | 210 } |
| 125 | 211 |
| 126 // now point here instead of fOrigBitmap | 212 // possiblyScaleImage will look to see if it can rescale the image as a |
| 127 fBitmap = &fMipBitmap; | 213 // preprocess; either by scaling up to the target size, or by selecting |
| 128 } | 214 // a nearby mipmap level. If it does, it will adjust the working |
| 129 } | 215 // matrix as well as the working bitmap. It may also adjust the filter |
| 130 | 216 // quality to avoid re-filtering an already perfectly scaled image. |
| 131 // wack our matrix to exactly no-scale, if we're really close to begin with | 217 |
| 132 if (matrix_only_scale_translate(*m)) { | 218 this->possiblyScaleImage(); |
| 219 | |
| 220 // Now that all possible changes to the matrix have taken place, check | |
| 221 // to see if we're really close to a no-scale matrix. If so, explicitly | |
| 222 // set it to be so. Subsequent code may inspect this matrix to choose | |
| 223 // a faster path in this case. | |
| 224 | |
| 225 // This code will only execute if the matrix has some scale component; | |
| 226 // if it's already pure translate then we won't do this inversion. | |
| 227 | |
| 228 if (matrix_only_scale_translate(fInvMatrix)) { | |
| 133 SkMatrix forward; | 229 SkMatrix forward; |
| 134 if (m->invert(&forward)) { | 230 if (fInvMatrix.invert(&forward)) { |
| 135 if (clamp_clamp ? just_trans_clamp(forward, *fBitmap) | 231 if (clamp_clamp ? just_trans_clamp(forward, *fBitmap) |
| 136 : just_trans_general(forward)) { | 232 : just_trans_general(forward)) { |
| 137 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX()); | 233 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX()); |
| 138 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY()); | 234 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY()); |
| 139 fUnitInvMatrix.setTranslate(tx, ty); | 235 fInvMatrix.setTranslate(tx, ty); |
| 140 m = &fUnitInvMatrix; | 236 |
| 141 // now the following code will sniff m, and decide to take the | |
| 142 // fast case (since m is purely translate). | |
| 143 } | 237 } |
| 144 } | 238 } |
| 145 } | 239 } |
| 146 | 240 |
| 147 // Below this point, we should never refer to the inv parameter, since we | 241 fInvProc = fInvMatrix.getMapXYProc(); |
| 148 // may be using a munged version for "our" inverse. | 242 fInvType = fInvMatrix.getType(); |
| 149 | 243 fInvSx = SkScalarToFixed(fInvMatrix.getScaleX()); |
| 150 fInvMatrix = m; | 244 fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix.getScaleX()); |
| 151 fInvProc = m->getMapXYProc(); | 245 fInvKy = SkScalarToFixed(fInvMatrix.getSkewY()); |
| 152 fInvType = m->getType(); | 246 fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix.getSkewY()); |
| 153 fInvSx = SkScalarToFixed(m->getScaleX()); | |
| 154 fInvSxFractionalInt = SkScalarToFractionalInt(m->getScaleX()); | |
| 155 fInvKy = SkScalarToFixed(m->getSkewY()); | |
| 156 fInvKyFractionalInt = SkScalarToFractionalInt(m->getSkewY()); | |
| 157 | 247 |
| 158 fAlphaScale = SkAlpha255To256(paint.getAlpha()); | 248 fAlphaScale = SkAlpha255To256(paint.getAlpha()); |
| 159 | 249 |
| 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; | 250 fShaderProc32 = NULL; |
| 170 fShaderProc16 = NULL; | 251 fShaderProc16 = NULL; |
| 171 fSampleProc32 = NULL; | 252 fSampleProc32 = NULL; |
| 172 fSampleProc16 = NULL; | 253 fSampleProc16 = NULL; |
| 173 | 254 |
| 255 if (kHQ_BitmapFilter == fFilterQuality) { | |
| 256 // If this is still set, that means we wanted HQ sampling | |
| 257 // but couldn't do it as a preprocess. Let's try to install | |
| 258 // the scanline version of the HQ sampler. If that process fails, | |
| 259 // downgrade to bilerp. | |
| 260 | |
| 261 // NOTE: Might need to be careful here in the future when we want | |
| 262 // to have the platform proc have a shot at this; it's possible that | |
| 263 // the chooseBitmapFilterProc will fail to install a shader but a | |
| 264 // platform-specific one might succeed, so it might be premature here | |
| 265 // to fall back to bilerp. This needs thought. | |
| 266 | |
| 267 SkASSERT(fInvType > SkMatrix::kTranslateMask); | |
| 268 | |
| 269 fShaderProc32 = this->chooseBitmapFilterProc(); | |
| 270 if (!fShaderProc32) { | |
| 271 fFilterQuality = kBilerp_BitmapFilter; | |
| 272 } | |
| 273 } | |
| 274 | |
| 275 if (kBilerp_BitmapFilter == fFilterQuality) { | |
| 276 // Only try bilerp if the matrix is "interesting" and | |
| 277 // the image has a suitable size. | |
| 278 | |
| 279 if (fInvType < SkMatrix::kTranslate_Mask || | |
| 280 !valid_for_filtering(fBitmap->width() | fBitmap->height())) { | |
| 281 fFilterQuality = kNone_BitmapFilter; | |
| 282 } | |
| 283 } | |
| 284 | |
| 285 // At this point, we know exactly what kind of sampling the per-scanline | |
| 286 // shader will perform. | |
| 287 | |
| 174 fMatrixProc = this->chooseMatrixProc(trivial_matrix); | 288 fMatrixProc = this->chooseMatrixProc(trivial_matrix); |
| 175 if (NULL == fMatrixProc) { | 289 if (NULL == fMatrixProc) { |
| 176 return false; | 290 return false; |
| 177 } | 291 } |
| 178 | 292 |
| 179 /////////////////////////////////////////////////////////////////////// | 293 /////////////////////////////////////////////////////////////////////// |
| 180 | 294 |
| 181 int index = 0; | 295 // 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 | 296 // still set to HQ by the time we get here, then we must have installed |
| 183 index |= 1; | 297 // 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 | 298 |
| 213 #if !SK_ARM_NEON_IS_ALWAYS | 299 if (fFilterQuality < kHQ_BitmapFilter) { |
| 214 static const SampleProc32 gSkBitmapProcStateSample32[] = { | 300 |
| 215 S32_opaque_D32_nofilter_DXDY, | 301 int index = 0; |
| 216 S32_alpha_D32_nofilter_DXDY, | 302 if (fAlphaScale < 256) { // note: this distinction is not used for D16 |
| 217 S32_opaque_D32_nofilter_DX, | 303 index |= 1; |
| 218 S32_alpha_D32_nofilter_DX, | 304 } |
| 219 S32_opaque_D32_filter_DXDY, | 305 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { |
| 220 S32_alpha_D32_filter_DXDY, | 306 index |= 2; |
| 221 S32_opaque_D32_filter_DX, | 307 } |
| 222 S32_alpha_D32_filter_DX, | 308 if (fFilterQuality != kNone_BitmapFilter) { |
| 309 index |= 4; | |
| 310 } | |
| 311 // bits 3,4,5 encoding the source bitmap format | |
| 312 switch (fBitmap->config()) { | |
| 313 case SkBitmap::kARGB_8888_Config: | |
| 314 index |= 0; | |
| 315 break; | |
| 316 case SkBitmap::kRGB_565_Config: | |
| 317 index |= 8; | |
| 318 break; | |
| 319 case SkBitmap::kIndex8_Config: | |
| 320 index |= 16; | |
| 321 break; | |
| 322 case SkBitmap::kARGB_4444_Config: | |
| 323 index |= 24; | |
| 324 break; | |
| 325 case SkBitmap::kA8_Config: | |
| 326 index |= 32; | |
| 327 fPaintPMColor = SkPreMultiplyColor(paint.getColor()); | |
| 328 break; | |
| 329 default: | |
| 330 return false; | |
| 331 } | |
| 223 | 332 |
| 224 S16_opaque_D32_nofilter_DXDY, | 333 #if !SK_ARM_NEON_IS_ALWAYS |
| 225 S16_alpha_D32_nofilter_DXDY, | 334 static const SampleProc32 gSkBitmapProcStateSample32[] = { |
| 226 S16_opaque_D32_nofilter_DX, | 335 S32_opaque_D32_nofilter_DXDY, |
| 227 S16_alpha_D32_nofilter_DX, | 336 S32_alpha_D32_nofilter_DXDY, |
| 228 S16_opaque_D32_filter_DXDY, | 337 S32_opaque_D32_nofilter_DX, |
| 229 S16_alpha_D32_filter_DXDY, | 338 S32_alpha_D32_nofilter_DX, |
| 230 S16_opaque_D32_filter_DX, | 339 S32_opaque_D32_filter_DXDY, |
| 231 S16_alpha_D32_filter_DX, | 340 S32_alpha_D32_filter_DXDY, |
| 341 S32_opaque_D32_filter_DX, | |
| 342 S32_alpha_D32_filter_DX, | |
| 232 | 343 |
| 233 SI8_opaque_D32_nofilter_DXDY, | 344 S16_opaque_D32_nofilter_DXDY, |
| 234 SI8_alpha_D32_nofilter_DXDY, | 345 S16_alpha_D32_nofilter_DXDY, |
| 235 SI8_opaque_D32_nofilter_DX, | 346 S16_opaque_D32_nofilter_DX, |
| 236 SI8_alpha_D32_nofilter_DX, | 347 S16_alpha_D32_nofilter_DX, |
| 237 SI8_opaque_D32_filter_DXDY, | 348 S16_opaque_D32_filter_DXDY, |
| 238 SI8_alpha_D32_filter_DXDY, | 349 S16_alpha_D32_filter_DXDY, |
| 239 SI8_opaque_D32_filter_DX, | 350 S16_opaque_D32_filter_DX, |
| 240 SI8_alpha_D32_filter_DX, | 351 S16_alpha_D32_filter_DX, |
| 241 | 352 |
| 242 S4444_opaque_D32_nofilter_DXDY, | 353 SI8_opaque_D32_nofilter_DXDY, |
| 243 S4444_alpha_D32_nofilter_DXDY, | 354 SI8_alpha_D32_nofilter_DXDY, |
| 244 S4444_opaque_D32_nofilter_DX, | 355 SI8_opaque_D32_nofilter_DX, |
| 245 S4444_alpha_D32_nofilter_DX, | 356 SI8_alpha_D32_nofilter_DX, |
| 246 S4444_opaque_D32_filter_DXDY, | 357 SI8_opaque_D32_filter_DXDY, |
| 247 S4444_alpha_D32_filter_DXDY, | 358 SI8_alpha_D32_filter_DXDY, |
| 248 S4444_opaque_D32_filter_DX, | 359 SI8_opaque_D32_filter_DX, |
| 249 S4444_alpha_D32_filter_DX, | 360 SI8_alpha_D32_filter_DX, |
| 250 | 361 |
| 251 // A8 treats alpha/opaque the same (equally efficient) | 362 S4444_opaque_D32_nofilter_DXDY, |
| 252 SA8_alpha_D32_nofilter_DXDY, | 363 S4444_alpha_D32_nofilter_DXDY, |
| 253 SA8_alpha_D32_nofilter_DXDY, | 364 S4444_opaque_D32_nofilter_DX, |
| 254 SA8_alpha_D32_nofilter_DX, | 365 S4444_alpha_D32_nofilter_DX, |
| 255 SA8_alpha_D32_nofilter_DX, | 366 S4444_opaque_D32_filter_DXDY, |
| 256 SA8_alpha_D32_filter_DXDY, | 367 S4444_alpha_D32_filter_DXDY, |
| 257 SA8_alpha_D32_filter_DXDY, | 368 S4444_opaque_D32_filter_DX, |
| 258 SA8_alpha_D32_filter_DX, | 369 S4444_alpha_D32_filter_DX, |
| 259 SA8_alpha_D32_filter_DX | |
| 260 }; | |
| 261 | 370 |
| 262 static const SampleProc16 gSkBitmapProcStateSample16[] = { | 371 // A8 treats alpha/opaque the same (equally efficient) |
| 263 S32_D16_nofilter_DXDY, | 372 SA8_alpha_D32_nofilter_DXDY, |
| 264 S32_D16_nofilter_DX, | 373 SA8_alpha_D32_nofilter_DXDY, |
| 265 S32_D16_filter_DXDY, | 374 SA8_alpha_D32_nofilter_DX, |
| 266 S32_D16_filter_DX, | 375 SA8_alpha_D32_nofilter_DX, |
| 376 SA8_alpha_D32_filter_DXDY, | |
| 377 SA8_alpha_D32_filter_DXDY, | |
| 378 SA8_alpha_D32_filter_DX, | |
| 379 SA8_alpha_D32_filter_DX | |
| 380 }; | |
| 267 | 381 |
| 268 S16_D16_nofilter_DXDY, | 382 static const SampleProc16 gSkBitmapProcStateSample16[] = { |
| 269 S16_D16_nofilter_DX, | 383 S32_D16_nofilter_DXDY, |
| 270 S16_D16_filter_DXDY, | 384 S32_D16_nofilter_DX, |
| 271 S16_D16_filter_DX, | 385 S32_D16_filter_DXDY, |
| 386 S32_D16_filter_DX, | |
| 272 | 387 |
| 273 SI8_D16_nofilter_DXDY, | 388 S16_D16_nofilter_DXDY, |
| 274 SI8_D16_nofilter_DX, | 389 S16_D16_nofilter_DX, |
| 275 SI8_D16_filter_DXDY, | 390 S16_D16_filter_DXDY, |
| 276 SI8_D16_filter_DX, | 391 S16_D16_filter_DX, |
| 277 | 392 |
| 278 // Don't support 4444 -> 565 | 393 SI8_D16_nofilter_DXDY, |
| 279 NULL, NULL, NULL, NULL, | 394 SI8_D16_nofilter_DX, |
| 280 // Don't support A8 -> 565 | 395 SI8_D16_filter_DXDY, |
| 281 NULL, NULL, NULL, NULL | 396 SI8_D16_filter_DX, |
| 282 }; | |
| 283 #endif | |
| 284 | 397 |
| 285 fSampleProc32 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample32)[index]; | 398 // Don't support 4444 -> 565 |
| 286 index >>= 1; // shift away any opaque/alpha distinction | 399 NULL, NULL, NULL, NULL, |
| 287 fSampleProc16 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample16)[index]; | 400 // Don't support A8 -> 565 |
| 401 NULL, NULL, NULL, NULL | |
| 402 }; | |
| 403 #endif | |
| 288 | 404 |
| 289 // our special-case shaderprocs | 405 fSampleProc32 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample32)[index]; |
| 290 if (SK_ARM_NEON_WRAP(S16_D16_filter_DX) == fSampleProc16) { | 406 index >>= 1; // shift away any opaque/alpha distinction |
| 291 if (clamp_clamp) { | 407 fSampleProc16 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample16)[index]; |
| 292 fShaderProc16 = SK_ARM_NEON_WRAP(Clamp_S16_D16_filter_DX_shaderproc) ; | 408 |
| 293 } else if (SkShader::kRepeat_TileMode == fTileModeX && | 409 // our special-case shaderprocs |
| 294 SkShader::kRepeat_TileMode == fTileModeY) { | 410 if (SK_ARM_NEON_WRAP(S16_D16_filter_DX) == fSampleProc16) { |
| 295 fShaderProc16 = SK_ARM_NEON_WRAP(Repeat_S16_D16_filter_DX_shaderproc ); | 411 if (clamp_clamp) { |
| 412 fShaderProc16 = SK_ARM_NEON_WRAP(Clamp_S16_D16_filter_DX_shaderp roc); | |
| 413 } else if (SkShader::kRepeat_TileMode == fTileModeX && | |
| 414 SkShader::kRepeat_TileMode == fTileModeY) { | |
| 415 fShaderProc16 = SK_ARM_NEON_WRAP(Repeat_S16_D16_filter_DX_shader proc); | |
| 416 } | |
| 417 } else if (SK_ARM_NEON_WRAP(SI8_opaque_D32_filter_DX) == fSampleProc32 & & clamp_clamp) { | |
| 418 fShaderProc32 = SK_ARM_NEON_WRAP(Clamp_SI8_opaque_D32_filter_DX_shad erproc); | |
| 296 } | 419 } |
| 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 | 420 |
| 301 if (NULL == fShaderProc32) { | 421 if (NULL == fShaderProc32) { |
| 302 fShaderProc32 = this->chooseShaderProc32(); | 422 fShaderProc32 = this->chooseShaderProc32(); |
| 303 } | 423 } |
| 304 | |
| 305 if (NULL == fShaderProc32) { | |
| 306 fShaderProc32 = this->chooseBitmapFilterProc(paint); | |
| 307 } | 424 } |
| 308 | 425 |
| 309 // see if our platform has any accelerated overrides | 426 // see if our platform has any accelerated overrides |
| 310 this->platformProcs(); | 427 this->platformProcs(); |
| 311 | 428 |
| 312 return true; | 429 return true; |
| 313 } | 430 } |
| 314 | 431 |
| 315 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, | 432 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, |
| 316 int x, int y, | 433 int x, int y, |
| 317 SkPMColor* SK_RESTRICT color s, | 434 SkPMColor* SK_RESTRICT color s, |
| 318 int count) { | 435 int count) { |
| 319 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); | 436 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); |
| 320 SkASSERT(s.fInvKy == 0); | 437 SkASSERT(s.fInvKy == 0); |
| 321 SkASSERT(count > 0 && colors != NULL); | 438 SkASSERT(count > 0 && colors != NULL); |
| 322 SkASSERT(!s.fDoFilter); | 439 SkASSERT(SkBitmapProcState::kNone_BitmapFilter == s.fFilterQuality); |
| 323 | 440 |
| 324 const int maxX = s.fBitmap->width() - 1; | 441 const int maxX = s.fBitmap->width() - 1; |
| 325 const int maxY = s.fBitmap->height() - 1; | 442 const int maxY = s.fBitmap->height() - 1; |
| 326 int ix = s.fFilterOneX + x; | 443 int ix = s.fFilterOneX + x; |
| 327 int iy = SkClampMax(s.fFilterOneY + y, maxY); | 444 int iy = SkClampMax(s.fFilterOneY + y, maxY); |
| 328 #ifdef SK_DEBUG | 445 #ifdef SK_DEBUG |
| 329 { | 446 { |
| 330 SkPoint pt; | 447 SkPoint pt; |
| 331 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, | 448 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, |
| 332 SkIntToScalar(y) + SK_ScalarHalf, &pt); | 449 SkIntToScalar(y) + SK_ScalarHalf, &pt); |
| 333 int iy2 = SkClampMax(SkScalarFloorToInt(pt.fY), maxY); | 450 int iy2 = SkClampMax(SkScalarFloorToInt(pt.fY), maxY); |
| 334 int ix2 = SkScalarFloorToInt(pt.fX); | 451 int ix2 = SkScalarFloorToInt(pt.fX); |
| 335 | 452 |
| 336 SkASSERT(iy == iy2); | 453 SkASSERT(iy == iy2); |
| 337 SkASSERT(ix == ix2); | 454 SkASSERT(ix == ix2); |
| 338 } | 455 } |
| 339 #endif | 456 #endif |
| 340 const SkPMColor* row = s.fBitmap->getAddr32(0, iy); | 457 const SkPMColor* row = s.fBitmap->getAddr32(0, iy); |
| 341 | 458 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 return x; | 503 return x; |
| 387 } | 504 } |
| 388 | 505 |
| 389 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, | 506 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, |
| 390 int x, int y, | 507 int x, int y, |
| 391 SkPMColor* SK_RESTRICT colo rs, | 508 SkPMColor* SK_RESTRICT colo rs, |
| 392 int count) { | 509 int count) { |
| 393 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); | 510 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); |
| 394 SkASSERT(s.fInvKy == 0); | 511 SkASSERT(s.fInvKy == 0); |
| 395 SkASSERT(count > 0 && colors != NULL); | 512 SkASSERT(count > 0 && colors != NULL); |
| 396 SkASSERT(!s.fDoFilter); | 513 SkASSERT(SkBitmapProcState::kNone_BitmapFilter == s.fFilterQuality); |
| 397 | 514 |
| 398 const int stopX = s.fBitmap->width(); | 515 const int stopX = s.fBitmap->width(); |
| 399 const int stopY = s.fBitmap->height(); | 516 const int stopY = s.fBitmap->height(); |
| 400 int ix = s.fFilterOneX + x; | 517 int ix = s.fFilterOneX + x; |
| 401 int iy = sk_int_mod(s.fFilterOneY + y, stopY); | 518 int iy = sk_int_mod(s.fFilterOneY + y, stopY); |
| 402 #ifdef SK_DEBUG | 519 #ifdef SK_DEBUG |
| 403 { | 520 { |
| 404 SkPoint pt; | 521 SkPoint pt; |
| 405 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, | 522 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, |
| 406 SkIntToScalar(y) + SK_ScalarHalf, &pt); | 523 SkIntToScalar(y) + SK_ScalarHalf, &pt); |
| 407 int iy2 = sk_int_mod(SkScalarFloorToInt(pt.fY), stopY); | 524 int iy2 = sk_int_mod(SkScalarFloorToInt(pt.fY), stopY); |
| 408 int ix2 = SkScalarFloorToInt(pt.fX); | 525 int ix2 = SkScalarFloorToInt(pt.fX); |
| 409 | 526 |
| 410 SkASSERT(iy == iy2); | 527 SkASSERT(iy == iy2); |
| 411 SkASSERT(ix == ix2); | 528 SkASSERT(ix == ix2); |
| 412 } | 529 } |
| 413 #endif | 530 #endif |
| 414 const SkPMColor* row = s.fBitmap->getAddr32(0, iy); | 531 const SkPMColor* row = s.fBitmap->getAddr32(0, iy); |
| 415 | 532 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 432 int count) { | 549 int count) { |
| 433 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0); | 550 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0); |
| 434 SkASSERT(s.fInvKy == 0); | 551 SkASSERT(s.fInvKy == 0); |
| 435 SkASSERT(count > 0 && colors != NULL); | 552 SkASSERT(count > 0 && colors != NULL); |
| 436 SkASSERT(1 == s.fBitmap->width()); | 553 SkASSERT(1 == s.fBitmap->width()); |
| 437 | 554 |
| 438 int iY0; | 555 int iY0; |
| 439 int iY1 SK_INIT_TO_AVOID_WARNING; | 556 int iY1 SK_INIT_TO_AVOID_WARNING; |
| 440 int iSubY SK_INIT_TO_AVOID_WARNING; | 557 int iSubY SK_INIT_TO_AVOID_WARNING; |
| 441 | 558 |
| 442 if (s.fDoFilter) { | 559 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) { |
| 443 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); | 560 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); |
| 444 uint32_t xy[2]; | 561 uint32_t xy[2]; |
| 445 | 562 |
| 446 mproc(s, xy, 1, x, y); | 563 mproc(s, xy, 1, x, y); |
| 447 | 564 |
| 448 iY0 = xy[0] >> 18; | 565 iY0 = xy[0] >> 18; |
| 449 iY1 = xy[0] & 0x3FFF; | 566 iY1 = xy[0] & 0x3FFF; |
| 450 iSubY = (xy[0] >> 14) & 0xF; | 567 iSubY = (xy[0] >> 14) & 0xF; |
| 451 } else { | 568 } else { |
| 452 int yTemp; | 569 int yTemp; |
| 453 | 570 |
| 454 if (s.fInvType > SkMatrix::kTranslate_Mask) { | 571 if (s.fInvType > SkMatrix::kTranslate_Mask) { |
| 455 SkPoint pt; | 572 SkPoint pt; |
| 456 s.fInvProc(*s.fInvMatrix, | 573 s.fInvProc(s.fInvMatrix, |
| 457 SkIntToScalar(x) + SK_ScalarHalf, | 574 SkIntToScalar(x) + SK_ScalarHalf, |
| 458 SkIntToScalar(y) + SK_ScalarHalf, | 575 SkIntToScalar(y) + SK_ScalarHalf, |
| 459 &pt); | 576 &pt); |
| 460 // When the matrix has a scale component the setup code in | 577 // When the matrix has a scale component the setup code in |
| 461 // chooseProcs multiples the inverse matrix by the inverse of the | 578 // chooseProcs multiples the inverse matrix by the inverse of the |
| 462 // bitmap's width and height. Since this method is going to do | 579 // bitmap's width and height. Since this method is going to do |
| 463 // its own tiling and sampling we need to undo that here. | 580 // its own tiling and sampling we need to undo that here. |
| 464 if (SkShader::kClamp_TileMode != s.fTileModeX || | 581 if (SkShader::kClamp_TileMode != s.fTileModeX || |
| 465 SkShader::kClamp_TileMode != s.fTileModeY) { | 582 SkShader::kClamp_TileMode != s.fTileModeY) { |
| 466 yTemp = SkScalarFloorToInt(pt.fY * s.fBitmap->height()); | 583 yTemp = SkScalarFloorToInt(pt.fY * s.fBitmap->height()); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 481 break; | 598 break; |
| 482 case SkShader::kMirror_TileMode: | 599 case SkShader::kMirror_TileMode: |
| 483 default: | 600 default: |
| 484 iY0 = sk_int_mirror(yTemp, stopY); | 601 iY0 = sk_int_mirror(yTemp, stopY); |
| 485 break; | 602 break; |
| 486 } | 603 } |
| 487 | 604 |
| 488 #ifdef SK_DEBUG | 605 #ifdef SK_DEBUG |
| 489 { | 606 { |
| 490 SkPoint pt; | 607 SkPoint pt; |
| 491 s.fInvProc(*s.fInvMatrix, | 608 s.fInvProc(s.fInvMatrix, |
| 492 SkIntToScalar(x) + SK_ScalarHalf, | 609 SkIntToScalar(x) + SK_ScalarHalf, |
| 493 SkIntToScalar(y) + SK_ScalarHalf, | 610 SkIntToScalar(y) + SK_ScalarHalf, |
| 494 &pt); | 611 &pt); |
| 495 if (s.fInvType > SkMatrix::kTranslate_Mask && | 612 if (s.fInvType > SkMatrix::kTranslate_Mask && |
| 496 (SkShader::kClamp_TileMode != s.fTileModeX || | 613 (SkShader::kClamp_TileMode != s.fTileModeX || |
| 497 SkShader::kClamp_TileMode != s.fTileModeY)) { | 614 SkShader::kClamp_TileMode != s.fTileModeY)) { |
| 498 pt.fY *= s.fBitmap->height(); | 615 pt.fY *= s.fBitmap->height(); |
| 499 } | 616 } |
| 500 int iY2; | 617 int iY2; |
| 501 | 618 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 513 } | 630 } |
| 514 | 631 |
| 515 SkASSERT(iY0 == iY2); | 632 SkASSERT(iY0 == iY2); |
| 516 } | 633 } |
| 517 #endif | 634 #endif |
| 518 } | 635 } |
| 519 | 636 |
| 520 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0); | 637 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0); |
| 521 SkPMColor color; | 638 SkPMColor color; |
| 522 | 639 |
| 523 if (s.fDoFilter) { | 640 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) { |
| 524 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1); | 641 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1); |
| 525 | 642 |
| 526 if (s.fAlphaScale < 256) { | 643 if (s.fAlphaScale < 256) { |
| 527 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale); | 644 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale); |
| 528 } else { | 645 } else { |
| 529 Filter_32_opaque(iSubY, *row0, *row1, &color); | 646 Filter_32_opaque(iSubY, *row0, *row1, &color); |
| 530 } | 647 } |
| 531 } else { | 648 } else { |
| 532 if (s.fAlphaScale < 256) { | 649 if (s.fAlphaScale < 256) { |
| 533 color = SkAlphaMulQ(*row0, s.fAlphaScale); | 650 color = SkAlphaMulQ(*row0, s.fAlphaScale); |
| 534 } else { | 651 } else { |
| 535 color = *row0; | 652 color = *row0; |
| 536 } | 653 } |
| 537 } | 654 } |
| 538 | 655 |
| 539 sk_memset32(colors, color, count); | 656 sk_memset32(colors, color, count); |
| 540 } | 657 } |
| 541 | 658 |
| 542 static void DoNothing_shaderproc(const SkBitmapProcState&, int x, int y, | 659 static void DoNothing_shaderproc(const SkBitmapProcState&, int x, int y, |
| 543 SkPMColor* SK_RESTRICT colors, int count) { | 660 SkPMColor* SK_RESTRICT colors, int count) { |
| 544 // if we get called, the matrix is too tricky, so we just draw nothing | 661 // if we get called, the matrix is too tricky, so we just draw nothing |
| 545 sk_memset32(colors, 0, count); | 662 sk_memset32(colors, 0, count); |
| 546 } | 663 } |
| 547 | 664 |
| 548 bool SkBitmapProcState::setupForTranslate() { | 665 bool SkBitmapProcState::setupForTranslate() { |
| 549 SkPoint pt; | 666 SkPoint pt; |
| 550 fInvProc(*fInvMatrix, SK_ScalarHalf, SK_ScalarHalf, &pt); | 667 fInvProc(fInvMatrix, SK_ScalarHalf, SK_ScalarHalf, &pt); |
| 551 | 668 |
| 552 /* | 669 /* |
| 553 * if the translate is larger than our ints, we can get random results, or | 670 * if the translate is larger than our ints, we can get random results, or |
| 554 * worse, we might get 0x80000000, which wreaks havoc on us, since we can't | 671 * worse, we might get 0x80000000, which wreaks havoc on us, since we can't |
| 555 * negate it. | 672 * negate it. |
| 556 */ | 673 */ |
| 557 const SkScalar too_big = SkIntToScalar(1 << 30); | 674 const SkScalar too_big = SkIntToScalar(1 << 30); |
| 558 if (SkScalarAbs(pt.fX) > too_big || SkScalarAbs(pt.fY) > too_big) { | 675 if (SkScalarAbs(pt.fX) > too_big || SkScalarAbs(pt.fY) > too_big) { |
| 559 return false; | 676 return false; |
| 560 } | 677 } |
| 561 | 678 |
| 562 // Since we know we're not filtered, we re-purpose these fields allow | 679 // Since we know we're not filtered, we re-purpose these fields allow |
| 563 // us to go from device -> src coordinates w/ just an integer add, | 680 // us to go from device -> src coordinates w/ just an integer add, |
| 564 // rather than running through the inverse-matrix | 681 // rather than running through the inverse-matrix |
| 565 fFilterOneX = SkScalarFloorToInt(pt.fX); | 682 fFilterOneX = SkScalarFloorToInt(pt.fX); |
| 566 fFilterOneY = SkScalarFloorToInt(pt.fY); | 683 fFilterOneY = SkScalarFloorToInt(pt.fY); |
| 567 return true; | 684 return true; |
| 568 } | 685 } |
| 569 | 686 |
| 570 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { | 687 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { |
| 571 | 688 |
| 572 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) { | 689 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) { |
| 573 return NULL; | 690 return NULL; |
| 574 } | 691 } |
| 575 | 692 |
| 576 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask; | 693 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask; |
| 577 | 694 |
| 578 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) { | 695 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) { |
| 579 if (!fDoFilter && fInvType <= SkMatrix::kTranslate_Mask && !this->setupF orTranslate()) { | 696 if (kNone_BitmapFilter == fFilterQuality && |
| 697 fInvType <= SkMatrix::kTranslate_Mask && | |
| 698 !this->setupForTranslate()) { | |
| 580 return DoNothing_shaderproc; | 699 return DoNothing_shaderproc; |
| 581 } | 700 } |
| 582 return S32_D32_constX_shaderproc; | 701 return S32_D32_constX_shaderproc; |
| 583 } | 702 } |
| 584 | 703 |
| 585 if (fAlphaScale < 256) { | 704 if (fAlphaScale < 256) { |
| 586 return NULL; | 705 return NULL; |
| 587 } | 706 } |
| 588 if (fInvType > SkMatrix::kTranslate_Mask) { | 707 if (fInvType > SkMatrix::kTranslate_Mask) { |
| 589 return NULL; | 708 return NULL; |
| 590 } | 709 } |
| 591 if (fDoFilter) { | 710 if (fFilterQuality != kNone_BitmapFilter) { |
| 592 return NULL; | 711 return NULL; |
| 593 } | 712 } |
| 594 | 713 |
| 595 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX; | 714 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX; |
| 596 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY; | 715 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY; |
| 597 | 716 |
| 598 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) { | 717 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) { |
| 599 if (this->setupForTranslate()) { | 718 if (this->setupForTranslate()) { |
| 600 return Clamp_S32_D32_nofilter_trans_shaderproc; | 719 return Clamp_S32_D32_nofilter_trans_shaderproc; |
| 601 } | 720 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 677 SkASSERT(count > 0); | 796 SkASSERT(count > 0); |
| 678 | 797 |
| 679 state.fMatrixProc(state, bitmapXY, count, x, y); | 798 state.fMatrixProc(state, bitmapXY, count, x, y); |
| 680 | 799 |
| 681 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my); | 800 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my); |
| 682 | 801 |
| 683 // There are four formats possible: | 802 // There are four formats possible: |
| 684 // scale -vs- affine | 803 // scale -vs- affine |
| 685 // filter -vs- nofilter | 804 // filter -vs- nofilter |
| 686 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { | 805 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { |
| 687 proc = state.fDoFilter ? check_scale_filter : check_scale_nofilter; | 806 proc = state.fFilterQuality != kNone_BitmapFilter ? check_scale_filter : check_scale_nofilter; |
| 688 } else { | 807 } else { |
| 689 proc = state.fDoFilter ? check_affine_filter : check_affine_nofilter; | 808 proc = state.fFilterQuality != kNone_BitmapFilter ? check_affine_filter : check_affine_nofilter; |
| 690 } | 809 } |
| 691 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height()); | 810 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height()); |
| 692 } | 811 } |
| 693 | 812 |
| 694 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const { | 813 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const { |
| 695 return DebugMatrixProc; | 814 return DebugMatrixProc; |
| 696 } | 815 } |
| 697 | 816 |
| 698 #endif | 817 #endif |
| 699 | 818 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 714 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { | 833 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { |
| 715 size -= 4; // the shared Y (or YY) coordinate | 834 size -= 4; // the shared Y (or YY) coordinate |
| 716 if (size < 0) { | 835 if (size < 0) { |
| 717 size = 0; | 836 size = 0; |
| 718 } | 837 } |
| 719 size >>= 1; | 838 size >>= 1; |
| 720 } else { | 839 } else { |
| 721 size >>= 2; | 840 size >>= 2; |
| 722 } | 841 } |
| 723 | 842 |
| 724 if (fDoFilter) { | 843 if (fFilterQuality != kNone_BitmapFilter) { |
| 725 size >>= 1; | 844 size >>= 1; |
| 726 } | 845 } |
| 727 | 846 |
| 728 return size; | 847 return size; |
| 729 } | 848 } |
| OLD | NEW |