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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 < (maximumAllocation * invMat.getScaleX() * invMat.getScaleY()); | 142 < (maximumAllocation * invMat.getScaleX() * invMat.getScaleY()); |
143 } | 143 } |
144 | 144 |
145 // TODO -- we may want to pass the clip into this function so we only scale | 145 // TODO -- we may want to pass the clip into this function so we only scale |
146 // the portion of the image that we're going to need. This will complicate | 146 // the portion of the image that we're going to need. This will complicate |
147 // the interface to the cache, but might be well worth it. | 147 // the interface to the cache, but might be well worth it. |
148 | 148 |
149 bool SkBitmapProcState::possiblyScaleImage() { | 149 bool SkBitmapProcState::possiblyScaleImage() { |
150 SkASSERT(NULL == fBitmap); | 150 SkASSERT(NULL == fBitmap); |
151 | 151 |
152 fAdjustedMatrix = false; | |
153 | |
154 if (fFilterLevel <= SkPaint::kLow_FilterLevel) { | 152 if (fFilterLevel <= SkPaint::kLow_FilterLevel) { |
155 return false; | 153 return false; |
156 } | 154 } |
157 // Check to see if the transformation matrix is simple, and if we're | 155 // Check to see if the transformation matrix is simple, and if we're |
158 // doing high quality scaling. If so, do the bitmap scale here and | 156 // doing high quality scaling. If so, do the bitmap scale here and |
159 // remove the (non-fractional) scaling component from the matrix. | 157 // remove the scaling component from the matrix. |
160 | |
161 SkScalar invScaleX = fInvMatrix.getScaleX(); | |
162 SkScalar invScaleY = fInvMatrix.getScaleY(); | |
163 | |
164 float trueDestWidth = fOrigBitmap.width() / invScaleX; | |
165 float trueDestHeight = fOrigBitmap.height() / invScaleY; | |
166 | |
167 #ifndef SK_IGNORE_PROPER_FRACTIONAL_SCALING | |
168 float roundedDestWidth = SkScalarRoundToScalar(trueDestWidth); | |
169 float roundedDestHeight = SkScalarRoundToScalar(trueDestHeight); | |
170 #else | |
171 float roundedDestWidth = trueDestWidth; | |
172 float roundedDestHeight = trueDestHeight; | |
173 #endif | |
174 | 158 |
175 if (SkPaint::kHigh_FilterLevel == fFilterLevel && | 159 if (SkPaint::kHigh_FilterLevel == fFilterLevel && |
176 fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Ma
sk) && | 160 fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Ma
sk) && |
177 kN32_SkColorType == fOrigBitmap.colorType() && | 161 kN32_SkColorType == fOrigBitmap.colorType() && |
178 cache_size_okay(fOrigBitmap, fInvMatrix)) { | 162 cache_size_okay(fOrigBitmap, fInvMatrix)) { |
179 | 163 |
| 164 SkScalar invScaleX = fInvMatrix.getScaleX(); |
| 165 SkScalar invScaleY = fInvMatrix.getScaleY(); |
| 166 |
180 if (SkScalarNearlyEqual(invScaleX,1.0f) && | 167 if (SkScalarNearlyEqual(invScaleX,1.0f) && |
181 SkScalarNearlyEqual(invScaleY,1.0f)) { | 168 SkScalarNearlyEqual(invScaleY,1.0f)) { |
182 // short-circuit identity scaling; the output is supposed to | 169 // short-circuit identity scaling; the output is supposed to |
183 // be the same as the input, so we might as well go fast. | 170 // be the same as the input, so we might as well go fast. |
184 | 171 |
185 // Note(humper): We could also probably do this if the scales | 172 // Note(humper): We could also probably do this if the scales |
186 // are close to -1 as well, since the flip doesn't require | 173 // are close to -1 as well, since the flip doesn't require |
187 // any fancy re-sampling... | 174 // any fancy re-sampling... |
188 | 175 |
189 // Set our filter level to low -- the only post-filtering this | 176 // Set our filter level to low -- the only post-filtering this |
190 // image might require is some interpolation if the translation | 177 // image might require is some interpolation if the translation |
191 // is fractional. | 178 // is fractional. |
192 fFilterLevel = SkPaint::kLow_FilterLevel; | 179 fFilterLevel = SkPaint::kLow_FilterLevel; |
193 return false; | 180 return false; |
194 } | 181 } |
195 | 182 |
196 if (!SkBitmapCache::Find(fOrigBitmap, roundedDestWidth, roundedDestHeigh
t, &fScaledBitmap)) { | 183 if (!SkBitmapCache::Find(fOrigBitmap, invScaleX, invScaleY, &fScaledBitm
ap)) { |
| 184 float dest_width = fOrigBitmap.width() / invScaleX; |
| 185 float dest_height = fOrigBitmap.height() / invScaleY; |
| 186 |
197 // All the criteria are met; let's make a new bitmap. | 187 // All the criteria are met; let's make a new bitmap. |
198 | 188 |
199 if (!SkBitmapScaler::Resize(&fScaledBitmap, | 189 if (!SkBitmapScaler::Resize(&fScaledBitmap, |
200 fOrigBitmap, | 190 fOrigBitmap, |
201 SkBitmapScaler::RESIZE_BEST, | 191 SkBitmapScaler::RESIZE_BEST, |
202 roundedDestWidth, | 192 dest_width, |
203 roundedDestHeight, | 193 dest_height, |
204 SkScaledImageCache::GetAllocator())) { | 194 SkScaledImageCache::GetAllocator())) { |
205 // we failed to create fScaledBitmap, so just return and let | 195 // we failed to create fScaledBitmap, so just return and let |
206 // the scanline proc handle it. | 196 // the scanline proc handle it. |
207 return false; | 197 return false; |
208 | 198 |
209 } | 199 } |
210 | 200 |
211 SkASSERT(NULL != fScaledBitmap.getPixels()); | 201 SkASSERT(NULL != fScaledBitmap.getPixels()); |
212 SkBitmapCache::Add(fOrigBitmap, roundedDestWidth, roundedDestHeight,
fScaledBitmap); | 202 SkBitmapCache::Add(fOrigBitmap, invScaleX, invScaleY, fScaledBitmap)
; |
213 } | 203 } |
214 | 204 |
215 SkASSERT(NULL != fScaledBitmap.getPixels()); | 205 SkASSERT(NULL != fScaledBitmap.getPixels()); |
216 fBitmap = &fScaledBitmap; | 206 fBitmap = &fScaledBitmap; |
217 | 207 |
218 // set the inv matrix type to translate-only; | 208 // set the inv matrix type to translate-only; |
219 fInvMatrix.setTranslate(fInvMatrix.getTranslateX() / fInvMatrix.getScale
X(), | 209 fInvMatrix.setTranslate(fInvMatrix.getTranslateX() / fInvMatrix.getScale
X(), |
220 fInvMatrix.getTranslateY() / fInvMatrix.getScale
Y()); | 210 fInvMatrix.getTranslateY() / fInvMatrix.getScale
Y()); |
221 | 211 |
222 #ifndef SK_IGNORE_PROPER_FRACTIONAL_SCALING | |
223 // reintroduce any fractional scaling missed by our integral scale done
above. | |
224 | |
225 float fractionalScaleX = trueDestWidth/roundedDestWidth; | |
226 float fractionalScaleY = trueDestHeight/roundedDestHeight; | |
227 | |
228 fInvMatrix.postScale(fractionalScaleX, fractionalScaleY); | |
229 #endif | |
230 fAdjustedMatrix = true; | |
231 | |
232 // Set our filter level to low -- the only post-filtering this | 212 // Set our filter level to low -- the only post-filtering this |
233 // image might require is some interpolation if the translation | 213 // image might require is some interpolation if the translation |
234 // is fractional or if there's any remaining scaling to be done. | 214 // is fractional. |
235 fFilterLevel = SkPaint::kLow_FilterLevel; | 215 fFilterLevel = SkPaint::kLow_FilterLevel; |
236 return true; | 216 return true; |
237 } | 217 } |
238 | 218 |
239 /* | 219 /* |
240 * If High, then our special-case for scale-only did not take, and so we | 220 * If High, then our special-case for scale-only did not take, and so we |
241 * have to make a choice: | 221 * have to make a choice: |
242 * 1. fall back on mipmaps + bilerp | 222 * 1. fall back on mipmaps + bilerp |
243 * 2. fall back on scanline bicubic filter | 223 * 2. fall back on scanline bicubic filter |
244 * For now, we compute the "scale" value from the matrix, and have a | 224 * For now, we compute the "scale" value from the matrix, and have a |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 // If we are "still" kMedium_FilterLevel, then the request was not fulfilled
by possiblyScale, | 360 // If we are "still" kMedium_FilterLevel, then the request was not fulfilled
by possiblyScale, |
381 // so we downgrade to kLow (so the rest of the sniffing code can assume that
) | 361 // so we downgrade to kLow (so the rest of the sniffing code can assume that
) |
382 if (SkPaint::kMedium_FilterLevel == fFilterLevel) { | 362 if (SkPaint::kMedium_FilterLevel == fFilterLevel) { |
383 fFilterLevel = SkPaint::kLow_FilterLevel; | 363 fFilterLevel = SkPaint::kLow_FilterLevel; |
384 } | 364 } |
385 | 365 |
386 bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) ==
0; | 366 bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) ==
0; |
387 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && | 367 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && |
388 SkShader::kClamp_TileMode == fTileModeY; | 368 SkShader::kClamp_TileMode == fTileModeY; |
389 | 369 |
390 if (!(fAdjustedMatrix || clampClamp || trivialMatrix)) { | 370 if (!(clampClamp || trivialMatrix)) { |
391 fInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); | 371 fInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); |
392 } | 372 } |
393 | 373 |
394 // Now that all possible changes to the matrix have taken place, check | 374 // Now that all possible changes to the matrix have taken place, check |
395 // to see if we're really close to a no-scale matrix. If so, explicitly | 375 // to see if we're really close to a no-scale matrix. If so, explicitly |
396 // set it to be so. Subsequent code may inspect this matrix to choose | 376 // set it to be so. Subsequent code may inspect this matrix to choose |
397 // a faster path in this case. | 377 // a faster path in this case. |
398 | 378 |
399 // This code will only execute if the matrix has some scale component; | 379 // This code will only execute if the matrix has some scale component; |
400 // if it's already pure translate then we won't do this inversion. | 380 // if it's already pure translate then we won't do this inversion. |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 } else { | 1007 } else { |
1028 size >>= 2; | 1008 size >>= 2; |
1029 } | 1009 } |
1030 | 1010 |
1031 if (fFilterLevel != SkPaint::kNone_FilterLevel) { | 1011 if (fFilterLevel != SkPaint::kNone_FilterLevel) { |
1032 size >>= 1; | 1012 size >>= 1; |
1033 } | 1013 } |
1034 | 1014 |
1035 return size; | 1015 return size; |
1036 } | 1016 } |
OLD | NEW |