diff options
Diffstat (limited to 'Source/WebCore/rendering/ImageQualityController.cpp')
-rw-r--r-- | Source/WebCore/rendering/ImageQualityController.cpp | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/Source/WebCore/rendering/ImageQualityController.cpp b/Source/WebCore/rendering/ImageQualityController.cpp index e82eed6dc..1bc82e97f 100644 --- a/Source/WebCore/rendering/ImageQualityController.cpp +++ b/Source/WebCore/rendering/ImageQualityController.cpp @@ -39,9 +39,7 @@ static const double cLowQualityTimeThreshold = 0.500; // 500 ms ImageQualityController::ImageQualityController(const RenderView& renderView) : m_renderView(renderView) - , m_timer(this, &ImageQualityController::highQualityRepaintTimerFired) - , m_animatedResizeIsActive(false) - , m_liveResizeOptimizationIsActive(false) + , m_timer(*this, &ImageQualityController::highQualityRepaintTimerFired) { } @@ -74,9 +72,9 @@ void ImageQualityController::removeObject(RenderBoxModelObject* object) } } -void ImageQualityController::highQualityRepaintTimerFired(Timer<ImageQualityController>&) +void ImageQualityController::highQualityRepaintTimerFired() { - if (m_renderView.documentBeingDestroyed()) + if (m_renderView.renderTreeBeingDestroyed()) return; if (!m_animatedResizeIsActive && !m_liveResizeOptimizationIsActive) return; @@ -99,26 +97,34 @@ void ImageQualityController::restartTimer() m_timer.startOneShot(cLowQualityTimeThreshold); } -bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, RenderBoxModelObject* object, Image* image, const void *layer, const LayoutSize& size) +std::optional<InterpolationQuality> ImageQualityController::interpolationQualityFromStyle(const RenderStyle& style) { - // If the image is not a bitmap image, then none of this is relevant and we just paint at high - // quality. - if (!image || !(image->isBitmapImage() || image->isPDFDocumentImage()) || context->paintingDisabled()) - return false; - - switch (object->style().imageRendering()) { + switch (style.imageRendering()) { case ImageRenderingOptimizeSpeed: + return InterpolationLow; case ImageRenderingCrispEdges: - return true; + case ImageRenderingPixelated: + return InterpolationNone; case ImageRenderingOptimizeQuality: - return false; + return InterpolationDefault; // FIXME: CSS 3 Images says that optimizeQuality should behave like 'auto', but that prevents authors from overriding this low quality rendering behavior. case ImageRenderingAuto: break; } + return std::nullopt; +} + +InterpolationQuality ImageQualityController::chooseInterpolationQuality(GraphicsContext& context, RenderBoxModelObject* object, Image& image, const void* layer, const LayoutSize& size) +{ + // If the image is not a bitmap image, then none of this is relevant and we just paint at high quality. + if (!(image.isBitmapImage() || image.isPDFDocumentImage()) || context.paintingDisabled()) + return InterpolationDefault; + + if (std::optional<InterpolationQuality> styleInterpolation = interpolationQualityFromStyle(object->style())) + return styleInterpolation.value(); // Make sure to use the unzoomed image size, since if a full page zoom is in effect, the image // is actually being scaled. - IntSize imageSize(image->width(), image->height()); + IntSize imageSize(image.width(), image.height()); // Look ourselves up in the hashtables. auto i = m_objectLayerSizeMap.find(object); @@ -140,32 +146,32 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R set(object, innerMap, layer, size); restartTimer(); m_liveResizeOptimizationIsActive = true; - return true; + return InterpolationLow; } if (m_liveResizeOptimizationIsActive) - return false; + return InterpolationDefault; } - const AffineTransform& currentTransform = context->getCTM(); + const AffineTransform& currentTransform = context.getCTM(); bool contextIsScaled = !currentTransform.isIdentityOrTranslationOrFlipped(); if (!contextIsScaled && size == imageSize) { // There is no scale in effect. If we had a scale in effect before, we can just remove this object from the list. removeLayer(object, innerMap, layer); - return false; + return InterpolationDefault; } // There is no need to hash scaled images that always use low quality mode when the page demands it. This is the iChat case. - if (m_renderView.frame().page()->inLowQualityImageInterpolationMode()) { - double totalPixels = static_cast<double>(image->width()) * static_cast<double>(image->height()); + if (m_renderView.page().inLowQualityImageInterpolationMode()) { + double totalPixels = static_cast<double>(image.width()) * static_cast<double>(image.height()); if (totalPixels > cInterpolationCutoff) - return true; + return InterpolationLow; } // If an animated resize is active, paint in low quality and kick the timer ahead. if (m_animatedResizeIsActive) { set(object, innerMap, layer, size); restartTimer(); - return true; + return InterpolationLow; } // If this is the first time resizing this image, or its size is the // same as the last resize, draw at high res, but record the paint @@ -173,13 +179,13 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R if (isFirstResize || oldSize == size) { restartTimer(); set(object, innerMap, layer, size); - return false; + return InterpolationDefault; } // If the timer is no longer active, draw at high quality and don't // set the timer. if (!m_timer.isActive()) { removeLayer(object, innerMap, layer); - return false; + return InterpolationDefault; } // This object has been resized to two different sizes while the timer // is active, so draw at low quality, set the flag for animated resizes and @@ -187,7 +193,7 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R set(object, innerMap, layer, size); m_animatedResizeIsActive = true; restartTimer(); - return true; + return InterpolationLow; } } |