OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBitmapCache.h" | 8 #include "SkBitmapCache.h" |
9 #include "SkBitmapProcState.h" | 9 #include "SkBitmapProcState.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 < (maximumAllocation * invMat.getScaleX() * invMat.getScaleY()); | 124 < (maximumAllocation * invMat.getScaleX() * invMat.getScaleY()); |
125 } | 125 } |
126 | 126 |
127 // TODO -- we may want to pass the clip into this function so we only scale | 127 // TODO -- we may want to pass the clip into this function so we only scale |
128 // the portion of the image that we're going to need. This will complicate | 128 // the portion of the image that we're going to need. This will complicate |
129 // the interface to the cache, but might be well worth it. | 129 // the interface to the cache, but might be well worth it. |
130 | 130 |
131 bool SkBitmapProcState::possiblyScaleImage() { | 131 bool SkBitmapProcState::possiblyScaleImage() { |
132 SkASSERT(NULL == fBitmap); | 132 SkASSERT(NULL == fBitmap); |
133 | 133 |
134 fAdjustedMatrix = false; | |
135 | |
136 if (fFilterLevel <= SkPaint::kLow_FilterLevel) { | 134 if (fFilterLevel <= SkPaint::kLow_FilterLevel) { |
137 return false; | 135 return false; |
138 } | 136 } |
139 // 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 |
140 // 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 |
141 // remove the (non-fractional) scaling component from the matrix. | 139 // remove the (non-fractional) scaling component from the matrix. |
142 | 140 |
143 SkScalar invScaleX = fInvMatrix.getScaleX(); | 141 SkScalar invScaleX = fInvMatrix.getScaleX(); |
144 SkScalar invScaleY = fInvMatrix.getScaleY(); | 142 SkScalar invScaleY = fInvMatrix.getScaleY(); |
145 | 143 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 } | 189 } |
192 | 190 |
193 SkASSERT(fScaledBitmap.getPixels()); | 191 SkASSERT(fScaledBitmap.getPixels()); |
194 fScaledBitmap.setImmutable(); | 192 fScaledBitmap.setImmutable(); |
195 SkBitmapCache::Add(fOrigBitmap, roundedDestWidth, roundedDestHeight,
fScaledBitmap); | 193 SkBitmapCache::Add(fOrigBitmap, roundedDestWidth, roundedDestHeight,
fScaledBitmap); |
196 } | 194 } |
197 | 195 |
198 SkASSERT(fScaledBitmap.getPixels()); | 196 SkASSERT(fScaledBitmap.getPixels()); |
199 fBitmap = &fScaledBitmap; | 197 fBitmap = &fScaledBitmap; |
200 | 198 |
201 // set the inv matrix type to translate-only; | 199 // clean up the inverse matrix by incorporating the scale we just perfor
med. |
202 fInvMatrix.setTranslate(fInvMatrix.getTranslateX() / fInvMatrix.getScale
X(), | |
203 fInvMatrix.getTranslateY() / fInvMatrix.getScale
Y()); | |
204 | 200 |
205 #ifndef SK_IGNORE_PROPER_FRACTIONAL_SCALING | 201 fInvMatrix.postScale(roundedDestWidth / fOrigBitmap.width(), |
206 // reintroduce any fractional scaling missed by our integral scale done
above. | 202 roundedDestHeight / fOrigBitmap.height()); |
207 | |
208 float fractionalScaleX = roundedDestWidth/trueDestWidth; | |
209 float fractionalScaleY = roundedDestHeight/trueDestHeight; | |
210 | |
211 fInvMatrix.postScale(fractionalScaleX, fractionalScaleY); | |
212 #endif | |
213 fAdjustedMatrix = true; | |
214 | 203 |
215 // Set our filter level to low -- the only post-filtering this | 204 // Set our filter level to low -- the only post-filtering this |
216 // image might require is some interpolation if the translation | 205 // image might require is some interpolation if the translation |
217 // is fractional or if there's any remaining scaling to be done. | 206 // is fractional or if there's any remaining scaling to be done. |
218 fFilterLevel = SkPaint::kLow_FilterLevel; | 207 fFilterLevel = SkPaint::kLow_FilterLevel; |
219 return true; | 208 return true; |
220 } | 209 } |
221 | 210 |
222 /* | 211 /* |
223 * If High, then our special-case for scale-only did not take, and so we | 212 * If High, then our special-case for scale-only did not take, and so we |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 // If we are "still" kMedium_FilterLevel, then the request was not fulfilled
by possiblyScale, | 356 // If we are "still" kMedium_FilterLevel, then the request was not fulfilled
by possiblyScale, |
368 // so we downgrade to kLow (so the rest of the sniffing code can assume that
) | 357 // so we downgrade to kLow (so the rest of the sniffing code can assume that
) |
369 if (SkPaint::kMedium_FilterLevel == fFilterLevel) { | 358 if (SkPaint::kMedium_FilterLevel == fFilterLevel) { |
370 fFilterLevel = SkPaint::kLow_FilterLevel; | 359 fFilterLevel = SkPaint::kLow_FilterLevel; |
371 } | 360 } |
372 | 361 |
373 bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) ==
0; | 362 bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) ==
0; |
374 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && | 363 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && |
375 SkShader::kClamp_TileMode == fTileModeY; | 364 SkShader::kClamp_TileMode == fTileModeY; |
376 | 365 |
377 if (!(fAdjustedMatrix || clampClamp || trivialMatrix)) { | 366 // Most of the scanline procs deal with "unit" texture coordinates, as this |
378 fInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); | 367 // makes it easy to perform tiling modes (repeat = (x & 0xFFFF)). To generat
e |
| 368 // those, we divide the matrix by its dimensions here. |
| 369 // |
| 370 // We don't do this if we're either trivial (can ignore the matrix) or clamp
ing |
| 371 // in both X and Y since clamping to width,height is just as easy as to 0xFF
FF. |
| 372 |
| 373 if (!(clampClamp || trivialMatrix)) { |
| 374 fInvMatrix.postIDiv(fBitmap->width(), fBitmap->height()); |
379 } | 375 } |
380 | 376 |
381 // Now that all possible changes to the matrix have taken place, check | 377 // Now that all possible changes to the matrix have taken place, check |
382 // to see if we're really close to a no-scale matrix. If so, explicitly | 378 // to see if we're really close to a no-scale matrix. If so, explicitly |
383 // set it to be so. Subsequent code may inspect this matrix to choose | 379 // set it to be so. Subsequent code may inspect this matrix to choose |
384 // a faster path in this case. | 380 // a faster path in this case. |
385 | 381 |
386 // This code will only execute if the matrix has some scale component; | 382 // This code will only execute if the matrix has some scale component; |
387 // if it's already pure translate then we won't do this inversion. | 383 // if it's already pure translate then we won't do this inversion. |
388 | 384 |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 fx += dx; | 1067 fx += dx; |
1072 } | 1068 } |
1073 } else { | 1069 } else { |
1074 for (int i = 0; i < count; ++i) { | 1070 for (int i = 0; i < count; ++i) { |
1075 dst[i] = src[SkClampMax(SkFractionalIntToInt(fx), maxX)]; | 1071 dst[i] = src[SkClampMax(SkFractionalIntToInt(fx), maxX)]; |
1076 fx += dx; | 1072 fx += dx; |
1077 } | 1073 } |
1078 } | 1074 } |
1079 } | 1075 } |
1080 | 1076 |
OLD | NEW |