/src/qt/qtwebkit/Source/WebCore/rendering/RenderLayerBacking.cpp
C++ | 1208 lines | 913 code | 194 blank | 101 comment | 250 complexity | 45e6df16fc1432918a208b7b3ce058f4 MD5 | raw file
- /*
- * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 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
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "config.h"
- #if USE(ACCELERATED_COMPOSITING)
- #include "RenderLayerBacking.h"
- #include "AnimationController.h"
- #include "CanvasRenderingContext.h"
- #include "CSSPropertyNames.h"
- #include "CachedImage.h"
- #include "Chrome.h"
- #include "FontCache.h"
- #include "FrameView.h"
- #include "GraphicsContext.h"
- #include "GraphicsLayer.h"
- #include "HTMLCanvasElement.h"
- #include "HTMLIFrameElement.h"
- #include "HTMLMediaElement.h"
- #include "HTMLNames.h"
- #include "HTMLPlugInElement.h"
- #include "InspectorInstrumentation.h"
- #include "KeyframeList.h"
- #include "PluginViewBase.h"
- #include "ProgressTracker.h"
- #include "RenderApplet.h"
- #include "RenderIFrame.h"
- #include "RenderImage.h"
- #include "RenderLayerCompositor.h"
- #include "RenderEmbeddedObject.h"
- #include "RenderVideo.h"
- #include "RenderView.h"
- #include "ScrollingCoordinator.h"
- #include "Settings.h"
- #include "StyleResolver.h"
- #include "TiledBacking.h"
- #include <wtf/text/StringBuilder.h>
- #if ENABLE(CSS_FILTERS)
- #include "FilterEffectRenderer.h"
- #if ENABLE(CSS_SHADERS)
- #include "CustomFilterOperation.h"
- #endif
- #endif
- #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
- #include "GraphicsContext3D.h"
- #endif
- using namespace std;
- namespace WebCore {
- using namespace HTMLNames;
- static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
- static IntRect clipBox(RenderBox* renderer);
- static inline bool isAcceleratedCanvas(RenderObject* renderer)
- {
- #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
- if (renderer->isCanvas()) {
- HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
- if (CanvasRenderingContext* context = canvas->renderingContext())
- return context->isAccelerated();
- }
- #else
- UNUSED_PARAM(renderer);
- #endif
- return false;
- }
- // 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_boundsConstrainedByClipping(false)
- , m_isMainFrameRenderViewLayer(false)
- , m_usingTiledCacheLayer(false)
- , m_requiresOwnBackingStore(true)
- #if ENABLE(CSS_FILTERS)
- , m_canCompositeFilters(false)
- #endif
- , m_backgroundLayerPaintsFixedRootBackground(false)
- , m_didSwitchToFullTileCoverageDuringLoading(false)
- {
- if (layer->isRootLayer()) {
- Frame* frame = toRenderView(renderer())->frameView()->frame();
- Page* page = frame ? frame->page() : 0;
- if (page && frame && page->mainFrame() == frame) {
- m_isMainFrameRenderViewLayer = true;
- #if PLATFORM(MAC)
- // FIXME: It's a little weird that we base this decision on whether there's a scrolling coordinator or not.
- if (page->scrollingCoordinator())
- m_usingTiledCacheLayer = true;
- #endif
- }
- }
-
- createPrimaryGraphicsLayer();
- if (m_usingTiledCacheLayer) {
- TiledBacking* tiledBacking = this->tiledBacking();
- if (Page* page = renderer()->frame()->page()) {
- Frame* frame = renderer()->frame();
- tiledBacking->setIsInWindow(page->isInWindow());
- if (m_isMainFrameRenderViewLayer)
- tiledBacking->setUnparentsOffscreenTiles(true);
- tiledBacking->setScrollingPerformanceLoggingEnabled(frame->settings() && frame->settings()->scrollingPerformanceLoggingEnabled());
- adjustTiledBackingCoverage();
- }
- }
- }
- RenderLayerBacking::~RenderLayerBacking()
- {
- updateClippingLayers(false, false);
- updateOverflowControlsLayers(false, false, false);
- updateForegroundLayer(false);
- updateBackgroundLayer(false);
- updateMaskLayer(false);
- updateScrollingLayers(false);
- detachFromScrollingCoordinator();
- destroyGraphicsLayers();
- }
- void RenderLayerBacking::willDestroyLayer(const GraphicsLayer* layer)
- {
- if (layer && layer->usingTiledBacking()) {
- if (RenderLayerCompositor* compositor = this->compositor())
- compositor->layerTiledBackingUsageChanged(layer, false);
- }
- }
- PassOwnPtr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name)
- {
- GraphicsLayerFactory* graphicsLayerFactory = 0;
- if (Page* page = renderer()->frame()->page())
- graphicsLayerFactory = page->chrome().client()->graphicsLayerFactory();
- OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this);
- #ifndef NDEBUG
- graphicsLayer->setName(name);
- #else
- UNUSED_PARAM(name);
- #endif
- graphicsLayer->setMaintainsPixelAlignment(compositor()->keepLayersPixelAligned());
- #if PLATFORM(MAC) && USE(CA)
- graphicsLayer->setAcceleratesDrawing(compositor()->acceleratedDrawingEnabled());
- #endif
-
- return graphicsLayer.release();
- }
- bool RenderLayerBacking::shouldUseTiledBacking(const GraphicsLayer*) const
- {
- return m_usingTiledCacheLayer && m_creatingPrimaryGraphicsLayer;
- }
- void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
- {
- compositor()->layerTiledBackingUsageChanged(layer, usingTiledBacking);
- }
- TiledBacking* RenderLayerBacking::tiledBacking() const
- {
- return m_graphicsLayer->tiledBacking();
- }
- static TiledBacking::TileCoverage computeTileCoverage(RenderLayerBacking* backing)
- {
- // FIXME: When we use TiledBacking for overflow, this should look at RenderView scrollability.
- Frame* frame = backing->owningLayer()->renderer()->frame();
- if (!frame)
- return TiledBacking::CoverageForVisibleArea;
- TiledBacking::TileCoverage tileCoverage = TiledBacking::CoverageForVisibleArea;
- FrameView* frameView = frame->view();
- bool useMinimalTilesDuringLiveResize = frameView->inLiveResize();
- bool useMinimalTilesDuringLoading = false;
- // Avoid churn.
- if (!backing->didSwitchToFullTileCoverageDuringLoading()) {
- useMinimalTilesDuringLoading = !frameView->isVisuallyNonEmpty() || (frame->page()->progress()->isMainLoadProgressing() && !frameView->wasScrolledByUser());
- if (!useMinimalTilesDuringLoading)
- backing->setDidSwitchToFullTileCoverageDuringLoading();
- }
- if (!(useMinimalTilesDuringLoading || useMinimalTilesDuringLiveResize)) {
- bool clipsToExposedRect = backing->tiledBacking()->clipsToExposedRect();
- 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->mainThreadScrollingReasons() & ~ScrollingCoordinator::ForcedOnMainThread)
- tileCoverage |= TiledBacking::CoverageForSlowScrolling;
- }
- return tileCoverage;
- }
- void RenderLayerBacking::adjustTiledBackingCoverage()
- {
- if (!m_usingTiledCacheLayer)
- return;
- TiledBacking::TileCoverage tileCoverage = computeTileCoverage(this);
- tiledBacking()->setTileCoverage(tileCoverage);
- }
- void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaintCounter)
- {
- m_graphicsLayer->setShowDebugBorder(showBorder);
- m_graphicsLayer->setShowRepaintCounter(showRepaintCounter);
-
- if (m_ancestorClippingLayer)
- m_ancestorClippingLayer->setShowDebugBorder(showBorder);
- if (m_foregroundLayer) {
- m_foregroundLayer->setShowDebugBorder(showBorder);
- m_foregroundLayer->setShowRepaintCounter(showRepaintCounter);
- }
-
- if (m_contentsContainmentLayer)
- m_contentsContainmentLayer->setShowDebugBorder(showBorder);
-
- if (m_backgroundLayer) {
- m_backgroundLayer->setShowDebugBorder(showBorder);
- m_backgroundLayer->setShowRepaintCounter(showRepaintCounter);
- }
- if (m_maskLayer) {
- m_maskLayer->setShowDebugBorder(showBorder);
- m_maskLayer->setShowRepaintCounter(showRepaintCounter);
- }
- if (m_layerForHorizontalScrollbar)
- m_layerForHorizontalScrollbar->setShowDebugBorder(showBorder);
- if (m_layerForVerticalScrollbar)
- m_layerForVerticalScrollbar->setShowDebugBorder(showBorder);
- if (m_layerForScrollCorner)
- m_layerForScrollCorner->setShowDebugBorder(showBorder);
- if (m_scrollingLayer)
- m_scrollingLayer->setShowDebugBorder(showBorder);
- if (m_scrollingContentsLayer) {
- m_scrollingContentsLayer->setShowDebugBorder(showBorder);
- m_scrollingContentsLayer->setShowRepaintCounter(showRepaintCounter);
- }
- }
- 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;
- if (m_usingTiledCacheLayer)
- m_childContainmentLayer = createGraphicsLayer("TiledBacking Flattening Layer");
- if (m_isMainFrameRenderViewLayer) {
- m_graphicsLayer->setContentsOpaque(true);
- m_graphicsLayer->setAppliesPageScale();
- }
- #if PLATFORM(MAC) && USE(CA)
- if (!compositor()->acceleratedDrawingEnabled() && renderer()->isCanvas()) {
- HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
- if (canvas->shouldAccelerate(canvas->size()))
- m_graphicsLayer->setAcceleratesDrawing(true);
- }
- #endif
-
- updateOpacity(renderer()->style());
- updateTransform(renderer()->style());
- #if ENABLE(CSS_FILTERS)
- updateFilters(renderer()->style());
- #endif
- #if ENABLE(CSS_COMPOSITING)
- updateLayerBlendMode(renderer()->style());
- #endif
- }
- void RenderLayerBacking::destroyGraphicsLayers()
- {
- if (m_graphicsLayer) {
- willDestroyLayer(m_graphicsLayer.get());
- m_graphicsLayer->removeFromParent();
- }
- m_ancestorClippingLayer = nullptr;
- m_contentsContainmentLayer = nullptr;
- m_graphicsLayer = nullptr;
- m_foregroundLayer = nullptr;
- m_backgroundLayer = nullptr;
- m_childContainmentLayer = nullptr;
- m_maskLayer = nullptr;
- m_scrollingLayer = nullptr;
- m_scrollingContentsLayer = nullptr;
- }
- void RenderLayerBacking::updateOpacity(const RenderStyle* style)
- {
- m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
- }
- 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);
- makeMatrixRenderable(t, compositor()->canRender3DTransforms());
- }
-
- if (m_contentsContainmentLayer) {
- m_contentsContainmentLayer->setTransform(t);
- m_graphicsLayer->setTransform(TransformationMatrix());
- } else
- m_graphicsLayer->setTransform(t);
- }
- #if ENABLE(CSS_FILTERS)
- void RenderLayerBacking::updateFilters(const RenderStyle* style)
- {
- m_canCompositeFilters = m_graphicsLayer->setFilters(owningLayer()->computeFilterOperations(style));
- }
- #endif
- #if ENABLE(CSS_COMPOSITING)
- void RenderLayerBacking::updateLayerBlendMode(const RenderStyle*)
- {
- }
- #endif
- static bool hasNonZeroTransformOrigin(const RenderObject* renderer)
- {
- RenderStyle* style = renderer->style();
- return (style->transformOriginX().type() == Fixed && style->transformOriginX().value())
- || (style->transformOriginY().type() == Fixed && style->transformOriginY().value());
- }
- static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer* layer)
- {
- for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
- if (curr->hasTransform() || curr->needsCompositedScrolling())
- return true;
- }
-
- return false;
- }
- bool RenderLayerBacking::shouldClipCompositedBounds() const
- {
- // Scrollbar layers use this layer for relative positioning, so don't clip.
- if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
- return false;
- if (m_usingTiledCacheLayer)
- return false;
- if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
- return false;
- return true;
- }
- void RenderLayerBacking::updateCompositedBounds()
- {
- LayoutRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
- // 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();
- RenderLayer* rootLayer = view->layer();
- LayoutRect clippingBounds;
- if (renderer()->style()->position() == FixedPosition && renderer()->container() == view)
- clippingBounds = view->frameView()->viewportConstrainedVisibleContentRect();
- else
- clippingBounds = view->unscaledDocumentRect();
- if (m_owningLayer != rootLayer)
- clippingBounds.intersect(m_owningLayer->backgroundClipRect(RenderLayer::ClipRectsContext(rootLayer, 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
- LayoutPoint delta;
- m_owningLayer->convertToLayerCoords(rootLayer, delta, RenderLayer::AdjustForColumns);
- clippingBounds.move(-delta.x(), -delta.y());
- layerBounds.intersect(clippingBounds);
- m_boundsConstrainedByClipping = true;
- } else
- m_boundsConstrainedByClipping = false;
-
- // 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())) {
- layerBounds.setWidth(1);
- layerBounds.setHeight(1);
- m_artificiallyInflatedBounds = true;
- } else
- m_artificiallyInflatedBounds = false;
- setCompositedBounds(layerBounds);
- }
- void RenderLayerBacking::updateAfterWidgetResize()
- {
- if (renderer()->isRenderPart()) {
- if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
- innerCompositor->frameViewDidChangeSize();
- innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contentsBox().location()));
- }
- }
- }
- void RenderLayerBacking::updateAfterLayout(UpdateAfterLayoutFlags flags)
- {
- RenderLayerCompositor* layerCompositor = compositor();
- if (!layerCompositor->compositingLayersNeedRebuild()) {
- // Calling updateGraphicsLayerGeometry() 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().
- //
- // The solution is to update compositing children of this layer here,
- // via updateCompositingChildrenGeometry().
- updateCompositedBounds();
- layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, flags & CompositingChildrenOnly);
-
- if (flags & IsUpdateRoot) {
- updateGraphicsLayerGeometry();
- layerCompositor->updateRootLayerPosition();
- RenderLayer* stackingContainer = m_owningLayer->enclosingStackingContainer();
- if (!layerCompositor->compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != m_owningLayer))
- layerCompositor->updateCompositingDescendantGeometry(stackingContainer, stackingContainer, flags & CompositingChildrenOnly);
- }
- }
-
- if (flags & NeedsFullRepaint && !paintsIntoWindow() && !paintsIntoCompositedAncestor())
- setContentsNeedDisplay();
- }
- bool RenderLayerBacking::updateGraphicsLayerConfiguration()
- {
- RenderLayerCompositor* compositor = this->compositor();
- RenderObject* renderer = this->renderer();
- m_owningLayer->updateDescendantDependentFlags();
- m_owningLayer->updateZOrderLists();
- bool layerConfigChanged = false;
- setBackgroundLayerPaintsFixedRootBackground(compositor->needsFixedRootBackgroundLayer(m_owningLayer));
-
- // The background layer is currently only used for fixed root backgrounds.
- if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
- layerConfigChanged = true;
- if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
- layerConfigChanged = true;
-
- bool needsDescendentsClippingLayer = compositor->clipsCompositingDescendants(m_owningLayer);
- // Our scrolling layer will clip.
- if (m_owningLayer->needsCompositedScrolling())
- needsDescendentsClippingLayer = false;
- if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), needsDescendentsClippingLayer))
- layerConfigChanged = true;
- if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
- layerConfigChanged = true;
- if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling()))
- layerConfigChanged = true;
- if (layerConfigChanged)
- updateInternalHierarchy();
- if (GraphicsLayer* flatteningLayer = tileCacheFlatteningLayer()) {
- flatteningLayer->removeFromParent();
- m_graphicsLayer->addChild(flatteningLayer);
- }
- if (updateMaskLayer(renderer->hasMask()))
- m_graphicsLayer->setMaskLayer(m_maskLayer.get());
- if (m_owningLayer->hasReflection()) {
- if (m_owningLayer->reflectionLayer()->backing()) {
- GraphicsLayer* reflectionLayer = m_owningLayer->reflectionLayer()->backing()->graphicsLayer();
- m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
- }
- } else
- m_graphicsLayer->setReplicatedByLayer(0);
- bool isSimpleContainer = isSimpleContainerCompositingLayer();
- bool didUpdateContentsRect = false;
- updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
- updateRootLayerConfiguration();
-
- if (isDirectlyCompositedImage())
- updateImageContents();
- if (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) {
- PluginViewBase* pluginViewBase = toPluginViewBase(toRenderWidget(renderer)->widget());
- if (!pluginViewBase->shouldNotAddLayer())
- m_graphicsLayer->setContentsToMedia(pluginViewBase->platformLayer());
- }
- #if ENABLE(VIDEO)
- else if (renderer->isVideo()) {
- HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer->node());
- m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
- }
- #endif
- #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
- else if (isAcceleratedCanvas(renderer)) {
- HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
- if (CanvasRenderingContext* context = canvas->renderingContext())
- m_graphicsLayer->setContentsToCanvas(context->platformLayer());
- layerConfigChanged = true;
- }
- #endif
- if (renderer->isRenderPart())
- layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer));
- return layerConfigChanged;
- }
- static IntRect clipBox(RenderBox* renderer)
- {
- LayoutRect result = PaintInfo::infiniteRect();
- if (renderer->hasOverflowClip())
- result = renderer->overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions.
- if (renderer->hasClip())
- result.intersect(renderer->clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
- return pixelSnappedIntRect(result);
- }
- void RenderLayerBacking::updateGraphicsLayerGeometry()
- {
- // If we haven't built z-order lists yet, wait until later.
- if (m_owningLayer->isStackingContainer() && m_owningLayer->m_zOrderListsDirty)
- return;
- // 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());
- // 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 ENABLE(CSS_COMPOSITING)
- updateLayerBlendMode(renderer()->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());
- 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);
- 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();
- 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 != PaintInfo::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));
- // Use the same size as m_graphicsLayer so transforms behave correctly.
- m_contentsContainmentLayer->setSize(contentsSize);
- graphicsLayerParentLocation = relativeCompositingBounds.location();
- }
- m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
- m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
- FloatSize oldSize = m_graphicsLayer->size();
- if (oldSize != contentsSize) {
- m_graphicsLayer->setSize(contentsSize);
- // Usually invalidation will happen via layout etc, but if we've affected the layer
- // size by constraining relative to a clipping ancestor or the viewport, we
- // have to invalidate to avoid showing stretched content.
- if (m_boundsConstrainedByClipping)
- m_graphicsLayer->setNeedsDisplay();
- }
- if (!m_isMainFrameRenderViewLayer) {
- // For non-root layers, background is always painted by the primary graphics layer.
- ASSERT(!m_backgroundLayer);
- m_graphicsLayer->setContentsOpaque(m_owningLayer->backgroundIsKnownToBeOpaqueInRect(localCompositingBounds));
- }
- // If we have a layer that clips children, position it.
- IntRect 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()));
- }
-
- if (m_maskLayer) {
- if (m_maskLayer->size() != m_graphicsLayer->size()) {
- m_maskLayer->setSize(m_graphicsLayer->size());
- m_maskLayer->setNeedsDisplay();
- }
- m_maskLayer->setPosition(FloatPoint());
- m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
- }
-
- 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);
- // 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());
- if (m_contentsContainmentLayer)
- m_contentsContainmentLayer->setAnchorPoint(anchor);
- else
- m_graphicsLayer->setAnchorPoint(anchor);
- RenderStyle* style = renderer()->style();
- GraphicsLayer* clipLayer = clippingLayer();
- if (style->hasPerspective()) {
- TransformationMatrix t = owningLayer()->perspectiveTransform();
-
- if (clipLayer) {
- clipLayer->setChildrenTransform(t);
- m_graphicsLayer->setChildrenTransform(TransformationMatrix());
- }
- else
- m_graphicsLayer->setChildrenTransform(t);
- } else {
- if (clipLayer)
- clipLayer->setChildrenTransform(TransformationMatrix());
- else
- m_graphicsLayer->setChildrenTransform(TransformationMatrix());
- }
- } else {
- m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
- if (m_contentsContainmentLayer)
- m_contentsContainmentLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
- }
- if (m_foregroundLayer) {
- FloatPoint foregroundPosition;
- FloatSize foregroundSize = contentsSize;
- IntSize 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());
- }
- m_foregroundLayer->setPosition(foregroundPosition);
- if (foregroundSize != m_foregroundLayer->size()) {
- m_foregroundLayer->setSize(foregroundSize);
- m_foregroundLayer->setNeedsDisplay();
- }
- m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
- }
- if (m_backgroundLayer) {
- FloatPoint backgroundPosition;
- FloatSize backgroundSize = contentsSize;
- if (backgroundLayerPaintsFixedRootBackground()) {
- FrameView* frameView = toRenderView(renderer())->frameView();
- backgroundPosition = IntPoint(frameView->scrollOffsetForFixedPosition());
- backgroundSize = frameView->visibleContentRect().size();
- }
- m_backgroundLayer->setPosition(backgroundPosition);
- if (backgroundSize != m_backgroundLayer->size()) {
- m_backgroundLayer->setSize(backgroundSize);
- m_backgroundLayer->setNeedsDisplay();
- }
- m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
- }
- if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) {
- RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing();
- reflectionBacking->updateGraphicsLayerGeometry();
-
- // 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 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();
- m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - localCompositingBounds.location()));
- m_scrollingLayer->setSize(paddingBox.size());
- m_scrollingContentsLayer->setPosition(FloatPoint(-scrollOffset.width(), -scrollOffset.height()));
- IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
- m_scrollingLayer->setOffsetFromRenderer(-toIntSize(paddingBox.location()));
- bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
- IntSize scrollSize(m_owningLayer->scrollWidth(), m_owningLayer->scrollHeight());
- if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
- m_scrollingContentsLayer->setNeedsDisplay();
- IntSize scrollingContentsOffset = toIntSize(paddingBox.location() - scrollOffset);
- if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size())
- compositor()->scrollingLayerDidChange(m_owningLayer);
- m_scrollingContentsLayer->setSize(scrollSize);
- // FIXME: The paint offset and the scroll offset should really be separate concepts.
- m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
- if (m_foregroundLayer) {
- if (m_foregroundLayer->size() != m_scrollingContentsLayer->size())
- m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
- m_foregroundLayer->setNeedsDisplay();
- m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer());
- }
- }
- // 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));
- bool didUpdateContentsRect = false;
- updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
- if (!didUpdateContentsRect && m_graphicsLayer->hasContentsLayer())
- resetContentsRect();
- updateDrawsContent(isSimpleContainer);
- updateAfterWidgetResize();
- registerScrollingLayers();
- }
- void RenderLayerBacking::updateDirectlyCompositedContents(bool isSimpleContainer, bool& didUpdateContentsRect)
- {
- if (!m_owningLayer->hasVisibleContent())
- return;
- // The order of operations here matters, since the last valid type of contents needs
- // to also update the contentsRect.
- updateDirectlyCompositedBackgroundColor(isSimpleContainer, didUpdateContentsRect);
- updateDirectlyCompositedBackgroundImage(isSimpleContainer, didUpdateContentsRect);
- }
- void RenderLayerBacking::registerScrollingLayers()
- {
- // 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;
- scrollingCoordinator->updateLayerPositionConstraint(m_owningLayer);
- // 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);
- }
- void RenderLayerBacking::updateInternalHierarchy()
- {
- // m_foregroundLayer has to be inserted in the correct order with child layers,
- // so it's not inserted here.
- if (m_ancestorClippingLayer)
- m_ancestorClippingLayer->removeAllChildren();
-
- if (m_contentsContainmentLayer) {
- m_contentsContainmentLayer->removeAllChildren();
- if (m_ancestorClippingLayer)
- m_ancestorClippingLayer->addChild(m_contentsContainmentLayer.get());
- }
-
- if (m_backgroundLayer)
- m_contentsContainmentLayer->addChild(m_backgroundLayer.get());
- m_graphicsLayer->removeFromParent();
- if (m_contentsContainmentLayer)
- m_contentsContainmentLayer->addChild(m_graphicsLayer.get());
- else if (m_ancestorClippingLayer)
- m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
- if (m_childContainmentLayer) {
- m_childContainmentLayer->removeFromParent();
- m_graphicsLayer->addChild(m_childContainmentLayer.get());
- }
- if (m_scrollingLayer) {
- GraphicsLayer* superlayer = m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
- m_scrollingLayer->removeFromParent();
- superlayer->addChild(m_scrollingLayer.get());
- }
- // The clip for child layers does not include space for overflow controls, so they exist as
- // siblings of the clipping layer if we have one. Normal children of this layer are set as
- // children of the clipping layer.
- if (m_layerForHorizontalScrollbar) {
- m_layerForHorizontalScrollbar->removeFromParent();
- m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
- }
- if (m_layerForVerticalScrollbar) {
- m_layerForVerticalScrollbar->removeFromParent();
- m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
- }
- if (m_layerForScrollCorner) {
- m_layerForScrollCorner->removeFromParent();
- m_graphicsLayer->addChild(m_layerForScrollCorner.get());
- }
- }
- void RenderLayerBacking::resetContentsRect()
- {
- IntRect rect = pixelSnappedIntRect(contentsBox());
- m_graphicsLayer->setContentsRect(rect);
- m_graphicsLayer->setContentsTileSize(IntSize());
- m_graphicsLayer->setContentsTilePhase(IntPoint());
- }
- void RenderLayerBacking::updateDrawsContent()
- {
- updateDrawsContent(isSimpleContainerCompositingLayer());
- }
- void RenderLayerBacking::updateDrawsContent(bool isSimpleContainer)
- {
- if (m_scrollingLayer) {
- // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
- // 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();
- m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
- bool hasScrollingPaintedContent = m_owningLayer->hasVisibleContent() && (renderer()->hasBackground() || paintsChildren());
- m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
- return;
- }
- bool hasPaintedContent = containsPaintedContent(isSimpleContainer);
- // FIXME: we could refine this to only allocate backing for one of these layers if possible.
- m_graphicsLayer->setDrawsContent(hasPaintedContent);
- if (m_foregroundLayer)
- m_foregroundLayer->setDrawsContent(hasPaintedContent);
- if (m_backgroundLayer)
- m_backgroundLayer->setDrawsContent(hasPaintedContent);
- }
- // Return true if the layers changed.
- bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
- {
- bool layersChanged = false;
- if (needsAncestorClip) {
- if (!m_ancestorClippingLayer) {
- m_ancestorClippingLayer = createGraphicsLayer("Ancestor clipping Layer");
- m_ancestorClippingLayer->setMasksToBounds(true);
- layersChanged = true;
- }
- } else if (m_ancestorClippingLayer) {
- willDestroyLayer(m_ancestorClippingLayer.get());
- m_ancestorClippingLayer->removeFromParent();
- m_ancestorClippingLayer = nullptr;
- layersChanged = true;
- }
-
- if (needsDescendantClip) {
- if (!m_childContainmentLayer && !m_usingTiledCacheLayer) {
- m_childContainmentLayer = createGraphicsLayer("Child clipping Layer");
- m_childContainmentLayer->setMasksToBounds(true);
- layersChanged = true;
- }
- } else if (hasClippingLayer()) {
- willDestroyLayer(m_childContainmentLayer.get());
- m_childContainmentLayer->removeFromParent();
- m_childContainmentLayer = nullptr;
- layersChanged = true;
- }
-
- return layersChanged;
- }
- void RenderLayerBacking::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
- {
- m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
- }
- bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
- {
- if (!m_owningLayer->hasOverlayScrollbars() && !m_owningLayer->needsCompositedScrolling())
- return false;
- return m_owningLayer->horizontalScrollbar();
- }
- bool RenderLayerBacking::requiresVerticalScrollbarLayer() const
- {
- if (!m_owningLayer->hasOverlayScrollbars() && !m_owningLayer->needsCompositedScrolling())
- return false;
- return m_owningLayer->verticalScrollbar();
- }
- bool RenderLayerBacking::requiresScrollCornerLayer() const
- {
- if (!m_owningLayer->hasOverlayScrollbars() && !m_owningLayer->needsCompositedScrolling())
- return false;
- return !m_owningLayer->scrollCornerAndResizerRect().isEmpty();
- }
- bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
- {
- bool horizontalScrollbarLayerChanged = false;
- if (needsHorizontalScrollbarLayer) {
- if (!m_layerForHorizontalScrollbar) {
- m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar");
- horizontalScrollbarLayerChanged = true;
- }
- } else if (m_layerForHorizontalScrollbar) {
- willDestroyLayer(m_layerForHorizontalScrollbar.get());
- m_layerForHorizontalScrollbar = nullptr;
- horizontalScrollbarLayerChanged = true;
- }
- bool verticalScrollbarLayerChanged = false;
- if (needsVerticalScrollbarLayer) {
- if (!m_layerForVerticalScrollbar) {
- m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar");
- verticalScrollbarLayerChanged = true;
- }
- } else if (m_layerForVerticalScrollbar) {
- willDestroyLayer(m_layerForVerticalScrollbar.get());
- m_layerForVerticalScrollbar = nullptr;
- verticalScrollbarLayerChanged = true;
- }
- bool scrollCornerLayerChanged = false;
- if (needsScrollCornerLayer) {
- if (!m_layerForScrollCorner) {
- m_layerForScrollCorner = createGraphicsLayer("scroll corner");
- scrollCornerLayerChanged = true;
- }
- } else if (m_layerForScrollCorner) {
- willDestroyLayer(m_layerForScrollCorner.get());
- m_layerForScrollCorner = nullptr;
- scrollCornerLayerChanged = true;
- }
- if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
- if (horizontalScrollbarLayerChanged)
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, HorizontalScrollbar);
- if (verticalScrollbarLayerChanged)
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, VerticalScrollbar);
- }
- return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
- }
- void RenderLayerBacking::positionOverflowControlsLayers(const IntSize& offsetFromRoot)
- {
- IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
- if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
- Scrollbar* hBar = m_owningLayer->horizontalScrollbar();
- if (hBar) {
- layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
- layer->setSize(hBar->frameRect().size());
- if (layer->hasContentsLayer())
- layer->setContentsRect(IntRect(IntPoint(), hBar->frameRect().size()));
- }
- layer->setDrawsContent(hBar && !layer->hasContentsLayer());
- }
-
- if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
- Scrollbar* vBar = m_owningLayer->verticalScrollbar();
- if (vBar) {
- layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
- layer->setSize(vBar->frameRect().size());
- if (layer->hasContentsLayer())
- layer->setContentsRect(IntRect(IntPoint(), vBar->frameRect().size()));
- }
- layer->setDrawsContent(vBar && !layer->hasContentsLayer());
- }
- if (GraphicsLayer* layer = layerForScrollCorner()) {
- const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect();
- layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
- layer->setSize(scrollCornerAndResizer.size());
- layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
- }
- }
- bool RenderLayerBacking::hasUnpositionedOverflowControlsLayers() const
- {
- if (GraphicsLayer* layer = layerForHorizontalScrollbar())
- if (!layer->drawsContent())
- return true;
- if (GraphicsLayer* layer = layerForVerticalScrollbar())
- if (!layer->drawsContent())
- return true;
- if (GraphicsLayer* layer = layerForScrollCorner())
- if (!layer->drawsContent())
- return true;
- return false;
- }
- bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
- {
- bool layerChanged = false;
- if (needsForegroundLayer) {
- if (!m_foregroundLayer) {
- String layerName;
- #ifndef NDEBUG
- layerName = m_owningLayer->name() + " (foreground)";
- #endif
- m_foregroundLayer = createGraphicsLayer(layerName);
- m_foregroundLayer->setDrawsContent(true);
- m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
- layerChanged = true;
- }
- } else if (m_foregroundLayer) {
- willDestroyLayer(m_foregroundLayer.get());
- m_foregroundLayer->removeFromParent();
- m_foregroundLayer = nullptr;
- layerChanged = true;
- }
- if (layerChanged) {
- m_graphicsLayer->setNeedsDisplay();
- m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
- }
- return layerChanged;
- }
- bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
- {
- bool layerChanged = false;
- if (needsBackgroundLayer) {
- if (!m_backgroundLayer) {
- String layerName;
- #ifndef NDEBUG
- layerName = m_owningLayer->name() + " (background)";
- #endif
- m_backgroundLayer = createGraphicsLayer(layerName);
- m_backgroundLayer->setDrawsContent(true);
- m_backgroundLayer->setAnchorPoint(FloatPoint3D());
- m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
- layerChanged = true;
- }
-
- if (!m_contentsContainmentLayer) {
- String layerName;
- #ifndef NDEBUG
- layerName = m_owningLayer->name() + " (contents containment)";
- #endif
- m_contentsContainmentLayer = createGraphicsLayer(layerName);
- m_contents