Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: src/core/SkBitmapScaler.cpp

Issue 1320513005: simplify bitmap scaler and cache (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkBitmapScaler.h ('k') | tests/SkResourceCacheTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 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 "SkBitmapScaler.h" 8 #include "SkBitmapScaler.h"
9 #include "SkBitmapFilter.h" 9 #include "SkBitmapFilter.h"
10 #include "SkConvolver.h" 10 #include "SkConvolver.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 SkConvolutionFilter1D fXFilter; 55 SkConvolutionFilter1D fXFilter;
56 SkConvolutionFilter1D fYFilter; 56 SkConvolutionFilter1D fYFilter;
57 }; 57 };
58 58
59 SkResizeFilter::SkResizeFilter(SkBitmapScaler::ResizeMethod method, 59 SkResizeFilter::SkResizeFilter(SkBitmapScaler::ResizeMethod method,
60 int srcFullWidth, int srcFullHeight, 60 int srcFullWidth, int srcFullHeight,
61 float destWidth, float destHeight, 61 float destWidth, float destHeight,
62 const SkRect& destSubset, 62 const SkRect& destSubset,
63 const SkConvolutionProcs& convolveProcs) { 63 const SkConvolutionProcs& convolveProcs) {
64 64
65 // method will only ever refer to an "algorithm method". 65 SkASSERT(method >= SkBitmapScaler::RESIZE_FirstMethod &&
66 SkASSERT((SkBitmapScaler::RESIZE_FIRST_ALGORITHM_METHOD <= method) && 66 method <= SkBitmapScaler::RESIZE_LastMethod);
67 (method <= SkBitmapScaler::RESIZE_LAST_ALGORITHM_METHOD));
68 67
68 fBitmapFilter = nullptr;
69 switch(method) { 69 switch(method) {
70 case SkBitmapScaler::RESIZE_BOX: 70 case SkBitmapScaler::RESIZE_BOX:
71 fBitmapFilter = new SkBoxFilter; 71 fBitmapFilter = new SkBoxFilter;
72 break; 72 break;
73 case SkBitmapScaler::RESIZE_TRIANGLE: 73 case SkBitmapScaler::RESIZE_TRIANGLE:
74 fBitmapFilter = new SkTriangleFilter; 74 fBitmapFilter = new SkTriangleFilter;
75 break; 75 break;
76 case SkBitmapScaler::RESIZE_MITCHELL: 76 case SkBitmapScaler::RESIZE_MITCHELL:
77 fBitmapFilter = new SkMitchellFilter(1.f / 3.f, 1.f / 3.f); 77 fBitmapFilter = new SkMitchellFilter(1.f / 3.f, 1.f / 3.f);
78 break; 78 break;
79 case SkBitmapScaler::RESIZE_HAMMING: 79 case SkBitmapScaler::RESIZE_HAMMING:
80 fBitmapFilter = new SkHammingFilter; 80 fBitmapFilter = new SkHammingFilter;
81 break; 81 break;
82 case SkBitmapScaler::RESIZE_LANCZOS3: 82 case SkBitmapScaler::RESIZE_LANCZOS3:
83 fBitmapFilter = new SkLanczosFilter; 83 fBitmapFilter = new SkLanczosFilter;
84 break; 84 break;
85 default:
86 // NOTREACHED:
87 fBitmapFilter = new SkMitchellFilter(1.f / 3.f, 1.f / 3.f);
88 break;
89 } 85 }
90 86
91 87
92 float scaleX = destWidth / srcFullWidth; 88 float scaleX = destWidth / srcFullWidth;
93 float scaleY = destHeight / srcFullHeight; 89 float scaleY = destHeight / srcFullHeight;
94 90
95 this->computeFilters(srcFullWidth, destSubset.fLeft, destSubset.width(), 91 this->computeFilters(srcFullWidth, destSubset.fLeft, destSubset.width(),
96 scaleX, &fXFilter, convolveProcs); 92 scaleX, &fXFilter, convolveProcs);
97 if (srcFullWidth == srcFullHeight && 93 if (srcFullWidth == srcFullHeight &&
98 destSubset.fLeft == destSubset.fTop && 94 destSubset.fLeft == destSubset.fTop &&
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 // Now it's ready to go. 203 // Now it's ready to go.
208 output->AddFilter(srcBegin, &fixedFilterValues[0], 204 output->AddFilter(srcBegin, &fixedFilterValues[0],
209 static_cast<int>(fixedFilterValues.count())); 205 static_cast<int>(fixedFilterValues.count()));
210 } 206 }
211 207
212 if (convolveProcs.fApplySIMDPadding) { 208 if (convolveProcs.fApplySIMDPadding) {
213 convolveProcs.fApplySIMDPadding( output ); 209 convolveProcs.fApplySIMDPadding( output );
214 } 210 }
215 } 211 }
216 212
217 static SkBitmapScaler::ResizeMethod ResizeMethodToAlgorithmMethod(
218 SkBitmapScaler::ResizeMethod method) {
219 // Convert any "Quality Method" into an "Algorithm Method"
220 if (method >= SkBitmapScaler::RESIZE_FIRST_ALGORITHM_METHOD &&
221 method <= SkBitmapScaler::RESIZE_LAST_ALGORITHM_METHOD) {
222 return method;
223 }
224 // The call to SkBitmapScalerGtv::Resize() above took care of
225 // GPU-acceleration in the cases where it is possible. So now we just
226 // pick the appropriate software method for each resize quality.
227 switch (method) {
228 // Users of RESIZE_GOOD are willing to trade a lot of quality to
229 // get speed, allowing the use of linear resampling to get hardware
230 // acceleration (SRB). Hence any of our "good" software filters
231 // will be acceptable, so we use a triangle.
232 case SkBitmapScaler::RESIZE_GOOD:
233 return SkBitmapScaler::RESIZE_TRIANGLE;
234 // Users of RESIZE_BETTER are willing to trade some quality in order
235 // to improve performance, but are guaranteed not to devolve to a linear
236 // resampling. In visual tests we see that Hamming-1 is not as good as
237 // Lanczos-2, however it is about 40% faster and Lanczos-2 itself is
238 // about 30% faster than Lanczos-3. The use of Hamming-1 has been deemed
239 // an acceptable trade-off between quality and speed.
240 case SkBitmapScaler::RESIZE_BETTER:
241 return SkBitmapScaler::RESIZE_HAMMING;
242 default:
243 #ifdef SK_HIGH_QUALITY_IS_LANCZOS
244 return SkBitmapScaler::RESIZE_LANCZOS3;
245 #else
246 return SkBitmapScaler::RESIZE_MITCHELL;
247 #endif
248 }
249 }
250
251 bool SkBitmapScaler::Resize(SkBitmap* resultPtr, const SkPixmap& source, ResizeM ethod method, 213 bool SkBitmapScaler::Resize(SkBitmap* resultPtr, const SkPixmap& source, ResizeM ethod method,
252 float destWidth, float destHeight, 214 int destWidth, int destHeight, SkBitmap::Allocator* allocator) {
253 SkBitmap::Allocator* allocator) {
254 if (nullptr == source.addr() || source.colorType() != kN32_SkColorType || 215 if (nullptr == source.addr() || source.colorType() != kN32_SkColorType ||
255 source.width() < 1 || source.height() < 1) 216 source.width() < 1 || source.height() < 1)
256 { 217 {
257 return false; 218 return false;
258 } 219 }
259 220
260 if (destWidth < 1 || destHeight < 1) { 221 if (destWidth < 1 || destHeight < 1) {
261 // todo: seems like we could handle negative dstWidth/Height, since that
262 // is just a negative scale (flip)
263 return false; 222 return false;
264 } 223 }
265 224
266 SkConvolutionProcs convolveProcs= { 0, nullptr, nullptr, nullptr, nullptr }; 225 SkConvolutionProcs convolveProcs= { 0, nullptr, nullptr, nullptr, nullptr };
267 PlatformConvolutionProcs(&convolveProcs); 226 PlatformConvolutionProcs(&convolveProcs);
268 227
269 SkRect destSubset = { 0, 0, destWidth, destHeight }; 228 SkRect destSubset = SkRect::MakeIWH(destWidth, destHeight);
270
271 // Ensure that the ResizeMethod enumeration is sound.
272 SkASSERT(((RESIZE_FIRST_QUALITY_METHOD <= method) &&
273 (method <= RESIZE_LAST_QUALITY_METHOD)) ||
274 ((RESIZE_FIRST_ALGORITHM_METHOD <= method) &&
275 (method <= RESIZE_LAST_ALGORITHM_METHOD)));
276
277 method = ResizeMethodToAlgorithmMethod(method);
278
279 // Check that we deal with an "algorithm methods" from this point onward.
280 SkASSERT((SkBitmapScaler::RESIZE_FIRST_ALGORITHM_METHOD <= method) &&
281 (method <= SkBitmapScaler::RESIZE_LAST_ALGORITHM_METHOD));
282 229
283 SkResizeFilter filter(method, source.width(), source.height(), 230 SkResizeFilter filter(method, source.width(), source.height(),
284 destWidth, destHeight, destSubset, convolveProcs); 231 destWidth, destHeight, destSubset, convolveProcs);
285 232
286 // Get a subset encompassing this touched area. We construct the 233 // Get a subset encompassing this touched area. We construct the
287 // offsets and row strides such that it looks like a new bitmap, while 234 // offsets and row strides such that it looks like a new bitmap, while
288 // referring to the old data. 235 // referring to the old data.
289 const uint8_t* sourceSubset = reinterpret_cast<const uint8_t*>(source.addr() ); 236 const uint8_t* sourceSubset = reinterpret_cast<const uint8_t*>(source.addr() );
290 237
291 // Convolve into the result. 238 // Convolve into the result.
(...skipping 11 matching lines...) Expand all
303 static_cast<int>(result.rowBytes()), 250 static_cast<int>(result.rowBytes()),
304 static_cast<unsigned char*>(result.getPixels()), 251 static_cast<unsigned char*>(result.getPixels()),
305 convolveProcs, true); 252 convolveProcs, true);
306 253
307 *resultPtr = result; 254 *resultPtr = result;
308 resultPtr->lockPixels(); 255 resultPtr->lockPixels();
309 SkASSERT(resultPtr->getPixels()); 256 SkASSERT(resultPtr->getPixels());
310 return true; 257 return true;
311 } 258 }
312 259
OLDNEW
« no previous file with comments | « src/core/SkBitmapScaler.h ('k') | tests/SkResourceCacheTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698