diff --git a/engine/core/core.gni b/engine/core/core.gni index 1e7ffae02a6..0c8c4c76639 100644 --- a/engine/core/core.gni +++ b/engine/core/core.gni @@ -1074,8 +1074,6 @@ sky_core_files = [ "rendering/HitTestRequest.h", "rendering/HitTestResult.cpp", "rendering/HitTestResult.h", - "rendering/ImageQualityController.cpp", - "rendering/ImageQualityController.h", "rendering/InlineBox.cpp", "rendering/InlineBox.h", "rendering/InlineFlowBox.cpp", diff --git a/engine/core/rendering/ImageQualityController.cpp b/engine/core/rendering/ImageQualityController.cpp deleted file mode 100644 index 981c5f7a7ed..00000000000 --- a/engine/core/rendering/ImageQualityController.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2013 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 "sky/engine/config.h" -#include "sky/engine/core/rendering/ImageQualityController.h" - -#include "sky/engine/core/frame/FrameView.h" -#include "sky/engine/core/frame/LocalFrame.h" -#include "sky/engine/platform/graphics/GraphicsContext.h" - -namespace blink { - -static const double cLowQualityTimeThreshold = 0.500; // 500 ms - -static ImageQualityController* gImageQualityController = 0; - -ImageQualityController* ImageQualityController::imageQualityController() -{ - if (!gImageQualityController) - gImageQualityController = new ImageQualityController; - - return gImageQualityController; -} - -void ImageQualityController::remove(RenderObject* renderer) -{ - if (gImageQualityController) { - gImageQualityController->objectDestroyed(renderer); - if (gImageQualityController->isEmpty()) { - delete gImageQualityController; - gImageQualityController = 0; - } - } -} - -bool ImageQualityController::has(RenderObject* renderer) -{ - return gImageQualityController && gImageQualityController->m_objectLayerSizeMap.contains(renderer); -} - -InterpolationQuality ImageQualityController::chooseInterpolationQuality(GraphicsContext* context, RenderObject* object, Image* image, const void* layer, const LayoutSize& layoutSize) -{ - if (object->style()->imageRendering() == ImageRenderingPixelated - && image - && (layoutSize.width() > image->width() || layoutSize.height() > image->height() || layoutSize == image->size())) { - return InterpolationNone; - } - - if (InterpolationDefault == InterpolationLow) - return InterpolationLow; - - if (shouldPaintAtLowQuality(context, object, image, layer, layoutSize)) - return InterpolationLow; - - // For images that are potentially animated we paint them at medium quality. - if (image && image->maybeAnimated()) - return InterpolationMedium; - - return InterpolationDefault; -} - -ImageQualityController::~ImageQualityController() -{ - // This will catch users of ImageQualityController that forget to call cleanUp. - ASSERT(!gImageQualityController || gImageQualityController->isEmpty()); -} - -// FIXME(sky): m_liveResizeOptimizationIsActive is never set to true. -ImageQualityController::ImageQualityController() - : m_timer(this, &ImageQualityController::highQualityRepaintTimerFired) - , m_animatedResizeIsActive(false) - , m_liveResizeOptimizationIsActive(false) -{ -} - -void ImageQualityController::removeLayer(RenderObject* object, LayerSizeMap* innerMap, const void* layer) -{ - if (innerMap) { - innerMap->remove(layer); - if (innerMap->isEmpty()) - objectDestroyed(object); - } -} - -void ImageQualityController::set(RenderObject* object, LayerSizeMap* innerMap, const void* layer, const LayoutSize& size) -{ - if (innerMap) - innerMap->set(layer, size); - else { - LayerSizeMap newInnerMap; - newInnerMap.set(layer, size); - m_objectLayerSizeMap.set(object, newInnerMap); - } -} - -void ImageQualityController::objectDestroyed(RenderObject* object) -{ - m_objectLayerSizeMap.remove(object); - if (m_objectLayerSizeMap.isEmpty()) { - m_animatedResizeIsActive = false; - m_timer.stop(); - } -} - -void ImageQualityController::highQualityRepaintTimerFired(Timer*) -{ - if (!m_animatedResizeIsActive && !m_liveResizeOptimizationIsActive) - return; - m_animatedResizeIsActive = false; - - for (ObjectLayerSizeMap::iterator it = m_objectLayerSizeMap.begin(); it != m_objectLayerSizeMap.end(); ++it) { - it->key->scheduleVisualUpdate(); - } - - m_liveResizeOptimizationIsActive = false; -} - -void ImageQualityController::restartTimer() -{ - m_timer.startOneShot(cLowQualityTimeThreshold, FROM_HERE); -} - -bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, RenderObject* object, Image* image, const void *layer, const LayoutSize& layoutSize) -{ - // 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()) - return false; - - if (object->style()->imageRendering() == ImageRenderingOptimizeContrast) - return true; - - // Look ourselves up in the hashtables. - ObjectLayerSizeMap::iterator i = m_objectLayerSizeMap.find(object); - LayerSizeMap* innerMap = i != m_objectLayerSizeMap.end() ? &i->value : 0; - LayoutSize oldSize; - bool isFirstResize = true; - if (innerMap) { - LayerSizeMap::iterator j = innerMap->find(layer); - if (j != innerMap->end()) { - isFirstResize = false; - oldSize = j->value; - } - } - - const AffineTransform& currentTransform = context->getCTM(); - bool contextIsScaled = !currentTransform.isIdentityOrTranslationOrFlipped(); - - LayoutSize scaledImageSize = currentTransform.mapSize(image->size()); - LayoutSize scaledLayoutSize = currentTransform.mapSize(roundedIntSize(layoutSize)); - - // If the containing FrameView is being resized, paint at low quality until resizing is finished. - if (m_liveResizeOptimizationIsActive) { - // Live resize has ended, paint in HQ and remove this object from the list. - removeLayer(object, innerMap, layer); - return false; - } - - // See crbug.com/382491. This test is insufficient to ensure that there is no scale - // applied in the compositor, but it is probably adequate here. In the worst case we - // draw at high quality when we need not. - if (!contextIsScaled && scaledLayoutSize == scaledImageSize) { - // 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; - } - - // If an animated resize is active, paint in low quality and kick the timer ahead. - if (m_animatedResizeIsActive) { - set(object, innerMap, layer, scaledLayoutSize); - restartTimer(); - return true; - } - // 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 - // size and set the timer. - if (isFirstResize || oldSize == scaledLayoutSize) { - restartTimer(); - set(object, innerMap, layer, scaledLayoutSize); - return false; - } - // 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; - } - // 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 - // the object to the list for high quality redraw. - set(object, innerMap, layer, scaledLayoutSize); - m_animatedResizeIsActive = true; - restartTimer(); - return true; -} - -} // namespace blink diff --git a/engine/core/rendering/ImageQualityController.h b/engine/core/rendering/ImageQualityController.h deleted file mode 100644 index 4179de3c5f9..00000000000 --- a/engine/core/rendering/ImageQualityController.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -#ifndef SKY_ENGINE_CORE_RENDERING_IMAGEQUALITYCONTROLLER_H_ -#define SKY_ENGINE_CORE_RENDERING_IMAGEQUALITYCONTROLLER_H_ - -#include "sky/engine/core/rendering/RenderObject.h" -#include "sky/engine/platform/geometry/IntSize.h" -#include "sky/engine/platform/geometry/LayoutSize.h" -#include "sky/engine/platform/graphics/Image.h" -#include "sky/engine/platform/graphics/ImageOrientation.h" -#include "sky/engine/platform/graphics/ImageSource.h" -#include "sky/engine/wtf/HashMap.h" - -namespace blink { - -typedef HashMap LayerSizeMap; -typedef HashMap ObjectLayerSizeMap; - -class ImageQualityController final { - WTF_MAKE_NONCOPYABLE(ImageQualityController); WTF_MAKE_FAST_ALLOCATED; -public: - ~ImageQualityController(); - - static ImageQualityController* imageQualityController(); - - static void remove(RenderObject*); - - InterpolationQuality chooseInterpolationQuality(GraphicsContext*, RenderObject*, Image*, const void* layer, const LayoutSize&); - - // For testing. - static bool has(RenderObject*); - // This is public for testing. Do not call this from other classes. - void set(RenderObject*, LayerSizeMap* innerMap, const void* layer, const LayoutSize&); - -private: - ImageQualityController(); - - bool shouldPaintAtLowQuality(GraphicsContext*, RenderObject*, Image*, const void* layer, const LayoutSize&); - void removeLayer(RenderObject*, LayerSizeMap* innerMap, const void* layer); - void objectDestroyed(RenderObject*); - bool isEmpty() { return m_objectLayerSizeMap.isEmpty(); } - - void highQualityRepaintTimerFired(Timer*); - void restartTimer(); - - ObjectLayerSizeMap m_objectLayerSizeMap; - Timer m_timer; - bool m_animatedResizeIsActive; - bool m_liveResizeOptimizationIsActive; -}; - -} // namespace blink - -#endif // SKY_ENGINE_CORE_RENDERING_IMAGEQUALITYCONTROLLER_H_ diff --git a/engine/core/rendering/RenderBoxModelObject.cpp b/engine/core/rendering/RenderBoxModelObject.cpp index 44d7c21eada..a9ab8dd745f 100644 --- a/engine/core/rendering/RenderBoxModelObject.cpp +++ b/engine/core/rendering/RenderBoxModelObject.cpp @@ -27,7 +27,6 @@ #include "sky/engine/core/rendering/RenderBoxModelObject.h" #include "sky/engine/core/frame/Settings.h" -#include "sky/engine/core/rendering/ImageQualityController.h" #include "sky/engine/core/rendering/RenderBlock.h" #include "sky/engine/core/rendering/RenderGeometryMap.h" #include "sky/engine/core/rendering/RenderInline.h" @@ -69,11 +68,6 @@ bool RenderBoxModelObject::hasAcceleratedCompositing() const return false; } -InterpolationQuality RenderBoxModelObject::chooseInterpolationQuality(GraphicsContext* context, Image* image, const void* layer, const LayoutSize& size) -{ - return ImageQualityController::imageQualityController()->chooseInterpolationQuality(context, this, image, layer, size); -} - RenderBoxModelObject::RenderBoxModelObject(ContainerNode* node) : RenderLayerModelObject(node) { @@ -83,12 +77,6 @@ RenderBoxModelObject::~RenderBoxModelObject() { } -void RenderBoxModelObject::willBeDestroyed() -{ - ImageQualityController::remove(this); - RenderLayerModelObject::willBeDestroyed(); -} - bool RenderBoxModelObject::calculateHasBoxDecorations() const { RenderStyle* styleToUse = style(); @@ -520,11 +508,10 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co CompositeOperator compositeOp = bgLayer.composite(); RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this; RefPtr image = bgImage->image(clientForBackgroundImage, geometry.tileSize()); - InterpolationQuality interpolationQuality = chooseInterpolationQuality(context, image.get(), &bgLayer, geometry.tileSize()); if (bgLayer.maskSourceType() == MaskLuminance) context->setColorFilter(ColorFilterLuminanceToAlpha); InterpolationQuality previousInterpolationQuality = context->imageInterpolationQuality(); - context->setImageInterpolationQuality(interpolationQuality); + context->setImageInterpolationQuality(InterpolationLow); context->drawTiledImage(image.get(), geometry.destRect(), geometry.relativePhase(), geometry.tileSize(), compositeOp, bgLayer.blendMode(), geometry.spaceSize()); context->setImageInterpolationQuality(previousInterpolationQuality); diff --git a/engine/core/rendering/RenderBoxModelObject.h b/engine/core/rendering/RenderBoxModelObject.h index ed48a212646..4db5769265f 100644 --- a/engine/core/rendering/RenderBoxModelObject.h +++ b/engine/core/rendering/RenderBoxModelObject.h @@ -169,8 +169,6 @@ public: bool hasAcceleratedCompositing() const; protected: - virtual void willBeDestroyed() override; - class BackgroundImageGeometry { public: BackgroundImageGeometry() @@ -244,8 +242,6 @@ protected: RoundedRect backgroundRoundedRectAdjustedForBleedAvoidance(GraphicsContext*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox*, const LayoutSize&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const; LayoutRect borderInnerRectAdjustedForBleedAvoidance(GraphicsContext*, const LayoutRect&, BackgroundBleedAvoidance) const; - InterpolationQuality chooseInterpolationQuality(GraphicsContext*, Image*, const void*, const LayoutSize&); - LayoutRect localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset); static void clipRoundedInnerRect(GraphicsContext*, const LayoutRect&, const RoundedRect& clipRect); diff --git a/engine/core/rendering/RenderImage.cpp b/engine/core/rendering/RenderImage.cpp index 2f3a8530f3b..a1a95039304 100644 --- a/engine/core/rendering/RenderImage.cpp +++ b/engine/core/rendering/RenderImage.cpp @@ -207,11 +207,10 @@ void RenderImage::paintIntoRect(GraphicsContext* context, const LayoutRect& rect return; Image* image = img.get(); - InterpolationQuality interpolationQuality = chooseInterpolationQuality(context, image, image, alignedRect.size()); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(*this)); InterpolationQuality previousInterpolationQuality = context->imageInterpolationQuality(); - context->setImageInterpolationQuality(interpolationQuality); + context->setImageInterpolationQuality(InterpolationLow); context->drawImage(image, alignedRect, CompositeSourceOver, shouldRespectImageOrientation()); context->setImageInterpolationQuality(previousInterpolationQuality); } diff --git a/tests/framework/flights-app-pixels-expected.sky b/tests/framework/flights-app-pixels-expected.sky index 88c89dc6d8e..91c4ee23ba3 100644 --- a/tests/framework/flights-app-pixels-expected.sky +++ b/tests/framework/flights-app-pixels-expected.sky @@ -1,7 +1,7 @@ - +