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

Unified Diff: Source/platform/graphics/skia/NativeImageSkia.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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/platform/graphics/skia/NativeImageSkia.h ('k') | Source/platform/graphics/skia/SkiaUtils.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/graphics/skia/NativeImageSkia.cpp
diff --git a/Source/platform/graphics/skia/NativeImageSkia.cpp b/Source/platform/graphics/skia/NativeImageSkia.cpp
index 50a31c7fc4718573c223235b55f25161dffc4344..618669d9e6dfbd78fbadf9fe6febb6389bd18238 100644
--- a/Source/platform/graphics/skia/NativeImageSkia.cpp
+++ b/Source/platform/graphics/skia/NativeImageSkia.cpp
@@ -46,118 +46,10 @@
#include "third_party/skia/include/core/SkScalar.h"
#include "third_party/skia/include/core/SkShader.h"
-#include <algorithm>
#include <math.h>
-#include <limits>
namespace blink {
-static bool nearlyIntegral(float value)
-{
- return fabs(value - floorf(value)) < std::numeric_limits<float>::epsilon();
-}
-
-InterpolationQuality NativeImageSkia::computeInterpolationQuality(const SkMatrix& matrix, float srcWidth, float srcHeight, float destWidth, float destHeight) const
-{
- // The percent change below which we will not resample. This usually means
- // an off-by-one error on the web page, and just doing nearest neighbor
- // sampling is usually good enough.
- const float kFractionalChangeThreshold = 0.025f;
-
- // Images smaller than this in either direction are considered "small" and
- // are not resampled ever (see below).
- const int kSmallImageSizeThreshold = 8;
-
- // The amount an image can be stretched in a single direction before we
- // say that it is being stretched so much that it must be a line or
- // background that doesn't need resampling.
- const float kLargeStretch = 3.0f;
-
- // Figure out if we should resample this image. We try to prune out some
- // common cases where resampling won't give us anything, since it is much
- // slower than drawing stretched.
- float diffWidth = fabs(destWidth - srcWidth);
- float diffHeight = fabs(destHeight - srcHeight);
- bool widthNearlyEqual = diffWidth < std::numeric_limits<float>::epsilon();
- bool heightNearlyEqual = diffHeight < std::numeric_limits<float>::epsilon();
- // We don't need to resample if the source and destination are the same.
- if (widthNearlyEqual && heightNearlyEqual)
- return InterpolationNone;
-
- if (srcWidth <= kSmallImageSizeThreshold
- || srcHeight <= kSmallImageSizeThreshold
- || destWidth <= kSmallImageSizeThreshold
- || destHeight <= kSmallImageSizeThreshold) {
- // Small image detected.
-
- // Resample in the case where the new size would be non-integral.
- // This can cause noticeable breaks in repeating patterns, except
- // when the source image is only one pixel wide in that dimension.
- if ((!nearlyIntegral(destWidth) && srcWidth > 1 + std::numeric_limits<float>::epsilon())
- || (!nearlyIntegral(destHeight) && srcHeight > 1 + std::numeric_limits<float>::epsilon()))
- return InterpolationLow;
-
- // Otherwise, don't resample small images. These are often used for
- // borders and rules (think 1x1 images used to make lines).
- return InterpolationNone;
- }
-
- if (srcHeight * kLargeStretch <= destHeight || srcWidth * kLargeStretch <= destWidth) {
- // Large image detected.
-
- // Don't resample if it is being stretched a lot in only one direction.
- // This is trying to catch cases where somebody has created a border
- // (which might be large) and then is stretching it to fill some part
- // of the page.
- if (widthNearlyEqual || heightNearlyEqual)
- return InterpolationNone;
-
- // The image is growing a lot and in more than one direction. Resampling
- // is slow and doesn't give us very much when growing a lot.
- return InterpolationLow;
- }
-
- if ((diffWidth / srcWidth < kFractionalChangeThreshold)
- && (diffHeight / srcHeight < kFractionalChangeThreshold)) {
- // It is disappointingly common on the web for image sizes to be off by
- // one or two pixels. We don't bother resampling if the size difference
- // is a small fraction of the original size.
- return InterpolationNone;
- }
-
- // When the image is not yet done loading, use linear. We don't cache the
- // partially resampled images, and as they come in incrementally, it causes
- // us to have to resample the whole thing every time.
- if (!isDataComplete())
- return InterpolationLow;
-
- // Everything else gets resampled.
- // High quality interpolation only enabled for scaling and translation.
- if (!(matrix.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)))
- return InterpolationHigh;
-
- return InterpolationLow;
-}
-
-static InterpolationQuality limitInterpolationQuality(GraphicsContext* context, InterpolationQuality resampling)
-{
- return std::min(resampling, context->imageInterpolationQuality());
-}
-
-static SkPaint::FilterLevel convertToSkiaFilterLevel(bool useBicubicFilter, InterpolationQuality resampling)
-{
- // FIXME: If we get rid of this special case, this function can go away entirely.
- if (useBicubicFilter)
- return SkPaint::kHigh_FilterLevel;
-
- // InterpolationHigh if useBicubicFilter is false means that we do
- // a manual high quality resampling before drawing to Skia.
- if (resampling == InterpolationHigh)
- return SkPaint::kNone_FilterLevel;
-
- return static_cast<SkPaint::FilterLevel>(resampling);
-}
-
// This function is used to scale an image and extract a scaled fragment.
//
// ALGORITHM
@@ -275,77 +167,19 @@ SkBitmap NativeImageSkia::resizedBitmap(const SkISize& scaledImageSize, const Sk
return resizedSubset;
}
-static bool shouldDrawAntiAliased(GraphicsContext* context, const SkRect& destRect)
-{
- if (!context->shouldAntialias())
- return false;
- const SkMatrix totalMatrix = context->getTotalMatrix();
- // Don't disable anti-aliasing if we're rotated or skewed.
- if (!totalMatrix.rectStaysRect())
- return true;
- // Disable anti-aliasing for scales or n*90 degree rotations.
- // Allow to opt out of the optimization though for "hairline" geometry
- // images - using the shouldAntialiasHairlineImages() GraphicsContext flag.
- if (!context->shouldAntialiasHairlineImages())
- return false;
- // Check if the dimensions of the destination are "small" (less than one
- // device pixel). To prevent sudden drop-outs. Since we know that
- // kRectStaysRect_Mask is set, the matrix either has scale and no skew or
- // vice versa. We can query the kAffine_Mask flag to determine which case
- // it is.
- // FIXME: This queries the CTM while drawing, which is generally
- // discouraged. Always drawing with AA can negatively impact performance
- // though - that's why it's not always on.
- SkScalar widthExpansion, heightExpansion;
- if (totalMatrix.getType() & SkMatrix::kAffine_Mask)
- widthExpansion = totalMatrix[SkMatrix::kMSkewY], heightExpansion = totalMatrix[SkMatrix::kMSkewX];
- else
- widthExpansion = totalMatrix[SkMatrix::kMScaleX], heightExpansion = totalMatrix[SkMatrix::kMScaleY];
- return destRect.width() * fabs(widthExpansion) < 1 || destRect.height() * fabs(heightExpansion) < 1;
-}
-
-void NativeImageSkia::draw(GraphicsContext* context, const SkRect& srcRect, const SkRect& destRect, PassRefPtr<SkXfermode> compOp) const
+void NativeImageSkia::draw(
+ GraphicsContext* context,
+ const SkRect& srcRect,
+ const SkRect& destRect,
+ CompositeOperator compositeOp,
+ blink::WebBlendMode blendMode) const
{
TRACE_EVENT0("skia", "NativeImageSkia::draw");
- SkPaint paint;
- paint.setXfermode(compOp.get());
- paint.setColorFilter(context->colorFilter());
- paint.setAlpha(context->getNormalizedAlpha());
- paint.setLooper(context->drawLooper());
- paint.setAntiAlias(shouldDrawAntiAliased(context, destRect));
bool isLazyDecoded = DeferredImageDecoder::isLazyDecoded(bitmap());
- InterpolationQuality resampling;
- if (context->isAccelerated()) {
- resampling = InterpolationLow;
- } else if (context->printing()) {
- resampling = InterpolationNone;
- } else if (isLazyDecoded) {
- resampling = InterpolationHigh;
- } else {
- // Take into account scale applied to the canvas when computing sampling mode (e.g. CSS scale or page scale).
- SkRect destRectTarget = destRect;
- SkMatrix totalMatrix = context->getTotalMatrix();
- if (!(totalMatrix.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)))
- totalMatrix.mapRect(&destRectTarget, destRect);
-
- resampling = computeInterpolationQuality(totalMatrix,
- SkScalarToFloat(srcRect.width()), SkScalarToFloat(srcRect.height()),
- SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTarget.height()));
- }
-
- if (resampling == InterpolationNone) {
- // FIXME: This is to not break tests (it results in the filter bitmap flag
- // being set to true). We need to decide if we respect InterpolationNone
- // being returned from computeInterpolationQuality.
- resampling = InterpolationLow;
- }
- resampling = limitInterpolationQuality(context, resampling);
-
- bool useBicubicFilter = resampling == InterpolationHigh;
- paint.setFilterLevel(convertToSkiaFilterLevel(useBicubicFilter, resampling));
-
+ SkPaint paint;
+ context->preparePaintForDrawRectToRect(&paint, srcRect, destRect, compositeOp, blendMode, isLazyDecoded, isDataComplete());
// We want to filter it if we decided to do interpolation above, or if
// there is something interesting going on with the matrix (like a rotation).
// Note: for serialization, we will want to subset the bitmap first so we
@@ -411,7 +245,7 @@ void NativeImageSkia::drawPattern(
else if (isLazyDecoded)
resampling = InterpolationHigh;
else
- resampling = computeInterpolationQuality(totalMatrix, normSrcRect.width(), normSrcRect.height(), destBitmapWidth, destBitmapHeight);
+ resampling = computeInterpolationQuality(totalMatrix, normSrcRect.width(), normSrcRect.height(), destBitmapWidth, destBitmapHeight, isDataComplete());
resampling = limitInterpolationQuality(context, resampling);
SkMatrix localMatrix;
« no previous file with comments | « Source/platform/graphics/skia/NativeImageSkia.h ('k') | Source/platform/graphics/skia/SkiaUtils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698