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

Unified Diff: Source/core/platform/graphics/skia/NativeImageSkia.cpp

Issue 99103006: Moving GraphicsContext and dependencies from core to platform. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Final patch - fixes Android Created 7 years 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
Index: Source/core/platform/graphics/skia/NativeImageSkia.cpp
diff --git a/Source/core/platform/graphics/skia/NativeImageSkia.cpp b/Source/core/platform/graphics/skia/NativeImageSkia.cpp
deleted file mode 100644
index 89d0d737e4d960d5096b69df22d1a43e4dc8df1c..0000000000000000000000000000000000000000
--- a/Source/core/platform/graphics/skia/NativeImageSkia.cpp
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * Copyright (c) 2008, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/platform/graphics/skia/NativeImageSkia.h"
-
-#include "core/platform/graphics/GraphicsContext.h"
-#include "core/platform/graphics/Image.h"
-#include "core/platform/graphics/DeferredImageDecoder.h"
-#include "core/platform/graphics/skia/SkiaUtils.h"
-#include "platform/PlatformInstrumentation.h"
-#include "platform/TraceEvent.h"
-#include "platform/geometry/FloatPoint.h"
-#include "platform/geometry/FloatRect.h"
-#include "platform/geometry/FloatSize.h"
-#include "skia/ext/image_operations.h"
-#include "third_party/skia/include/core/SkMatrix.h"
-#include "third_party/skia/include/core/SkPaint.h"
-#include "third_party/skia/include/core/SkScalar.h"
-#include "third_party/skia/include/core/SkShader.h"
-
-#include <math.h>
-#include <limits>
-
-namespace WebCore {
-
-static bool nearlyIntegral(float value)
-{
- return fabs(value - floorf(value)) < std::numeric_limits<float>::epsilon();
-}
-
-ResamplingMode NativeImageSkia::computeResamplingMode(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 NoResampling;
-
- 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 LinearResampling;
-
- // Otherwise, don't resample small images. These are often used for
- // borders and rules (think 1x1 images used to make lines).
- return NoResampling;
- }
-
- 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 NoResampling;
-
- // 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 LinearResampling;
- }
-
- 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 NoResampling;
- }
-
- // 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 LinearResampling;
-
- // Everything else gets resampled.
- // High quality interpolation only enabled for scaling and translation.
- if (!(matrix.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)))
- return AwesomeResampling;
-
- return LinearResampling;
-}
-
-static ResamplingMode limitResamplingMode(GraphicsContext* context, ResamplingMode resampling)
-{
- switch (context->imageInterpolationQuality()) {
- case InterpolationNone:
- return NoResampling;
- case InterpolationMedium:
- // For now we treat InterpolationMedium and InterpolationLow the same.
- case InterpolationLow:
- if (resampling == AwesomeResampling)
- return LinearResampling;
- break;
- case InterpolationHigh:
- case InterpolationDefault:
- break;
- }
-
- return resampling;
-}
-
-// This function is used to scale an image and extract a scaled fragment.
-//
-// ALGORITHM
-//
-// Because the scaled image size has to be integers, we approximate the real
-// scale with the following formula (only X direction is shown):
-//
-// scaledImageWidth = round(scaleX * imageRect.width())
-// approximateScaleX = scaledImageWidth / imageRect.width()
-//
-// With this method we maintain a constant scale factor among fragments in
-// the scaled image. This allows fragments to stitch together to form the
-// full scaled image. The downside is there will be a small difference
-// between |scaleX| and |approximateScaleX|.
-//
-// A scaled image fragment is identified by:
-//
-// - Scaled image size
-// - Scaled image fragment rectangle (IntRect)
-//
-// Scaled image size has been determined and the next step is to compute the
-// rectangle for the scaled image fragment which needs to be an IntRect.
-//
-// scaledSrcRect = srcRect * (approximateScaleX, approximateScaleY)
-// enclosingScaledSrcRect = enclosingIntRect(scaledSrcRect)
-//
-// Finally we extract the scaled image fragment using
-// (scaledImageSize, enclosingScaledSrcRect).
-//
-SkBitmap NativeImageSkia::extractScaledImageFragment(const SkRect& srcRect, float scaleX, float scaleY, SkRect* scaledSrcRect) const
-{
- SkISize imageSize = SkISize::Make(bitmap().width(), bitmap().height());
- SkISize scaledImageSize = SkISize::Make(clampToInteger(roundf(imageSize.width() * scaleX)),
- clampToInteger(roundf(imageSize.height() * scaleY)));
-
- SkRect imageRect = SkRect::MakeWH(imageSize.width(), imageSize.height());
- SkRect scaledImageRect = SkRect::MakeWH(scaledImageSize.width(), scaledImageSize.height());
-
- SkMatrix scaleTransform;
- scaleTransform.setRectToRect(imageRect, scaledImageRect, SkMatrix::kFill_ScaleToFit);
- scaleTransform.mapRect(scaledSrcRect, srcRect);
-
- scaledSrcRect->intersect(scaledImageRect);
- SkIRect enclosingScaledSrcRect = enclosingIntRect(*scaledSrcRect);
-
- // |enclosingScaledSrcRect| can be larger than |scaledImageSize| because
- // of float inaccuracy so clip to get inside.
- enclosingScaledSrcRect.intersect(SkIRect::MakeSize(scaledImageSize));
-
- // scaledSrcRect is relative to the pixel snapped fragment we're extracting.
- scaledSrcRect->offset(-enclosingScaledSrcRect.x(), -enclosingScaledSrcRect.y());
-
- return resizedBitmap(scaledImageSize, enclosingScaledSrcRect);
-}
-
-// This does a lot of computation to resample only the portion of the bitmap
-// that will only be drawn. This is critical for performance since when we are
-// scrolling, for example, we are only drawing a small strip of the image.
-// Resampling the whole image every time is very slow, so this speeds up things
-// dramatically.
-//
-// Note: this code is only used when the canvas transformation is limited to
-// scaling or translation.
-void NativeImageSkia::drawResampledBitmap(GraphicsContext* context, SkPaint& paint, const SkRect& srcRect, const SkRect& destRect) const
-{
- TRACE_EVENT0("skia", "drawResampledBitmap");
- // We want to scale |destRect| with transformation in the canvas to obtain
- // the final scale. The final scale is a combination of scale transform
- // in canvas and explicit scaling (srcRect and destRect).
- SkRect screenRect;
- context->getTotalMatrix().mapRect(&screenRect, destRect);
- float realScaleX = screenRect.width() / srcRect.width();
- float realScaleY = screenRect.height() / srcRect.height();
-
- // This part of code limits scaling only to visible portion in the
- SkRect destRectVisibleSubset;
- ClipRectToCanvas(context, destRect, &destRectVisibleSubset);
-
- // ClipRectToCanvas often overshoots, resulting in a larger region than our
- // original destRect. Intersecting gets us back inside.
- if (!destRectVisibleSubset.intersect(destRect))
- return; // Nothing visible in destRect.
-
- // Find the corresponding rect in the source image.
- SkMatrix destToSrcTransform;
- SkRect srcRectVisibleSubset;
- destToSrcTransform.setRectToRect(destRect, srcRect, SkMatrix::kFill_ScaleToFit);
- destToSrcTransform.mapRect(&srcRectVisibleSubset, destRectVisibleSubset);
-
- SkRect scaledSrcRect;
- SkBitmap scaledImageFragment = extractScaledImageFragment(srcRectVisibleSubset, realScaleX, realScaleY, &scaledSrcRect);
-
- context->drawBitmapRect(scaledImageFragment, &scaledSrcRect, destRectVisibleSubset, &paint);
-}
-
-NativeImageSkia::NativeImageSkia()
- : m_resolutionScale(1)
- , m_resizeRequests(0)
-{
-}
-
-NativeImageSkia::NativeImageSkia(const SkBitmap& other, float resolutionScale)
- : m_image(other)
- , m_resolutionScale(resolutionScale)
- , m_resizeRequests(0)
-{
-}
-
-NativeImageSkia::NativeImageSkia(const SkBitmap& image, float resolutionScale, const SkBitmap& resizedImage, const ImageResourceInfo& cachedImageInfo, int resizeRequests)
- : m_image(image)
- , m_resolutionScale(resolutionScale)
- , m_resizedImage(resizedImage)
- , m_cachedImageInfo(cachedImageInfo)
- , m_resizeRequests(resizeRequests)
-{
-}
-
-NativeImageSkia::~NativeImageSkia()
-{
-}
-
-int NativeImageSkia::decodedSize() const
-{
- return m_image.getSize() + m_resizedImage.getSize();
-}
-
-bool NativeImageSkia::hasResizedBitmap(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const
-{
- bool imageScaleEqual = m_cachedImageInfo.scaledImageSize == scaledImageSize;
- bool scaledImageSubsetAvailable = m_cachedImageInfo.scaledImageSubset.contains(scaledImageSubset);
- return imageScaleEqual && scaledImageSubsetAvailable && !m_resizedImage.empty();
-}
-
-SkBitmap NativeImageSkia::resizedBitmap(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const
-{
- ASSERT(!DeferredImageDecoder::isLazyDecoded(m_image));
-
- if (!hasResizedBitmap(scaledImageSize, scaledImageSubset)) {
- bool shouldCache = isDataComplete()
- && shouldCacheResampling(scaledImageSize, scaledImageSubset);
-
- PlatformInstrumentation::willResizeImage(shouldCache);
- SkBitmap resizedImage = skia::ImageOperations::Resize(m_image, skia::ImageOperations::RESIZE_LANCZOS3, scaledImageSize.width(), scaledImageSize.height(), scaledImageSubset);
- resizedImage.setImmutable();
- PlatformInstrumentation::didResizeImage();
-
- if (!shouldCache)
- return resizedImage;
-
- m_resizedImage = resizedImage;
- }
-
- SkBitmap resizedSubset;
- SkIRect resizedSubsetRect = m_cachedImageInfo.rectInSubset(scaledImageSubset);
- m_resizedImage.extractSubset(&resizedSubset, resizedSubsetRect);
- return resizedSubset;
-}
-
-static bool hasNon90rotation(GraphicsContext* context)
-{
- return !context->getTotalMatrix().rectStaysRect();
-}
-
-void NativeImageSkia::draw(GraphicsContext* context, const SkRect& srcRect, const SkRect& destRect, PassRefPtr<SkXfermode> compOp) const
-{
- TRACE_EVENT0("skia", "NativeImageSkia::draw");
- SkPaint paint;
- paint.setXfermode(compOp.get());
- paint.setColorFilter(context->colorFilter());
- paint.setAlpha(context->getNormalizedAlpha());
- paint.setLooper(context->drawLooper());
- // only antialias if we're rotated or skewed
- paint.setAntiAlias(hasNon90rotation(context));
-
- ResamplingMode resampling;
- if (context->isAccelerated()) {
- resampling = LinearResampling;
- } else if (context->printing()) {
- resampling = NoResampling;
- } 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 = computeResamplingMode(totalMatrix,
- SkScalarToFloat(srcRect.width()), SkScalarToFloat(srcRect.height()),
- SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTarget.height()));
- }
-
- if (resampling == NoResampling) {
- // 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 NoResampling
- // being returned from computeResamplingMode.
- resampling = LinearResampling;
- }
- resampling = limitResamplingMode(context, resampling);
- paint.setFilterBitmap(resampling == LinearResampling);
-
- bool isLazyDecoded = DeferredImageDecoder::isLazyDecoded(bitmap());
- // FIXME: Bicubic filtering in Skia is only applied to defer-decoded images
- // as an experiment. Once this filtering code path becomes stable we should
- // turn this on for all cases, including non-defer-decoded images.
- bool useBicubicFilter = resampling == AwesomeResampling && isLazyDecoded;
-
- if (useBicubicFilter)
- paint.setFilterLevel(SkPaint::kHigh_FilterLevel);
-
- if (resampling == AwesomeResampling && !useBicubicFilter) {
- // Resample the image and then draw the result to canvas with bilinear
- // filtering.
- drawResampledBitmap(context, paint, srcRect, destRect);
- } else {
- // 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
- // don't send extra pixels.
- context->drawBitmapRect(bitmap(), &srcRect, destRect, &paint);
- }
- if (isLazyDecoded)
- PlatformInstrumentation::didDrawLazyPixelRef(reinterpret_cast<unsigned long long>(bitmap().pixelRef()));
- context->didDrawRect(destRect, paint, &bitmap());
-}
-
-static SkBitmap createBitmapWithSpace(const SkBitmap& bitmap, int spaceWidth, int spaceHeight)
-{
- SkBitmap result;
- result.setConfig(bitmap.config(),
- bitmap.width() + spaceWidth,
- bitmap.height() + spaceHeight);
- result.allocPixels();
-
- result.eraseColor(SK_ColorTRANSPARENT);
- bitmap.copyPixelsTo(reinterpret_cast<uint8_t*>(result.getPixels()), result.rowBytes() * result.height(), result.rowBytes());
-
- return result;
-}
-
-void NativeImageSkia::drawPattern(
- GraphicsContext* context,
- const FloatRect& floatSrcRect,
- const FloatSize& scale,
- const FloatPoint& phase,
- CompositeOperator compositeOp,
- const FloatRect& destRect,
- blink::WebBlendMode blendMode,
- const IntSize& repeatSpacing) const
-{
- FloatRect normSrcRect = floatSrcRect;
- normSrcRect.intersect(FloatRect(0, 0, bitmap().width(), bitmap().height()));
- if (destRect.isEmpty() || normSrcRect.isEmpty())
- return; // nothing to draw
-
- SkMatrix totalMatrix = context->getTotalMatrix();
- SkScalar ctmScaleX = totalMatrix.getScaleX();
- SkScalar ctmScaleY = totalMatrix.getScaleY();
- totalMatrix.preScale(scale.width(), scale.height());
-
- // Figure out what size the bitmap will be in the destination. The
- // destination rect is the bounds of the pattern, we need to use the
- // matrix to see how big it will be.
- SkRect destRectTarget;
- totalMatrix.mapRect(&destRectTarget, normSrcRect);
-
- float destBitmapWidth = SkScalarToFloat(destRectTarget.width());
- float destBitmapHeight = SkScalarToFloat(destRectTarget.height());
-
- // Compute the resampling mode.
- ResamplingMode resampling;
- if (context->isAccelerated() || context->printing())
- resampling = LinearResampling;
- else
- resampling = computeResamplingMode(totalMatrix, normSrcRect.width(), normSrcRect.height(), destBitmapWidth, destBitmapHeight);
- resampling = limitResamplingMode(context, resampling);
-
- SkMatrix shaderTransform;
- RefPtr<SkShader> shader;
-
- bool isLazyDecoded = DeferredImageDecoder::isLazyDecoded(bitmap());
- // Bicubic filter is only applied to defer-decoded images, see
- // NativeImageSkia::draw for details.
- bool useBicubicFilter = resampling == AwesomeResampling && isLazyDecoded;
-
- if (resampling == AwesomeResampling && !useBicubicFilter) {
- // Do nice resampling.
- float scaleX = destBitmapWidth / normSrcRect.width();
- float scaleY = destBitmapHeight / normSrcRect.height();
- SkRect scaledSrcRect;
-
- // The image fragment generated here is not exactly what is
- // requested. The scale factor used is approximated and image
- // fragment is slightly larger to align to integer
- // boundaries.
- SkBitmap resampled = extractScaledImageFragment(normSrcRect, scaleX, scaleY, &scaledSrcRect);
- if (repeatSpacing.isZero()) {
- shader = adoptRef(SkShader::CreateBitmapShader(resampled, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
- } else {
- shader = adoptRef(SkShader::CreateBitmapShader(
- createBitmapWithSpace(resampled, repeatSpacing.width() * ctmScaleX, repeatSpacing.height() * ctmScaleY),
- SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
- }
-
- // Since we just resized the bitmap, we need to remove the scale
- // applied to the pixels in the bitmap shader. This means we need
- // CTM * shaderTransform to have identity scale. Since we
- // can't modify CTM (or the rectangle will be drawn in the wrong
- // place), we must set shaderTransform's scale to the inverse of
- // CTM scale.
- shaderTransform.setScale(ctmScaleX ? 1 / ctmScaleX : 1, ctmScaleY ? 1 / ctmScaleY : 1);
- } else {
- // No need to resample before drawing.
- SkBitmap srcSubset;
- bitmap().extractSubset(&srcSubset, enclosingIntRect(normSrcRect));
- if (repeatSpacing.isZero()) {
- shader = adoptRef(SkShader::CreateBitmapShader(srcSubset, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
- } else {
- shader = adoptRef(SkShader::CreateBitmapShader(
- createBitmapWithSpace(srcSubset, repeatSpacing.width() * ctmScaleX, repeatSpacing.height() * ctmScaleY),
- SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
- }
-
- // Because no resizing occurred, the shader transform should be
- // set to the pattern's transform, which just includes scale.
- shaderTransform.setScale(scale.width(), scale.height());
- }
-
- // We also need to translate it such that the origin of the pattern is the
- // origin of the destination rect, which is what WebKit expects. Skia uses
- // the coordinate system origin as the base for the pattern. If WebKit wants
- // a shifted image, it will shift it from there using the shaderTransform.
- float adjustedX = phase.x() + normSrcRect.x() * scale.width();
- float adjustedY = phase.y() + normSrcRect.y() * scale.height();
- shaderTransform.postTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjustedY));
- shader->setLocalMatrix(shaderTransform);
-
- SkPaint paint;
- paint.setShader(shader.get());
- paint.setXfermode(WebCoreCompositeToSkiaComposite(compositeOp, blendMode).get());
- paint.setColorFilter(context->colorFilter());
-
- paint.setFilterBitmap(resampling == LinearResampling);
- if (useBicubicFilter)
- paint.setFilterLevel(SkPaint::kHigh_FilterLevel);
- if (isLazyDecoded)
- PlatformInstrumentation::didDrawLazyPixelRef(reinterpret_cast<unsigned long long>(bitmap().pixelRef()));
-
- context->drawRect(destRect, paint);
-}
-
-bool NativeImageSkia::shouldCacheResampling(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const
-{
- // Check whether the requested dimensions match previous request.
- bool matchesPreviousRequest = m_cachedImageInfo.isEqual(scaledImageSize, scaledImageSubset);
- if (matchesPreviousRequest)
- ++m_resizeRequests;
- else {
- m_cachedImageInfo.set(scaledImageSize, scaledImageSubset);
- m_resizeRequests = 0;
- // Reset m_resizedImage now, because we don't distinguish
- // between the last requested resize info and m_resizedImage's
- // resize info.
- m_resizedImage.reset();
- }
-
- // We can not cache incomplete frames. This might be a good optimization in
- // the future, were we know how much of the frame has been decoded, so when
- // we incrementally draw more of the image, we only have to resample the
- // parts that are changed.
- if (!isDataComplete())
- return false;
-
- // If the destination bitmap is excessively large, we'll never allow caching.
- static const unsigned long long kLargeBitmapSize = 4096ULL * 4096ULL;
- unsigned long long fullSize = static_cast<unsigned long long>(scaledImageSize.width()) * static_cast<unsigned long long>(scaledImageSize.height());
- unsigned long long fragmentSize = static_cast<unsigned long long>(scaledImageSubset.width()) * static_cast<unsigned long long>(scaledImageSubset.height());
-
- if (fragmentSize > kLargeBitmapSize)
- return false;
-
- // If the destination bitmap is small, we'll always allow caching, since
- // there is not very much penalty for computing it and it may come in handy.
- static const unsigned kSmallBitmapSize = 4096;
- if (fragmentSize <= kSmallBitmapSize)
- return true;
-
- // If "too many" requests have been made for this bitmap, we assume that
- // many more will be made as well, and we'll go ahead and cache it.
- static const int kManyRequestThreshold = 4;
- if (m_resizeRequests >= kManyRequestThreshold)
- return true;
-
- // If more than 1/4 of the resized image is requested, it's worth caching.
- return fragmentSize > fullSize / 4;
-}
-
-NativeImageSkia::ImageResourceInfo::ImageResourceInfo()
-{
- scaledImageSize.setEmpty();
- scaledImageSubset.setEmpty();
-}
-
-bool NativeImageSkia::ImageResourceInfo::isEqual(const SkISize& otherScaledImageSize, const SkIRect& otherScaledImageSubset) const
-{
- return scaledImageSize == otherScaledImageSize && scaledImageSubset == otherScaledImageSubset;
-}
-
-void NativeImageSkia::ImageResourceInfo::set(const SkISize& otherScaledImageSize, const SkIRect& otherScaledImageSubset)
-{
- scaledImageSize = otherScaledImageSize;
- scaledImageSubset = otherScaledImageSubset;
-}
-
-SkIRect NativeImageSkia::ImageResourceInfo::rectInSubset(const SkIRect& otherScaledImageSubset)
-{
- if (!scaledImageSubset.contains(otherScaledImageSubset))
- return SkIRect::MakeEmpty();
- SkIRect subsetRect = otherScaledImageSubset;
- subsetRect.offset(-scaledImageSubset.x(), -scaledImageSubset.y());
- return subsetRect;
-}
-
-} // namespace WebCore
« no previous file with comments | « Source/core/platform/graphics/skia/NativeImageSkia.h ('k') | Source/core/platform/graphics/skia/OpaqueRegionSkia.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698