summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderLayerBacking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderLayerBacking.cpp')
-rw-r--r--Source/WebCore/rendering/RenderLayerBacking.cpp1868
1 files changed, 1055 insertions, 813 deletions
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index 1c1c6e9a8..a8961494a 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. 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
@@ -25,19 +25,18 @@
#include "config.h"
-#if USE(ACCELERATED_COMPOSITING)
-
#include "RenderLayerBacking.h"
-#include "AnimationController.h"
+#include "CSSAnimationController.h"
#include "CanvasRenderingContext.h"
#include "CSSPropertyNames.h"
#include "CachedImage.h"
#include "Chrome.h"
-#include "FontCache.h"
+#include "FilterEffectRenderer.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "GraphicsLayer.h"
+#include "HTMLBodyElement.h"
#include "HTMLCanvasElement.h"
#include "HTMLIFrameElement.h"
#include "HTMLMediaElement.h"
@@ -46,13 +45,16 @@
#include "InspectorInstrumentation.h"
#include "KeyframeList.h"
#include "MainFrame.h"
+#include "Page.h"
#include "PluginViewBase.h"
#include "ProgressTracker.h"
#include "RenderFlowThread.h"
+#include "RenderHTMLCanvas.h"
#include "RenderIFrame.h"
#include "RenderImage.h"
#include "RenderLayerCompositor.h"
#include "RenderEmbeddedObject.h"
+#include "RenderMedia.h"
#include "RenderNamedFlowFragment.h"
#include "RenderRegion.h"
#include "RenderVideo.h"
@@ -61,28 +63,20 @@
#include "Settings.h"
#include "StyleResolver.h"
#include "TiledBacking.h"
-#include <wtf/text/StringBuilder.h>
-
-#if ENABLE(CSS_FILTERS)
-#include "FilterEffectRenderer.h"
-#endif
-#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
-#include "GraphicsContext3D.h"
+#if PLATFORM(IOS)
+#include "RuntimeApplicationChecks.h"
#endif
namespace WebCore {
using namespace HTMLNames;
-static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
-static IntRect clipBox(RenderBox& renderer);
-
CanvasCompositingStrategy canvasCompositingStrategy(const RenderObject& renderer)
{
ASSERT(renderer.isCanvas());
- const HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer.node());
+ const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer.node());
CanvasRenderingContext* context = canvas->renderingContext();
if (!context || !context->isAccelerated())
return UnacceleratedCanvas;
@@ -97,106 +91,86 @@ CanvasCompositingStrategy canvasCompositingStrategy(const RenderObject& renderer
#endif
}
-// Get the scrolling coordinator in a way that works inside RenderLayerBacking's destructor.
-static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer& layer)
-{
- Page* page = layer.renderer().frame().page();
- if (!page)
- return 0;
-
- return page->scrollingCoordinator();
-}
-
-bool RenderLayerBacking::m_creatingPrimaryGraphicsLayer = false;
-
RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
: m_owningLayer(layer)
- , m_scrollLayerID(0)
- , m_artificiallyInflatedBounds(false)
- , m_isMainFrameRenderViewLayer(false)
- , m_usingTiledCacheLayer(false)
- , m_requiresOwnBackingStore(true)
-#if ENABLE(CSS_FILTERS)
- , m_canCompositeFilters(false)
-#endif
- , m_backgroundLayerPaintsFixedRootBackground(false)
{
- Page* page = renderer().frame().page();
-
- if (layer.isRootLayer() && page) {
- if (renderer().frame().isMainFrame())
- m_isMainFrameRenderViewLayer = true;
-
- m_usingTiledCacheLayer = page->chrome().client().shouldUseTiledBackingForFrameView(renderer().frame().view());
+ if (layer.isRootLayer()) {
+ m_isMainFrameRenderViewLayer = renderer().frame().isMainFrame();
+ m_isMainFrameLayerWithTiledBacking = renderer().page().chrome().client().shouldUseTiledBackingForFrameView(renderer().view().frameView());
}
createPrimaryGraphicsLayer();
- if (m_usingTiledCacheLayer && page) {
- TiledBacking* tiledBacking = this->tiledBacking();
-
- tiledBacking->setIsInWindow(page->isInWindow());
+ if (TiledBacking* tiledBacking = this->tiledBacking()) {
+ tiledBacking->setIsInWindow(renderer().page().isInWindow());
- if (m_isMainFrameRenderViewLayer) {
- tiledBacking->setExposedRect(renderer().frame().view()->exposedRect());
- tiledBacking->setUnparentsOffscreenTiles(true);
- setTiledBackingHasMargins(page->settings().backgroundShouldExtendBeyondPage());
+ if (m_isMainFrameLayerWithTiledBacking) {
+ tiledBacking->setScrollingPerformanceLoggingEnabled(renderer().settings().scrollingPerformanceLoggingEnabled());
+ adjustTiledBackingCoverage();
}
-
- tiledBacking->setScrollingPerformanceLoggingEnabled(page->settings().scrollingPerformanceLoggingEnabled());
- adjustTiledBackingCoverage();
}
}
RenderLayerBacking::~RenderLayerBacking()
{
updateAncestorClippingLayer(false);
+ updateChildClippingStrategy(false);
updateDescendantClippingLayer(false);
updateOverflowControlsLayers(false, false, false);
updateForegroundLayer(false);
updateBackgroundLayer(false);
- updateMaskLayer(false);
+ updateMaskingLayer(false, false);
updateScrollingLayers(false);
- detachFromScrollingCoordinator();
+ detachFromScrollingCoordinator(Scrolling | ViewportConstrained);
destroyGraphicsLayers();
}
void RenderLayerBacking::willDestroyLayer(const GraphicsLayer* layer)
{
- if (layer && layer->usingTiledBacking())
+ if (layer && layer->type() == GraphicsLayer::Type::Normal && layer->tiledBacking())
compositor().layerTiledBackingUsageChanged(layer, false);
}
-std::unique_ptr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name)
+std::unique_ptr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name, GraphicsLayer::Type layerType)
{
- GraphicsLayerFactory* graphicsLayerFactory = 0;
- if (Page* page = renderer().frame().page())
- graphicsLayerFactory = page->chrome().client().graphicsLayerFactory();
+ auto* graphicsLayerFactory = renderer().page().chrome().client().graphicsLayerFactory();
- std::unique_ptr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this);
+ std::unique_ptr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, *this, layerType);
-#ifndef NDEBUG
graphicsLayer->setName(name);
-#else
- UNUSED_PARAM(name);
-#endif
- graphicsLayer->setMaintainsPixelAlignment(compositor().keepLayersPixelAligned());
-#if PLATFORM(MAC) && USE(CA)
+#if PLATFORM(COCOA) && USE(CA)
graphicsLayer->setAcceleratesDrawing(compositor().acceleratedDrawingEnabled());
-#endif
+ graphicsLayer->setUsesDisplayListDrawing(compositor().displayListDrawingEnabled());
+#endif
return graphicsLayer;
}
-bool RenderLayerBacking::shouldUseTiledBacking(const GraphicsLayer*) const
+void RenderLayerBacking::setUsesDisplayListDrawing(bool usesDisplayListDrawing)
{
- return m_usingTiledCacheLayer && m_creatingPrimaryGraphicsLayer;
+ // Note that this only affects the primary layer.
+ if (usesDisplayListDrawing == m_graphicsLayer->usesDisplayListDrawing())
+ return;
+
+ m_graphicsLayer->setUsesDisplayListDrawing(usesDisplayListDrawing);
+ if (m_graphicsLayer->drawsContent())
+ m_graphicsLayer->setNeedsDisplay();
}
-bool RenderLayerBacking::tiledBackingHasMargin() const
+String RenderLayerBacking::displayListAsText(DisplayList::AsTextFlags flags) const
{
- return m_usingTiledCacheLayer && tiledBacking()->hasMargins();
+ return m_graphicsLayer->displayListAsText(flags);
+}
+
+void RenderLayerBacking::setIsTrackingDisplayListReplay(bool isTrackingReplay)
+{
+ m_graphicsLayer->setIsTrackingDisplayListReplay(isTrackingReplay);
+}
+
+String RenderLayerBacking::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
+{
+ return m_graphicsLayer->replayDisplayListAsText(flags);
}
void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
@@ -209,7 +183,7 @@ TiledBacking* RenderLayerBacking::tiledBacking() const
return m_graphicsLayer->tiledBacking();
}
-static TiledBacking::TileCoverage computeTileCoverage(RenderLayerBacking* backing)
+static TiledBacking::TileCoverage computePageTiledBackingCoverage(RenderLayerBacking* backing)
{
// FIXME: When we use TiledBacking for overflow, this should look at RenderView scrollability.
FrameView& frameView = backing->owningLayer().renderer().view().frameView();
@@ -217,38 +191,31 @@ static TiledBacking::TileCoverage computeTileCoverage(RenderLayerBacking* backin
TiledBacking::TileCoverage tileCoverage = TiledBacking::CoverageForVisibleArea;
bool useMinimalTilesDuringLiveResize = frameView.inLiveResize();
if (frameView.speculativeTilingEnabled() && !useMinimalTilesDuringLiveResize) {
- bool clipsToExposedRect = !frameView.exposedRect().isInfinite();
+ bool clipsToExposedRect = static_cast<bool>(frameView.viewExposedRect());
if (frameView.horizontalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
tileCoverage |= TiledBacking::CoverageForHorizontalScrolling;
if (frameView.verticalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
tileCoverage |= TiledBacking::CoverageForVerticalScrolling;
}
- if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(backing->owningLayer())) {
- // Ask our TiledBacking for large tiles unless the only reason we're main-thread-scrolling
- // is a page overlay (find-in-page, the Web Inspector highlight mechanism, etc.).
- if (scrollingCoordinator->synchronousScrollingReasons() & ~ScrollingCoordinator::ForcedOnMainThread)
- tileCoverage |= TiledBacking::CoverageForSlowScrolling;
- }
return tileCoverage;
}
void RenderLayerBacking::adjustTiledBackingCoverage()
{
- if (!m_usingTiledCacheLayer)
+ if (!m_isMainFrameLayerWithTiledBacking)
return;
- TiledBacking::TileCoverage tileCoverage = computeTileCoverage(this);
+ TiledBacking::TileCoverage tileCoverage = computePageTiledBackingCoverage(this);
tiledBacking()->setTileCoverage(tileCoverage);
}
-void RenderLayerBacking::setTiledBackingHasMargins(bool extendBackground)
+void RenderLayerBacking::setTiledBackingHasMargins(bool hasExtendedBackgroundOnLeftAndRight, bool hasExtendedBackgroundOnTopAndBottom)
{
- if (!m_usingTiledCacheLayer)
+ if (!m_isMainFrameLayerWithTiledBacking)
return;
- int marginSize = extendBackground ? 512 : 0;
- tiledBacking()->setTileMargins(marginSize, marginSize, marginSize, marginSize);
+ tiledBacking()->setHasMargins(hasExtendedBackgroundOnTopAndBottom, hasExtendedBackgroundOnTopAndBottom, hasExtendedBackgroundOnLeftAndRight, hasExtendedBackgroundOnLeftAndRight);
}
void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaintCounter)
@@ -297,59 +264,68 @@ void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaint
void RenderLayerBacking::createPrimaryGraphicsLayer()
{
- String layerName;
-#ifndef NDEBUG
- layerName = m_owningLayer.name();
-#endif
-
- // The call to createGraphicsLayer ends calling back into here as
- // a GraphicsLayerClient to ask if it shouldUseTiledBacking(). We only want
- // the tile cache on our main layer. This is pretty ugly, but saves us from
- // exposing the API to all clients.
-
- m_creatingPrimaryGraphicsLayer = true;
- m_graphicsLayer = createGraphicsLayer(layerName);
- m_creatingPrimaryGraphicsLayer = false;
+ String layerName = m_owningLayer.name();
+ const unsigned maxLayerNameLength = 100;
+ if (layerName.length() > maxLayerNameLength) {
+ layerName.truncate(maxLayerNameLength);
+ layerName.append("...");
+ }
+ m_graphicsLayer = createGraphicsLayer(layerName, m_isMainFrameLayerWithTiledBacking ? GraphicsLayer::Type::PageTiledBacking : GraphicsLayer::Type::Normal);
- if (m_usingTiledCacheLayer)
- m_childContainmentLayer = createGraphicsLayer("TiledBacking Flattening Layer");
+ if (m_isMainFrameLayerWithTiledBacking) {
+ m_childContainmentLayer = createGraphicsLayer("Page TiledBacking containment");
+ m_graphicsLayer->addChild(m_childContainmentLayer.get());
+ }
- if (m_isMainFrameRenderViewLayer) {
#if !PLATFORM(IOS)
+ if (m_isMainFrameRenderViewLayer) {
// Page scale is applied above the RenderView on iOS.
- m_graphicsLayer->setContentsOpaque(true);
+ m_graphicsLayer->setContentsOpaque(!compositor().viewHasTransparentBackground());
m_graphicsLayer->setAppliesPageScale();
-#endif
}
+#endif
-#if PLATFORM(MAC) && USE(CA)
+#if PLATFORM(COCOA) && USE(CA)
if (!compositor().acceleratedDrawingEnabled() && renderer().isCanvas()) {
- const HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer().element());
+ const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer().element());
if (canvas->shouldAccelerate(canvas->size()))
m_graphicsLayer->setAcceleratesDrawing(true);
}
#endif
- updateOpacity(&renderer().style());
- updateTransform(&renderer().style());
-#if ENABLE(CSS_FILTERS)
- updateFilters(&renderer().style());
+ updateOpacity(renderer().style());
+ updateTransform(renderer().style());
+ updateFilters(renderer().style());
+#if ENABLE(FILTERS_LEVEL_2)
+ updateBackdropFilters(renderer().style());
#endif
#if ENABLE(CSS_COMPOSITING)
- updateBlendMode(&renderer().style());
+ updateBlendMode(renderer().style());
#endif
+ updateCustomAppearance(renderer().style());
}
#if PLATFORM(IOS)
void RenderLayerBacking::layerWillBeDestroyed()
{
RenderObject& renderer = this->renderer();
- if (renderer.isEmbeddedObject() && toRenderEmbeddedObject(renderer).allowsAcceleratedCompositing()) {
- PluginViewBase* pluginViewBase = toPluginViewBase(toRenderWidget(renderer).widget());
+ if (is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing()) {
+ PluginViewBase* pluginViewBase = downcast<PluginViewBase>(downcast<RenderWidget>(renderer).widget());
if (pluginViewBase && m_graphicsLayer->contentsLayerForMedia())
pluginViewBase->detachPluginLayer();
}
}
+
+bool RenderLayerBacking::needsIOSDumpRenderTreeMainFrameRenderViewLayerIsAlwaysOpaqueHack(const GraphicsLayer& layer) const
+{
+ if (m_isMainFrameRenderViewLayer && IOSApplication::isDumpRenderTree()) {
+ // In iOS WebKit1 the main frame's RenderView layer is always transparent. We lie that it is opaque so that
+ // internals.layerTreeAsText() tests succeed.
+ ASSERT_UNUSED(layer, !layer.contentsOpaque());
+ return true;
+ }
+ return false;
+}
#endif
void RenderLayerBacking::destroyGraphicsLayers()
@@ -366,23 +342,25 @@ void RenderLayerBacking::destroyGraphicsLayers()
m_backgroundLayer = nullptr;
m_childContainmentLayer = nullptr;
m_maskLayer = nullptr;
+ m_childClippingMaskLayer = nullptr;
m_scrollingLayer = nullptr;
m_scrollingContentsLayer = nullptr;
}
-void RenderLayerBacking::updateOpacity(const RenderStyle* style)
+void RenderLayerBacking::updateOpacity(const RenderStyle& style)
{
- m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
+ m_graphicsLayer->setOpacity(compositingOpacity(style.opacity()));
}
-void RenderLayerBacking::updateTransform(const RenderStyle* style)
+void RenderLayerBacking::updateTransform(const RenderStyle& style)
{
// FIXME: This could use m_owningLayer.transform(), but that currently has transform-origin
// baked into it, and we don't want that.
TransformationMatrix t;
if (m_owningLayer.hasTransform()) {
- style->applyTransform(t, toRenderBox(renderer()).pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
+ auto& renderBox = downcast<RenderBox>(renderer());
+ style.applyTransform(t, snapRectToDevicePixels(renderBox.borderBoxRect(), deviceScaleFactor()), RenderStyle::ExcludeTransformOrigin);
makeMatrixRenderable(t, compositor().canRender3DTransforms());
}
@@ -393,54 +371,81 @@ void RenderLayerBacking::updateTransform(const RenderStyle* style)
m_graphicsLayer->setTransform(t);
}
-#if ENABLE(CSS_FILTERS)
-void RenderLayerBacking::updateFilters(const RenderStyle* style)
+void RenderLayerBacking::updateFilters(const RenderStyle& style)
{
- m_canCompositeFilters = m_graphicsLayer->setFilters(style->filter());
+ m_canCompositeFilters = m_graphicsLayer->setFilters(style.filter());
}
-#endif
-#if ENABLE(CSS_COMPOSITING)
-void RenderLayerBacking::updateBlendMode(const RenderStyle* style)
+#if ENABLE(FILTERS_LEVEL_2)
+void RenderLayerBacking::updateBackdropFilters(const RenderStyle& style)
{
- if (m_ancestorClippingLayer)
- m_ancestorClippingLayer->setBlendMode(style->blendMode());
+ m_canCompositeBackdropFilters = m_graphicsLayer->setBackdropFilters(style.backdropFilter());
+}
+
+void RenderLayerBacking::updateBackdropFiltersGeometry()
+{
+ if (!m_canCompositeBackdropFilters)
+ return;
+
+ if (!is<RenderBox>(renderer()))
+ return;
+
+ RenderBox& renderer = downcast<RenderBox>(this->renderer());
+ LayoutRect boxRect = renderer.borderBoxRect();
+ if (renderer.hasClip())
+ boxRect.intersect(renderer.clipRect(LayoutPoint(), nullptr));
+ boxRect.move(contentOffsetInCompostingLayer());
+
+ FloatRoundedRect backdropFiltersRect;
+ if (renderer.style().hasBorderRadius() && !renderer.hasClip())
+ backdropFiltersRect = renderer.style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
else
- m_graphicsLayer->setBlendMode(style->blendMode());
+ backdropFiltersRect = FloatRoundedRect(snapRectToDevicePixels(boxRect, deviceScaleFactor()));
+
+ m_graphicsLayer->setBackdropFiltersRect(backdropFiltersRect);
}
#endif
-static bool hasNonZeroTransformOrigin(const RenderObject& renderer)
+#if ENABLE(CSS_COMPOSITING)
+void RenderLayerBacking::updateBlendMode(const RenderStyle& style)
{
- const RenderStyle& style = renderer.style();
- return (style.transformOriginX().type() == Fixed && style.transformOriginX().value())
- || (style.transformOriginY().type() == Fixed && style.transformOriginY().value());
+ // FIXME: where is the blend mode updated when m_ancestorClippingLayers come and go?
+ if (m_ancestorClippingLayer) {
+ m_ancestorClippingLayer->setBlendMode(style.blendMode());
+ m_graphicsLayer->setBlendMode(BlendModeNormal);
+ } else
+ m_graphicsLayer->setBlendMode(style.blendMode());
}
+#endif
-#if PLATFORM(IOS)
-// FIXME: We should merge the concept of RenderLayer::{hasAcceleratedTouchScrolling, needsCompositedScrolling}()
-// so that we can remove this iOS-specific variant.
-static bool layerOrAncestorIsTransformedOrScrolling(RenderLayer& layer)
+void RenderLayerBacking::updateCustomAppearance(const RenderStyle& style)
{
- for (RenderLayer* curr = &layer; curr; curr = curr->parent()) {
- if (curr->hasTransform() || curr->hasAcceleratedTouchScrolling())
- return true;
- }
-
- return false;
+ ControlPart appearance = style.appearance();
+ if (appearance == MediaControlsLightBarBackgroundPart)
+ m_graphicsLayer->setCustomAppearance(GraphicsLayer::LightBackdropAppearance);
+ else if (appearance == MediaControlsDarkBarBackgroundPart)
+ m_graphicsLayer->setCustomAppearance(GraphicsLayer::DarkBackdropAppearance);
+ else
+ m_graphicsLayer->setCustomAppearance(GraphicsLayer::NoCustomAppearance);
}
-#else
+
+// FIXME: the hasAcceleratedTouchScrolling()/needsCompositedScrolling() concepts need to be merged.
static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer& layer)
{
for (RenderLayer* curr = &layer; curr; curr = curr->parent()) {
- if (curr->hasTransform() || curr->needsCompositedScrolling())
+ if (curr->hasTransform()
+#if PLATFORM(IOS)
+ || curr->hasTouchScrollableOverflow()
+#else
+ || curr->needsCompositedScrolling()
+#endif
+ )
return true;
}
return false;
}
-#endif
-
+
bool RenderLayerBacking::shouldClipCompositedBounds() const
{
#if !PLATFORM(IOS)
@@ -449,16 +454,11 @@ bool RenderLayerBacking::shouldClipCompositedBounds() const
return false;
#endif
- if (m_usingTiledCacheLayer)
+ if (m_isMainFrameLayerWithTiledBacking)
return false;
-#if !PLATFORM(IOS)
if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
return false;
-#else
- if (layerOrAncestorIsTransformedOrScrolling(m_owningLayer))
- return false;
-#endif
if (m_owningLayer.isFlowThreadCollectingGraphicsLayersUnderRegions())
return false;
@@ -466,32 +466,33 @@ bool RenderLayerBacking::shouldClipCompositedBounds() const
return true;
}
-void RenderLayerBacking::updateCompositedBounds()
+static bool hasNonZeroTransformOrigin(const RenderObject& renderer)
{
- LayoutRect layerBounds = compositor().calculateCompositedBounds(m_owningLayer, m_owningLayer);
+ const RenderStyle& style = renderer.style();
+ return (style.transformOriginX().type() == Fixed && style.transformOriginX().value())
+ || (style.transformOriginY().type() == Fixed && style.transformOriginY().value());
+}
+void RenderLayerBacking::updateCompositedBounds()
+{
+ LayoutRect layerBounds = m_owningLayer.calculateLayerBounds(&m_owningLayer, LayoutSize(), RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask);
// Clip to the size of the document or enclosing overflow-scroll layer.
// If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
// We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
if (shouldClipCompositedBounds()) {
- RenderView& view = m_owningLayer.renderer().view();
+ RenderView& view = renderer().view();
RenderLayer* rootLayer = view.layer();
LayoutRect clippingBounds;
- if (renderer().style().position() == FixedPosition && renderer().container() == &view) {
-#if PLATFORM(IOS)
- clippingBounds = view.frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect);
-#else
- clippingBounds = view.frameView().viewportConstrainedVisibleContentRect();
-#endif
- } else
+ if (renderer().style().position() == FixedPosition && renderer().container() == &view)
+ clippingBounds = view.frameView().rectForFixedPositionLayout();
+ else
clippingBounds = view.unscaledDocumentRect();
if (&m_owningLayer != rootLayer)
- clippingBounds.intersect(m_owningLayer.backgroundClipRect(RenderLayer::ClipRectsContext(rootLayer, 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
+ clippingBounds.intersect(m_owningLayer.backgroundClipRect(RenderLayer::ClipRectsContext(rootLayer, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
- LayoutPoint delta;
- m_owningLayer.convertToLayerCoords(rootLayer, delta, RenderLayer::AdjustForColumns);
+ LayoutPoint delta = m_owningLayer.convertToLayerCoords(rootLayer, LayoutPoint(), RenderLayer::AdjustForColumns);
clippingBounds.move(-delta.x(), -delta.y());
layerBounds.intersect(clippingBounds);
@@ -500,7 +501,7 @@ void RenderLayerBacking::updateCompositedBounds()
// If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
// then we need to ensure that the compositing layer has non-zero size so that we can apply
// the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
- if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) {
+ if (layerBounds.isEmpty() && (hasNonZeroTransformOrigin(renderer()) || renderer().style().hasPerspective())) {
layerBounds.setWidth(1);
layerBounds.setHeight(1);
m_artificiallyInflatedBounds = true;
@@ -512,9 +513,9 @@ void RenderLayerBacking::updateCompositedBounds()
void RenderLayerBacking::updateAfterWidgetResize()
{
- if (!renderer().isWidget())
+ if (!is<RenderWidget>(renderer()))
return;
- if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderWidget(&renderer()))) {
+ if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(&downcast<RenderWidget>(renderer()))) {
innerCompositor->frameViewDidChangeSize();
innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contentsBox().location()));
}
@@ -523,7 +524,7 @@ void RenderLayerBacking::updateAfterWidgetResize()
void RenderLayerBacking::updateAfterLayout(UpdateAfterLayoutFlags flags)
{
if (!compositor().compositingLayersNeedRebuild()) {
- // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the
+ // Calling updateGeometry() here gives incorrect results, because the
// position of this layer's GraphicsLayer depends on the position of our compositing
// ancestor's GraphicsLayer. That cannot be determined until all the descendant
// RenderLayers of that ancestor have been processed via updateLayerPositions().
@@ -534,7 +535,7 @@ void RenderLayerBacking::updateAfterLayout(UpdateAfterLayoutFlags flags)
compositor().updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, flags & CompositingChildrenOnly);
if (flags & IsUpdateRoot) {
- updateGraphicsLayerGeometry();
+ updateGeometry();
compositor().updateRootLayerPosition();
RenderLayer* stackingContainer = m_owningLayer.enclosingStackingContainer();
if (!compositor().compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != &m_owningLayer))
@@ -542,11 +543,11 @@ void RenderLayerBacking::updateAfterLayout(UpdateAfterLayoutFlags flags)
}
}
- if (flags & NeedsFullRepaint && !paintsIntoWindow() && !paintsIntoCompositedAncestor())
+ if (flags & NeedsFullRepaint && canIssueSetNeedsDisplay())
setContentsNeedDisplay();
}
-bool RenderLayerBacking::updateGraphicsLayerConfiguration()
+bool RenderLayerBacking::updateConfiguration()
{
m_owningLayer.updateDescendantDependentFlags();
m_owningLayer.updateZOrderLists();
@@ -561,34 +562,31 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
if (updateForegroundLayer(compositor().needsContentsCompositingLayer(m_owningLayer)))
layerConfigChanged = true;
- bool needsDescendentsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
+ bool needsDescendantsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
+ if (!renderer().view().needsLayout()) {
+ bool usesCompositedScrolling;
#if PLATFORM(IOS)
- // Our scrolling layer will clip.
- if (m_owningLayer.hasAcceleratedTouchScrolling())
- needsDescendentsClippingLayer = false;
+ usesCompositedScrolling = m_owningLayer.hasTouchScrollableOverflow();
#else
- // Our scrolling layer will clip.
- if (m_owningLayer.needsCompositedScrolling())
- needsDescendentsClippingLayer = false;
-#endif // PLATFORM(IOS)
+ usesCompositedScrolling = m_owningLayer.needsCompositedScrolling();
+#endif
+ // Our scrolling layer will clip.
+ if (usesCompositedScrolling)
+ needsDescendantsClippingLayer = false;
- if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
- layerConfigChanged = true;
+ if (updateScrollingLayers(usesCompositedScrolling))
+ layerConfigChanged = true;
- if (updateDescendantClippingLayer(needsDescendentsClippingLayer))
- layerConfigChanged = true;
+ if (updateDescendantClippingLayer(needsDescendantsClippingLayer))
+ layerConfigChanged = true;
+ }
- if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
+ if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
layerConfigChanged = true;
-#if PLATFORM(IOS)
- if (updateScrollingLayers(m_owningLayer.hasAcceleratedTouchScrolling()))
- layerConfigChanged = true;
-#else
- if (updateScrollingLayers(m_owningLayer.needsCompositedScrolling()))
+ if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
layerConfigChanged = true;
-#endif // PLATFORM(IOS)
if (layerConfigChanged)
updateInternalHierarchy();
@@ -598,8 +596,9 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
m_graphicsLayer->addChild(flatteningLayer);
}
- if (updateMaskLayer(renderer().hasMask()))
- m_graphicsLayer->setMaskLayer(m_maskLayer.get());
+ updateMaskingLayer(renderer().hasMask(), renderer().hasClipPath());
+
+ updateChildClippingStrategy(needsDescendantsClippingLayer);
if (m_owningLayer.hasReflection()) {
if (m_owningLayer.reflectionLayer()->backing()) {
@@ -607,19 +606,20 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
}
} else
- m_graphicsLayer->setReplicatedByLayer(0);
-
- bool isSimpleContainer = isSimpleContainerCompositingLayer();
- bool didUpdateContentsRect = false;
- updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
+ m_graphicsLayer->setReplicatedByLayer(nullptr);
- updateRootLayerConfiguration();
+ if (!m_owningLayer.isRootLayer()) {
+ bool isSimpleContainer = isSimpleContainerCompositingLayer();
+ bool didUpdateContentsRect = false;
+ updateDirectlyCompositedBoxDecorations(isSimpleContainer, didUpdateContentsRect);
+ } else
+ updateRootLayerConfiguration();
if (isDirectlyCompositedImage())
updateImageContents();
- if (renderer().isEmbeddedObject() && toRenderEmbeddedObject(&renderer())->allowsAcceleratedCompositing()) {
- PluginViewBase* pluginViewBase = toPluginViewBase(toRenderWidget(&renderer())->widget());
+ if (is<RenderEmbeddedObject>(renderer()) && downcast<RenderEmbeddedObject>(renderer()).allowsAcceleratedCompositing()) {
+ PluginViewBase* pluginViewBase = downcast<PluginViewBase>(downcast<RenderWidget>(renderer()).widget());
#if PLATFORM(IOS)
if (pluginViewBase && !m_graphicsLayer->contentsLayerForMedia()) {
pluginViewBase->detachPluginLayer();
@@ -627,30 +627,30 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
}
#else
if (!pluginViewBase->shouldNotAddLayer())
- m_graphicsLayer->setContentsToMedia(pluginViewBase->platformLayer());
+ m_graphicsLayer->setContentsToPlatformLayer(pluginViewBase->platformLayer(), GraphicsLayer::ContentsLayerForPlugin);
#endif
}
#if ENABLE(VIDEO)
- else if (renderer().isVideo()) {
- HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer().element());
- m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
+ else if (is<RenderVideo>(renderer()) && downcast<RenderVideo>(renderer()).shouldDisplayVideo()) {
+ HTMLMediaElement* mediaElement = downcast<HTMLMediaElement>(renderer().element());
+ m_graphicsLayer->setContentsToPlatformLayer(mediaElement->platformLayer(), GraphicsLayer::ContentsLayerForMedia);
}
#endif
#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
else if (renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
- const HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer().element());
+ const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer().element());
if (CanvasRenderingContext* context = canvas->renderingContext())
- m_graphicsLayer->setContentsToCanvas(context->platformLayer());
+ m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer(), GraphicsLayer::ContentsLayerForCanvas);
layerConfigChanged = true;
}
#endif
- if (renderer().isWidget())
- layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderWidget(&renderer()));
+ if (is<RenderWidget>(renderer()))
+ layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(&downcast<RenderWidget>(renderer()));
return layerConfigChanged;
}
-static IntRect clipBox(RenderBox& renderer)
+static LayoutRect clipBox(RenderBox& renderer)
{
LayoutRect result = LayoutRect::infiniteRect();
if (renderer.hasOverflowClip())
@@ -659,175 +659,289 @@ static IntRect clipBox(RenderBox& renderer)
if (renderer.hasClip())
result.intersect(renderer.clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
- return pixelSnappedIntRect(result);
+ return result;
}
-void RenderLayerBacking::updateGraphicsLayerGeometry()
+static bool subpixelOffsetFromRendererChanged(const LayoutSize& oldSubpixelOffsetFromRenderer, const LayoutSize& newSubpixelOffsetFromRenderer, float deviceScaleFactor)
+{
+ FloatSize previous = snapSizeToDevicePixel(oldSubpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor);
+ FloatSize current = snapSizeToDevicePixel(newSubpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor);
+ return previous != current;
+}
+
+static FloatSize subpixelForLayerPainting(const LayoutPoint& point, float pixelSnappingFactor)
+{
+ LayoutUnit x = point.x();
+ LayoutUnit y = point.y();
+ x = x >= 0 ? floorToDevicePixel(x, pixelSnappingFactor) : ceilToDevicePixel(x, pixelSnappingFactor);
+ y = y >= 0 ? floorToDevicePixel(y, pixelSnappingFactor) : ceilToDevicePixel(y, pixelSnappingFactor);
+ return point - LayoutPoint(x, y);
+}
+
+struct OffsetFromRenderer {
+ // 1.2px - > { m_devicePixelOffset = 1px m_subpixelOffset = 0.2px }
+ LayoutSize m_devicePixelOffset;
+ LayoutSize m_subpixelOffset;
+};
+
+static OffsetFromRenderer computeOffsetFromRenderer(const LayoutSize& offset, float deviceScaleFactor)
+{
+ OffsetFromRenderer offsetFromRenderer;
+ offsetFromRenderer.m_subpixelOffset = LayoutSize(subpixelForLayerPainting(toLayoutPoint(offset), deviceScaleFactor));
+ offsetFromRenderer.m_devicePixelOffset = offset - offsetFromRenderer.m_subpixelOffset;
+ return offsetFromRenderer;
+}
+
+struct SnappedRectInfo {
+ LayoutRect m_snappedRect;
+ LayoutSize m_snapDelta;
+};
+
+static SnappedRectInfo snappedGraphicsLayer(const LayoutSize& offset, const LayoutSize& size, float deviceScaleFactor)
+{
+ SnappedRectInfo snappedGraphicsLayer;
+ LayoutRect graphicsLayerRect = LayoutRect(toLayoutPoint(offset), size);
+ snappedGraphicsLayer.m_snappedRect = LayoutRect(snapRectToDevicePixels(graphicsLayerRect, deviceScaleFactor));
+ snappedGraphicsLayer.m_snapDelta = snappedGraphicsLayer.m_snappedRect.location() - toLayoutPoint(offset);
+ return snappedGraphicsLayer;
+}
+
+static LayoutSize computeOffsetFromAncestorGraphicsLayer(RenderLayer* compositedAncestor, const LayoutPoint& location, float deviceScaleFactor)
+{
+ if (!compositedAncestor)
+ return toLayoutSize(location);
+
+ // FIXME: This is a workaround until after webkit.org/162634 gets fixed. ancestorSubpixelOffsetFromRenderer
+ // could be stale when a dynamic composited state change triggers a pre-order updateGeometry() traversal.
+ LayoutSize ancestorSubpixelOffsetFromRenderer = compositedAncestor->backing()->subpixelOffsetFromRenderer();
+ LayoutRect ancestorCompositedBounds = compositedAncestor->backing()->compositedBounds();
+ LayoutSize floored = toLayoutSize(LayoutPoint(floorPointToDevicePixels(ancestorCompositedBounds.location() - ancestorSubpixelOffsetFromRenderer, deviceScaleFactor)));
+ LayoutSize ancestorRendererOffsetFromAncestorGraphicsLayer = -(floored + ancestorSubpixelOffsetFromRenderer);
+ return ancestorRendererOffsetFromAncestorGraphicsLayer + toLayoutSize(location);
+}
+
+class ComputedOffsets {
+public:
+ ComputedOffsets(const RenderLayer& renderLayer, const LayoutRect& localRect, const LayoutRect& parentGraphicsLayerRect, const LayoutRect& primaryGraphicsLayerRect)
+ : m_renderLayer(renderLayer)
+ , m_location(localRect.location())
+ , m_parentGraphicsLayerOffset(toLayoutSize(parentGraphicsLayerRect.location()))
+ , m_primaryGraphicsLayerOffset(toLayoutSize(primaryGraphicsLayerRect.location()))
+ , m_deviceScaleFactor(renderLayer.renderer().document().deviceScaleFactor())
+ {
+ }
+
+ LayoutSize fromParentGraphicsLayer()
+ {
+ if (!m_fromParentGraphicsLayer)
+ m_fromParentGraphicsLayer = fromAncestorGraphicsLayer() - m_parentGraphicsLayerOffset;
+ return m_fromParentGraphicsLayer.value();
+ }
+
+ LayoutSize fromPrimaryGraphicsLayer()
+ {
+ if (!m_fromPrimaryGraphicsLayer)
+ m_fromPrimaryGraphicsLayer = fromAncestorGraphicsLayer() - m_parentGraphicsLayerOffset - m_primaryGraphicsLayerOffset;
+ return m_fromPrimaryGraphicsLayer.value();
+ }
+
+private:
+ LayoutSize fromAncestorGraphicsLayer()
+ {
+ if (!m_fromAncestorGraphicsLayer) {
+ RenderLayer* compositedAncestor = m_renderLayer.ancestorCompositingLayer();
+ LayoutPoint localPointInAncestorRenderLayerCoords = m_renderLayer.convertToLayerCoords(compositedAncestor, m_location, RenderLayer::AdjustForColumns);
+ m_fromAncestorGraphicsLayer = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, localPointInAncestorRenderLayerCoords, m_deviceScaleFactor);
+ }
+ return m_fromAncestorGraphicsLayer.value();
+ }
+
+ std::optional<LayoutSize> m_fromAncestorGraphicsLayer;
+ std::optional<LayoutSize> m_fromParentGraphicsLayer;
+ std::optional<LayoutSize> m_fromPrimaryGraphicsLayer;
+
+ const RenderLayer& m_renderLayer;
+ // Location is relative to the renderer.
+ const LayoutPoint m_location;
+ const LayoutSize m_parentGraphicsLayerOffset;
+ const LayoutSize m_primaryGraphicsLayerOffset;
+ float m_deviceScaleFactor;
+};
+
+LayoutRect RenderLayerBacking::computePrimaryGraphicsLayerRect(const LayoutRect& parentGraphicsLayerRect) const
+{
+ ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, LayoutRect());
+ return LayoutRect(encloseRectToDevicePixels(LayoutRect(toLayoutPoint(compositedBoundsOffset.fromParentGraphicsLayer()), compositedBounds().size()),
+ deviceScaleFactor()));
+}
+
+LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize& ancestorClippingLayerOffset) const
+{
+ if (!compositedAncestor || !compositedAncestor->backing())
+ return renderer().view().documentRect();
+
+ auto* ancestorBackingLayer = compositedAncestor->backing();
+ LayoutRect parentGraphicsLayerRect;
+ if (m_owningLayer.isInsideFlowThread()) {
+ /// FIXME: flows/columns need work.
+ LayoutRect ancestorCompositedBounds = ancestorBackingLayer->compositedBounds();
+ ancestorCompositedBounds.setLocation(LayoutPoint());
+ adjustAncestorCompositingBoundsForFlowThread(ancestorCompositedBounds, compositedAncestor);
+ parentGraphicsLayerRect = ancestorCompositedBounds;
+ }
+
+ if (ancestorBackingLayer->hasClippingLayer()) {
+ // If the compositing ancestor has a layer to clip children, we parent in that, and therefore position relative to it.
+ LayoutRect clippingBox = clipBox(downcast<RenderBox>(compositedAncestor->renderer()));
+ LayoutSize clippingBoxOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, clippingBox.location(), deviceScaleFactor());
+ parentGraphicsLayerRect = snappedGraphicsLayer(clippingBoxOffset, clippingBox.size(), deviceScaleFactor()).m_snappedRect;
+ }
+
+#if PLATFORM(IOS)
+ if (compositedAncestor->hasTouchScrollableOverflow()) {
+ LayoutRect ancestorCompositedBounds = ancestorBackingLayer->compositedBounds();
+ auto& renderBox = downcast<RenderBox>(compositedAncestor->renderer());
+ LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
+ ScrollOffset scrollOffset = compositedAncestor->scrollOffset();
+ parentGraphicsLayerRect = LayoutRect((paddingBox.location() - toLayoutSize(ancestorCompositedBounds.location()) - toLayoutSize(scrollOffset)), paddingBox.size());
+ }
+#else
+ if (compositedAncestor->needsCompositedScrolling()) {
+ auto& renderBox = downcast<RenderBox>(compositedAncestor->renderer());
+ LayoutPoint scrollOrigin(renderBox.borderLeft(), renderBox.borderTop());
+ parentGraphicsLayerRect = LayoutRect(scrollOrigin - toLayoutSize(compositedAncestor->scrollOffset()), renderBox.borderBoxRect().size());
+ }
+#endif
+
+ if (m_ancestorClippingLayer) {
+ // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
+ // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
+ // for a compositing layer, rootLayer is the layer itself.
+ ShouldRespectOverflowClip shouldRespectOverflowClip = compositedAncestor->isolatesCompositedBlending() ? RespectOverflowClip : IgnoreOverflowClip;
+ RenderLayer::ClipRectsContext clipRectsContext(compositedAncestor, TemporaryClipRects, IgnoreOverlayScrollbarSize, shouldRespectOverflowClip);
+ LayoutRect parentClipRect = m_owningLayer.backgroundClipRect(clipRectsContext).rect(); // FIXME: Incorrect for CSS regions.
+ ASSERT(!parentClipRect.isInfinite());
+ LayoutSize clippingOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, parentClipRect.location(), deviceScaleFactor());
+ LayoutRect snappedClippingLayerRect = snappedGraphicsLayer(clippingOffset, parentClipRect.size(), deviceScaleFactor()).m_snappedRect;
+ // The primary layer is then parented in, and positioned relative to this clipping layer.
+ ancestorClippingLayerOffset = snappedClippingLayerRect.location() - parentGraphicsLayerRect.location();
+ parentGraphicsLayerRect = snappedClippingLayerRect;
+ }
+ return parentGraphicsLayerRect;
+}
+
+void RenderLayerBacking::updateGeometry()
{
// If we haven't built z-order lists yet, wait until later.
if (m_owningLayer.isStackingContainer() && m_owningLayer.m_zOrderListsDirty)
return;
+ const RenderStyle& style = renderer().style();
// Set transform property, if it is not animating. We have to do this here because the transform
// is affected by the layer dimensions.
- if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(&renderer(), CSSPropertyWebkitTransform))
- updateTransform(&renderer().style());
+ if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused))
+ updateTransform(style);
// Set opacity, if it is not animating.
- if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(&renderer(), CSSPropertyOpacity))
- updateOpacity(&renderer().style());
-
-#if ENABLE(CSS_FILTERS)
- updateFilters(&renderer().style());
-#endif
+ if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity, AnimationBase::Running | AnimationBase::Paused))
+ updateOpacity(style);
+ updateFilters(style);
+#if ENABLE(FILTERS_LEVEL_2)
+ updateBackdropFilters(style);
+#endif
#if ENABLE(CSS_COMPOSITING)
- updateBlendMode(&renderer().style());
+ updateBlendMode(style);
#endif
-
- bool isSimpleContainer = isSimpleContainerCompositingLayer();
-
m_owningLayer.updateDescendantDependentFlags();
- // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
- // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
- // non-compositing visible layers.
- m_graphicsLayer->setContentsVisible(m_owningLayer.hasVisibleContent() || hasVisibleNonCompositingDescendantLayers());
-
- const RenderStyle& style = renderer().style();
// FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
bool preserves3D = style.transformStyle3D() == TransformStyle3DPreserve3D && !renderer().hasReflection();
m_graphicsLayer->setPreserves3D(preserves3D);
m_graphicsLayer->setBackfaceVisibility(style.backfaceVisibility() == BackfaceVisibilityVisible);
- RenderLayer* compAncestor = m_owningLayer.ancestorCompositingLayer();
-
- // We compute everything relative to the enclosing compositing layer.
- IntRect ancestorCompositingBounds;
- if (compAncestor) {
- ASSERT(compAncestor->backing());
- ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->backing()->compositedBounds());
- }
-
- LayoutRect localRawCompositingBounds = compositedBounds();
- LayoutPoint rawDelta;
- m_owningLayer.convertToLayerCoords(compAncestor, rawDelta, RenderLayer::AdjustForColumns);
- IntPoint delta = flooredIntPoint(rawDelta);
- m_subpixelAccumulation = toLayoutSize(rawDelta.fraction());
- // Move the bounds by the subpixel accumulation so that it pixel-snaps relative to absolute pixels instead of local coordinates.
- localRawCompositingBounds.move(m_subpixelAccumulation);
-
- IntRect localCompositingBounds = pixelSnappedIntRect(localRawCompositingBounds);
- IntRect relativeCompositingBounds(localCompositingBounds);
- relativeCompositingBounds.moveBy(delta);
-
- adjustAncestorCompositingBoundsForFlowThread(ancestorCompositingBounds, compAncestor);
-
- IntPoint graphicsLayerParentLocation;
- if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
- // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
- // position relative to it.
- IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
- graphicsLayerParentLocation = clippingBox.location();
- } else if (compAncestor)
- graphicsLayerParentLocation = ancestorCompositingBounds.location();
- else
- graphicsLayerParentLocation = renderer().view().documentRect().location();
+ RenderLayer* compositedAncestor = m_owningLayer.ancestorCompositingLayer();
+ LayoutSize ancestorClippingLayerOffset;
+ LayoutRect parentGraphicsLayerRect = computeParentGraphicsLayerRect(compositedAncestor, ancestorClippingLayerOffset);
+ LayoutRect primaryGraphicsLayerRect = computePrimaryGraphicsLayerRect(parentGraphicsLayerRect);
-#if PLATFORM(IOS)
- if (compAncestor && compAncestor->hasAcceleratedTouchScrolling()) {
- RenderBox* renderBox = toRenderBox(&compAncestor->renderer());
- IntRect paddingBox(renderBox->borderLeft(), renderBox->borderTop(),
- renderBox->width() - renderBox->borderLeft() - renderBox->borderRight(),
- renderBox->height() - renderBox->borderTop() - renderBox->borderBottom());
+ ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
+ m_compositedBoundsOffsetFromGraphicsLayer = compositedBoundsOffset.fromPrimaryGraphicsLayer();
+ m_graphicsLayer->setPosition(primaryGraphicsLayerRect.location());
+ m_graphicsLayer->setSize(primaryGraphicsLayerRect.size());
- IntSize scrollOffset = compAncestor->scrolledContentOffset();
- graphicsLayerParentLocation = paddingBox.location() - scrollOffset;
+ ComputedOffsets rendererOffset(m_owningLayer, LayoutRect(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
+ if (m_ancestorClippingLayer) {
+ // Clipping layer is parented in the ancestor layer.
+ m_ancestorClippingLayer->setPosition(toLayoutPoint(ancestorClippingLayerOffset));
+ m_ancestorClippingLayer->setSize(parentGraphicsLayerRect.size());
+ m_ancestorClippingLayer->setOffsetFromRenderer(-rendererOffset.fromParentGraphicsLayer());
}
-#endif
-
- if (compAncestor && compAncestor->needsCompositedScrolling()) {
- RenderBox& renderBox = toRenderBox(compAncestor->renderer());
- IntSize scrollOffset = compAncestor->scrolledContentOffset();
- IntPoint scrollOrigin(renderBox.borderLeft(), renderBox.borderTop());
- graphicsLayerParentLocation = scrollOrigin - scrollOffset;
- }
-
- if (compAncestor && m_ancestorClippingLayer) {
- // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
- // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
- // for a compositing layer, rootLayer is the layer itself.
- RenderLayer::ClipRectsContext clipRectsContext(compAncestor, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
- IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer.backgroundClipRect(clipRectsContext).rect()); // FIXME: Incorrect for CSS regions.
- ASSERT(parentClipRect != IntRect::infiniteRect());
- m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
- m_ancestorClippingLayer->setSize(parentClipRect.size());
- // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
- m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);
-
- // The primary layer is then parented in, and positioned relative to this clipping layer.
- graphicsLayerParentLocation = parentClipRect.location();
- }
-
- FloatSize contentsSize = relativeCompositingBounds.size();
-
if (m_contentsContainmentLayer) {
m_contentsContainmentLayer->setPreserves3D(preserves3D);
- m_contentsContainmentLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
+ m_contentsContainmentLayer->setPosition(primaryGraphicsLayerRect.location());
+ m_graphicsLayer->setPosition(FloatPoint());
// Use the same size as m_graphicsLayer so transforms behave correctly.
- m_contentsContainmentLayer->setSize(contentsSize);
- graphicsLayerParentLocation = relativeCompositingBounds.location();
+ m_contentsContainmentLayer->setSize(primaryGraphicsLayerRect.size());
}
- m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
- m_graphicsLayer->setSize(contentsSize);
- IntSize offsetFromRenderer = toIntSize(localCompositingBounds.location());
- if (offsetFromRenderer != m_graphicsLayer->offsetFromRenderer()) {
- m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
+ // Compute renderer offset from primary graphics layer. Note that primaryGraphicsLayerRect is in parentGraphicsLayer's coordidate system which is not necessarily
+ // the same as the ancestor graphics layer.
+ OffsetFromRenderer primaryGraphicsLayerOffsetFromRenderer;
+ LayoutSize oldSubpixelOffsetFromRenderer = m_subpixelOffsetFromRenderer;
+ primaryGraphicsLayerOffsetFromRenderer = computeOffsetFromRenderer(-rendererOffset.fromPrimaryGraphicsLayer(), deviceScaleFactor());
+ m_subpixelOffsetFromRenderer = primaryGraphicsLayerOffsetFromRenderer.m_subpixelOffset;
+
+ if (primaryGraphicsLayerOffsetFromRenderer.m_devicePixelOffset != m_graphicsLayer->offsetFromRenderer()) {
+ m_graphicsLayer->setOffsetFromRenderer(primaryGraphicsLayerOffsetFromRenderer.m_devicePixelOffset);
positionOverflowControlsLayers();
}
if (!m_isMainFrameRenderViewLayer) {
// For non-root layers, background is always painted by the primary graphics layer.
ASSERT(!m_backgroundLayer);
- bool hadSubpixelRounding = LayoutSize(relativeCompositingBounds.size()) != localRawCompositingBounds.size();
- m_graphicsLayer->setContentsOpaque(!hadSubpixelRounding && m_owningLayer.backgroundIsKnownToBeOpaqueInRect(localCompositingBounds));
+ // Subpixel offset from graphics layer or size changed.
+ bool hadSubpixelRounding = !m_subpixelOffsetFromRenderer.isZero() || compositedBounds().size() != primaryGraphicsLayerRect.size();
+ m_graphicsLayer->setContentsOpaque(!hadSubpixelRounding && m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
}
// If we have a layer that clips children, position it.
- IntRect clippingBox;
+ LayoutRect clippingBox;
if (GraphicsLayer* clipLayer = clippingLayer()) {
- clippingBox = clipBox(toRenderBox(renderer()));
- clipLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location()));
- clipLayer->setSize(clippingBox.size());
- clipLayer->setOffsetFromRenderer(toIntSize(clippingBox.location()));
+ clippingBox = clipBox(downcast<RenderBox>(renderer()));
+ // Clipping layer is parented in the primary graphics layer.
+ LayoutSize clipBoxOffsetFromGraphicsLayer = toLayoutSize(clippingBox.location()) + rendererOffset.fromPrimaryGraphicsLayer();
+ SnappedRectInfo snappedClippingGraphicsLayer = snappedGraphicsLayer(clipBoxOffsetFromGraphicsLayer, clippingBox.size(), deviceScaleFactor());
+ clipLayer->setPosition(snappedClippingGraphicsLayer.m_snappedRect.location());
+ clipLayer->setSize(snappedClippingGraphicsLayer.m_snappedRect.size());
+ clipLayer->setOffsetFromRenderer(toLayoutSize(clippingBox.location() - snappedClippingGraphicsLayer.m_snapDelta));
+
+ if (m_childClippingMaskLayer && !m_scrollingLayer) {
+ m_childClippingMaskLayer->setSize(clipLayer->size());
+ m_childClippingMaskLayer->setPosition(FloatPoint());
+ m_childClippingMaskLayer->setOffsetFromRenderer(clipLayer->offsetFromRenderer());
+ }
}
- if (m_maskLayer) {
- m_maskLayer->setSize(m_graphicsLayer->size());
- m_maskLayer->setPosition(FloatPoint());
- m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
- }
+ if (m_maskLayer)
+ updateMaskingLayerGeometry();
- if (m_owningLayer.hasTransform()) {
- const IntRect borderBox = toRenderBox(renderer()).pixelSnappedBorderBoxRect();
-
- // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
- IntRect layerBounds(delta, borderBox.size());
-
- // Update properties that depend on layer dimensions
- FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
+ if (m_owningLayer.renderer().hasTransformRelatedProperty()) {
+ // Update properties that depend on layer dimensions.
+ FloatPoint3D transformOrigin = computeTransformOriginForPainting(downcast<RenderBox>(renderer()).borderBoxRect());
+ FloatPoint layerOffset = roundPointToDevicePixels(toLayoutPoint(rendererOffset.fromParentGraphicsLayer()), deviceScaleFactor());
// Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
- FloatPoint3D anchor(relativeCompositingBounds.width() != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width() : 0.5f,
- relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
- transformOrigin.z());
+ FloatPoint3D anchor(
+ primaryGraphicsLayerRect.width() ? ((layerOffset.x() - primaryGraphicsLayerRect.x()) + transformOrigin.x()) / primaryGraphicsLayerRect.width() : 0.5,
+ primaryGraphicsLayerRect.height() ? ((layerOffset.y() - primaryGraphicsLayerRect.y())+ transformOrigin.y()) / primaryGraphicsLayerRect.height() : 0.5,
+ transformOrigin.z());
+
if (m_contentsContainmentLayer)
m_contentsContainmentLayer->setAnchorPoint(anchor);
else
m_graphicsLayer->setAnchorPoint(anchor);
- const RenderStyle& style = renderer().style();
GraphicsLayer* clipLayer = clippingLayer();
if (style.hasPerspective()) {
TransformationMatrix t = owningLayer().perspectiveTransform();
@@ -845,20 +959,20 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
m_graphicsLayer->setChildrenTransform(TransformationMatrix());
}
} else {
- m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
+ m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5, 0.5, 0));
if (m_contentsContainmentLayer)
- m_contentsContainmentLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
+ m_contentsContainmentLayer->setAnchorPoint(FloatPoint3D(0.5, 0.5, 0));
}
if (m_foregroundLayer) {
FloatPoint foregroundPosition;
- FloatSize foregroundSize = contentsSize;
- IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
+ FloatSize foregroundSize = primaryGraphicsLayerRect.size();
+ FloatSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
if (hasClippingLayer()) {
// If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
// so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
foregroundSize = FloatSize(clippingBox.size());
- foregroundOffset = toIntSize(clippingBox.location());
+ foregroundOffset = toFloatSize(clippingBox.location());
}
m_foregroundLayer->setPosition(foregroundPosition);
@@ -868,11 +982,11 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
if (m_backgroundLayer) {
FloatPoint backgroundPosition;
- FloatSize backgroundSize = contentsSize;
+ FloatSize backgroundSize = primaryGraphicsLayerRect.size();
if (backgroundLayerPaintsFixedRootBackground()) {
const FrameView& frameView = renderer().view().frameView();
- backgroundPosition = IntPoint(frameView.scrollOffsetForFixedPosition());
- backgroundSize = frameView.visibleContentRect().size();
+ backgroundPosition = frameView.scrollPositionForFixedPosition();
+ backgroundSize = frameView.layoutSize();
}
m_backgroundLayer->setPosition(backgroundPosition);
m_backgroundLayer->setSize(backgroundSize);
@@ -881,36 +995,37 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
if (m_owningLayer.reflectionLayer() && m_owningLayer.reflectionLayer()->isComposited()) {
RenderLayerBacking* reflectionBacking = m_owningLayer.reflectionLayer()->backing();
- reflectionBacking->updateGraphicsLayerGeometry();
+ reflectionBacking->updateGeometry();
// The reflection layer has the bounds of m_owningLayer.reflectionLayer(),
// but the reflected layer is the bounds of this layer, so we need to position it appropriately.
- FloatRect layerBounds = compositedBounds();
+ FloatRect layerBounds = this->compositedBounds();
FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location()));
}
if (m_scrollingLayer) {
ASSERT(m_scrollingContentsLayer);
- RenderBox& renderBox = toRenderBox(renderer());
- IntRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
- IntSize scrollOffset = m_owningLayer.scrollOffset();
+ auto& renderBox = downcast<RenderBox>(renderer());
+ LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
+ ScrollOffset scrollOffset = m_owningLayer.scrollOffset();
- m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - localCompositingBounds.location()));
+ // FIXME: need to do some pixel snapping here.
+ m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - compositedBounds().location()));
- m_scrollingLayer->setSize(paddingBox.size());
+ m_scrollingLayer->setSize(roundedIntSize(LayoutSize(renderBox.clientWidth(), renderBox.clientHeight())));
#if PLATFORM(IOS)
- IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
- m_scrollingLayer->setOffsetFromRenderer(IntPoint() - paddingBox.location());
+ FloatSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
+ m_scrollingLayer->setOffsetFromRenderer(FloatPoint() - paddingBox.location());
bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
if (m_owningLayer.isInUserScroll()) {
- // If scrolling is happening externally, we don't want to touch the layer bounds origin here because that will cause
- // jitter. Set a flag to ensure that we sync up later.
+ // If scrolling is happening externally, we don't want to touch the layer bounds origin here because that will cause jitter.
+ m_scrollingLayer->syncBoundsOrigin(scrollOffset);
m_owningLayer.setRequiresScrollBoundsOriginUpdate(true);
} else {
// Note that we implement the contents offset via the bounds origin on this layer, rather than a position on the sublayer.
- m_scrollingLayer->setBoundsOrigin(FloatPoint(scrollOffset.width(), scrollOffset.height()));
+ m_scrollingLayer->setBoundsOrigin(scrollOffset);
m_owningLayer.setRequiresScrollBoundsOriginUpdate(false);
}
@@ -924,14 +1039,19 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
m_scrollingContentsLayer->setSize(scrollSize);
// Scrolling the content layer does not need to trigger a repaint. The offset will be compensated away during painting.
// FIXME: The paint offset and the scroll offset should really be separate concepts.
- m_scrollingContentsLayer->setOffsetFromRenderer(paddingBox.location() - IntPoint() - scrollOffset, GraphicsLayer::DontSetNeedsDisplay);
-
- compositor().scrollingLayerAddedOrUpdated(&m_owningLayer);
+ LayoutSize scrollingContentsOffset = toLayoutSize(paddingBox.location() - toLayoutSize(scrollOffset));
+ m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
#else
- m_scrollingContentsLayer->setPosition(FloatPoint(-scrollOffset.width(), -scrollOffset.height()));
+ m_scrollingContentsLayer->setPosition(-scrollOffset);
- IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
- m_scrollingLayer->setOffsetFromRenderer(-toIntSize(paddingBox.location()));
+ FloatSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
+ m_scrollingLayer->setOffsetFromRenderer(-toFloatSize(paddingBox.location()));
+
+ if (m_childClippingMaskLayer) {
+ m_childClippingMaskLayer->setPosition(m_scrollingLayer->position());
+ m_childClippingMaskLayer->setSize(m_scrollingLayer->size());
+ m_childClippingMaskLayer->setOffsetFromRenderer(toFloatSize(paddingBox.location()));
+ }
bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
@@ -939,7 +1059,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
m_scrollingContentsLayer->setNeedsDisplay();
- IntSize scrollingContentsOffset = toIntSize(paddingBox.location() - scrollOffset);
+ LayoutSize scrollingContentsOffset = toLayoutSize(paddingBox.location() - toLayoutSize(scrollOffset));
if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size())
compositor().scrollingLayerDidChange(m_owningLayer);
@@ -955,24 +1075,72 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
}
// If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store.
- setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compAncestor, relativeCompositingBounds, ancestorCompositingBounds));
+ LayoutRect ancestorCompositedBounds = compositedAncestor ? compositedAncestor->backing()->compositedBounds() : LayoutRect();
+ setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compositedAncestor,
+ LayoutRect(toLayoutPoint(compositedBoundsOffset.fromParentGraphicsLayer()), compositedBounds().size()), ancestorCompositedBounds));
+#if ENABLE(FILTERS_LEVEL_2)
+ updateBackdropFiltersGeometry();
+#endif
+ updateAfterWidgetResize();
+
+ if (subpixelOffsetFromRendererChanged(oldSubpixelOffsetFromRenderer, m_subpixelOffsetFromRenderer, deviceScaleFactor()) && canIssueSetNeedsDisplay())
+ setContentsNeedDisplay();
- bool didUpdateContentsRect = false;
- updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
- if (!didUpdateContentsRect && m_graphicsLayer->hasContentsLayer())
- resetContentsRect();
+ compositor().updateScrollCoordinatedStatus(m_owningLayer);
+}
+
+void RenderLayerBacking::updateAfterDescendants()
+{
+ bool isSimpleContainer = false;
+ if (!m_owningLayer.isRootLayer()) {
+ bool didUpdateContentsRect = false;
+ // FIXME: this duplicates work we did in updateConfiguration().
+ isSimpleContainer = isSimpleContainerCompositingLayer();
+ updateDirectlyCompositedBoxDecorations(isSimpleContainer, didUpdateContentsRect);
+ if (!didUpdateContentsRect && m_graphicsLayer->usesContentsLayer())
+ resetContentsRect();
+ }
updateDrawsContent(isSimpleContainer);
- updateAfterWidgetResize();
- registerScrollingLayers();
+
+ m_graphicsLayer->setContentsVisible(m_owningLayer.hasVisibleContent() || hasVisibleNonCompositedDescendants());
+ if (m_scrollingLayer) {
+ m_scrollingLayer->setContentsVisible(renderer().style().visibility() == VISIBLE);
+ m_scrollingLayer->setUserInteractionEnabled(renderer().style().pointerEvents() != PE_NONE);
+ }
}
-void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(IntRect& ancestorCompositingBounds, const RenderLayer* compositingAncestor) const
+// FIXME: Avoid repaints when clip path changes.
+void RenderLayerBacking::updateMaskingLayerGeometry()
{
- if (!m_owningLayer.isInsideFlowThread())
- return;
+ m_maskLayer->setSize(m_graphicsLayer->size());
+ m_maskLayer->setPosition(FloatPoint());
+ m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
+
+ if (!m_maskLayer->drawsContent()) {
+ if (renderer().hasClipPath()) {
+ ASSERT(renderer().style().clipPath()->type() != ClipPathOperation::Reference);
+
+ WindRule windRule;
+ // FIXME: Use correct reference box for inlines: https://bugs.webkit.org/show_bug.cgi?id=129047
+ LayoutRect boundingBox = m_owningLayer.boundingBox(&m_owningLayer);
+ LayoutRect referenceBoxForClippedInline = LayoutRect(snapRectToDevicePixels(boundingBox, deviceScaleFactor()));
+ LayoutSize offset = LayoutSize(snapSizeToDevicePixel(-m_subpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor()));
+ Path clipPath = m_owningLayer.computeClipPath(offset, referenceBoxForClippedInline, windRule);
+
+ FloatSize pathOffset = m_maskLayer->offsetFromRenderer();
+ if (!pathOffset.isZero())
+ clipPath.translate(-pathOffset);
+
+ m_maskLayer->setShapeLayerPath(clipPath);
+ m_maskLayer->setShapeLayerWindRule(windRule);
+ }
+ }
+}
- RenderLayer* flowThreadLayer = m_owningLayer.isInsideOutOfFlowThread() ? m_owningLayer.stackingContainer() : m_owningLayer.enclosingFlowThreadAncestor();
+void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(LayoutRect& ancestorCompositingBounds, const RenderLayer* compositingAncestor) const
+{
+ RenderLayer* flowThreadLayer = m_owningLayer.isInsideOutOfFlowThread() ? m_owningLayer.stackingContainer() : nullptr;
if (flowThreadLayer && flowThreadLayer->isRenderFlowThread()) {
if (m_owningLayer.isFlowThreadCollectingGraphicsLayersUnderRegions()) {
// The RenderNamedFlowThread is not composited, as we need it to paint the
@@ -984,15 +1152,15 @@ void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(IntRect& a
}
// Move the ancestor position at the top of the region where the composited layer is going to display.
- RenderFlowThread& flowThread = toRenderFlowThread(flowThreadLayer->renderer());
+ RenderFlowThread& flowThread = downcast<RenderFlowThread>(flowThreadLayer->renderer());
RenderNamedFlowFragment* parentRegion = flowThread.cachedRegionForCompositedLayer(m_owningLayer);
if (!parentRegion)
return;
IntPoint flowDelta;
m_owningLayer.convertToPixelSnappedLayerCoords(flowThreadLayer, flowDelta);
- parentRegion->adjustRegionBoundsFromFlowThreadPortionRect(flowDelta, ancestorCompositingBounds);
- RenderBoxModelObject& layerOwner = toRenderBoxModelObject(parentRegion->layerOwner());
+ parentRegion->adjustRegionBoundsFromFlowThreadPortionRect(ancestorCompositingBounds);
+ RenderBoxModelObject& layerOwner = downcast<RenderBoxModelObject>(parentRegion->layerOwner());
RenderLayerBacking* layerOwnerBacking = layerOwner.layer()->backing();
if (!layerOwnerBacking)
return;
@@ -1012,7 +1180,7 @@ void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(IntRect& a
}
}
-void RenderLayerBacking::updateDirectlyCompositedContents(bool isSimpleContainer, bool& didUpdateContentsRect)
+void RenderLayerBacking::updateDirectlyCompositedBoxDecorations(bool isSimpleContainer, bool& didUpdateContentsRect)
{
if (!m_owningLayer.hasVisibleContent())
return;
@@ -1023,29 +1191,6 @@ void RenderLayerBacking::updateDirectlyCompositedContents(bool isSimpleContainer
updateDirectlyCompositedBackgroundImage(isSimpleContainer, didUpdateContentsRect);
}
-void RenderLayerBacking::registerScrollingLayers()
-{
-#if PLATFORM(IOS)
- compositor().updateViewportConstraintStatus(m_owningLayer);
-#else
- // Register fixed position layers and their containers with the scrolling coordinator.
- ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
- if (!scrollingCoordinator)
- return;
-
- compositor().updateViewportConstraintStatus(m_owningLayer);
-
- if (!scrollingCoordinator->supportsFixedPositionLayers())
- return;
-
- // Page scale is applied as a transform on the root render view layer. Because the scroll
- // layer is further up in the hierarchy, we need to avoid marking the root render view
- // layer as a container.
- bool isContainer = m_owningLayer.hasTransform() && !m_owningLayer.isRootLayer();
- scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer);
-#endif
-}
-
void RenderLayerBacking::updateInternalHierarchy()
{
// m_foregroundLayer has to be inserted in the correct order with child layers,
@@ -1097,17 +1242,17 @@ void RenderLayerBacking::updateInternalHierarchy()
void RenderLayerBacking::resetContentsRect()
{
- m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
+ m_graphicsLayer->setContentsRect(snapRectToDevicePixels(contentsBox(), deviceScaleFactor()));
- LayoutRect contentsClippingRect;
- if (renderer().isBox())
- contentsClippingRect = toRenderBox(renderer()).contentBoxRect();
-
- contentsClippingRect.move(contentOffsetInCompostingLayer());
- m_graphicsLayer->setContentsClippingRect(pixelSnappedIntRect(contentsClippingRect));
+ if (is<RenderBox>(renderer())) {
+ LayoutRect boxRect(LayoutPoint(), downcast<RenderBox>(renderer()).size());
+ boxRect.move(contentOffsetInCompostingLayer());
+ FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
+ m_graphicsLayer->setContentsClippingRect(contentsClippingRect);
+ }
m_graphicsLayer->setContentsTileSize(IntSize());
- m_graphicsLayer->setContentsTilePhase(IntPoint());
+ m_graphicsLayer->setContentsTilePhase(IntSize());
}
void RenderLayerBacking::updateDrawsContent()
@@ -1122,10 +1267,10 @@ void RenderLayerBacking::updateDrawsContent(bool isSimpleContainer)
// m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
// m_scrollingLayer never has backing store.
// m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
- bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasBoxDecorationsOrBackground();
+ bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasVisibleBoxDecorationsOrBackground();
m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
- bool hasScrollingPaintedContent = m_owningLayer.hasVisibleContent() && (renderer().hasBackground() || paintsChildren());
+ bool hasScrollingPaintedContent = m_owningLayer.hasVisibleContent() && (renderer().hasBackground() || paintsChildRenderers());
m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
return;
}
@@ -1148,7 +1293,7 @@ bool RenderLayerBacking::updateAncestorClippingLayer(bool needsAncestorClip)
if (needsAncestorClip) {
if (!m_ancestorClippingLayer) {
- m_ancestorClippingLayer = createGraphicsLayer("Ancestor clipping Layer");
+ m_ancestorClippingLayer = createGraphicsLayer("ancestor clipping");
m_ancestorClippingLayer->setMasksToBounds(true);
layersChanged = true;
}
@@ -1168,8 +1313,8 @@ bool RenderLayerBacking::updateDescendantClippingLayer(bool needsDescendantClip)
bool layersChanged = false;
if (needsDescendantClip) {
- if (!m_childContainmentLayer && !m_usingTiledCacheLayer) {
- m_childContainmentLayer = createGraphicsLayer("Child clipping Layer");
+ if (!m_childContainmentLayer && !m_isMainFrameLayerWithTiledBacking) {
+ m_childContainmentLayer = createGraphicsLayer("child clipping");
m_childContainmentLayer->setMasksToBounds(true);
layersChanged = true;
}
@@ -1247,11 +1392,11 @@ bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScroll
scrollCornerLayerChanged = true;
}
- if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
+ if (auto* scrollingCoordinator = m_owningLayer.page().scrollingCoordinator()) {
if (horizontalScrollbarLayerChanged)
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_owningLayer, HorizontalScrollbar);
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, HorizontalScrollbar);
if (verticalScrollbarLayerChanged)
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_owningLayer, VerticalScrollbar);
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, VerticalScrollbar);
}
return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
@@ -1262,31 +1407,31 @@ void RenderLayerBacking::positionOverflowControlsLayers()
if (!m_owningLayer.hasScrollbars())
return;
- const IntRect borderBox = toRenderBox(renderer()).pixelSnappedBorderBoxRect();
+ const IntRect borderBox = snappedIntRect(renderBox()->borderBoxRect());
- IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
+ FloatSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
IntRect hBarRect = m_owningLayer.rectForHorizontalScrollbar(borderBox);
layer->setPosition(hBarRect.location() - offsetFromRenderer);
layer->setSize(hBarRect.size());
- if (layer->hasContentsLayer()) {
+ if (layer->usesContentsLayer()) {
IntRect barRect = IntRect(IntPoint(), hBarRect.size());
layer->setContentsRect(barRect);
- layer->setContentsClippingRect(barRect);
+ layer->setContentsClippingRect(FloatRoundedRect(barRect));
}
- layer->setDrawsContent(m_owningLayer.horizontalScrollbar() && !layer->hasContentsLayer());
+ layer->setDrawsContent(m_owningLayer.horizontalScrollbar() && !layer->usesContentsLayer());
}
if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
IntRect vBarRect = m_owningLayer.rectForVerticalScrollbar(borderBox);
layer->setPosition(vBarRect.location() - offsetFromRenderer);
layer->setSize(vBarRect.size());
- if (layer->hasContentsLayer()) {
+ if (layer->usesContentsLayer()) {
IntRect barRect = IntRect(IntPoint(), vBarRect.size());
layer->setContentsRect(barRect);
- layer->setContentsClippingRect(barRect);
+ layer->setContentsClippingRect(FloatRoundedRect(barRect));
}
- layer->setDrawsContent(m_owningLayer.verticalScrollbar() && !layer->hasContentsLayer());
+ layer->setDrawsContent(m_owningLayer.verticalScrollbar() && !layer->usesContentsLayer());
}
if (GraphicsLayer* layer = layerForScrollCorner()) {
@@ -1319,10 +1464,7 @@ bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
bool layerChanged = false;
if (needsForegroundLayer) {
if (!m_foregroundLayer) {
- String layerName;
-#ifndef NDEBUG
- layerName = m_owningLayer.name() + " (foreground)";
-#endif
+ String layerName = m_owningLayer.name() + " (foreground)";
m_foregroundLayer = createGraphicsLayer(layerName);
m_foregroundLayer->setDrawsContent(true);
m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
@@ -1348,10 +1490,7 @@ bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
bool layerChanged = false;
if (needsBackgroundLayer) {
if (!m_backgroundLayer) {
- String layerName;
-#ifndef NDEBUG
- layerName = m_owningLayer.name() + " (background)";
-#endif
+ String layerName = m_owningLayer.name() + " (background)";
m_backgroundLayer = createGraphicsLayer(layerName);
m_backgroundLayer->setDrawsContent(true);
m_backgroundLayer->setAnchorPoint(FloatPoint3D());
@@ -1360,10 +1499,7 @@ bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
}
if (!m_contentsContainmentLayer) {
- String layerName;
-#ifndef NDEBUG
- layerName = m_owningLayer.name() + " (contents containment)";
-#endif
+ String layerName = m_owningLayer.name() + " (contents containment)";
m_contentsContainmentLayer = createGraphicsLayer(layerName);
m_contentsContainmentLayer->setAppliesPageScale(true);
m_graphicsLayer->setAppliesPageScale(false);
@@ -1394,17 +1530,38 @@ bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
return layerChanged;
}
-bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
+// Masking layer is used for masks or clip-path.
+void RenderLayerBacking::updateMaskingLayer(bool hasMask, bool hasClipPath)
{
bool layerChanged = false;
- if (needsMaskLayer) {
+ if (hasMask || hasClipPath) {
+ GraphicsLayerPaintingPhase maskPhases = 0;
+ if (hasMask)
+ maskPhases = GraphicsLayerPaintMask;
+
+ if (hasClipPath) {
+ // If we have a mask, we need to paint the combined clip-path and mask into the mask layer.
+ if (hasMask || renderer().style().clipPath()->type() == ClipPathOperation::Reference || !GraphicsLayer::supportsLayerType(GraphicsLayer::Type::Shape))
+ maskPhases |= GraphicsLayerPaintClipPath;
+ }
+
+ bool paintsContent = maskPhases;
+ GraphicsLayer::Type requiredLayerType = paintsContent ? GraphicsLayer::Type::Normal : GraphicsLayer::Type::Shape;
+ if (m_maskLayer && m_maskLayer->type() != requiredLayerType) {
+ m_graphicsLayer->setMaskLayer(nullptr);
+ willDestroyLayer(m_maskLayer.get());
+ m_maskLayer = nullptr;
+ }
+
if (!m_maskLayer) {
- m_maskLayer = createGraphicsLayer("Mask");
- m_maskLayer->setDrawsContent(true);
- m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
+ m_maskLayer = createGraphicsLayer("mask", requiredLayerType);
+ m_maskLayer->setDrawsContent(paintsContent);
+ m_maskLayer->setPaintingPhase(maskPhases);
layerChanged = true;
+ m_graphicsLayer->setMaskLayer(m_maskLayer.get());
}
} else if (m_maskLayer) {
+ m_graphicsLayer->setMaskLayer(nullptr);
willDestroyLayer(m_maskLayer.get());
m_maskLayer = nullptr;
layerChanged = true;
@@ -1412,97 +1569,101 @@ bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
if (layerChanged)
m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
+}
- return layerChanged;
+void RenderLayerBacking::updateChildClippingStrategy(bool needsDescendantsClippingLayer)
+{
+ if (hasClippingLayer() && needsDescendantsClippingLayer) {
+ if (is<RenderBox>(renderer()) && (renderer().style().clipPath() || renderer().style().hasBorderRadius())) {
+ // FIXME: we shouldn't get geometry here as layout may not have been udpated.
+ LayoutRect boxRect(LayoutPoint(), downcast<RenderBox>(renderer()).size());
+ boxRect.move(contentOffsetInCompostingLayer());
+ FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
+ if (clippingLayer()->setMasksToBoundsRect(contentsClippingRect)) {
+ if (m_childClippingMaskLayer)
+ m_childClippingMaskLayer = nullptr;
+ return;
+ }
+
+ if (!m_childClippingMaskLayer) {
+ m_childClippingMaskLayer = createGraphicsLayer("child clipping mask");
+ m_childClippingMaskLayer->setDrawsContent(true);
+ m_childClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintChildClippingMask);
+ clippingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
+ }
+ }
+ } else {
+ if (m_childClippingMaskLayer) {
+ if (hasClippingLayer())
+ clippingLayer()->setMaskLayer(nullptr);
+ m_childClippingMaskLayer = nullptr;
+ } else
+ if (hasClippingLayer())
+ clippingLayer()->setMasksToBoundsRect(FloatRoundedRect(FloatRect(FloatPoint(), clippingLayer()->size())));
+ }
}
bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
{
- ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
+ if (needsScrollingLayers == !!m_scrollingLayer)
+ return false;
- bool layerChanged = false;
- if (needsScrollingLayers) {
- if (!m_scrollingLayer) {
- // Outer layer which corresponds with the scroll view.
- m_scrollingLayer = createGraphicsLayer("Scrolling container");
- m_scrollingLayer->setDrawsContent(false);
- m_scrollingLayer->setMasksToBounds(true);
-
- // Inner layer which renders the content that scrolls.
- m_scrollingContentsLayer = createGraphicsLayer("Scrolled Contents");
- m_scrollingContentsLayer->setDrawsContent(true);
- GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
- if (!m_foregroundLayer)
- paintPhase |= GraphicsLayerPaintForeground;
- m_scrollingContentsLayer->setPaintingPhase(paintPhase);
- m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
+ if (!m_scrollingLayer) {
+ // Outer layer which corresponds with the scroll view.
+ m_scrollingLayer = createGraphicsLayer("scrolling container", GraphicsLayer::Type::Scrolling);
+ m_scrollingLayer->setDrawsContent(false);
+ m_scrollingLayer->setMasksToBounds(true);
+
+ // Inner layer which renders the content that scrolls.
+ m_scrollingContentsLayer = createGraphicsLayer("scrolled Contents");
+ m_scrollingContentsLayer->setDrawsContent(true);
+
+ GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
+ if (!m_foregroundLayer)
+ paintPhase |= GraphicsLayerPaintForeground;
+ m_scrollingContentsLayer->setPaintingPhase(paintPhase);
+ m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
+ } else {
+ compositor().willRemoveScrollingLayerWithBacking(m_owningLayer, *this);
- layerChanged = true;
- if (scrollingCoordinator)
- scrollingCoordinator->scrollableAreaScrollLayerDidChange(&m_owningLayer);
-#if PLATFORM(IOS)
- if (m_owningLayer.parent())
- compositor().scrollingLayerAddedOrUpdated(&m_owningLayer);
-#endif
- }
- } else if (m_scrollingLayer) {
-#if PLATFORM(IOS)
- if (!renderer().documentBeingDestroyed())
- compositor().scrollingLayerRemoved(&m_owningLayer, m_scrollingLayer->platformLayer(), m_scrollingContentsLayer->platformLayer());
-#endif
willDestroyLayer(m_scrollingLayer.get());
willDestroyLayer(m_scrollingContentsLayer.get());
m_scrollingLayer = nullptr;
m_scrollingContentsLayer = nullptr;
- layerChanged = true;
- if (scrollingCoordinator)
- scrollingCoordinator->scrollableAreaScrollLayerDidChange(&m_owningLayer);
}
- if (layerChanged) {
- updateInternalHierarchy();
- m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
-#if !PLATFORM(IOS)
- m_graphicsLayer->setNeedsDisplay();
- compositor().scrollingLayerDidChange(m_owningLayer);
-#endif
- }
+ m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
+ m_graphicsLayer->setNeedsDisplay(); // Because painting phases changed.
- return layerChanged;
+ if (m_scrollingLayer)
+ compositor().didAddScrollingLayer(m_owningLayer);
+
+ return true;
}
-void RenderLayerBacking::attachToScrollingCoordinatorWithParent(RenderLayerBacking* parent)
+void RenderLayerBacking::detachFromScrollingCoordinator(LayerScrollCoordinationRoles roles)
{
- ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
- if (!scrollingCoordinator)
+ if (!m_scrollingNodeID && !m_viewportConstrainedNodeID)
return;
- // FIXME: When we support overflow areas, we will have to refine this for overflow areas that are also
- // positon:fixed.
- ScrollingNodeType nodeType;
- if (renderer().style().position() == FixedPosition)
- nodeType = FixedNode;
- else if (renderer().style().position() == StickyPosition)
- nodeType = StickyNode;
- else
- nodeType = ScrollingNode;
+ auto* scrollingCoordinator = m_owningLayer.page().scrollingCoordinator();
+ if (!scrollingCoordinator)
+ return;
- ScrollingNodeID parentID = parent ? parent->scrollLayerID() : 0;
- m_scrollLayerID = scrollingCoordinator->attachToStateTree(nodeType, m_scrollLayerID ? m_scrollLayerID : scrollingCoordinator->uniqueScrollLayerID(), parentID);
+ if ((roles & Scrolling) && m_scrollingNodeID) {
+ scrollingCoordinator->detachFromStateTree(m_scrollingNodeID);
+ m_scrollingNodeID = 0;
+ }
+
+ if ((roles & ViewportConstrained) && m_viewportConstrainedNodeID) {
+ scrollingCoordinator->detachFromStateTree(m_viewportConstrainedNodeID);
+ m_viewportConstrainedNodeID = 0;
+ }
}
-void RenderLayerBacking::detachFromScrollingCoordinator()
+void RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole(bool viewportCoordinated)
{
- // If m_scrollLayerID is 0, then this backing is not attached to the ScrollingCoordinator.
- if (!m_scrollLayerID)
- return;
-
- ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
- if (!scrollingCoordinator)
- return;
-
- scrollingCoordinator->detachFromStateTree(m_scrollLayerID);
- m_scrollLayerID = 0;
+ m_graphicsLayer->setIsViewportConstrained(viewportCoordinated);
}
GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
@@ -1512,8 +1673,6 @@ GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() co
phase |= GraphicsLayerPaintBackground;
if (!m_foregroundLayer)
phase |= GraphicsLayerPaintForeground;
- if (!m_maskLayer)
- phase |= GraphicsLayerPaintMask;
if (m_scrollingContentsLayer) {
phase &= ~GraphicsLayerPaintForeground;
@@ -1544,38 +1703,75 @@ float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
return finalOpacity;
}
-static bool hasBoxDecorations(const RenderStyle* style)
+// FIXME: Code is duplicated in RenderLayer. Also, we should probably not consider filters a box decoration here.
+static inline bool hasVisibleBoxDecorations(const RenderStyle& style)
{
- return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
+ return style.hasVisibleBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
}
-static bool canCreateTiledImage(const RenderStyle*);
+static bool canDirectlyCompositeBackgroundBackgroundImage(const RenderStyle& style)
+{
+ if (!GraphicsLayer::supportsContentsTiling())
+ return false;
+
+ auto& fillLayer = style.backgroundLayers();
+ if (fillLayer.next())
+ return false;
+
+ if (!fillLayer.imagesAreLoaded())
+ return false;
+
+ if (fillLayer.attachment() != ScrollBackgroundAttachment)
+ return false;
+
+ // FIXME: Allow color+image compositing when it makes sense.
+ // For now bailing out.
+ if (style.visitedDependentColor(CSSPropertyBackgroundColor).isVisible())
+ return false;
+
+ // FIXME: support gradients with isGeneratedImage.
+ auto* styleImage = fillLayer.image();
+ if (!styleImage->isCachedImage())
+ return false;
+
+ auto* image = styleImage->cachedImage()->image();
+ if (!image->isBitmapImage())
+ return false;
+
+ return true;
+}
-static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
+static bool hasPaintedBoxDecorationsOrBackgroundImage(const RenderStyle& style)
{
- if (hasBoxDecorations(style))
+ if (hasVisibleBoxDecorations(style))
return true;
- if (!style->hasBackgroundImage())
+ if (!style.hasBackgroundImage())
return false;
- return !GraphicsLayer::supportsContentsTiling() || !canCreateTiledImage(style);
+ return !canDirectlyCompositeBackgroundBackgroundImage(style);
}
-static bool hasPerspectiveOrPreserves3D(const RenderStyle* style)
+static inline bool hasPerspectiveOrPreserves3D(const RenderStyle& style)
{
- return style->hasPerspective() || style->preserves3D();
+ return style.hasPerspective() || style.preserves3D();
}
Color RenderLayerBacking::rendererBackgroundColor() const
{
- const auto& backgroundRenderer = renderer().isRoot() ? renderer().rendererForRootBackground() : renderer();
- return backgroundRenderer.style().visitedDependentColor(CSSPropertyBackgroundColor);
+ RenderElement* backgroundRenderer = nullptr;
+ if (renderer().isDocumentElementRenderer())
+ backgroundRenderer = renderer().view().rendererForRootBackground();
+
+ if (!backgroundRenderer)
+ backgroundRenderer = &renderer();
+
+ return backgroundRenderer->style().visitedDependentColor(CSSPropertyBackgroundColor);
}
void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(bool isSimpleContainer, bool& didUpdateContentsRect)
{
- if (!isSimpleContainer) {
+ if (!isSimpleContainer || (is<RenderBox>(renderer()) && !downcast<RenderBox>(renderer()).paintsOwnBackground())) {
m_graphicsLayer->setContentsToSolidColor(Color());
return;
}
@@ -1584,44 +1780,12 @@ void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(bool isSimpleCo
// An unset (invalid) color will remove the solid color.
m_graphicsLayer->setContentsToSolidColor(backgroundColor);
- IntRect contentsRect = backgroundBox();
+ FloatRect contentsRect = backgroundBoxForSimpleContainerPainting();
m_graphicsLayer->setContentsRect(contentsRect);
- m_graphicsLayer->setContentsClippingRect(contentsRect);
+ m_graphicsLayer->setContentsClippingRect(FloatRoundedRect(contentsRect));
didUpdateContentsRect = true;
}
-bool canCreateTiledImage(const RenderStyle* style)
-{
- const FillLayer* fillLayer = style->backgroundLayers();
- if (fillLayer->next())
- return false;
-
- if (!fillLayer->imagesAreLoaded())
- return false;
-
- if (fillLayer->attachment() != ScrollBackgroundAttachment)
- return false;
-
- Color color = style->visitedDependentColor(CSSPropertyBackgroundColor);
-
- // FIXME: Allow color+image compositing when it makes sense.
- // For now bailing out.
- if (color.isValid() && color.alpha())
- return false;
-
- StyleImage* styleImage = fillLayer->image();
-
- // FIXME: support gradients with isGeneratedImage.
- if (!styleImage->isCachedImage())
- return false;
-
- Image* image = styleImage->cachedImage()->image();
- if (!image->isBitmapImage())
- return false;
-
- return true;
-}
-
void RenderLayerBacking::updateDirectlyCompositedBackgroundImage(bool isSimpleContainer, bool& didUpdateContentsRect)
{
if (!GraphicsLayer::supportsContentsTiling())
@@ -1630,30 +1794,30 @@ void RenderLayerBacking::updateDirectlyCompositedBackgroundImage(bool isSimpleCo
if (isDirectlyCompositedImage())
return;
- const RenderStyle& style = renderer().style();
-
+ auto& style = renderer().style();
if (!isSimpleContainer || !style.hasBackgroundImage()) {
m_graphicsLayer->setContentsToImage(0);
return;
}
- IntRect destRect = backgroundBox();
- IntPoint phase;
- IntSize tileSize;
+ auto destRect = backgroundBoxForSimpleContainerPainting();
+ FloatSize phase;
+ FloatSize tileSize;
+ // FIXME: Absolute paint location is required here.
+ downcast<RenderBox>(renderer()).getGeometryForBackgroundImage(&renderer(), LayoutPoint(), destRect, phase, tileSize);
- RefPtr<Image> image = style.backgroundLayers()->image()->cachedImage()->image();
- toRenderBox(renderer()).getGeometryForBackgroundImage(&m_owningLayer.renderer(), destRect, phase, tileSize);
m_graphicsLayer->setContentsTileSize(tileSize);
m_graphicsLayer->setContentsTilePhase(phase);
m_graphicsLayer->setContentsRect(destRect);
- m_graphicsLayer->setContentsClippingRect(destRect);
- m_graphicsLayer->setContentsToImage(image.get());
+ m_graphicsLayer->setContentsClippingRect(FloatRoundedRect(destRect));
+ m_graphicsLayer->setContentsToImage(style.backgroundLayers().image()->cachedImage()->image());
+
didUpdateContentsRect = true;
}
void RenderLayerBacking::updateRootLayerConfiguration()
{
- if (!m_usingTiledCacheLayer)
+ if (!m_isMainFrameLayerWithTiledBacking)
return;
Color backgroundColor;
@@ -1671,15 +1835,16 @@ void RenderLayerBacking::updateRootLayerConfiguration()
}
}
-static bool supportsDirectBoxDecorationsComposition(const RenderLayerModelObject& renderer)
+static bool supportsDirectlyCompositedBoxDecorations(const RenderLayerModelObject& renderer)
{
if (!GraphicsLayer::supportsBackgroundColorContent())
return false;
+ const RenderStyle& style = renderer.style();
if (renderer.hasClip())
return false;
- if (hasBoxDecorationsOrBackgroundImage(&renderer.style()))
+ if (hasPaintedBoxDecorationsOrBackgroundImage(style))
return false;
// FIXME: We can't create a directly composited background if this
@@ -1687,14 +1852,11 @@ static bool supportsDirectBoxDecorationsComposition(const RenderLayerModelObject
// A better solution might be to introduce a flattening layer if
// we do direct box decoration composition.
// https://bugs.webkit.org/show_bug.cgi?id=119461
- if (hasPerspectiveOrPreserves3D(&renderer.style()))
+ if (hasPerspectiveOrPreserves3D(style))
return false;
// FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
- if (renderer.style().backgroundComposite() != CompositeSourceOver)
- return false;
-
- if (renderer.style().backgroundClip() == TextFillBox)
+ if (style.backgroundComposite() != CompositeSourceOver)
return false;
return true;
@@ -1705,38 +1867,35 @@ bool RenderLayerBacking::paintsBoxDecorations() const
if (!m_owningLayer.hasVisibleBoxDecorations())
return false;
- if (!supportsDirectBoxDecorationsComposition(renderer()))
- return true;
-
- return false;
+ return !supportsDirectlyCompositedBoxDecorations(renderer());
}
-bool RenderLayerBacking::paintsChildren() const
+bool RenderLayerBacking::paintsChildRenderers() const
{
if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers())
return true;
- if (hasVisibleNonCompositingDescendantLayers())
+ if (isPaintDestinationForDescendantLayers())
return true;
return false;
}
-static bool isRestartedPlugin(RenderObject* renderer)
+static bool isRestartedPlugin(RenderObject& renderer)
{
- if (!renderer->isEmbeddedObject())
+ if (!is<RenderEmbeddedObject>(renderer))
return false;
- Element* element = toElement(renderer->node());
- if (!element || !element->isPluginElement())
+ HTMLFrameOwnerElement& element = downcast<RenderEmbeddedObject>(renderer).frameOwnerElement();
+ if (!is<HTMLPlugInElement>(element))
return false;
- return toHTMLPlugInElement(element)->isRestartedPlugin();
+ return downcast<HTMLPlugInElement>(element).isRestartedPlugin();
}
-static bool isCompositedPlugin(RenderObject* renderer)
+static bool isCompositedPlugin(RenderObject& renderer)
{
- return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
+ return is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing();
}
// A "simple container layer" is a RenderLayer which has no visible content to render.
@@ -1744,47 +1903,53 @@ static bool isCompositedPlugin(RenderObject* renderer)
// This is a useful optimization, because it allows us to avoid allocating backing store.
bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
{
- if (renderer().hasMask()) // masks require special treatment
+ if (renderer().isRenderReplaced() && (!isCompositedPlugin(renderer()) || isRestartedPlugin(renderer())))
return false;
- if (renderer().isReplaced() && (!isCompositedPlugin(&renderer()) || isRestartedPlugin(&renderer())))
+ if (renderer().isTextControl())
return false;
- if (paintsBoxDecorations() || paintsChildren())
+ if (paintsBoxDecorations() || paintsChildRenderers())
return false;
+ if (renderer().style().backgroundClip() == TextFillBox)
+ return false;
+
if (renderer().isRenderNamedFlowFragmentContainer())
return false;
+ if (renderer().isDocumentElementRenderer() && m_owningLayer.isolatesCompositedBlending())
+ return false;
+
if (renderer().isRenderView()) {
// Look to see if the root object has a non-simple background
- RenderObject* rootObject = renderer().document().documentElement() ? renderer().document().documentElement()->renderer() : 0;
+ auto* rootObject = renderer().document().documentElement() ? renderer().document().documentElement()->renderer() : nullptr;
if (!rootObject)
return false;
- RenderStyle* style = &rootObject->style();
-
// Reject anything that has a border, a border-radius or outline,
// or is not a simple background (no background, or solid color).
- if (hasBoxDecorationsOrBackgroundImage(style))
+ if (hasPaintedBoxDecorationsOrBackgroundImage(rootObject->style()))
return false;
// Now look at the body's renderer.
- HTMLElement* body = renderer().document().body();
- RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
- if (!bodyObject)
+ auto* body = renderer().document().body();
+ if (!body)
+ return false;
+ auto* bodyRenderer = body->renderer();
+ if (!bodyRenderer)
return false;
- style = &bodyObject->style();
-
- if (hasBoxDecorationsOrBackgroundImage(style))
+ if (hasPaintedBoxDecorationsOrBackgroundImage(bodyRenderer->style()))
return false;
}
return true;
}
-static bool hasVisibleNonCompositingDescendant(RenderLayer& parent)
+enum class LayerTraversal { Continue, Stop };
+
+static LayerTraversal traverseVisibleNonCompositedDescendantLayers(RenderLayer& parent, std::function<LayerTraversal (const RenderLayer&)> layerFunc)
{
// FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
parent.updateLayerListsIfNeeded();
@@ -1793,49 +1958,75 @@ static bool hasVisibleNonCompositingDescendant(RenderLayer& parent)
LayerListMutationDetector mutationChecker(&parent);
#endif
- if (Vector<RenderLayer*>* normalFlowList = parent.normalFlowList()) {
- size_t listSize = normalFlowList->size();
- for (size_t i = 0; i < listSize; ++i) {
- RenderLayer* curLayer = normalFlowList->at(i);
- if (!curLayer->isComposited()
- && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(*curLayer)))
- return true;
+ if (auto* normalFlowList = parent.normalFlowList()) {
+ for (auto* childLayer : *normalFlowList) {
+ if (compositedWithOwnBackingStore(*childLayer))
+ continue;
+
+ if (layerFunc(*childLayer) == LayerTraversal::Stop)
+ return LayerTraversal::Stop;
+
+ if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
+ return LayerTraversal::Stop;
}
}
if (parent.isStackingContainer()) {
if (!parent.hasVisibleDescendant())
- return false;
+ return LayerTraversal::Continue;
// Use the m_hasCompositingDescendant bit to optimize?
- if (Vector<RenderLayer*>* negZOrderList = parent.negZOrderList()) {
- size_t listSize = negZOrderList->size();
- for (size_t i = 0; i < listSize; ++i) {
- RenderLayer* curLayer = negZOrderList->at(i);
- if (!curLayer->isComposited()
- && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(*curLayer)))
- return true;
+ if (auto* negZOrderList = parent.negZOrderList()) {
+ for (auto* childLayer : *negZOrderList) {
+ if (compositedWithOwnBackingStore(*childLayer))
+ continue;
+
+ if (layerFunc(*childLayer) == LayerTraversal::Stop)
+ return LayerTraversal::Stop;
+
+ if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
+ return LayerTraversal::Stop;
}
}
- if (Vector<RenderLayer*>* posZOrderList = parent.posZOrderList()) {
- size_t listSize = posZOrderList->size();
- for (size_t i = 0; i < listSize; ++i) {
- RenderLayer* curLayer = posZOrderList->at(i);
- if (!curLayer->isComposited()
- && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(*curLayer)))
- return true;
+ if (auto* posZOrderList = parent.posZOrderList()) {
+ for (auto* childLayer : *posZOrderList) {
+ if (compositedWithOwnBackingStore(*childLayer))
+ continue;
+
+ if (layerFunc(*childLayer) == LayerTraversal::Stop)
+ return LayerTraversal::Stop;
+
+ if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
+ return LayerTraversal::Stop;
}
}
}
- return false;
+ return LayerTraversal::Continue;
}
// Conservative test for having no rendered children.
-bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const
+bool RenderLayerBacking::isPaintDestinationForDescendantLayers() const
{
- return hasVisibleNonCompositingDescendant(m_owningLayer);
+ bool hasPaintingDescendant = false;
+ traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasPaintingDescendant](const RenderLayer& layer) {
+ hasPaintingDescendant = layer.isVisuallyNonEmpty();
+ return hasPaintingDescendant ? LayerTraversal::Stop : LayerTraversal::Continue;
+ });
+
+ return hasPaintingDescendant;
+}
+
+bool RenderLayerBacking::hasVisibleNonCompositedDescendants() const
+{
+ bool hasVisibleDescendant = false;
+ traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasVisibleDescendant](const RenderLayer& layer) {
+ hasVisibleDescendant = layer.hasVisibleContent();
+ return hasVisibleDescendant ? LayerTraversal::Stop : LayerTraversal::Continue;
+ });
+
+ return hasVisibleDescendant;
}
bool RenderLayerBacking::containsPaintedContent(bool isSimpleContainer) const
@@ -1849,13 +2040,13 @@ bool RenderLayerBacking::containsPaintedContent(bool isSimpleContainer) const
// FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
// and set background color on the layer in that case, instead of allocating backing store and painting.
#if ENABLE(VIDEO)
- if (renderer().isVideo() && toRenderVideo(renderer()).shouldDisplayVideo())
- return m_owningLayer.hasBoxDecorationsOrBackground();
+ if (is<RenderVideo>(renderer()) && downcast<RenderVideo>(renderer()).shouldDisplayVideo())
+ return m_owningLayer.hasVisibleBoxDecorationsOrBackground() || (!(downcast<RenderVideo>(renderer()).supportsAcceleratedRendering()) && m_requiresOwnBackingStore);
#endif
#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
- if (renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents)
- return m_owningLayer.hasBoxDecorationsOrBackground();
+ if (is<RenderHTMLCanvas>(renderer()) && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents)
+ return m_owningLayer.hasVisibleBoxDecorationsOrBackground();
#endif
return true;
@@ -1865,10 +2056,15 @@ bool RenderLayerBacking::containsPaintedContent(bool isSimpleContainer) const
// that require painting. Direct compositing saves backing store.
bool RenderLayerBacking::isDirectlyCompositedImage() const
{
- if (!renderer().isRenderImage() || renderer().isMedia() || m_owningLayer.hasBoxDecorationsOrBackground() || renderer().hasClip())
+ if (!is<RenderImage>(renderer()) || m_owningLayer.hasVisibleBoxDecorationsOrBackground() || m_owningLayer.paintsWithFilters() || renderer().hasClip())
return false;
- RenderImage& imageRenderer = toRenderImage(renderer());
+#if ENABLE(VIDEO)
+ if (is<RenderMedia>(renderer()))
+ return false;
+#endif
+
+ auto& imageRenderer = downcast<RenderImage>(renderer());
if (CachedImage* cachedImage = imageRenderer.cachedImage()) {
if (!cachedImage->hasImage())
return false;
@@ -1893,8 +2089,8 @@ void RenderLayerBacking::contentChanged(ContentChangeType changeType)
return;
}
- if ((changeType == BackgroundImageChanged) && canCreateTiledImage(&renderer().style()))
- updateGraphicsLayerGeometry();
+ if ((changeType == BackgroundImageChanged) && canDirectlyCompositeBackgroundBackgroundImage(renderer().style()))
+ updateGeometry();
if ((changeType == MaskImageChanged) && m_maskLayer) {
// The composited layer bounds relies on box->maskClipRect(), which changes
@@ -1912,8 +2108,7 @@ void RenderLayerBacking::contentChanged(ContentChangeType changeType)
void RenderLayerBacking::updateImageContents()
{
- ASSERT(renderer().isRenderImage());
- RenderImage& imageRenderer = toRenderImage(renderer());
+ auto& imageRenderer = downcast<RenderImage>(renderer());
CachedImage* cachedImage = imageRenderer.cachedImage();
if (!cachedImage)
@@ -1928,11 +2123,12 @@ void RenderLayerBacking::updateImageContents()
return;
// This is a no-op if the layer doesn't have an inner layer for the image.
- m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
+ m_graphicsLayer->setContentsRect(snapRectToDevicePixels(contentsBox(), deviceScaleFactor()));
- LayoutRect contentsClippingRect = imageRenderer.contentBoxRect();
- contentsClippingRect.move(contentOffsetInCompostingLayer());
- m_graphicsLayer->setContentsClippingRect(pixelSnappedIntRect(contentsClippingRect));
+ LayoutRect boxRect(LayoutPoint(), imageRenderer.size());
+ boxRect.move(contentOffsetInCompostingLayer());
+ FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
+ m_graphicsLayer->setContentsClippingRect(contentsClippingRect);
m_graphicsLayer->setContentsToImage(image);
bool isSimpleContainer = false;
@@ -1944,52 +2140,39 @@ void RenderLayerBacking::updateImageContents()
image->startAnimation();
}
-FloatPoint3D RenderLayerBacking::computeTransformOrigin(const IntRect& borderBox) const
+FloatPoint3D RenderLayerBacking::computeTransformOriginForPainting(const LayoutRect& borderBox) const
{
const RenderStyle& style = renderer().style();
+ float deviceScaleFactor = this->deviceScaleFactor();
FloatPoint3D origin;
- origin.setX(floatValueForLength(style.transformOriginX(), borderBox.width()));
- origin.setY(floatValueForLength(style.transformOriginY(), borderBox.height()));
+ origin.setX(roundToDevicePixel(floatValueForLength(style.transformOriginX(), borderBox.width()), deviceScaleFactor));
+ origin.setY(roundToDevicePixel(floatValueForLength(style.transformOriginY(), borderBox.height()), deviceScaleFactor));
origin.setZ(style.transformOriginZ());
return origin;
}
-FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox) const
-{
- const RenderStyle& style = renderer().style();
-
- float boxWidth = borderBox.width();
- float boxHeight = borderBox.height();
-
- FloatPoint origin;
- origin.setX(floatValueForLength(style.perspectiveOriginX(), boxWidth));
- origin.setY(floatValueForLength(style.perspectiveOriginY(), boxHeight));
-
- return origin;
-}
-
// Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
{
- return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y());
+ return LayoutSize(-m_compositedBounds.x() + m_compositedBoundsOffsetFromGraphicsLayer.width(), -m_compositedBounds.y() + m_compositedBoundsOffsetFromGraphicsLayer.height());
}
LayoutRect RenderLayerBacking::contentsBox() const
{
- if (!renderer().isBox())
+ if (!is<RenderBox>(renderer()))
return LayoutRect();
- RenderBox& renderBox = toRenderBox(renderer());
+ auto& renderBox = downcast<RenderBox>(renderer());
LayoutRect contentsRect;
#if ENABLE(VIDEO)
- if (renderBox.isVideo())
- contentsRect = toRenderVideo(renderBox).videoBox();
+ if (is<RenderVideo>(renderBox))
+ contentsRect = downcast<RenderVideo>(renderBox).videoBox();
else
#endif
- if (renderBox.isRenderReplaced()) {
- RenderReplaced& renderReplaced = *toRenderReplaced(&renderBox);
+ if (is<RenderReplaced>(renderBox)) {
+ RenderReplaced& renderReplaced = downcast<RenderReplaced>(renderBox);
contentsRect = renderReplaced.replacedContentRect(renderBox.intrinsicSize());
} else
contentsRect = renderBox.contentBoxRect();
@@ -2007,7 +2190,7 @@ static LayoutRect backgroundRectForBox(const RenderBox& box)
return box.paddingBoxRect();
case ContentFillBox:
return box.contentBoxRect();
- case TextFillBox:
+ default:
break;
}
@@ -2015,14 +2198,14 @@ static LayoutRect backgroundRectForBox(const RenderBox& box)
return LayoutRect();
}
-IntRect RenderLayerBacking::backgroundBox() const
+FloatRect RenderLayerBacking::backgroundBoxForSimpleContainerPainting() const
{
- if (!renderer().isBox())
- return IntRect();
+ if (!is<RenderBox>(renderer()))
+ return FloatRect();
- LayoutRect backgroundBox = backgroundRectForBox(toRenderBox(renderer()));
+ LayoutRect backgroundBox = backgroundRectForBox(downcast<RenderBox>(renderer()));
backgroundBox.move(contentOffsetInCompostingLayer());
- return pixelSnappedIntRect(backgroundBox);
+ return snapRectToDevicePixels(backgroundBox, deviceScaleFactor());
}
GraphicsLayer* RenderLayerBacking::parentForSublayers() const
@@ -2030,14 +2213,7 @@ GraphicsLayer* RenderLayerBacking::parentForSublayers() const
if (m_scrollingContentsLayer)
return m_scrollingContentsLayer.get();
-#if PLATFORM(IOS)
- // FIXME: Can we remove this iOS-specific code path?
- if (GraphicsLayer* clippingLayer = this->clippingLayer())
- return clippingLayer;
- return m_graphicsLayer.get();
-#else
return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
-#endif
}
GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
@@ -2053,7 +2229,11 @@ GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
bool RenderLayerBacking::paintsIntoWindow() const
{
- if (m_usingTiledCacheLayer)
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ return false;
+#endif
+
+ if (m_isMainFrameLayerWithTiledBacking)
return false;
if (m_owningLayer.isRootLayer()) {
@@ -2083,20 +2263,13 @@ void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking)
compositor().repaintInCompositedAncestor(m_owningLayer, compositedBounds());
}
-#if ENABLE(CSS_COMPOSITING)
-void RenderLayerBacking::setBlendMode(BlendMode blendMode)
-{
- m_graphicsLayer->setBlendMode(blendMode);
-}
-#endif
-
void RenderLayerBacking::setContentsNeedDisplay(GraphicsLayer::ShouldClipToLayer shouldClip)
{
ASSERT(!paintsIntoCompositedAncestor());
FrameView& frameView = owningLayer().renderer().view().frameView();
if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
- frameView.addTrackedRepaintRect(owningLayer().absoluteBoundingBox());
+ frameView.addTrackedRepaintRect(owningLayer().absoluteBoundingBoxForPainting());
if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
// By default, setNeedsDisplay will clip to the size of the GraphicsLayer, which does not include margin tiles.
@@ -2116,61 +2289,72 @@ void RenderLayerBacking::setContentsNeedDisplay(GraphicsLayer::ShouldClipToLayer
if (m_maskLayer && m_maskLayer->drawsContent())
m_maskLayer->setNeedsDisplay();
+ if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent())
+ m_childClippingMaskLayer->setNeedsDisplay();
+
if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
m_scrollingContentsLayer->setNeedsDisplay();
}
// r is in the coordinate space of the layer's render object
-void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r, GraphicsLayer::ShouldClipToLayer shouldClip)
+void RenderLayerBacking::setContentsNeedDisplayInRect(const LayoutRect& r, GraphicsLayer::ShouldClipToLayer shouldClip)
{
ASSERT(!paintsIntoCompositedAncestor());
+ FloatRect pixelSnappedRectForPainting = snapRectToDevicePixels(r, deviceScaleFactor());
FrameView& frameView = owningLayer().renderer().view().frameView();
if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
- frameView.addTrackedRepaintRect(pixelSnappedIntRect(r));
+ frameView.addTrackedRepaintRect(pixelSnappedRectForPainting);
if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer());
+ FloatRect layerDirtyRect = pixelSnappedRectForPainting;
+ layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
}
if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer());
+ FloatRect layerDirtyRect = pixelSnappedRectForPainting;
+ layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
}
// FIXME: need to split out repaints for the background.
if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer());
+ FloatRect layerDirtyRect = pixelSnappedRectForPainting;
+ layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
}
if (m_maskLayer && m_maskLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_maskLayer->offsetFromRenderer());
+ FloatRect layerDirtyRect = pixelSnappedRectForPainting;
+ layerDirtyRect.move(-m_maskLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
m_maskLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
}
+ if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent()) {
+ FloatRect layerDirtyRect = r;
+ layerDirtyRect.move(-m_childClippingMaskLayer->offsetFromRenderer());
+ m_childClippingMaskLayer->setNeedsDisplayInRect(layerDirtyRect);
+ }
+
if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer());
+ FloatRect layerDirtyRect = pixelSnappedRectForPainting;
+ layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
#if PLATFORM(IOS)
- // Account for the fact that RenderLayerBacking::updateGraphicsLayerGeometry() bakes scrollOffset into offsetFromRenderer on iOS.
- layerDirtyRect.move(-m_owningLayer.scrollOffset());
+ // Account for the fact that RenderLayerBacking::updateGeometry() bakes scrollOffset into offsetFromRenderer on iOS,
+ // but the repaint rect is computed without taking the scroll position into account (see shouldApplyClipAndScrollPositionForRepaint()).
+ layerDirtyRect.moveBy(-m_owningLayer.scrollPosition());
#endif
m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
}
}
-void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext* context,
- const IntRect& paintDirtyRect, // In the coords of rootLayer.
- PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
+void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext& context,
+ const IntRect& paintDirtyRect, // In the coords of rootLayer.
+ PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
{
- if (paintsIntoWindow() || paintsIntoCompositedAncestor()) {
-#if !PLATFORM(IOS)
+ if ((paintsIntoWindow() || paintsIntoCompositedAncestor()) && paintingPhase != GraphicsLayerPaintChildClippingMask) {
+#if !PLATFORM(IOS) && !OS(WINDOWS)
// FIXME: Looks like the CALayer tree is out of sync with the GraphicsLayer heirarchy
// when pages are restored from the PageCache.
// <rdar://problem/8712587> ASSERT: When Going Back to Page with Plugins in PageCache
@@ -2179,8 +2363,6 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
return;
}
- FontCachePurgePreventer fontCachePurgePreventer;
-
RenderLayer::PaintLayerFlags paintFlags = 0;
if (paintingPhase & GraphicsLayerPaintBackground)
paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
@@ -2188,6 +2370,10 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
if (paintingPhase & GraphicsLayerPaintMask)
paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
+ if (paintingPhase & GraphicsLayerPaintClipPath)
+ paintFlags |= RenderLayer::PaintLayerPaintingCompositingClipPathPhase;
+ if (paintingPhase & GraphicsLayerPaintChildClippingMask)
+ paintFlags |= RenderLayer::PaintLayerPaintingChildClippingMaskPhase;
if (paintingPhase & GraphicsLayerPaintOverflowContents)
paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents;
if (paintingPhase & GraphicsLayerPaintCompositedScroll)
@@ -2197,74 +2383,73 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
else if (compositor().fixedRootBackgroundLayer())
paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
-
+
+#ifndef NDEBUG
+ RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&renderer());
+#endif
+
+ FrameView::PaintingState paintingState;
+ if (m_owningLayer.isRootLayer())
+ renderer().view().frameView().willPaintContents(context, paintDirtyRect, paintingState);
+
// FIXME: GraphicsLayers need a way to split for RenderRegions.
- RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, m_subpixelAccumulation);
+ RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
if (m_owningLayer.containsDirtyOverlayScrollbars())
m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
+ if (m_owningLayer.isRootLayer())
+ renderer().view().frameView().didPaintContents(context, paintDirtyRect, paintingState);
+
compositor().didPaintBacking(this);
ASSERT(!m_owningLayer.m_usedTransparency);
}
-static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
-{
- if (!scrollbar)
- return;
-
- context.save();
- const IntRect& scrollbarRect = scrollbar->frameRect();
- context.translate(-scrollbarRect.x(), -scrollbarRect.y());
- IntRect transformedClip = clip;
- transformedClip.moveBy(scrollbarRect.location());
- scrollbar->paint(&context, transformedClip);
- context.restore();
-}
-
// Up-call from compositing layer drawing callback.
-void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
+void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const FloatRect& clip)
{
#ifndef NDEBUG
- if (Page* page = renderer().frame().page())
- page->setIsPainting(true);
+ renderer().page().setIsPainting(true);
#endif
+ // The dirtyRect is in the coords of the painting root.
+ FloatRect adjustedClipRect = clip;
+ adjustedClipRect.move(m_subpixelOffsetFromRenderer);
+ IntRect dirtyRect = enclosingIntRect(adjustedClipRect);
+
if (graphicsLayer == m_graphicsLayer.get()
|| graphicsLayer == m_foregroundLayer.get()
|| graphicsLayer == m_backgroundLayer.get()
|| graphicsLayer == m_maskLayer.get()
+ || graphicsLayer == m_childClippingMaskLayer.get()
|| graphicsLayer == m_scrollingContentsLayer.get()) {
- InspectorInstrumentation::willPaint(&renderer());
+ InspectorInstrumentation::willPaint(renderer());
- // The dirtyRect is in the coords of the painting root.
- IntRect dirtyRect = clip;
if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
dirtyRect.intersect(enclosingIntRect(compositedBoundsIncludingMargin()));
// We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
- paintIntoLayer(graphicsLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase);
+ paintIntoLayer(graphicsLayer, context, dirtyRect, PaintBehaviorNormal, paintingPhase);
- InspectorInstrumentation::didPaint(&renderer(), &context, clip);
+ InspectorInstrumentation::didPaint(renderer(), dirtyRect);
} else if (graphicsLayer == layerForHorizontalScrollbar()) {
- paintScrollbar(m_owningLayer.horizontalScrollbar(), context, clip);
+ paintScrollbar(m_owningLayer.horizontalScrollbar(), context, dirtyRect);
} else if (graphicsLayer == layerForVerticalScrollbar()) {
- paintScrollbar(m_owningLayer.verticalScrollbar(), context, clip);
+ paintScrollbar(m_owningLayer.verticalScrollbar(), context, dirtyRect);
} else if (graphicsLayer == layerForScrollCorner()) {
const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
context.save();
context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
- LayoutRect transformedClip = clip;
+ LayoutRect transformedClip = LayoutRect(clip);
transformedClip.moveBy(scrollCornerAndResizer.location());
- m_owningLayer.paintScrollCorner(&context, IntPoint(), pixelSnappedIntRect(transformedClip));
- m_owningLayer.paintResizer(&context, IntPoint(), transformedClip);
+ m_owningLayer.paintScrollCorner(context, IntPoint(), snappedIntRect(transformedClip));
+ m_owningLayer.paintResizer(context, IntPoint(), transformedClip);
context.restore();
}
#ifndef NDEBUG
- if (Page* page = renderer().frame().page())
- page->setIsPainting(false);
+ renderer().page().setIsPainting(false);
#endif
}
@@ -2273,6 +2458,11 @@ float RenderLayerBacking::pageScaleFactor() const
return compositor().pageScaleFactor();
}
+float RenderLayerBacking::zoomedOutPageScaleFactor() const
+{
+ return compositor().zoomedOutPageScaleFactor();
+}
+
float RenderLayerBacking::deviceScaleFactor() const
{
return compositor().deviceScaleFactor();
@@ -2283,6 +2473,11 @@ float RenderLayerBacking::contentsScaleMultiplierForNewTiles(const GraphicsLayer
return compositor().contentsScaleMultiplierForNewTiles(layer);
}
+bool RenderLayerBacking::paintsOpaquelyAtNonIntegralScales(const GraphicsLayer*) const
+{
+ return m_isMainFrameRenderViewLayer;
+}
+
void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer* layer) const
{
compositor().didFlushChangesForLayer(m_owningLayer, layer);
@@ -2306,8 +2501,11 @@ bool RenderLayerBacking::isTrackingRepaints() const
return static_cast<GraphicsLayerClient&>(compositor()).isTrackingRepaints();
}
-bool RenderLayerBacking::shouldSkipLayerInDump(const GraphicsLayer* layer) const
+bool RenderLayerBacking::shouldSkipLayerInDump(const GraphicsLayer* layer, LayerTreeAsTextBehavior behavior) const
{
+ if (behavior & LayerTreeAsTextDebug)
+ return false;
+
// Skip the root tile cache's flattening layer.
return m_isMainFrameRenderViewLayer && layer && layer == m_childContainmentLayer.get();
}
@@ -2333,30 +2531,52 @@ bool RenderLayerBacking::shouldDumpPropertyForLayer(const GraphicsLayer* layer,
return true;
}
+bool RenderLayerBacking::shouldAggressivelyRetainTiles(const GraphicsLayer*) const
+{
+ // Only the main frame TileController has enough information about in-window state to
+ // correctly implement aggressive tile retention.
+ if (!m_isMainFrameRenderViewLayer)
+ return false;
+
+ return renderer().settings().aggressiveTileRetentionEnabled();
+}
+
+bool RenderLayerBacking::shouldTemporarilyRetainTileCohorts(const GraphicsLayer*) const
+{
+ return renderer().settings().temporaryTileCohortRetentionEnabled();
+}
+
+bool RenderLayerBacking::useGiantTiles() const
+{
+ return renderer().settings().useGiantTiles();
+}
+
#ifndef NDEBUG
void RenderLayerBacking::verifyNotPainting()
{
- ASSERT(!renderer().frame().page() || !renderer().frame().page()->isPainting());
+ ASSERT(!renderer().page().isPainting());
}
#endif
bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
{
bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
- bool hasTransform = renderer().isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
-#if ENABLE(CSS_FILTERS)
- bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
-#else
- bool hasFilter = false;
+ bool hasTransform = renderer().isBox() && keyframes.containsProperty(CSSPropertyTransform);
+ bool hasFilter = keyframes.containsProperty(CSSPropertyFilter);
+
+ bool hasBackdropFilter = false;
+#if ENABLE(FILTERS_LEVEL_2)
+ hasBackdropFilter = keyframes.containsProperty(CSSPropertyWebkitBackdropFilter);
#endif
- if (!hasOpacity && !hasTransform && !hasFilter)
+ if (!hasOpacity && !hasTransform && !hasFilter && !hasBackdropFilter)
return false;
-
- KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
+
+ KeyframeValueList transformVector(AnimatedPropertyTransform);
KeyframeValueList opacityVector(AnimatedPropertyOpacity);
-#if ENABLE(CSS_FILTERS)
- KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
+ KeyframeValueList filterVector(AnimatedPropertyFilter);
+#if ENABLE(FILTERS_LEVEL_2)
+ KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
#endif
size_t numKeyframes = keyframes.size();
@@ -2368,36 +2588,41 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim
if (!keyframeStyle)
continue;
- // Get timing function.
- RefPtr<TimingFunction> tf = keyframeStyle->hasAnimations() ? (*keyframeStyle->animations()).animation(0).timingFunction() : 0;
+ TimingFunction* tf = currentKeyframe.timingFunction(keyframes.animationName());
bool isFirstOrLastKeyframe = key == 0 || key == 1;
- if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitTransform))
- transformVector.insert(TransformAnimationValue::create(key, keyframeStyle->transform(), tf));
+ if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyTransform))
+ transformVector.insert(std::make_unique<TransformAnimationValue>(key, keyframeStyle->transform(), tf));
if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
- opacityVector.insert(FloatAnimationValue::create(key, keyframeStyle->opacity(), tf));
+ opacityVector.insert(std::make_unique<FloatAnimationValue>(key, keyframeStyle->opacity(), tf));
+
+ if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyFilter))
+ filterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->filter(), tf));
-#if ENABLE(CSS_FILTERS)
- if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
- filterVector.insert(FilterAnimationValue::create(key, keyframeStyle->filter(), tf));
+#if ENABLE(FILTERS_LEVEL_2)
+ if ((hasBackdropFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitBackdropFilter))
+ backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->backdropFilter(), tf));
#endif
}
- if (renderer().frame().page() && !renderer().frame().page()->settings().acceleratedCompositedAnimationsEnabled())
+ if (!renderer().settings().acceleratedCompositedAnimationsEnabled())
return false;
bool didAnimate = false;
- if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer()).pixelSnappedBorderBoxRect().size(), anim, keyframes.animationName(), timeOffset))
+ if (hasTransform && m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), anim, keyframes.animationName(), timeOffset))
didAnimate = true;
if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
didAnimate = true;
-#if ENABLE(CSS_FILTERS)
if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
didAnimate = true;
+
+#if ENABLE(FILTERS_LEVEL_2)
+ if (hasBackdropFilter && m_graphicsLayer->addAnimation(backdropFilterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
+ didAnimate = true;
#endif
return didAnimate;
@@ -2423,41 +2648,55 @@ bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID proper
const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
KeyframeValueList opacityVector(AnimatedPropertyOpacity);
- opacityVector.insert(FloatAnimationValue::create(0, compositingOpacity(fromStyle->opacity())));
- opacityVector.insert(FloatAnimationValue::create(1, compositingOpacity(toStyle->opacity())));
+ opacityVector.insert(std::make_unique<FloatAnimationValue>(0, compositingOpacity(fromStyle->opacity())));
+ opacityVector.insert(std::make_unique<FloatAnimationValue>(1, compositingOpacity(toStyle->opacity())));
// The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
- if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
+ if (m_graphicsLayer->addAnimation(opacityVector, FloatSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
// To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
- updateOpacity(toStyle);
+ updateOpacity(*toStyle);
didAnimate = true;
}
}
}
- if (property == CSSPropertyWebkitTransform && m_owningLayer.hasTransform()) {
- const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform);
+ if (property == CSSPropertyTransform && m_owningLayer.hasTransform()) {
+ const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyTransform);
if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
- KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
- transformVector.insert(TransformAnimationValue::create(0, fromStyle->transform()));
- transformVector.insert(TransformAnimationValue::create(1, toStyle->transform()));
- if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer()).pixelSnappedBorderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
+ KeyframeValueList transformVector(AnimatedPropertyTransform);
+ transformVector.insert(std::make_unique<TransformAnimationValue>(0, fromStyle->transform()));
+ transformVector.insert(std::make_unique<TransformAnimationValue>(1, toStyle->transform()));
+ if (m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyTransform), timeOffset)) {
// To ensure that the correct transform is visible when the animation ends, also set the final transform.
- updateTransform(toStyle);
+ updateTransform(*toStyle);
didAnimate = true;
}
}
}
-#if ENABLE(CSS_FILTERS)
- if (property == CSSPropertyWebkitFilter && m_owningLayer.hasFilter()) {
- const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter);
+ if (property == CSSPropertyFilter && m_owningLayer.hasFilter()) {
+ const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyFilter);
if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
- KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
- filterVector.insert(FilterAnimationValue::create(0, fromStyle->filter()));
- filterVector.insert(FilterAnimationValue::create(1, toStyle->filter()));
- if (m_graphicsLayer->addAnimation(filterVector, IntSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset)) {
+ KeyframeValueList filterVector(AnimatedPropertyFilter);
+ filterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->filter()));
+ filterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->filter()));
+ if (m_graphicsLayer->addAnimation(filterVector, FloatSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyFilter), timeOffset)) {
// To ensure that the correct filter is visible when the animation ends, also set the final filter.
- updateFilters(toStyle);
+ updateFilters(*toStyle);
+ didAnimate = true;
+ }
+ }
+ }
+
+#if ENABLE(FILTERS_LEVEL_2)
+ if (property == CSSPropertyWebkitBackdropFilter && m_owningLayer.hasBackdropFilter()) {
+ const Animation* backdropFilterAnim = toStyle->transitionForProperty(CSSPropertyWebkitBackdropFilter);
+ if (backdropFilterAnim && !backdropFilterAnim->isEmptyOrZeroDuration()) {
+ KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
+ backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->backdropFilter()));
+ backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->backdropFilter()));
+ if (m_graphicsLayer->addAnimation(backdropFilterVector, FloatSize(), backdropFilterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitBackdropFilter), timeOffset)) {
+ // To ensure that the correct backdrop filter is visible when the animation ends, also set the final backdrop filter.
+ updateBackdropFilters(*toStyle);
didAnimate = true;
}
}
@@ -2481,14 +2720,14 @@ void RenderLayerBacking::transitionFinished(CSSPropertyID property)
m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
}
-void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time)
+void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, const String&, double time)
{
- renderer().animation().notifyAnimationStarted(&renderer(), time);
+ renderer().animation().notifyAnimationStarted(renderer(), time);
}
void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer* layer)
{
- if (renderer().documentBeingDestroyed())
+ if (renderer().renderTreeBeingDestroyed())
return;
compositor().scheduleLayerFlush(layer->canThrottleLayerFlush());
}
@@ -2529,8 +2768,8 @@ LayoutRect RenderLayerBacking::compositedBoundsIncludingMargin() const
LayoutUnit leftMarginWidth = tiledBacking->leftMarginWidth();
LayoutUnit topMarginHeight = tiledBacking->topMarginHeight();
- boundsIncludingMargin.moveBy(IntPoint(-leftMarginWidth, -topMarginHeight));
- boundsIncludingMargin.expand(leftMarginWidth + (LayoutUnit)tiledBacking->rightMarginWidth(), topMarginHeight + (LayoutUnit)tiledBacking->bottomMarginHeight());
+ boundsIncludingMargin.moveBy(LayoutPoint(-leftMarginWidth, -topMarginHeight));
+ boundsIncludingMargin.expand(leftMarginWidth + tiledBacking->rightMarginWidth(), topMarginHeight + tiledBacking->bottomMarginHeight());
return boundsIncludingMargin;
}
@@ -2539,24 +2778,25 @@ CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID
{
CSSPropertyID cssProperty = CSSPropertyInvalid;
switch (property) {
- case AnimatedPropertyWebkitTransform:
- cssProperty = CSSPropertyWebkitTransform;
- break;
- case AnimatedPropertyOpacity:
- cssProperty = CSSPropertyOpacity;
- break;
- case AnimatedPropertyBackgroundColor:
- cssProperty = CSSPropertyBackgroundColor;
- break;
- case AnimatedPropertyWebkitFilter:
-#if ENABLE(CSS_FILTERS)
- cssProperty = CSSPropertyWebkitFilter;
-#else
- ASSERT_NOT_REACHED();
+ case AnimatedPropertyTransform:
+ cssProperty = CSSPropertyTransform;
+ break;
+ case AnimatedPropertyOpacity:
+ cssProperty = CSSPropertyOpacity;
+ break;
+ case AnimatedPropertyBackgroundColor:
+ cssProperty = CSSPropertyBackgroundColor;
+ break;
+ case AnimatedPropertyFilter:
+ cssProperty = CSSPropertyFilter;
+ break;
+#if ENABLE(FILTERS_LEVEL_2)
+ case AnimatedPropertyWebkitBackdropFilter:
+ cssProperty = CSSPropertyWebkitBackdropFilter;
+ break;
#endif
- break;
- case AnimatedPropertyInvalid:
- ASSERT_NOT_REACHED();
+ case AnimatedPropertyInvalid:
+ ASSERT_NOT_REACHED();
}
return cssProperty;
}
@@ -2564,30 +2804,32 @@ CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID
AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
{
switch (cssProperty) {
- case CSSPropertyWebkitTransform:
- return AnimatedPropertyWebkitTransform;
- case CSSPropertyOpacity:
- return AnimatedPropertyOpacity;
- case CSSPropertyBackgroundColor:
- return AnimatedPropertyBackgroundColor;
-#if ENABLE(CSS_FILTERS)
- case CSSPropertyWebkitFilter:
- return AnimatedPropertyWebkitFilter;
+ case CSSPropertyTransform:
+ return AnimatedPropertyTransform;
+ case CSSPropertyOpacity:
+ return AnimatedPropertyOpacity;
+ case CSSPropertyBackgroundColor:
+ return AnimatedPropertyBackgroundColor;
+ case CSSPropertyFilter:
+ return AnimatedPropertyFilter;
+#if ENABLE(FILTERS_LEVEL_2)
+ case CSSPropertyWebkitBackdropFilter:
+ return AnimatedPropertyWebkitBackdropFilter;
#endif
- default:
- // It's fine if we see other css properties here; they are just not accelerated.
- break;
+ default:
+ // It's fine if we see other css properties here; they are just not accelerated.
+ break;
}
return AnimatedPropertyInvalid;
}
CompositingLayerType RenderLayerBacking::compositingLayerType() const
{
- if (m_graphicsLayer->hasContentsLayer())
+ if (m_graphicsLayer->usesContentsLayer())
return MediaCompositingLayer;
if (m_graphicsLayer->drawsContent())
- return m_graphicsLayer->usingTiledBacking() ? TiledCompositingLayer : NormalCompositingLayer;
+ return m_graphicsLayer->tiledBacking() ? TiledCompositingLayer : NormalCompositingLayer;
return ContainerCompositingLayer;
}
@@ -2604,6 +2846,8 @@ double RenderLayerBacking::backingStoreMemoryEstimate() const
backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
if (m_maskLayer)
backingMemory += m_maskLayer->backingStoreMemoryEstimate();
+ if (m_childClippingMaskLayer)
+ backingMemory += m_childClippingMaskLayer->backingStoreMemoryEstimate();
if (m_scrollingContentsLayer)
backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
@@ -2621,5 +2865,3 @@ double RenderLayerBacking::backingStoreMemoryEstimate() const
}
} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)