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

Side by Side Diff: Source/platform/graphics/skia/SkiaUtils.cpp

Issue 416543002: Move logic from NativeImageSkia to GraphicsContext and SkiaUtils (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Test regressions fixed Created 6 years, 5 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 | « Source/platform/graphics/skia/SkiaUtils.h ('k') | no next file » | 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 (c) 2006,2007,2008, Google Inc. All rights reserved. 2 * Copyright (c) 2006,2007,2008, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 result.setTranslateY(WebCoreDoubleToSkScalar(source.f())); 182 result.setTranslateY(WebCoreDoubleToSkScalar(source.f()));
183 183
184 // FIXME: Set perspective properly. 184 // FIXME: Set perspective properly.
185 result.setPerspX(0); 185 result.setPerspX(0);
186 result.setPerspY(0); 186 result.setPerspY(0);
187 result.set(SkMatrix::kMPersp2, SK_Scalar1); 187 result.set(SkMatrix::kMPersp2, SK_Scalar1);
188 188
189 return result; 189 return result;
190 } 190 }
191 191
192 bool nearlyIntegral(float value)
193 {
194 return fabs(value - floorf(value)) < std::numeric_limits<float>::epsilon();
195 }
196
197 InterpolationQuality limitInterpolationQuality(const GraphicsContext* context, I nterpolationQuality resampling)
198 {
199 return std::min(resampling, context->imageInterpolationQuality());
200 }
201
202 SkPaint::FilterLevel convertToSkiaFilterLevel(bool useBicubicFilter, Interpolati onQuality resampling)
203 {
204 // FIXME: If we get rid of this special case, this function can go away enti rely.
205 if (useBicubicFilter)
206 return SkPaint::kHigh_FilterLevel;
207
208 // InterpolationHigh if useBicubicFilter is false means that we do
209 // a manual high quality resampling before drawing to Skia.
210 if (resampling == InterpolationHigh)
211 return SkPaint::kNone_FilterLevel;
212
213 return static_cast<SkPaint::FilterLevel>(resampling);
214 }
215
216 InterpolationQuality computeInterpolationQuality(
217 const SkMatrix& matrix,
218 float srcWidth,
219 float srcHeight,
220 float destWidth,
221 float destHeight,
222 bool isDataComplete)
223 {
224 // The percent change below which we will not resample. This usually means
225 // an off-by-one error on the web page, and just doing nearest neighbor
226 // sampling is usually good enough.
227 const float kFractionalChangeThreshold = 0.025f;
228
229 // Images smaller than this in either direction are considered "small" and
230 // are not resampled ever (see below).
231 const int kSmallImageSizeThreshold = 8;
232
233 // The amount an image can be stretched in a single direction before we
234 // say that it is being stretched so much that it must be a line or
235 // background that doesn't need resampling.
236 const float kLargeStretch = 3.0f;
237
238 // Figure out if we should resample this image. We try to prune out some
239 // common cases where resampling won't give us anything, since it is much
240 // slower than drawing stretched.
241 float diffWidth = fabs(destWidth - srcWidth);
242 float diffHeight = fabs(destHeight - srcHeight);
243 bool widthNearlyEqual = diffWidth < std::numeric_limits<float>::epsilon();
244 bool heightNearlyEqual = diffHeight < std::numeric_limits<float>::epsilon();
245 // We don't need to resample if the source and destination are the same.
246 if (widthNearlyEqual && heightNearlyEqual)
247 return InterpolationNone;
248
249 if (srcWidth <= kSmallImageSizeThreshold
250 || srcHeight <= kSmallImageSizeThreshold
251 || destWidth <= kSmallImageSizeThreshold
252 || destHeight <= kSmallImageSizeThreshold) {
253 // Small image detected.
254
255 // Resample in the case where the new size would be non-integral.
256 // This can cause noticeable breaks in repeating patterns, except
257 // when the source image is only one pixel wide in that dimension.
258 if ((!nearlyIntegral(destWidth) && srcWidth > 1 + std::numeric_limits<fl oat>::epsilon())
259 || (!nearlyIntegral(destHeight) && srcHeight > 1 + std::numeric_limi ts<float>::epsilon()))
260 return InterpolationLow;
261
262 // Otherwise, don't resample small images. These are often used for
263 // borders and rules (think 1x1 images used to make lines).
264 return InterpolationNone;
265 }
266
267 if (srcHeight * kLargeStretch <= destHeight || srcWidth * kLargeStretch <= d estWidth) {
268 // Large image detected.
269
270 // Don't resample if it is being stretched a lot in only one direction.
271 // This is trying to catch cases where somebody has created a border
272 // (which might be large) and then is stretching it to fill some part
273 // of the page.
274 if (widthNearlyEqual || heightNearlyEqual)
275 return InterpolationNone;
276
277 // The image is growing a lot and in more than one direction. Resampling
278 // is slow and doesn't give us very much when growing a lot.
279 return InterpolationLow;
280 }
281
282 if ((diffWidth / srcWidth < kFractionalChangeThreshold)
283 && (diffHeight / srcHeight < kFractionalChangeThreshold)) {
284 // It is disappointingly common on the web for image sizes to be off by
285 // one or two pixels. We don't bother resampling if the size difference
286 // is a small fraction of the original size.
287 return InterpolationNone;
288 }
289
290 // When the image is not yet done loading, use linear. We don't cache the
291 // partially resampled images, and as they come in incrementally, it causes
292 // us to have to resample the whole thing every time.
293 if (!isDataComplete)
294 return InterpolationLow;
295
296 // Everything else gets resampled.
297 // High quality interpolation only enabled for scaling and translation.
298 if (!(matrix.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Ma sk)))
299 return InterpolationHigh;
300
301 return InterpolationLow;
302 }
303
304
305 bool shouldDrawAntiAliased(const GraphicsContext* context, const SkRect& destRec t)
306 {
307 if (!context->shouldAntialias())
308 return false;
309 const SkMatrix totalMatrix = context->getTotalMatrix();
310 // Don't disable anti-aliasing if we're rotated or skewed.
311 if (!totalMatrix.rectStaysRect())
312 return true;
313 // Disable anti-aliasing for scales or n*90 degree rotations.
314 // Allow to opt out of the optimization though for "hairline" geometry
315 // images - using the shouldAntialiasHairlineImages() GraphicsContext flag.
316 if (!context->shouldAntialiasHairlineImages())
317 return false;
318 // Check if the dimensions of the destination are "small" (less than one
319 // device pixel). To prevent sudden drop-outs. Since we know that
320 // kRectStaysRect_Mask is set, the matrix either has scale and no skew or
321 // vice versa. We can query the kAffine_Mask flag to determine which case
322 // it is.
323 // FIXME: This queries the CTM while drawing, which is generally
324 // discouraged. Always drawing with AA can negatively impact performance
325 // though - that's why it's not always on.
326 SkScalar widthExpansion, heightExpansion;
327 if (totalMatrix.getType() & SkMatrix::kAffine_Mask)
328 widthExpansion = totalMatrix[SkMatrix::kMSkewY], heightExpansion = total Matrix[SkMatrix::kMSkewX];
329 else
330 widthExpansion = totalMatrix[SkMatrix::kMScaleX], heightExpansion = tota lMatrix[SkMatrix::kMScaleY];
331 return destRect.width() * fabs(widthExpansion) < 1 || destRect.height() * fa bs(heightExpansion) < 1;
332 }
333
192 } // namespace blink 334 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/graphics/skia/SkiaUtils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698