blob: b42bf516460174bccad70cc8e9213d9bb9574409 [file] [log] [blame]
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001/*
darin@apple.com4bca5c92011-07-01 23:13:28 +00002 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
mjs@apple.com92047332014-03-15 04:08:27 +000016 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +000017 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
jamesr@google.combab91912010-09-03 18:38:37 +000028#include "RenderLayerBacking.h"
29
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +000030#include "AnimationController.h"
jamesr@google.comd8c61572010-08-06 21:49:20 +000031#include "CanvasRenderingContext.h"
simon.fraser@apple.com99cac4b2009-02-04 23:56:55 +000032#include "CSSPropertyNames.h"
abarth@webkit.org401a3792013-03-03 10:12:59 +000033#include "CachedImage.h"
darin@apple.com4bca5c92011-07-01 23:13:28 +000034#include "Chrome.h"
commit-queue@webkit.org9e58b3d2014-09-04 18:43:39 +000035#include "FilterEffectRenderer.h"
simon.fraser@apple.coma43acab32011-11-02 21:02:07 +000036#include "FontCache.h"
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +000037#include "FrameView.h"
38#include "GraphicsContext.h"
39#include "GraphicsLayer.h"
cmarrin@apple.com4e7728f2009-08-27 23:55:44 +000040#include "HTMLCanvasElement.h"
cmarrin@apple.com10c77cf2010-05-05 01:50:03 +000041#include "HTMLIFrameElement.h"
simon.fraser@apple.com62178892010-02-16 21:46:06 +000042#include "HTMLMediaElement.h"
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +000043#include "HTMLNames.h"
dino@apple.com2e06ec82013-04-03 20:13:20 +000044#include "HTMLPlugInElement.h"
podivilov@chromium.orgb6cd0252010-10-07 09:43:02 +000045#include "InspectorInstrumentation.h"
dbates@webkit.org57aa8de2009-11-30 01:32:38 +000046#include "KeyframeList.h"
darin@apple.com0e83ab12013-09-28 17:19:04 +000047#include "MainFrame.h"
andersca@apple.comf0fc23f2010-07-19 00:09:01 +000048#include "PluginViewBase.h"
antti@apple.com40d67242013-04-10 11:34:53 +000049#include "ProgressTracker.h"
commit-queue@webkit.org83e19482013-10-21 19:38:30 +000050#include "RenderFlowThread.h"
cdumez@apple.com3abcc792014-10-20 03:42:03 +000051#include "RenderHTMLCanvas.h"
simon.fraser@apple.combe8126e2010-05-11 05:08:18 +000052#include "RenderIFrame.h"
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +000053#include "RenderImage.h"
54#include "RenderLayerCompositor.h"
simon.fraser@apple.comd6aff5e2010-01-12 00:15:06 +000055#include "RenderEmbeddedObject.h"
cdumez@apple.com8bb794b2014-10-21 16:46:13 +000056#include "RenderMedia.h"
commit-queue@webkit.org83e19482013-10-21 19:38:30 +000057#include "RenderNamedFlowFragment.h"
58#include "RenderRegion.h"
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +000059#include "RenderVideo.h"
60#include "RenderView.h"
commit-queue@webkit.orgb07824e2012-06-14 17:45:05 +000061#include "ScrollingCoordinator.h"
timothy_horton@apple.comabf4b252012-08-09 07:26:35 +000062#include "Settings.h"
alexis.menard@openbossa.orge6db2f62012-04-25 15:49:08 +000063#include "StyleResolver.h"
andersca@apple.com1533e932012-03-21 19:24:24 +000064#include "TiledBacking.h"
abarth@webkit.orga40070b2012-08-30 08:20:03 +000065#include <wtf/text/StringBuilder.h>
timothy_horton@apple.com7ce2a732012-05-11 21:24:09 +000066
ddkilzer@apple.com7313f642011-02-15 23:59:07 +000067#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
68#include "GraphicsContext3D.h"
69#endif
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +000070
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +000071namespace WebCore {
72
darin@apple.com5554b3a2009-08-17 17:30:27 +000073using namespace HTMLNames;
74
simon.fraser@apple.comefaa4122013-12-20 03:48:10 +000075CanvasCompositingStrategy canvasCompositingStrategy(const RenderObject& renderer)
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +000076{
simon.fraser@apple.comefaa4122013-12-20 03:48:10 +000077 ASSERT(renderer.isCanvas());
78
cdumez@apple.com72754ba2014-09-23 22:03:15 +000079 const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer.node());
simon.fraser@apple.comefaa4122013-12-20 03:48:10 +000080 CanvasRenderingContext* context = canvas->renderingContext();
81 if (!context || !context->isAccelerated())
82 return UnacceleratedCanvas;
83
84 if (context->is3d())
85 return CanvasAsLayerContents;
86
87#if ENABLE(ACCELERATED_2D_CANVAS)
88 return CanvasAsLayerContents;
andersca@apple.comd576cbe2010-01-18 22:04:20 +000089#else
simon.fraser@apple.comefaa4122013-12-20 03:48:10 +000090 return CanvasPaintedToLayer; // On Mac and iOS we paint accelerated canvases into their layers.
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +000091#endif
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +000092}
simon.fraser@apple.com699dc0b2009-04-07 17:45:00 +000093
simon.fraser@apple.come6ad1f62013-01-15 23:46:18 +000094// Get the scrolling coordinator in a way that works inside RenderLayerBacking's destructor.
akling@apple.comc68fe752013-10-13 18:39:27 +000095static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer& layer)
simon.fraser@apple.come6ad1f62013-01-15 23:46:18 +000096{
akling@apple.comc68fe752013-10-13 18:39:27 +000097 Page* page = layer.renderer().frame().page();
simon.fraser@apple.come6ad1f62013-01-15 23:46:18 +000098 if (!page)
99 return 0;
100
101 return page->scrollingCoordinator();
102}
103
dino@apple.comeebfa9062012-07-09 20:36:21 +0000104bool RenderLayerBacking::m_creatingPrimaryGraphicsLayer = false;
105
akling@apple.comc68fe752013-10-13 18:39:27 +0000106RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000107 : m_owningLayer(layer)
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +0000108 , m_viewportConstrainedNodeID(0)
109 , m_scrollingNodeID(0)
simon.fraser@apple.comc6e466c2009-09-19 03:44:10 +0000110 , m_artificiallyInflatedBounds(false)
simon.fraser@apple.com5429b7f2011-12-13 01:05:32 +0000111 , m_isMainFrameRenderViewLayer(false)
112 , m_usingTiledCacheLayer(false)
simon.fraser@apple.comb7cec682012-04-16 18:32:13 +0000113 , m_requiresOwnBackingStore(true)
cmarrin@apple.com3106ca82011-12-17 17:46:57 +0000114 , m_canCompositeFilters(false)
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +0000115 , m_backgroundLayerPaintsFixedRootBackground(false)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000116{
timothy_horton@apple.com017ef582013-09-26 17:34:33 +0000117 Page* page = renderer().frame().page();
118
akling@apple.comc68fe752013-10-13 18:39:27 +0000119 if (layer.isRootLayer() && page) {
zalan@apple.com655863c2014-05-21 16:06:55 +0000120 m_isMainFrameRenderViewLayer = renderer().frame().isMainFrame();
timothy_horton@apple.com017ef582013-09-26 17:34:33 +0000121 m_usingTiledCacheLayer = page->chrome().client().shouldUseTiledBackingForFrameView(renderer().frame().view());
simon.fraser@apple.com5429b7f2011-12-13 01:05:32 +0000122 }
123
simon.fraser@apple.comec223212011-07-13 21:57:57 +0000124 createPrimaryGraphicsLayer();
andersca@apple.com1533e932012-03-21 19:24:24 +0000125
timothy_horton@apple.com017ef582013-09-26 17:34:33 +0000126 if (m_usingTiledCacheLayer && page) {
simon.fraser@apple.com6141c312012-10-25 18:08:21 +0000127 TiledBacking* tiledBacking = this->tiledBacking();
timothy_horton@apple.com11ed3442013-01-07 23:17:36 +0000128
timothy_horton@apple.com017ef582013-09-26 17:34:33 +0000129 tiledBacking->setIsInWindow(page->isInWindow());
timothy_horton@apple.com11ed3442013-01-07 23:17:36 +0000130
antti@apple.com60abb112014-04-08 20:50:47 +0000131 if (m_isMainFrameRenderViewLayer)
timothy_horton@apple.com017ef582013-09-26 17:34:33 +0000132 tiledBacking->setUnparentsOffscreenTiles(true);
133
134 tiledBacking->setScrollingPerformanceLoggingEnabled(page->settings().scrollingPerformanceLoggingEnabled());
135 adjustTiledBackingCoverage();
andersca@apple.com1533e932012-03-21 19:24:24 +0000136 }
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000137}
138
139RenderLayerBacking::~RenderLayerBacking()
140{
zalan@apple.comc3d72182013-09-12 14:03:21 +0000141 updateAncestorClippingLayer(false);
142 updateDescendantClippingLayer(false);
jamesr@google.come53ce642011-04-14 06:51:50 +0000143 updateOverflowControlsLayers(false, false, false);
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +0000144 updateForegroundLayer(false);
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +0000145 updateBackgroundLayer(false);
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +0000146 updateMaskLayer(false);
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000147 updateScrollingLayers(false);
bdakin@apple.com0643c9f2012-10-09 18:47:49 +0000148 detachFromScrollingCoordinator();
simon.fraser@apple.comec223212011-07-13 21:57:57 +0000149 destroyGraphicsLayers();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000150}
151
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +0000152void RenderLayerBacking::willDestroyLayer(const GraphicsLayer* layer)
153{
akling@apple.comc3466042013-08-24 18:27:32 +0000154 if (layer && layer->usingTiledBacking())
155 compositor().layerTiledBackingUsageChanged(layer, false);
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +0000156}
157
andersca@apple.comcc3b2dc2013-09-27 18:38:51 +0000158std::unique_ptr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000159{
andersca@apple.comd857c852012-10-03 17:47:36 +0000160 GraphicsLayerFactory* graphicsLayerFactory = 0;
akling@apple.com32c7a6e2013-08-26 02:21:32 +0000161 if (Page* page = renderer().frame().page())
akling@apple.comfedaa632013-08-19 10:56:27 +0000162 graphicsLayerFactory = page->chrome().client().graphicsLayerFactory();
andersca@apple.comd857c852012-10-03 17:47:36 +0000163
commit-queue@webkit.org65a639f2014-05-07 11:44:00 +0000164 std::unique_ptr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, *this);
andersca@apple.comd857c852012-10-03 17:47:36 +0000165
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000166#ifndef NDEBUG
simon.fraser@apple.comec223212011-07-13 21:57:57 +0000167 graphicsLayer->setName(name);
simon.fraser@apple.comb8fae942011-07-13 22:56:06 +0000168#else
169 UNUSED_PARAM(name);
darin@apple.com4bca5c92011-07-01 23:13:28 +0000170#endif
mitz@apple.com28c9d4a2014-02-08 22:26:50 +0000171#if PLATFORM(COCOA) && USE(CA)
akling@apple.comc3466042013-08-24 18:27:32 +0000172 graphicsLayer->setAcceleratesDrawing(compositor().acceleratedDrawingEnabled());
simon.fraser@apple.com5cce05c2012-03-23 21:40:21 +0000173#endif
174
andersca@apple.comcc3b2dc2013-09-27 18:38:51 +0000175 return graphicsLayer;
simon.fraser@apple.comec223212011-07-13 21:57:57 +0000176}
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000177
simon.fraser@apple.come5c278d2013-03-07 23:54:13 +0000178bool RenderLayerBacking::shouldUseTiledBacking(const GraphicsLayer*) const
simon.fraser@apple.com5429b7f2011-12-13 01:05:32 +0000179{
dino@apple.comeebfa9062012-07-09 20:36:21 +0000180 return m_usingTiledCacheLayer && m_creatingPrimaryGraphicsLayer;
simon.fraser@apple.com5429b7f2011-12-13 01:05:32 +0000181}
182
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +0000183void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
184{
akling@apple.comc3466042013-08-24 18:27:32 +0000185 compositor().layerTiledBackingUsageChanged(layer, usingTiledBacking);
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +0000186}
187
simon.fraser@apple.com6141c312012-10-25 18:08:21 +0000188TiledBacking* RenderLayerBacking::tiledBacking() const
189{
190 return m_graphicsLayer->tiledBacking();
191}
192
antti@apple.com4d3b2172013-04-15 13:00:50 +0000193static TiledBacking::TileCoverage computeTileCoverage(RenderLayerBacking* backing)
simon.fraser@apple.com6141c312012-10-25 18:08:21 +0000194{
antti@apple.com40d67242013-04-10 11:34:53 +0000195 // FIXME: When we use TiledBacking for overflow, this should look at RenderView scrollability.
akling@apple.comc68fe752013-10-13 18:39:27 +0000196 FrameView& frameView = backing->owningLayer().renderer().view().frameView();
simon.fraser@apple.com6141c312012-10-25 18:08:21 +0000197
198 TiledBacking::TileCoverage tileCoverage = TiledBacking::CoverageForVisibleArea;
akling@apple.come4b42ff2013-08-24 22:50:46 +0000199 bool useMinimalTilesDuringLiveResize = frameView.inLiveResize();
antti@apple.com091c8a92014-01-23 22:03:27 +0000200 if (frameView.speculativeTilingEnabled() && !useMinimalTilesDuringLiveResize) {
timothy_horton@apple.com50af46e2014-01-09 01:38:13 +0000201 bool clipsToExposedRect = !frameView.exposedRect().isInfinite();
akling@apple.come4b42ff2013-08-24 22:50:46 +0000202 if (frameView.horizontalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
simon.fraser@apple.com6141c312012-10-25 18:08:21 +0000203 tileCoverage |= TiledBacking::CoverageForHorizontalScrolling;
204
akling@apple.come4b42ff2013-08-24 22:50:46 +0000205 if (frameView.verticalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
simon.fraser@apple.com6141c312012-10-25 18:08:21 +0000206 tileCoverage |= TiledBacking::CoverageForVerticalScrolling;
simon.fraser@apple.com6141c312012-10-25 18:08:21 +0000207 }
antti@apple.com40d67242013-04-10 11:34:53 +0000208 return tileCoverage;
209}
simon.fraser@apple.com6141c312012-10-25 18:08:21 +0000210
antti@apple.com40d67242013-04-10 11:34:53 +0000211void RenderLayerBacking::adjustTiledBackingCoverage()
212{
213 if (!m_usingTiledCacheLayer)
214 return;
215
216 TiledBacking::TileCoverage tileCoverage = computeTileCoverage(this);
simon.fraser@apple.com6141c312012-10-25 18:08:21 +0000217 tiledBacking()->setTileCoverage(tileCoverage);
218}
219
weinig@apple.com55b0ff62014-05-06 16:44:41 +0000220void RenderLayerBacking::setTiledBackingHasMargins(bool hasExtendedBackgroundOnLeftAndRight, bool hasExtendedBackgroundOnTopAndBottom)
bdakin@apple.comd99f20e2014-01-18 00:05:59 +0000221{
222 if (!m_usingTiledCacheLayer)
223 return;
224
weinig@apple.com55b0ff62014-05-06 16:44:41 +0000225 int marginLeftAndRightSize = hasExtendedBackgroundOnLeftAndRight ? defaultTileWidth : 0;
226 int marginTopAndBottomSize = hasExtendedBackgroundOnTopAndBottom ? defaultTileHeight : 0;
bdakin@apple.com8a00da92014-01-31 21:06:38 +0000227 tiledBacking()->setTileMargins(marginTopAndBottomSize, marginTopAndBottomSize, marginLeftAndRightSize, marginLeftAndRightSize);
bdakin@apple.comd99f20e2014-01-18 00:05:59 +0000228}
229
simon.fraser@apple.come2605d52012-11-05 21:07:33 +0000230void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaintCounter)
231{
232 m_graphicsLayer->setShowDebugBorder(showBorder);
233 m_graphicsLayer->setShowRepaintCounter(showRepaintCounter);
234
235 if (m_ancestorClippingLayer)
236 m_ancestorClippingLayer->setShowDebugBorder(showBorder);
237
238 if (m_foregroundLayer) {
239 m_foregroundLayer->setShowDebugBorder(showBorder);
240 m_foregroundLayer->setShowRepaintCounter(showRepaintCounter);
241 }
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000242
243 if (m_contentsContainmentLayer)
244 m_contentsContainmentLayer->setShowDebugBorder(showBorder);
245
246 if (m_backgroundLayer) {
247 m_backgroundLayer->setShowDebugBorder(showBorder);
248 m_backgroundLayer->setShowRepaintCounter(showRepaintCounter);
249 }
simon.fraser@apple.come2605d52012-11-05 21:07:33 +0000250
251 if (m_maskLayer) {
252 m_maskLayer->setShowDebugBorder(showBorder);
253 m_maskLayer->setShowRepaintCounter(showRepaintCounter);
254 }
255
simon.fraser@apple.com8d8c4c12012-11-15 23:46:07 +0000256 if (m_layerForHorizontalScrollbar)
257 m_layerForHorizontalScrollbar->setShowDebugBorder(showBorder);
258
259 if (m_layerForVerticalScrollbar)
260 m_layerForVerticalScrollbar->setShowDebugBorder(showBorder);
261
262 if (m_layerForScrollCorner)
263 m_layerForScrollCorner->setShowDebugBorder(showBorder);
264
simon.fraser@apple.come2605d52012-11-05 21:07:33 +0000265 if (m_scrollingLayer)
266 m_scrollingLayer->setShowDebugBorder(showBorder);
267
simon.fraser@apple.com8d8c4c12012-11-15 23:46:07 +0000268 if (m_scrollingContentsLayer) {
simon.fraser@apple.come2605d52012-11-05 21:07:33 +0000269 m_scrollingContentsLayer->setShowDebugBorder(showBorder);
simon.fraser@apple.com8d8c4c12012-11-15 23:46:07 +0000270 m_scrollingContentsLayer->setShowRepaintCounter(showRepaintCounter);
271 }
simon.fraser@apple.come2605d52012-11-05 21:07:33 +0000272}
273
simon.fraser@apple.comec223212011-07-13 21:57:57 +0000274void RenderLayerBacking::createPrimaryGraphicsLayer()
275{
276 String layerName;
277#ifndef NDEBUG
akling@apple.comc68fe752013-10-13 18:39:27 +0000278 layerName = m_owningLayer.name();
simon.fraser@apple.comec223212011-07-13 21:57:57 +0000279#endif
dino@apple.comeebfa9062012-07-09 20:36:21 +0000280
281 // The call to createGraphicsLayer ends calling back into here as
simon.fraser@apple.come5c278d2013-03-07 23:54:13 +0000282 // a GraphicsLayerClient to ask if it shouldUseTiledBacking(). We only want
dino@apple.comeebfa9062012-07-09 20:36:21 +0000283 // the tile cache on our main layer. This is pretty ugly, but saves us from
284 // exposing the API to all clients.
285
286 m_creatingPrimaryGraphicsLayer = true;
simon.fraser@apple.comec223212011-07-13 21:57:57 +0000287 m_graphicsLayer = createGraphicsLayer(layerName);
dino@apple.comeebfa9062012-07-09 20:36:21 +0000288 m_creatingPrimaryGraphicsLayer = false;
289
simon.fraser@apple.comd3ca15b2014-03-27 03:53:31 +0000290 if (m_usingTiledCacheLayer) {
simon.fraser@apple.come5c278d2013-03-07 23:54:13 +0000291 m_childContainmentLayer = createGraphicsLayer("TiledBacking Flattening Layer");
simon.fraser@apple.comd3ca15b2014-03-27 03:53:31 +0000292 m_graphicsLayer->addChild(m_childContainmentLayer.get());
293 }
simon.fraser@apple.com5429b7f2011-12-13 01:05:32 +0000294
gyuyoung.kim@samsung.com8411ddd2014-08-27 07:56:09 +0000295#if !PLATFORM(IOS)
andersca@apple.com00534a32011-12-16 23:26:31 +0000296 if (m_isMainFrameRenderViewLayer) {
dbates@webkit.org395fca72013-12-06 19:59:38 +0000297 // Page scale is applied above the RenderView on iOS.
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +0000298 m_graphicsLayer->setContentsOpaque(true);
simon.fraser@apple.com5429b7f2011-12-13 01:05:32 +0000299 m_graphicsLayer->setAppliesPageScale();
andersca@apple.com00534a32011-12-16 23:26:31 +0000300 }
ryuan.choi@samsung.com973da222014-04-01 06:09:55 +0000301#endif
simon.fraser@apple.com5cce05c2012-03-23 21:40:21 +0000302
mitz@apple.com28c9d4a2014-02-08 22:26:50 +0000303#if PLATFORM(COCOA) && USE(CA)
akling@apple.com32c7a6e2013-08-26 02:21:32 +0000304 if (!compositor().acceleratedDrawingEnabled() && renderer().isCanvas()) {
cdumez@apple.com72754ba2014-09-23 22:03:15 +0000305 const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer().element());
simon.fraser@apple.com5cce05c2012-03-23 21:40:21 +0000306 if (canvas->shouldAccelerate(canvas->size()))
307 m_graphicsLayer->setAcceleratesDrawing(true);
308 }
309#endif
simon.fraser@apple.comec223212011-07-13 21:57:57 +0000310
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000311 updateOpacity(renderer().style());
312 updateTransform(renderer().style());
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000313 updateFilters(renderer().style());
krit@webkit.org70a7a222012-08-21 00:35:27 +0000314#if ENABLE(CSS_COMPOSITING)
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000315 updateBlendMode(renderer().style());
krit@webkit.org70a7a222012-08-21 00:35:27 +0000316#endif
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000317}
318
dbates@webkit.org395fca72013-12-06 19:59:38 +0000319#if PLATFORM(IOS)
320void RenderLayerBacking::layerWillBeDestroyed()
321{
322 RenderObject& renderer = this->renderer();
cdumez@apple.com63c654d2014-10-09 16:45:32 +0000323 if (is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing()) {
324 PluginViewBase* pluginViewBase = downcast<PluginViewBase>(downcast<RenderWidget>(renderer).widget());
dbates@webkit.org395fca72013-12-06 19:59:38 +0000325 if (pluginViewBase && m_graphicsLayer->contentsLayerForMedia())
326 pluginViewBase->detachPluginLayer();
327 }
328}
329#endif
330
simon.fraser@apple.comec223212011-07-13 21:57:57 +0000331void RenderLayerBacking::destroyGraphicsLayers()
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000332{
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +0000333 if (m_graphicsLayer) {
334 willDestroyLayer(m_graphicsLayer.get());
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000335 m_graphicsLayer->removeFromParent();
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +0000336 }
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000337
simon.fraser@apple.com632ced12013-01-15 23:17:01 +0000338 m_ancestorClippingLayer = nullptr;
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000339 m_contentsContainmentLayer = nullptr;
abarth@webkit.org462d90a2011-04-27 21:25:22 +0000340 m_graphicsLayer = nullptr;
341 m_foregroundLayer = nullptr;
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000342 m_backgroundLayer = nullptr;
simon.fraser@apple.com632ced12013-01-15 23:17:01 +0000343 m_childContainmentLayer = nullptr;
abarth@webkit.org462d90a2011-04-27 21:25:22 +0000344 m_maskLayer = nullptr;
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000345
346 m_scrollingLayer = nullptr;
347 m_scrollingContentsLayer = nullptr;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000348}
349
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000350void RenderLayerBacking::updateOpacity(const RenderStyle& style)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000351{
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000352 m_graphicsLayer->setOpacity(compositingOpacity(style.opacity()));
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000353}
354
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000355void RenderLayerBacking::updateTransform(const RenderStyle& style)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000356{
akling@apple.comc68fe752013-10-13 18:39:27 +0000357 // FIXME: This could use m_owningLayer.transform(), but that currently has transform-origin
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000358 // baked into it, and we don't want that.
359 TransformationMatrix t;
akling@apple.comc68fe752013-10-13 18:39:27 +0000360 if (m_owningLayer.hasTransform()) {
cdumez@apple.com0abff8b2014-10-17 21:25:10 +0000361 auto& renderBox = downcast<RenderBox>(renderer());
zalan@apple.com376339c2014-08-28 04:24:31 +0000362 style.applyTransform(t, snapRectToDevicePixels(renderBox.borderBoxRect(), deviceScaleFactor()), RenderStyle::ExcludeTransformOrigin);
akling@apple.comc3466042013-08-24 18:27:32 +0000363 makeMatrixRenderable(t, compositor().canRender3DTransforms());
simon.fraser@apple.comccf36902009-03-17 19:24:35 +0000364 }
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000365
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000366 if (m_contentsContainmentLayer) {
367 m_contentsContainmentLayer->setTransform(t);
368 m_graphicsLayer->setTransform(TransformationMatrix());
369 } else
370 m_graphicsLayer->setTransform(t);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000371}
372
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000373void RenderLayerBacking::updateFilters(const RenderStyle& style)
cmarrin@apple.com3106ca82011-12-17 17:46:57 +0000374{
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000375 m_canCompositeFilters = m_graphicsLayer->setFilters(style.filter());
cmarrin@apple.com3106ca82011-12-17 17:46:57 +0000376}
cmarrin@apple.com3106ca82011-12-17 17:46:57 +0000377
krit@webkit.org70a7a222012-08-21 00:35:27 +0000378#if ENABLE(CSS_COMPOSITING)
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000379void RenderLayerBacking::updateBlendMode(const RenderStyle& style)
krit@webkit.org70a7a222012-08-21 00:35:27 +0000380{
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000381 // FIXME: where is the blend mode updated when m_ancestorClippingLayers come and go?
commit-queue@webkit.orgf24a35f2014-03-31 21:07:39 +0000382 if (m_ancestorClippingLayer) {
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000383 m_ancestorClippingLayer->setBlendMode(style.blendMode());
commit-queue@webkit.orgf24a35f2014-03-31 21:07:39 +0000384 m_graphicsLayer->setBlendMode(BlendModeNormal);
385 } else
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000386 m_graphicsLayer->setBlendMode(style.blendMode());
krit@webkit.org70a7a222012-08-21 00:35:27 +0000387}
388#endif
389
simon.fraser@apple.com2a2bd4d2014-04-29 23:53:57 +0000390// FIXME: the hasAcceleratedTouchScrolling()/needsCompositedScrolling() concepts need to be merged.
akling@apple.comc68fe752013-10-13 18:39:27 +0000391static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer& layer)
simon.fraser@apple.comcc875e42010-07-15 20:08:41 +0000392{
akling@apple.comc68fe752013-10-13 18:39:27 +0000393 for (RenderLayer* curr = &layer; curr; curr = curr->parent()) {
simon.fraser@apple.com2a2bd4d2014-04-29 23:53:57 +0000394 if (curr->hasTransform()
395#if PLATFORM(IOS)
simon.fraser@apple.com9fd8d642014-05-02 21:24:54 +0000396 || curr->hasTouchScrollableOverflow()
simon.fraser@apple.com2a2bd4d2014-04-29 23:53:57 +0000397#else
398 || curr->needsCompositedScrolling()
399#endif
400 )
simon.fraser@apple.com3d117662010-07-27 00:21:41 +0000401 return true;
simon.fraser@apple.comcc875e42010-07-15 20:08:41 +0000402 }
dbates@webkit.org395fca72013-12-06 19:59:38 +0000403
simon.fraser@apple.com3d117662010-07-27 00:21:41 +0000404 return false;
simon.fraser@apple.comcc875e42010-07-15 20:08:41 +0000405}
simon.fraser@apple.com2a2bd4d2014-04-29 23:53:57 +0000406
andersca@apple.comb5314522012-03-07 01:25:46 +0000407bool RenderLayerBacking::shouldClipCompositedBounds() const
408{
dbates@webkit.org395fca72013-12-06 19:59:38 +0000409#if !PLATFORM(IOS)
enne@google.com5979acb2012-06-19 21:00:09 +0000410 // Scrollbar layers use this layer for relative positioning, so don't clip.
411 if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
412 return false;
dbates@webkit.org395fca72013-12-06 19:59:38 +0000413#endif
enne@google.com5979acb2012-06-19 21:00:09 +0000414
andersca@apple.comb5314522012-03-07 01:25:46 +0000415 if (m_usingTiledCacheLayer)
simon.fraser@apple.com199fa152012-12-12 23:33:05 +0000416 return false;
andersca@apple.comb5314522012-03-07 01:25:46 +0000417
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000418 if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
andersca@apple.comb5314522012-03-07 01:25:46 +0000419 return false;
420
commit-queue@webkit.org83e19482013-10-21 19:38:30 +0000421 if (m_owningLayer.isFlowThreadCollectingGraphicsLayersUnderRegions())
422 return false;
423
andersca@apple.comb5314522012-03-07 01:25:46 +0000424 return true;
425}
426
simon.fraser@apple.com2a2bd4d2014-04-29 23:53:57 +0000427static bool hasNonZeroTransformOrigin(const RenderObject& renderer)
428{
429 const RenderStyle& style = renderer.style();
430 return (style.transformOriginX().type() == Fixed && style.transformOriginX().value())
431 || (style.transformOriginY().type() == Fixed && style.transformOriginY().value());
432}
433
simon.fraser@apple.comc6e466c2009-09-19 03:44:10 +0000434void RenderLayerBacking::updateCompositedBounds()
435{
zalan@apple.com12662502014-07-14 19:15:24 +0000436 LayoutRect layerBounds = m_owningLayer.calculateLayerBounds(&m_owningLayer, LayoutSize(), RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask);
simon.fraser@apple.comcc875e42010-07-15 20:08:41 +0000437 // Clip to the size of the document or enclosing overflow-scroll layer.
simon.fraser@apple.com3d117662010-07-27 00:21:41 +0000438 // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
jer.noble@apple.comc99c8cf2012-03-08 23:14:46 +0000439 // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
andersca@apple.comb5314522012-03-07 01:25:46 +0000440 if (shouldClipCompositedBounds()) {
mihnea@adobe.com388bf222014-09-22 07:51:54 +0000441 RenderView& view = renderer().view();
akling@apple.com691cf5c2013-08-24 16:33:15 +0000442 RenderLayer* rootLayer = view.layer();
simon.fraser@apple.comcc875e42010-07-15 20:08:41 +0000443
simon.fraser@apple.com8b548152013-02-16 01:05:20 +0000444 LayoutRect clippingBounds;
simon.fraser@apple.com2e9410a2014-01-31 01:47:45 +0000445 if (renderer().style().position() == FixedPosition && renderer().container() == &view)
simon.fraser@apple.com539397f2014-05-13 04:32:09 +0000446 clippingBounds = view.frameView().viewportConstrainedVisibleContentRect();
simon.fraser@apple.com2e9410a2014-01-31 01:47:45 +0000447 else
akling@apple.com691cf5c2013-08-24 16:33:15 +0000448 clippingBounds = view.unscaledDocumentRect();
simon.fraser@apple.comcc875e42010-07-15 20:08:41 +0000449
akling@apple.comc68fe752013-10-13 18:39:27 +0000450 if (&m_owningLayer != rootLayer)
abucur@adobe.com7f9668a2014-05-16 13:22:00 +0000451 clippingBounds.intersect(m_owningLayer.backgroundClipRect(RenderLayer::ClipRectsContext(rootLayer, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
simon.fraser@apple.com3d117662010-07-27 00:21:41 +0000452
zalan@apple.com93ff24a2014-06-20 22:57:42 +0000453 LayoutPoint delta = m_owningLayer.convertToLayerCoords(rootLayer, LayoutPoint(), RenderLayer::AdjustForColumns);
eae@chromium.org53dc8b52011-06-02 06:41:17 +0000454 clippingBounds.move(-delta.x(), -delta.y());
simon.fraser@apple.com3d117662010-07-27 00:21:41 +0000455
allan.jensen@digia.comd5cbc752013-08-13 17:08:19 +0000456 layerBounds.intersect(clippingBounds);
simon.fraser@apple.combd93c752013-08-23 00:28:48 +0000457 }
simon.fraser@apple.comcc875e42010-07-15 20:08:41 +0000458
simon.fraser@apple.comc6e466c2009-09-19 03:44:10 +0000459 // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
460 // then we need to ensure that the compositing layer has non-zero size so that we can apply
461 // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
462 if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) {
463 layerBounds.setWidth(1);
464 layerBounds.setHeight(1);
465 m_artificiallyInflatedBounds = true;
466 } else
467 m_artificiallyInflatedBounds = false;
468
469 setCompositedBounds(layerBounds);
470}
471
simon.fraser@apple.com0debf0a2010-07-09 05:33:01 +0000472void RenderLayerBacking::updateAfterWidgetResize()
473{
cdumez@apple.com3abcc792014-10-20 03:42:03 +0000474 if (!is<RenderWidget>(renderer()))
akling@apple.comb95111f2013-09-12 05:21:14 +0000475 return;
cdumez@apple.com3abcc792014-10-20 03:42:03 +0000476 if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(&downcast<RenderWidget>(renderer()))) {
akling@apple.comb95111f2013-09-12 05:21:14 +0000477 innerCompositor->frameViewDidChangeSize();
478 innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contentsBox().location()));
simon.fraser@apple.com0debf0a2010-07-09 05:33:01 +0000479 }
480}
481
simon.fraser@apple.comfc750292012-12-15 22:11:27 +0000482void RenderLayerBacking::updateAfterLayout(UpdateAfterLayoutFlags flags)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000483{
akling@apple.comc3466042013-08-24 18:27:32 +0000484 if (!compositor().compositingLayersNeedRebuild()) {
simon.fraser@apple.come33dc482014-05-19 15:53:32 +0000485 // Calling updateGeometry() here gives incorrect results, because the
simon.fraser@apple.comb2fc99c2009-06-22 22:45:24 +0000486 // position of this layer's GraphicsLayer depends on the position of our compositing
487 // ancestor's GraphicsLayer. That cannot be determined until all the descendant
488 // RenderLayers of that ancestor have been processed via updateLayerPositions().
489 //
490 // The solution is to update compositing children of this layer here,
491 // via updateCompositingChildrenGeometry().
simon.fraser@apple.comc6e466c2009-09-19 03:44:10 +0000492 updateCompositedBounds();
akling@apple.comc68fe752013-10-13 18:39:27 +0000493 compositor().updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, flags & CompositingChildrenOnly);
simon.fraser@apple.comb2fc99c2009-06-22 22:45:24 +0000494
simon.fraser@apple.comfc750292012-12-15 22:11:27 +0000495 if (flags & IsUpdateRoot) {
simon.fraser@apple.come33dc482014-05-19 15:53:32 +0000496 updateGeometry();
akling@apple.comc3466042013-08-24 18:27:32 +0000497 compositor().updateRootLayerPosition();
akling@apple.comc68fe752013-10-13 18:39:27 +0000498 RenderLayer* stackingContainer = m_owningLayer.enclosingStackingContainer();
499 if (!compositor().compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != &m_owningLayer))
darin@apple.com8cdf7122013-09-30 02:40:50 +0000500 compositor().updateCompositingDescendantGeometry(*stackingContainer, *stackingContainer, flags & CompositingChildrenOnly);
simon.fraser@apple.comfc8f94b2009-07-02 06:30:05 +0000501 }
simon.fraser@apple.comb2fc99c2009-06-22 22:45:24 +0000502 }
simon.fraser@apple.comfc750292012-12-15 22:11:27 +0000503
simon.fraser@apple.com4baf9a32012-12-16 18:14:52 +0000504 if (flags & NeedsFullRepaint && !paintsIntoWindow() && !paintsIntoCompositedAncestor())
simon.fraser@apple.comfc750292012-12-15 22:11:27 +0000505 setContentsNeedDisplay();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000506}
507
simon.fraser@apple.come33dc482014-05-19 15:53:32 +0000508bool RenderLayerBacking::updateConfiguration()
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000509{
akling@apple.comc68fe752013-10-13 18:39:27 +0000510 m_owningLayer.updateDescendantDependentFlags();
511 m_owningLayer.updateZOrderLists();
jchaffraix@webkit.org99e09932012-05-15 21:33:41 +0000512
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000513 bool layerConfigChanged = false;
akling@apple.comc68fe752013-10-13 18:39:27 +0000514 setBackgroundLayerPaintsFixedRootBackground(compositor().needsFixedRootBackgroundLayer(m_owningLayer));
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000515
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +0000516 // The background layer is currently only used for fixed root backgrounds.
517 if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000518 layerConfigChanged = true;
519
akling@apple.comc68fe752013-10-13 18:39:27 +0000520 if (updateForegroundLayer(compositor().needsContentsCompositingLayer(m_owningLayer)))
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000521 layerConfigChanged = true;
522
akling@apple.comc68fe752013-10-13 18:39:27 +0000523 bool needsDescendentsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
simon.fraser@apple.com2a2bd4d2014-04-29 23:53:57 +0000524
simon.fraser@apple.com9fd8d642014-05-02 21:24:54 +0000525 if (!renderer().view().needsLayout()) {
526 bool usesCompositedScrolling;
527#if PLATFORM(IOS)
528 usesCompositedScrolling = m_owningLayer.hasTouchScrollableOverflow();
529#else
530 usesCompositedScrolling = m_owningLayer.needsCompositedScrolling();
531#endif
532 // Our scrolling layer will clip.
533 if (usesCompositedScrolling)
534 needsDescendentsClippingLayer = false;
535
536 if (updateScrollingLayers(usesCompositedScrolling))
537 layerConfigChanged = true;
538
539 if (updateDescendantClippingLayer(needsDescendentsClippingLayer))
540 layerConfigChanged = true;
541 }
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000542
akling@apple.comc68fe752013-10-13 18:39:27 +0000543 if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
zalan@apple.comc3d72182013-09-12 14:03:21 +0000544 layerConfigChanged = true;
545
jamesr@google.come53ce642011-04-14 06:51:50 +0000546 if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
547 layerConfigChanged = true;
548
549 if (layerConfigChanged)
550 updateInternalHierarchy();
551
dino@apple.comeebfa9062012-07-09 20:36:21 +0000552 if (GraphicsLayer* flatteningLayer = tileCacheFlatteningLayer()) {
andersca@apple.comcc3b2dc2013-09-27 18:38:51 +0000553 if (layerConfigChanged || flatteningLayer->parent() != m_graphicsLayer.get())
simon.fraser@apple.com32c18df2013-08-13 20:18:30 +0000554 m_graphicsLayer->addChild(flatteningLayer);
dino@apple.comeebfa9062012-07-09 20:36:21 +0000555 }
556
simon.fraser@apple.com0749dee2014-06-20 20:56:16 +0000557 updateMaskLayer(renderer().hasMask());
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +0000558
akling@apple.comc68fe752013-10-13 18:39:27 +0000559 if (m_owningLayer.hasReflection()) {
560 if (m_owningLayer.reflectionLayer()->backing()) {
561 GraphicsLayer* reflectionLayer = m_owningLayer.reflectionLayer()->backing()->graphicsLayer();
simon.fraser@apple.com823f73c2010-01-16 05:07:42 +0000562 m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
563 }
564 } else
565 m_graphicsLayer->setReplicatedByLayer(0);
566
simon.fraser@apple.com3547efb2014-09-05 00:23:05 +0000567 if (!m_owningLayer.isRootLayer()) {
568 bool isSimpleContainer = isSimpleContainerCompositingLayer();
569 bool didUpdateContentsRect = false;
570 updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
571 } else
572 updateRootLayerConfiguration();
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +0000573
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +0000574 if (isDirectlyCompositedImage())
575 updateImageContents();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000576
cdumez@apple.com63c654d2014-10-09 16:45:32 +0000577 if (is<RenderEmbeddedObject>(renderer()) && downcast<RenderEmbeddedObject>(renderer()).allowsAcceleratedCompositing()) {
578 PluginViewBase* pluginViewBase = downcast<PluginViewBase>(downcast<RenderWidget>(renderer()).widget());
dbates@webkit.org395fca72013-12-06 19:59:38 +0000579#if PLATFORM(IOS)
580 if (pluginViewBase && !m_graphicsLayer->contentsLayerForMedia()) {
581 pluginViewBase->detachPluginLayer();
582 pluginViewBase->attachPluginLayer();
583 }
584#else
roger_fong@apple.com78dd6182013-07-11 23:53:40 +0000585 if (!pluginViewBase->shouldNotAddLayer())
commit-queue@webkit.orgf0edcda2014-08-23 09:24:44 +0000586 m_graphicsLayer->setContentsToPlatformLayer(pluginViewBase->platformLayer(), GraphicsLayer::ContentsLayerForPlugin);
dbates@webkit.org395fca72013-12-06 19:59:38 +0000587#endif
ossy@webkit.org497bedb2010-02-16 23:03:58 +0000588 }
589#if ENABLE(VIDEO)
akling@apple.com32c7a6e2013-08-26 02:21:32 +0000590 else if (renderer().isVideo()) {
cdumez@apple.comcd131532014-09-27 01:32:34 +0000591 HTMLMediaElement* mediaElement = downcast<HTMLMediaElement>(renderer().element());
commit-queue@webkit.orgf0edcda2014-08-23 09:24:44 +0000592 m_graphicsLayer->setContentsToPlatformLayer(mediaElement->platformLayer(), GraphicsLayer::ContentsLayerForMedia);
simon.fraser@apple.comd6aff5e2010-01-12 00:15:06 +0000593 }
ossy@webkit.org497bedb2010-02-16 23:03:58 +0000594#endif
cmarrin@apple.com8b28bbc2011-01-25 17:27:30 +0000595#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
simon.fraser@apple.comefaa4122013-12-20 03:48:10 +0000596 else if (renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
cdumez@apple.com72754ba2014-09-23 22:03:15 +0000597 const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer().element());
jamesr@google.comd8c61572010-08-06 21:49:20 +0000598 if (CanvasRenderingContext* context = canvas->renderingContext())
commit-queue@webkit.orgf0edcda2014-08-23 09:24:44 +0000599 m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer(), GraphicsLayer::ContentsLayerForCanvas);
jamesr@google.combab91912010-09-03 18:38:37 +0000600 layerConfigChanged = true;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000601 }
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +0000602#endif
cdumez@apple.com3abcc792014-10-20 03:42:03 +0000603 if (is<RenderWidget>(renderer()))
604 layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(&downcast<RenderWidget>(renderer()));
simon.fraser@apple.comc0c558c2010-05-11 05:44:06 +0000605
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000606 return layerConfigChanged;
607}
608
zalan@apple.com545c48a2014-02-20 05:02:37 +0000609static LayoutRect clipBox(RenderBox& renderer)
simon.fraser@apple.com02d55992010-06-16 19:16:17 +0000610{
carlosgc@webkit.org60d416c2014-01-07 20:01:31 +0000611 LayoutRect result = LayoutRect::infiniteRect();
akling@apple.com4c166d62013-09-01 05:29:00 +0000612 if (renderer.hasOverflowClip())
613 result = renderer.overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions.
simon.fraser@apple.com02d55992010-06-16 19:16:17 +0000614
akling@apple.com4c166d62013-09-01 05:29:00 +0000615 if (renderer.hasClip())
616 result.intersect(renderer.clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
simon.fraser@apple.com02d55992010-06-16 19:16:17 +0000617
zalan@apple.com5e034f62014-02-20 23:04:20 +0000618 return result;
619}
620
621static FloatSize pixelFractionForLayerPainting(const LayoutPoint& point, float pixelSnappingFactor)
622{
623 LayoutUnit x = point.x();
624 LayoutUnit y = point.y();
625 x = x >= 0 ? floorToDevicePixel(x, pixelSnappingFactor) : ceilToDevicePixel(x, pixelSnappingFactor);
626 y = y >= 0 ? floorToDevicePixel(y, pixelSnappingFactor) : ceilToDevicePixel(y, pixelSnappingFactor);
627 return point - LayoutPoint(x, y);
628}
629
630static void calculateDevicePixelOffsetFromRenderer(const LayoutSize& rendererOffsetFromGraphicsLayer, FloatSize& devicePixelOffsetFromRenderer,
631 LayoutSize& devicePixelFractionFromRenderer, float deviceScaleFactor)
632{
633 devicePixelFractionFromRenderer = LayoutSize(pixelFractionForLayerPainting(toLayoutPoint(rendererOffsetFromGraphicsLayer), deviceScaleFactor));
634 devicePixelOffsetFromRenderer = rendererOffsetFromGraphicsLayer - devicePixelFractionFromRenderer;
simon.fraser@apple.com02d55992010-06-16 19:16:17 +0000635}
636
simon.fraser@apple.come33dc482014-05-19 15:53:32 +0000637void RenderLayerBacking::updateGeometry()
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000638{
639 // If we haven't built z-order lists yet, wait until later.
akling@apple.comc68fe752013-10-13 18:39:27 +0000640 if (m_owningLayer.isStackingContainer() && m_owningLayer.m_zOrderListsDirty)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000641 return;
642
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000643 const RenderStyle& style = renderer().style();
644
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000645 // Set transform property, if it is not animating. We have to do this here because the transform
646 // is affected by the layer dimensions.
cdumez@apple.combc6f7402014-10-17 01:53:09 +0000647 if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitTransform, AnimationBase::Running | AnimationBase::Paused | AnimationBase::FillingFowards))
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000648 updateTransform(style);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000649
simon.fraser@apple.com699dc0b2009-04-07 17:45:00 +0000650 // Set opacity, if it is not animating.
cdumez@apple.combc6f7402014-10-17 01:53:09 +0000651 if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity, AnimationBase::Running | AnimationBase::Paused | AnimationBase::FillingFowards))
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000652 updateOpacity(style);
commit-queue@webkit.org9e58b3d2014-09-04 18:43:39 +0000653
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000654 updateFilters(style);
krit@webkit.org70a7a222012-08-21 00:35:27 +0000655
656#if ENABLE(CSS_COMPOSITING)
simon.fraser@apple.com33e25452014-05-19 15:53:37 +0000657 updateBlendMode(style);
krit@webkit.org70a7a222012-08-21 00:35:27 +0000658#endif
commit-queue@webkit.org90f15662012-12-08 23:46:05 +0000659
akling@apple.comc68fe752013-10-13 18:39:27 +0000660 m_owningLayer.updateDescendantDependentFlags();
shawnsingh@chromium.org976a6082012-02-01 10:31:15 +0000661
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000662 // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
akling@apple.com827be9c2013-10-29 02:58:43 +0000663 bool preserves3D = style.transformStyle3D() == TransformStyle3DPreserve3D && !renderer().hasReflection();
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000664 m_graphicsLayer->setPreserves3D(preserves3D);
akling@apple.com827be9c2013-10-29 02:58:43 +0000665 m_graphicsLayer->setBackfaceVisibility(style.backfaceVisibility() == BackfaceVisibilityVisible);
simon.fraser@apple.com699dc0b2009-04-07 17:45:00 +0000666
akling@apple.comc68fe752013-10-13 18:39:27 +0000667 RenderLayer* compAncestor = m_owningLayer.ancestorCompositingLayer();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000668
669 // We compute everything relative to the enclosing compositing layer.
zalan@apple.com545c48a2014-02-20 05:02:37 +0000670 LayoutRect ancestorCompositingBounds;
simon.fraser@apple.comb2fc99c2009-06-22 22:45:24 +0000671 if (compAncestor) {
672 ASSERT(compAncestor->backing());
zalan@apple.com5e034f62014-02-20 23:04:20 +0000673 ancestorCompositingBounds = compAncestor->backing()->compositedBounds();
simon.fraser@apple.comb2fc99c2009-06-22 22:45:24 +0000674 }
675
zalan@apple.com5e034f62014-02-20 23:04:20 +0000676 /*
zalan@apple.comc1841252014-04-21 05:21:45 +0000677 * GraphicsLayer: device pixel positioned, enclosing rect.
zalan@apple.com5e034f62014-02-20 23:04:20 +0000678 * RenderLayer: subpixel positioned.
679 * Offset from renderer (GraphicsLayer <-> RenderLayer::renderer()): subpixel based offset.
680 *
681 * relativeCompositingBounds
682 * _______________________________________
683 * |\ GraphicsLayer |
684 * | \ |
685 * | \ offset from renderer: (device pixel + subpixel)
686 * | \ |
687 * | \______________________________ |
688 * | | localCompositingBounds | |
689 * | | | |
690 * | | RenderLayer::renderer() | |
691 * | | | |
692 *
693 * localCompositingBounds: this RenderLayer relative to its renderer().
694 * relativeCompositingBounds: this RenderLayer relative to its parent compositing layer.
zalan@apple.comc1841252014-04-21 05:21:45 +0000695 * enclosingRelativeCompositingBounds: this RenderLayer relative to its parent, device pixel enclosing.
zalan@apple.com5e034f62014-02-20 23:04:20 +0000696 * rendererOffsetFromGraphicsLayer: RenderLayer::renderer()'s offset from its enclosing GraphicsLayer.
697 * devicePixelOffsetFromRenderer: rendererOffsetFromGraphicsLayer's device pixel part. (6.9px -> 6.5px in case of 2x display)
698 * devicePixelFractionFromRenderer: rendererOffsetFromGraphicsLayer's fractional part (6.9px -> 0.4px in case of 2x display)
699 */
700 float deviceScaleFactor = this->deviceScaleFactor();
701 LayoutRect localCompositingBounds = compositedBounds();
zalan@apple.com545c48a2014-02-20 05:02:37 +0000702 LayoutRect relativeCompositingBounds(localCompositingBounds);
zalan@apple.com5e034f62014-02-20 23:04:20 +0000703
zalan@apple.com93ff24a2014-06-20 22:57:42 +0000704 LayoutPoint offsetFromParent = m_owningLayer.convertToLayerCoords(compAncestor, LayoutPoint(), RenderLayer::AdjustForColumns);
zalan@apple.com8c4a9fb2014-03-20 14:20:22 +0000705 // Device pixel fractions get accumulated through ancestor layers. Our painting offset is layout offset + parent's painting offset.
706 offsetFromParent = offsetFromParent + (compAncestor ? compAncestor->backing()->devicePixelFractionFromRenderer() : LayoutSize());
zalan@apple.com5e034f62014-02-20 23:04:20 +0000707 relativeCompositingBounds.moveBy(offsetFromParent);
708
zalan@apple.com376339c2014-08-28 04:24:31 +0000709 LayoutRect enclosingRelativeCompositingBounds = LayoutRect(encloseRectToDevicePixels(relativeCompositingBounds, deviceScaleFactor));
zalan@apple.com5e034f62014-02-20 23:04:20 +0000710 LayoutSize subpixelOffsetAdjustment = enclosingRelativeCompositingBounds.location() - relativeCompositingBounds.location();
711 LayoutSize rendererOffsetFromGraphicsLayer = toLayoutSize(localCompositingBounds.location()) + subpixelOffsetAdjustment;
712
713 FloatSize devicePixelOffsetFromRenderer;
714 LayoutSize devicePixelFractionFromRenderer;
715 calculateDevicePixelOffsetFromRenderer(rendererOffsetFromGraphicsLayer, devicePixelOffsetFromRenderer, devicePixelFractionFromRenderer, deviceScaleFactor);
zalan@apple.comb333b3a2014-07-15 02:55:26 +0000716 m_devicePixelFractionFromRenderer = LayoutSize(-devicePixelFractionFromRenderer.width(), -devicePixelFractionFromRenderer.height());
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000717
commit-queue@webkit.org83e19482013-10-21 19:38:30 +0000718 adjustAncestorCompositingBoundsForFlowThread(ancestorCompositingBounds, compAncestor);
719
zalan@apple.com545c48a2014-02-20 05:02:37 +0000720 LayoutPoint graphicsLayerParentLocation;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000721 if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
722 // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
723 // position relative to it.
simon.fraser@apple.comd6d9d642014-05-01 02:15:17 +0000724 // FIXME: need to do some pixel snapping here.
cdumez@apple.com0abff8b2014-10-17 21:25:10 +0000725 LayoutRect clippingBox = clipBox(downcast<RenderBox>(compAncestor->renderer()));
simon.fraser@apple.com02d55992010-06-16 19:16:17 +0000726 graphicsLayerParentLocation = clippingBox.location();
enne@google.com84515952011-06-24 18:35:12 +0000727 } else if (compAncestor)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000728 graphicsLayerParentLocation = ancestorCompositingBounds.location();
enne@google.comf1e52712011-06-24 19:16:48 +0000729 else
akling@apple.com32c7a6e2013-08-26 02:21:32 +0000730 graphicsLayerParentLocation = renderer().view().documentRect().location();
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000731
dbates@webkit.org395fca72013-12-06 19:59:38 +0000732#if PLATFORM(IOS)
simon.fraser@apple.com9fd8d642014-05-02 21:24:54 +0000733 if (compAncestor && compAncestor->hasTouchScrollableOverflow()) {
cdumez@apple.com0abff8b2014-10-17 21:25:10 +0000734 auto& renderBox = downcast<RenderBox>(compAncestor->renderer());
735 LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(),
736 renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(),
737 renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
dbates@webkit.org395fca72013-12-06 19:59:38 +0000738
simon.fraser@apple.comd6d9d642014-05-01 02:15:17 +0000739 IntSize scrollOffset = compAncestor->scrolledContentOffset();
740 // FIXME: pixel snap the padding box.
dbates@webkit.org395fca72013-12-06 19:59:38 +0000741 graphicsLayerParentLocation = paddingBox.location() - scrollOffset;
742 }
simon.fraser@apple.comd6d9d642014-05-01 02:15:17 +0000743#else
vollick@chromium.org013915f2012-12-16 02:07:57 +0000744 if (compAncestor && compAncestor->needsCompositedScrolling()) {
cdumez@apple.com0abff8b2014-10-17 21:25:10 +0000745 auto& renderBox = downcast<RenderBox>(compAncestor->renderer());
zalan@apple.com545c48a2014-02-20 05:02:37 +0000746 LayoutSize scrollOffset = compAncestor->scrolledContentOffset();
747 LayoutPoint scrollOrigin(renderBox.borderLeft(), renderBox.borderTop());
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000748 graphicsLayerParentLocation = scrollOrigin - scrollOffset;
749 }
simon.fraser@apple.comd6d9d642014-05-01 02:15:17 +0000750#endif
751
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000752 if (compAncestor && m_ancestorClippingLayer) {
753 // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
754 // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
755 // for a compositing layer, rootLayer is the layer itself.
commit-queue@webkit.orgbcb0f1c2014-05-05 21:08:25 +0000756 ShouldRespectOverflowClip shouldRespectOverflowClip = compAncestor->isolatesCompositedBlending() ? RespectOverflowClip : IgnoreOverflowClip;
abucur@adobe.com7f9668a2014-05-16 13:22:00 +0000757 RenderLayer::ClipRectsContext clipRectsContext(compAncestor, TemporaryClipRects, IgnoreOverlayScrollbarSize, shouldRespectOverflowClip);
zalan@apple.com5e034f62014-02-20 23:04:20 +0000758 LayoutRect parentClipRect = m_owningLayer.backgroundClipRect(clipRectsContext).rect(); // FIXME: Incorrect for CSS regions.
zalan@apple.com545c48a2014-02-20 05:02:37 +0000759 ASSERT(parentClipRect != LayoutRect::infiniteRect());
commit-queue@webkit.org444304f2013-01-08 06:07:55 +0000760 m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
simon.fraser@apple.coma9214f632009-03-26 18:34:03 +0000761 m_ancestorClippingLayer->setSize(parentClipRect.size());
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000762
763 // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
zalan@apple.com5e034f62014-02-20 23:04:20 +0000764 m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - offsetFromParent);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000765
766 // The primary layer is then parented in, and positioned relative to this clipping layer.
simon.fraser@apple.coma9214f632009-03-26 18:34:03 +0000767 graphicsLayerParentLocation = parentClipRect.location();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000768 }
769
zalan@apple.com5e034f62014-02-20 23:04:20 +0000770 LayoutSize contentsSize = enclosingRelativeCompositingBounds.size();
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000771
772 if (m_contentsContainmentLayer) {
773 m_contentsContainmentLayer->setPreserves3D(preserves3D);
zalan@apple.com5e034f62014-02-20 23:04:20 +0000774 m_contentsContainmentLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - graphicsLayerParentLocation));
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000775 // Use the same size as m_graphicsLayer so transforms behave correctly.
776 m_contentsContainmentLayer->setSize(contentsSize);
zalan@apple.com5e034f62014-02-20 23:04:20 +0000777 graphicsLayerParentLocation = enclosingRelativeCompositingBounds.location();
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000778 }
779
zalan@apple.com5e034f62014-02-20 23:04:20 +0000780 m_graphicsLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - graphicsLayerParentLocation));
simon.fraser@apple.combd93c752013-08-23 00:28:48 +0000781 m_graphicsLayer->setSize(contentsSize);
zalan@apple.com5e034f62014-02-20 23:04:20 +0000782 if (devicePixelOffsetFromRenderer != m_graphicsLayer->offsetFromRenderer()) {
783 m_graphicsLayer->setOffsetFromRenderer(devicePixelOffsetFromRenderer);
simon.fraser@apple.com1c06cdd2013-11-12 00:50:29 +0000784 positionOverflowControlsLayers();
785 }
allan.jensen@digia.comd5cbc752013-08-13 17:08:19 +0000786
alokp@chromium.org1f006a42013-03-21 22:29:30 +0000787 if (!m_isMainFrameRenderViewLayer) {
788 // For non-root layers, background is always painted by the primary graphics layer.
789 ASSERT(!m_backgroundLayer);
zalan@apple.comc1841252014-04-21 05:21:45 +0000790 bool hadSubpixelRounding = enclosingRelativeCompositingBounds != relativeCompositingBounds;
simon.fraser@apple.comec171c62013-11-18 23:33:04 +0000791 m_graphicsLayer->setContentsOpaque(!hadSubpixelRounding && m_owningLayer.backgroundIsKnownToBeOpaqueInRect(localCompositingBounds));
alokp@chromium.org1f006a42013-03-21 22:29:30 +0000792 }
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000793
794 // If we have a layer that clips children, position it.
zalan@apple.com545c48a2014-02-20 05:02:37 +0000795 LayoutRect clippingBox;
dino@apple.comeebfa9062012-07-09 20:36:21 +0000796 if (GraphicsLayer* clipLayer = clippingLayer()) {
simon.fraser@apple.comd6d9d642014-05-01 02:15:17 +0000797 // FIXME: need to do some pixel snapping here.
cdumez@apple.com0abff8b2014-10-17 21:25:10 +0000798 clippingBox = clipBox(downcast<RenderBox>(renderer()));
commit-queue@webkit.org444304f2013-01-08 06:07:55 +0000799 clipLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location()));
dino@apple.comeebfa9062012-07-09 20:36:21 +0000800 clipLayer->setSize(clippingBox.size());
zalan@apple.com545c48a2014-02-20 05:02:37 +0000801 clipLayer->setOffsetFromRenderer(toFloatSize(clippingBox.location()));
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000802 }
803
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +0000804 if (m_maskLayer) {
simon.fraser@apple.combd93c752013-08-23 00:28:48 +0000805 m_maskLayer->setSize(m_graphicsLayer->size());
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +0000806 m_maskLayer->setPosition(FloatPoint());
simon.fraser@apple.come7881fb2011-04-29 05:19:10 +0000807 m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +0000808 }
809
akling@apple.comc68fe752013-10-13 18:39:27 +0000810 if (m_owningLayer.hasTransform()) {
zalan@apple.com88965072014-03-19 14:25:34 +0000811 // Update properties that depend on layer dimensions.
cdumez@apple.com0abff8b2014-10-17 21:25:10 +0000812 FloatPoint3D transformOrigin = computeTransformOriginForPainting(downcast<RenderBox>(renderer()).borderBoxRect());
simon.fraser@apple.com90a56642009-04-06 17:51:53 +0000813 // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
zalan@apple.com592254d2014-08-28 02:34:35 +0000814 FloatPoint layerOffset = roundPointToDevicePixels(offsetFromParent, deviceScaleFactor);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000815 // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
zalan@apple.com88965072014-03-19 14:25:34 +0000816 FloatPoint3D anchor(enclosingRelativeCompositingBounds.width() ? ((layerOffset.x() - enclosingRelativeCompositingBounds.x()) + transformOrigin.x())
817 / enclosingRelativeCompositingBounds.width() : 0.5, enclosingRelativeCompositingBounds.height() ? ((layerOffset.y() - enclosingRelativeCompositingBounds.y())
818 + transformOrigin.y()) / enclosingRelativeCompositingBounds.height() : 0.5, transformOrigin.z());
819
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000820 if (m_contentsContainmentLayer)
821 m_contentsContainmentLayer->setAnchorPoint(anchor);
822 else
823 m_graphicsLayer->setAnchorPoint(anchor);
simon.fraser@apple.com61cf5eb2009-02-13 05:10:12 +0000824
dino@apple.comeebfa9062012-07-09 20:36:21 +0000825 GraphicsLayer* clipLayer = clippingLayer();
akling@apple.com827be9c2013-10-29 02:58:43 +0000826 if (style.hasPerspective()) {
akling@apple.comc68fe752013-10-13 18:39:27 +0000827 TransformationMatrix t = owningLayer().perspectiveTransform();
simon.fraser@apple.com61cf5eb2009-02-13 05:10:12 +0000828
dino@apple.comeebfa9062012-07-09 20:36:21 +0000829 if (clipLayer) {
830 clipLayer->setChildrenTransform(t);
simon.fraser@apple.com61cf5eb2009-02-13 05:10:12 +0000831 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
832 }
833 else
834 m_graphicsLayer->setChildrenTransform(t);
835 } else {
dino@apple.comeebfa9062012-07-09 20:36:21 +0000836 if (clipLayer)
837 clipLayer->setChildrenTransform(TransformationMatrix());
simon.fraser@apple.com61cf5eb2009-02-13 05:10:12 +0000838 else
839 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
840 }
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000841 } else {
zalan@apple.com88965072014-03-19 14:25:34 +0000842 m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5, 0.5, 0));
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000843 if (m_contentsContainmentLayer)
zalan@apple.com88965072014-03-19 14:25:34 +0000844 m_contentsContainmentLayer->setAnchorPoint(FloatPoint3D(0.5, 0.5, 0));
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000845 }
846
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +0000847 if (m_foregroundLayer) {
simon.fraser@apple.comfdaa7882009-08-18 03:31:57 +0000848 FloatPoint foregroundPosition;
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000849 FloatSize foregroundSize = contentsSize;
zalan@apple.com545c48a2014-02-20 05:02:37 +0000850 FloatSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
dino@apple.comeebfa9062012-07-09 20:36:21 +0000851 if (hasClippingLayer()) {
simon.fraser@apple.com83c504a2011-03-22 23:17:23 +0000852 // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
853 // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
simon.fraser@apple.comfdaa7882009-08-18 03:31:57 +0000854 foregroundSize = FloatSize(clippingBox.size());
zalan@apple.com545c48a2014-02-20 05:02:37 +0000855 foregroundOffset = toFloatSize(clippingBox.location());
simon.fraser@apple.comfdaa7882009-08-18 03:31:57 +0000856 }
857
858 m_foregroundLayer->setPosition(foregroundPosition);
simon.fraser@apple.combd93c752013-08-23 00:28:48 +0000859 m_foregroundLayer->setSize(foregroundSize);
simon.fraser@apple.comfdaa7882009-08-18 03:31:57 +0000860 m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +0000861 }
862
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000863 if (m_backgroundLayer) {
simon.fraser@apple.coma5614962013-01-19 01:20:32 +0000864 FloatPoint backgroundPosition;
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000865 FloatSize backgroundSize = contentsSize;
simon.fraser@apple.coma5614962013-01-19 01:20:32 +0000866 if (backgroundLayerPaintsFixedRootBackground()) {
akling@apple.com32c7a6e2013-08-26 02:21:32 +0000867 const FrameView& frameView = renderer().view().frameView();
simon.fraser@apple.comeb58fa32014-03-12 18:15:06 +0000868 backgroundPosition = toLayoutPoint(frameView.scrollOffsetForFixedPosition());
akling@apple.com61dc1432013-08-23 16:34:12 +0000869 backgroundSize = frameView.visibleContentRect().size();
simon.fraser@apple.coma5614962013-01-19 01:20:32 +0000870 }
871 m_backgroundLayer->setPosition(backgroundPosition);
simon.fraser@apple.combd93c752013-08-23 00:28:48 +0000872 m_backgroundLayer->setSize(backgroundSize);
simon.fraser@apple.coma5614962013-01-19 01:20:32 +0000873 m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +0000874 }
875
akling@apple.comc68fe752013-10-13 18:39:27 +0000876 if (m_owningLayer.reflectionLayer() && m_owningLayer.reflectionLayer()->isComposited()) {
877 RenderLayerBacking* reflectionBacking = m_owningLayer.reflectionLayer()->backing();
simon.fraser@apple.come33dc482014-05-19 15:53:32 +0000878 reflectionBacking->updateGeometry();
simon.fraser@apple.com823f73c2010-01-16 05:07:42 +0000879
akling@apple.comc68fe752013-10-13 18:39:27 +0000880 // The reflection layer has the bounds of m_owningLayer.reflectionLayer(),
simon.fraser@apple.com823f73c2010-01-16 05:07:42 +0000881 // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
simon.fraser@apple.com498c8482010-01-19 22:18:22 +0000882 FloatRect layerBounds = compositedBounds();
883 FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
commit-queue@webkit.org444304f2013-01-08 06:07:55 +0000884 reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location()));
simon.fraser@apple.com823f73c2010-01-16 05:07:42 +0000885 }
886
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000887 if (m_scrollingLayer) {
888 ASSERT(m_scrollingContentsLayer);
cdumez@apple.com0abff8b2014-10-17 21:25:10 +0000889 auto& renderBox = downcast<RenderBox>(renderer());
zalan@apple.com5e034f62014-02-20 23:04:20 +0000890 LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
891 LayoutSize scrollOffset = m_owningLayer.scrollOffset();
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000892
simon.fraser@apple.comd6d9d642014-05-01 02:15:17 +0000893 // FIXME: need to do some pixel snapping here.
commit-queue@webkit.org444304f2013-01-08 06:07:55 +0000894 m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - localCompositingBounds.location()));
tonikitoo@webkit.org94cb8dd2012-09-04 21:10:32 +0000895
simon.fraser@apple.comd6d9d642014-05-01 02:15:17 +0000896 IntSize pixelSnappedClientSize(renderBox.pixelSnappedClientWidth(), renderBox.pixelSnappedClientHeight());
897 m_scrollingLayer->setSize(pixelSnappedClientSize);
dbates@webkit.org395fca72013-12-06 19:59:38 +0000898#if PLATFORM(IOS)
zalan@apple.com545c48a2014-02-20 05:02:37 +0000899 FloatSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
zalan@apple.com5e034f62014-02-20 23:04:20 +0000900 m_scrollingLayer->setOffsetFromRenderer(FloatPoint() - paddingBox.location());
dbates@webkit.org395fca72013-12-06 19:59:38 +0000901 bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
902
903 if (m_owningLayer.isInUserScroll()) {
simon.fraser@apple.comc1a4d462014-05-06 01:10:30 +0000904 // If scrolling is happening externally, we don't want to touch the layer bounds origin here because that will cause jitter.
905 m_scrollingLayer->syncBoundsOrigin(FloatPoint(scrollOffset.width(), scrollOffset.height()));
dbates@webkit.org395fca72013-12-06 19:59:38 +0000906 m_owningLayer.setRequiresScrollBoundsOriginUpdate(true);
907 } else {
908 // Note that we implement the contents offset via the bounds origin on this layer, rather than a position on the sublayer.
909 m_scrollingLayer->setBoundsOrigin(FloatPoint(scrollOffset.width(), scrollOffset.height()));
910 m_owningLayer.setRequiresScrollBoundsOriginUpdate(false);
911 }
912
913 IntSize scrollSize(m_owningLayer.scrollWidth(), m_owningLayer.scrollHeight());
914
915 m_scrollingContentsLayer->setPosition(FloatPoint());
916
917 if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
918 m_scrollingContentsLayer->setNeedsDisplay();
919
920 m_scrollingContentsLayer->setSize(scrollSize);
921 // Scrolling the content layer does not need to trigger a repaint. The offset will be compensated away during painting.
922 // FIXME: The paint offset and the scroll offset should really be separate concepts.
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +0000923 m_scrollingContentsLayer->setOffsetFromRenderer(paddingBox.location() - IntPoint() - scrollOffset, GraphicsLayer::DontSetNeedsDisplay);
dbates@webkit.org395fca72013-12-06 19:59:38 +0000924#else
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000925 m_scrollingContentsLayer->setPosition(FloatPoint(-scrollOffset.width(), -scrollOffset.height()));
926
zalan@apple.com545c48a2014-02-20 05:02:37 +0000927 FloatSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
zalan@apple.com5e034f62014-02-20 23:04:20 +0000928 m_scrollingLayer->setOffsetFromRenderer(-toFloatSize(paddingBox.location()));
tonikitoo@webkit.org94cb8dd2012-09-04 21:10:32 +0000929
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000930 bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
931
akling@apple.comc68fe752013-10-13 18:39:27 +0000932 IntSize scrollSize(m_owningLayer.scrollWidth(), m_owningLayer.scrollHeight());
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000933 if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
934 m_scrollingContentsLayer->setNeedsDisplay();
935
zalan@apple.com5e034f62014-02-20 23:04:20 +0000936 LayoutSize scrollingContentsOffset = toLayoutSize(paddingBox.location() - scrollOffset);
commit-queue@webkit.orgc0328312012-09-04 18:54:00 +0000937 if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size())
akling@apple.comc68fe752013-10-13 18:39:27 +0000938 compositor().scrollingLayerDidChange(m_owningLayer);
commit-queue@webkit.orgc0328312012-09-04 18:54:00 +0000939
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000940 m_scrollingContentsLayer->setSize(scrollSize);
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000941 // FIXME: The paint offset and the scroll offset should really be separate concepts.
commit-queue@webkit.orge7dc60c2012-11-14 18:51:51 +0000942 m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
dbates@webkit.org395fca72013-12-06 19:59:38 +0000943#endif
vollick@chromium.org0015c122013-03-07 14:00:57 +0000944
945 if (m_foregroundLayer) {
simon.fraser@apple.combd93c752013-08-23 00:28:48 +0000946 m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
vollick@chromium.org0015c122013-03-07 14:00:57 +0000947 m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer());
948 }
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +0000949 }
950
simon.fraser@apple.comb7cec682012-04-16 18:32:13 +0000951 // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store.
zalan@apple.com5e034f62014-02-20 23:04:20 +0000952 setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compAncestor, enclosingRelativeCompositingBounds, ancestorCompositingBounds));
simon.fraser@apple.comb7cec682012-04-16 18:32:13 +0000953
simon.fraser@apple.comd305a892014-05-19 18:33:26 +0000954 updateAfterWidgetResize();
955
956 compositor().updateScrollCoordinatedStatus(m_owningLayer);
957}
958
mihnea@adobe.com5bdad312014-09-22 07:08:42 +0000959void RenderLayerBacking::updateAfterDescendants()
simon.fraser@apple.comd305a892014-05-19 18:33:26 +0000960{
simon.fraser@apple.com3547efb2014-09-05 00:23:05 +0000961 bool isSimpleContainer = false;
962 if (!m_owningLayer.isRootLayer()) {
963 bool didUpdateContentsRect = false;
964 // FIXME: this duplicates work we did in updateConfiguration().
965 isSimpleContainer = isSimpleContainerCompositingLayer();
966 updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
967 if (!didUpdateContentsRect && m_graphicsLayer->usesContentsLayer())
968 resetContentsRect();
969 }
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +0000970
commit-queue@webkit.org90f15662012-12-08 23:46:05 +0000971 updateDrawsContent(isSimpleContainer);
simon.fraser@apple.comf5323c12014-01-31 05:42:27 +0000972
simon.fraser@apple.comd305a892014-05-19 18:33:26 +0000973 m_graphicsLayer->setContentsVisible(m_owningLayer.hasVisibleContent() || isPaintDestinationForDescendentLayers());
simon.fraser@apple.come6ad1f62013-01-15 23:46:18 +0000974}
975
zalan@apple.com545c48a2014-02-20 05:02:37 +0000976void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(LayoutRect& ancestorCompositingBounds, const RenderLayer* compositingAncestor) const
commit-queue@webkit.org83e19482013-10-21 19:38:30 +0000977{
978 if (!m_owningLayer.isInsideFlowThread())
979 return;
980
hyatt@apple.combcde3b42014-04-29 22:59:26 +0000981 RenderLayer* flowThreadLayer = m_owningLayer.isInsideOutOfFlowThread() ? m_owningLayer.stackingContainer() : nullptr;
commit-queue@webkit.org83e19482013-10-21 19:38:30 +0000982 if (flowThreadLayer && flowThreadLayer->isRenderFlowThread()) {
commit-queue@webkit.org83e19482013-10-21 19:38:30 +0000983 if (m_owningLayer.isFlowThreadCollectingGraphicsLayersUnderRegions()) {
984 // The RenderNamedFlowThread is not composited, as we need it to paint the
985 // background layer of the regions. We need to compensate for that by manually
986 // subtracting the position of the flow-thread.
987 IntPoint flowPosition;
988 flowThreadLayer->convertToPixelSnappedLayerCoords(compositingAncestor, flowPosition);
989 ancestorCompositingBounds.moveBy(flowPosition);
990 }
991
992 // Move the ancestor position at the top of the region where the composited layer is going to display.
cdumez@apple.comdd2b64a2014-10-10 15:49:24 +0000993 RenderFlowThread& flowThread = downcast<RenderFlowThread>(flowThreadLayer->renderer());
commit-queue@webkit.org83e19482013-10-21 19:38:30 +0000994 RenderNamedFlowFragment* parentRegion = flowThread.cachedRegionForCompositedLayer(m_owningLayer);
commit-queue@webkit.org4affaa02014-01-23 14:19:54 +0000995 if (!parentRegion)
996 return;
997
998 IntPoint flowDelta;
999 m_owningLayer.convertToPixelSnappedLayerCoords(flowThreadLayer, flowDelta);
mihnea@adobe.com3a877582014-10-09 06:34:46 +00001000 parentRegion->adjustRegionBoundsFromFlowThreadPortionRect(ancestorCompositingBounds);
cdumez@apple.comdd2b64a2014-10-10 15:49:24 +00001001 RenderBoxModelObject& layerOwner = downcast<RenderBoxModelObject>(parentRegion->layerOwner());
commit-queue@webkit.org4affaa02014-01-23 14:19:54 +00001002 RenderLayerBacking* layerOwnerBacking = layerOwner.layer()->backing();
1003 if (!layerOwnerBacking)
1004 return;
1005
1006 // Make sure that the region propagates its borders, paddings, outlines or box-shadows to layers inside it.
1007 // Note that the composited bounds of the RenderRegion are already calculated because
1008 // RenderLayerCompositor::rebuildCompositingLayerTree will only iterate on the content of the region after the
1009 // region itself is computed.
1010 ancestorCompositingBounds.moveBy(roundedIntPoint(layerOwnerBacking->compositedBounds().location()));
1011 ancestorCompositingBounds.move(-layerOwner.borderAndPaddingStart(), -layerOwner.borderAndPaddingBefore());
1012
1013 // If there's a clipping GraphicsLayer on the hierarchy (region graphics layer -> clipping graphics layer ->
1014 // composited content graphics layer), substract the offset of the clipping layer, since it's its parent
1015 // that positions us (the graphics layer of the region).
1016 if (layerOwnerBacking->clippingLayer())
1017 ancestorCompositingBounds.moveBy(roundedIntPoint(layerOwnerBacking->clippingLayer()->position()));
commit-queue@webkit.org83e19482013-10-21 19:38:30 +00001018 }
1019}
1020
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001021void RenderLayerBacking::updateDirectlyCompositedContents(bool isSimpleContainer, bool& didUpdateContentsRect)
1022{
akling@apple.comc68fe752013-10-13 18:39:27 +00001023 if (!m_owningLayer.hasVisibleContent())
commit-queue@webkit.org845ae1d2013-05-24 16:34:46 +00001024 return;
1025
noam.rosenthal@nokia.com0ffc7802013-05-25 09:51:25 +00001026 // The order of operations here matters, since the last valid type of contents needs
1027 // to also update the contentsRect.
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001028 updateDirectlyCompositedBackgroundColor(isSimpleContainer, didUpdateContentsRect);
noam.rosenthal@nokia.com0ffc7802013-05-25 09:51:25 +00001029 updateDirectlyCompositedBackgroundImage(isSimpleContainer, didUpdateContentsRect);
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001030}
1031
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001032void RenderLayerBacking::updateInternalHierarchy()
1033{
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00001034 // m_foregroundLayer has to be inserted in the correct order with child layers,
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001035 // so it's not inserted here.
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001036 if (m_ancestorClippingLayer)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001037 m_ancestorClippingLayer->removeAllChildren();
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001038
1039 if (m_contentsContainmentLayer) {
1040 m_contentsContainmentLayer->removeAllChildren();
1041 if (m_ancestorClippingLayer)
1042 m_ancestorClippingLayer->addChild(m_contentsContainmentLayer.get());
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001043 }
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001044
1045 if (m_backgroundLayer)
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00001046 m_contentsContainmentLayer->addChild(m_backgroundLayer.get());
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001047
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001048 if (m_contentsContainmentLayer)
1049 m_contentsContainmentLayer->addChild(m_graphicsLayer.get());
1050 else if (m_ancestorClippingLayer)
1051 m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001052
simon.fraser@apple.com632ced12013-01-15 23:17:01 +00001053 if (m_childContainmentLayer) {
1054 m_childContainmentLayer->removeFromParent();
1055 m_graphicsLayer->addChild(m_childContainmentLayer.get());
enne@google.com30eba0c2012-06-19 03:04:50 +00001056 }
jamesr@google.come53ce642011-04-14 06:51:50 +00001057
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001058 if (m_scrollingLayer) {
simon.fraser@apple.com632ced12013-01-15 23:17:01 +00001059 GraphicsLayer* superlayer = m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001060 m_scrollingLayer->removeFromParent();
1061 superlayer->addChild(m_scrollingLayer.get());
1062 }
1063
enne@google.com30eba0c2012-06-19 03:04:50 +00001064 // The clip for child layers does not include space for overflow controls, so they exist as
1065 // siblings of the clipping layer if we have one. Normal children of this layer are set as
1066 // children of the clipping layer.
1067 if (m_layerForHorizontalScrollbar) {
1068 m_layerForHorizontalScrollbar->removeFromParent();
1069 m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
1070 }
1071 if (m_layerForVerticalScrollbar) {
1072 m_layerForVerticalScrollbar->removeFromParent();
1073 m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
1074 }
1075 if (m_layerForScrollCorner) {
1076 m_layerForScrollCorner->removeFromParent();
1077 m_graphicsLayer->addChild(m_layerForScrollCorner.get());
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001078 }
1079}
1080
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001081void RenderLayerBacking::resetContentsRect()
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001082{
zalan@apple.com376339c2014-08-28 04:24:31 +00001083 m_graphicsLayer->setContentsRect(snappedIntRect(contentsBox()));
simon.fraser@apple.coma0dfed962013-08-31 00:14:41 +00001084
1085 LayoutRect contentsClippingRect;
cdumez@apple.com0abff8b2014-10-17 21:25:10 +00001086 if (is<RenderBox>(renderer()))
1087 contentsClippingRect = downcast<RenderBox>(renderer()).contentBoxRect();
simon.fraser@apple.coma0dfed962013-08-31 00:14:41 +00001088
1089 contentsClippingRect.move(contentOffsetInCompostingLayer());
zalan@apple.com376339c2014-08-28 04:24:31 +00001090 m_graphicsLayer->setContentsClippingRect(snappedIntRect(contentsClippingRect));
simon.fraser@apple.coma0dfed962013-08-31 00:14:41 +00001091
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001092 m_graphicsLayer->setContentsTileSize(IntSize());
1093 m_graphicsLayer->setContentsTilePhase(IntPoint());
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001094}
1095
simon.fraser@apple.comc0c558c2010-05-11 05:44:06 +00001096void RenderLayerBacking::updateDrawsContent()
1097{
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001098 updateDrawsContent(isSimpleContainerCompositingLayer());
1099}
1100
1101void RenderLayerBacking::updateDrawsContent(bool isSimpleContainer)
1102{
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001103 if (m_scrollingLayer) {
1104 // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
1105 // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
1106 // m_scrollingLayer never has backing store.
1107 // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
akling@apple.comc68fe752013-10-13 18:39:27 +00001108 bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasBoxDecorationsOrBackground();
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001109 m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
1110
akling@apple.comc68fe752013-10-13 18:39:27 +00001111 bool hasScrollingPaintedContent = m_owningLayer.hasVisibleContent() && (renderer().hasBackground() || paintsChildren());
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001112 m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
1113 return;
1114 }
1115
simon.fraser@apple.com9ca8cf72013-06-29 20:22:19 +00001116 bool hasPaintedContent = containsPaintedContent(isSimpleContainer);
simon.fraser@apple.comc0fc3132012-04-18 16:17:04 +00001117
1118 // FIXME: we could refine this to only allocate backing for one of these layers if possible.
1119 m_graphicsLayer->setDrawsContent(hasPaintedContent);
1120 if (m_foregroundLayer)
1121 m_foregroundLayer->setDrawsContent(hasPaintedContent);
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00001122
1123 if (m_backgroundLayer)
1124 m_backgroundLayer->setDrawsContent(hasPaintedContent);
simon.fraser@apple.comc0c558c2010-05-11 05:44:06 +00001125}
1126
zalan@apple.comc3d72182013-09-12 14:03:21 +00001127// Return true if the layer changed.
1128bool RenderLayerBacking::updateAncestorClippingLayer(bool needsAncestorClip)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001129{
1130 bool layersChanged = false;
1131
1132 if (needsAncestorClip) {
1133 if (!m_ancestorClippingLayer) {
simon.fraser@apple.comec223212011-07-13 21:57:57 +00001134 m_ancestorClippingLayer = createGraphicsLayer("Ancestor clipping Layer");
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001135 m_ancestorClippingLayer->setMasksToBounds(true);
1136 layersChanged = true;
1137 }
zalan@apple.comc3d72182013-09-12 14:03:21 +00001138 } else if (hasAncestorClippingLayer()) {
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001139 willDestroyLayer(m_ancestorClippingLayer.get());
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001140 m_ancestorClippingLayer->removeFromParent();
abarth@webkit.org462d90a2011-04-27 21:25:22 +00001141 m_ancestorClippingLayer = nullptr;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001142 layersChanged = true;
1143 }
1144
zalan@apple.comc3d72182013-09-12 14:03:21 +00001145 return layersChanged;
1146}
1147
1148// Return true if the layer changed.
1149bool RenderLayerBacking::updateDescendantClippingLayer(bool needsDescendantClip)
1150{
1151 bool layersChanged = false;
1152
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001153 if (needsDescendantClip) {
simon.fraser@apple.com632ced12013-01-15 23:17:01 +00001154 if (!m_childContainmentLayer && !m_usingTiledCacheLayer) {
1155 m_childContainmentLayer = createGraphicsLayer("Child clipping Layer");
1156 m_childContainmentLayer->setMasksToBounds(true);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001157 layersChanged = true;
1158 }
dino@apple.comeebfa9062012-07-09 20:36:21 +00001159 } else if (hasClippingLayer()) {
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001160 willDestroyLayer(m_childContainmentLayer.get());
simon.fraser@apple.com632ced12013-01-15 23:17:01 +00001161 m_childContainmentLayer->removeFromParent();
1162 m_childContainmentLayer = nullptr;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001163 layersChanged = true;
1164 }
1165
jamesr@google.come53ce642011-04-14 06:51:50 +00001166 return layersChanged;
1167}
1168
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00001169void RenderLayerBacking::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
1170{
1171 m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
1172}
1173
jamesr@google.come53ce642011-04-14 06:51:50 +00001174bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
1175{
akling@apple.comc68fe752013-10-13 18:39:27 +00001176 if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
jamesr@google.come53ce642011-04-14 06:51:50 +00001177 return false;
akling@apple.comc68fe752013-10-13 18:39:27 +00001178 return m_owningLayer.horizontalScrollbar();
jamesr@google.come53ce642011-04-14 06:51:50 +00001179}
1180
1181bool RenderLayerBacking::requiresVerticalScrollbarLayer() const
1182{
akling@apple.comc68fe752013-10-13 18:39:27 +00001183 if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
jamesr@google.come53ce642011-04-14 06:51:50 +00001184 return false;
akling@apple.comc68fe752013-10-13 18:39:27 +00001185 return m_owningLayer.verticalScrollbar();
jamesr@google.come53ce642011-04-14 06:51:50 +00001186}
1187
1188bool RenderLayerBacking::requiresScrollCornerLayer() const
1189{
akling@apple.comc68fe752013-10-13 18:39:27 +00001190 if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
jamesr@google.come53ce642011-04-14 06:51:50 +00001191 return false;
akling@apple.comc68fe752013-10-13 18:39:27 +00001192 return !m_owningLayer.scrollCornerAndResizerRect().isEmpty();
jamesr@google.come53ce642011-04-14 06:51:50 +00001193}
1194
1195bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
1196{
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001197 bool horizontalScrollbarLayerChanged = false;
jamesr@google.come53ce642011-04-14 06:51:50 +00001198 if (needsHorizontalScrollbarLayer) {
1199 if (!m_layerForHorizontalScrollbar) {
simon.fraser@apple.comec223212011-07-13 21:57:57 +00001200 m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar");
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001201 horizontalScrollbarLayerChanged = true;
jamesr@google.come53ce642011-04-14 06:51:50 +00001202 }
1203 } else if (m_layerForHorizontalScrollbar) {
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001204 willDestroyLayer(m_layerForHorizontalScrollbar.get());
1205 m_layerForHorizontalScrollbar = nullptr;
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001206 horizontalScrollbarLayerChanged = true;
jamesr@google.come53ce642011-04-14 06:51:50 +00001207 }
1208
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001209 bool verticalScrollbarLayerChanged = false;
jamesr@google.come53ce642011-04-14 06:51:50 +00001210 if (needsVerticalScrollbarLayer) {
1211 if (!m_layerForVerticalScrollbar) {
simon.fraser@apple.comec223212011-07-13 21:57:57 +00001212 m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar");
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001213 verticalScrollbarLayerChanged = true;
jamesr@google.come53ce642011-04-14 06:51:50 +00001214 }
1215 } else if (m_layerForVerticalScrollbar) {
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001216 willDestroyLayer(m_layerForVerticalScrollbar.get());
1217 m_layerForVerticalScrollbar = nullptr;
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001218 verticalScrollbarLayerChanged = true;
jamesr@google.come53ce642011-04-14 06:51:50 +00001219 }
1220
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001221 bool scrollCornerLayerChanged = false;
jamesr@google.come53ce642011-04-14 06:51:50 +00001222 if (needsScrollCornerLayer) {
1223 if (!m_layerForScrollCorner) {
simon.fraser@apple.comec223212011-07-13 21:57:57 +00001224 m_layerForScrollCorner = createGraphicsLayer("scroll corner");
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001225 scrollCornerLayerChanged = true;
jamesr@google.come53ce642011-04-14 06:51:50 +00001226 }
1227 } else if (m_layerForScrollCorner) {
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001228 willDestroyLayer(m_layerForScrollCorner.get());
1229 m_layerForScrollCorner = nullptr;
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001230 scrollCornerLayerChanged = true;
jamesr@google.come53ce642011-04-14 06:51:50 +00001231 }
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001232
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001233 if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
1234 if (horizontalScrollbarLayerChanged)
akling@apple.comc68fe752013-10-13 18:39:27 +00001235 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_owningLayer, HorizontalScrollbar);
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001236 if (verticalScrollbarLayerChanged)
akling@apple.comc68fe752013-10-13 18:39:27 +00001237 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_owningLayer, VerticalScrollbar);
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001238 }
1239
1240 return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001241}
1242
simon.fraser@apple.com1c06cdd2013-11-12 00:50:29 +00001243void RenderLayerBacking::positionOverflowControlsLayers()
simon.fraser@apple.com4030b0a2012-09-08 00:48:40 +00001244{
simon.fraser@apple.com1c06cdd2013-11-12 00:50:29 +00001245 if (!m_owningLayer.hasScrollbars())
1246 return;
1247
cdumez@apple.com0abff8b2014-10-17 21:25:10 +00001248 const IntRect borderBox = downcast<RenderBox>(renderer()).pixelSnappedBorderBoxRect();
simon.fraser@apple.com1c06cdd2013-11-12 00:50:29 +00001249
zalan@apple.com545c48a2014-02-20 05:02:37 +00001250 FloatSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
simon.fraser@apple.com4030b0a2012-09-08 00:48:40 +00001251 if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
simon.fraser@apple.com1c06cdd2013-11-12 00:50:29 +00001252 IntRect hBarRect = m_owningLayer.rectForHorizontalScrollbar(borderBox);
1253 layer->setPosition(hBarRect.location() - offsetFromRenderer);
1254 layer->setSize(hBarRect.size());
simon.fraser@apple.comff549312014-04-19 05:31:39 +00001255 if (layer->usesContentsLayer()) {
simon.fraser@apple.com1c06cdd2013-11-12 00:50:29 +00001256 IntRect barRect = IntRect(IntPoint(), hBarRect.size());
1257 layer->setContentsRect(barRect);
1258 layer->setContentsClippingRect(barRect);
simon.fraser@apple.com4030b0a2012-09-08 00:48:40 +00001259 }
simon.fraser@apple.comff549312014-04-19 05:31:39 +00001260 layer->setDrawsContent(m_owningLayer.horizontalScrollbar() && !layer->usesContentsLayer());
simon.fraser@apple.com4030b0a2012-09-08 00:48:40 +00001261 }
1262
1263 if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
simon.fraser@apple.com1c06cdd2013-11-12 00:50:29 +00001264 IntRect vBarRect = m_owningLayer.rectForVerticalScrollbar(borderBox);
1265 layer->setPosition(vBarRect.location() - offsetFromRenderer);
1266 layer->setSize(vBarRect.size());
simon.fraser@apple.comff549312014-04-19 05:31:39 +00001267 if (layer->usesContentsLayer()) {
simon.fraser@apple.com1c06cdd2013-11-12 00:50:29 +00001268 IntRect barRect = IntRect(IntPoint(), vBarRect.size());
1269 layer->setContentsRect(barRect);
1270 layer->setContentsClippingRect(barRect);
simon.fraser@apple.com4030b0a2012-09-08 00:48:40 +00001271 }
simon.fraser@apple.comff549312014-04-19 05:31:39 +00001272 layer->setDrawsContent(m_owningLayer.verticalScrollbar() && !layer->usesContentsLayer());
simon.fraser@apple.com4030b0a2012-09-08 00:48:40 +00001273 }
1274
1275 if (GraphicsLayer* layer = layerForScrollCorner()) {
akling@apple.comc68fe752013-10-13 18:39:27 +00001276 const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
simon.fraser@apple.com4030b0a2012-09-08 00:48:40 +00001277 layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
1278 layer->setSize(scrollCornerAndResizer.size());
1279 layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
1280 }
1281}
1282
vollick@chromium.org013915f2012-12-16 02:07:57 +00001283bool RenderLayerBacking::hasUnpositionedOverflowControlsLayers() const
1284{
1285 if (GraphicsLayer* layer = layerForHorizontalScrollbar())
1286 if (!layer->drawsContent())
1287 return true;
1288
1289 if (GraphicsLayer* layer = layerForVerticalScrollbar())
1290 if (!layer->drawsContent())
1291 return true;
1292
1293 if (GraphicsLayer* layer = layerForScrollCorner())
1294 if (!layer->drawsContent())
1295 return true;
1296
1297 return false;
1298}
1299
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00001300bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001301{
1302 bool layerChanged = false;
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00001303 if (needsForegroundLayer) {
1304 if (!m_foregroundLayer) {
simon.fraser@apple.comec223212011-07-13 21:57:57 +00001305 String layerName;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001306#ifndef NDEBUG
akling@apple.comc68fe752013-10-13 18:39:27 +00001307 layerName = m_owningLayer.name() + " (foreground)";
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001308#endif
simon.fraser@apple.comec223212011-07-13 21:57:57 +00001309 m_foregroundLayer = createGraphicsLayer(layerName);
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00001310 m_foregroundLayer->setDrawsContent(true);
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001311 m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001312 layerChanged = true;
1313 }
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00001314 } else if (m_foregroundLayer) {
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001315 willDestroyLayer(m_foregroundLayer.get());
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00001316 m_foregroundLayer->removeFromParent();
abarth@webkit.org462d90a2011-04-27 21:25:22 +00001317 m_foregroundLayer = nullptr;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001318 layerChanged = true;
1319 }
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001320
simon.fraser@apple.com6c21fd52013-05-16 23:57:46 +00001321 if (layerChanged) {
1322 m_graphicsLayer->setNeedsDisplay();
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001323 m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
simon.fraser@apple.com6c21fd52013-05-16 23:57:46 +00001324 }
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001325
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001326 return layerChanged;
1327}
1328
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001329bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
1330{
1331 bool layerChanged = false;
1332 if (needsBackgroundLayer) {
1333 if (!m_backgroundLayer) {
1334 String layerName;
1335#ifndef NDEBUG
akling@apple.comc68fe752013-10-13 18:39:27 +00001336 layerName = m_owningLayer.name() + " (background)";
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001337#endif
1338 m_backgroundLayer = createGraphicsLayer(layerName);
1339 m_backgroundLayer->setDrawsContent(true);
1340 m_backgroundLayer->setAnchorPoint(FloatPoint3D());
1341 m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
1342 layerChanged = true;
1343 }
1344
1345 if (!m_contentsContainmentLayer) {
1346 String layerName;
1347#ifndef NDEBUG
akling@apple.comc68fe752013-10-13 18:39:27 +00001348 layerName = m_owningLayer.name() + " (contents containment)";
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001349#endif
1350 m_contentsContainmentLayer = createGraphicsLayer(layerName);
1351 m_contentsContainmentLayer->setAppliesPageScale(true);
1352 m_graphicsLayer->setAppliesPageScale(false);
1353 layerChanged = true;
1354 }
1355 } else {
1356 if (m_backgroundLayer) {
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001357 willDestroyLayer(m_backgroundLayer.get());
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001358 m_backgroundLayer->removeFromParent();
1359 m_backgroundLayer = nullptr;
1360 layerChanged = true;
1361 }
1362 if (m_contentsContainmentLayer) {
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001363 willDestroyLayer(m_contentsContainmentLayer.get());
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001364 m_contentsContainmentLayer->removeFromParent();
1365 m_contentsContainmentLayer = nullptr;
1366 layerChanged = true;
1367 m_graphicsLayer->setAppliesPageScale(true);
1368 }
1369 }
simon.fraser@apple.coma5614962013-01-19 01:20:32 +00001370
1371 if (layerChanged) {
simon.fraser@apple.com6c21fd52013-05-16 23:57:46 +00001372 m_graphicsLayer->setNeedsDisplay();
simon.fraser@apple.coma5614962013-01-19 01:20:32 +00001373 // This assumes that the background layer is only used for fixed backgrounds, which is currently a correct assumption.
akling@apple.comc3466042013-08-24 18:27:32 +00001374 compositor().fixedRootBackgroundLayerChanged();
simon.fraser@apple.coma5614962013-01-19 01:20:32 +00001375 }
1376
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001377 return layerChanged;
1378}
1379
simon.fraser@apple.com0749dee2014-06-20 20:56:16 +00001380void RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001381{
1382 bool layerChanged = false;
1383 if (needsMaskLayer) {
1384 if (!m_maskLayer) {
simon.fraser@apple.comec223212011-07-13 21:57:57 +00001385 m_maskLayer = createGraphicsLayer("Mask");
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001386 m_maskLayer->setDrawsContent(true);
1387 m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
1388 layerChanged = true;
simon.fraser@apple.com0749dee2014-06-20 20:56:16 +00001389 m_graphicsLayer->setMaskLayer(m_maskLayer.get());
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001390 }
1391 } else if (m_maskLayer) {
simon.fraser@apple.com0749dee2014-06-20 20:56:16 +00001392 m_graphicsLayer->setMaskLayer(nullptr);
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001393 willDestroyLayer(m_maskLayer.get());
abarth@webkit.org462d90a2011-04-27 21:25:22 +00001394 m_maskLayer = nullptr;
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001395 layerChanged = true;
1396 }
1397
1398 if (layerChanged)
1399 m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001400}
1401
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001402bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
1403{
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +00001404 if (needsScrollingLayers == !!m_scrollingLayer)
1405 return false;
commit-queue@webkit.orgb93f5c82013-02-26 09:13:32 +00001406
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +00001407 if (!m_scrollingLayer) {
1408 // Outer layer which corresponds with the scroll view.
1409 m_scrollingLayer = createGraphicsLayer("Scrolling container");
1410 m_scrollingLayer->setDrawsContent(false);
1411 m_scrollingLayer->setMasksToBounds(true);
simon.fraser@apple.com405bbce12014-03-26 19:36:49 +00001412#if PLATFORM(IOS)
1413 m_scrollingLayer->setCustomBehavior(GraphicsLayer::CustomScrollingBehavior);
1414#endif
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +00001415 // Inner layer which renders the content that scrolls.
1416 m_scrollingContentsLayer = createGraphicsLayer("Scrolled Contents");
1417 m_scrollingContentsLayer->setDrawsContent(true);
simon.fraser@apple.com523dffe2014-05-07 21:49:10 +00001418#if PLATFORM(IOS)
1419 m_scrollingContentsLayer->setCustomBehavior(GraphicsLayer::CustomScrolledContentsBehavior);
1420#endif
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +00001421 GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
1422 if (!m_foregroundLayer)
1423 paintPhase |= GraphicsLayerPaintForeground;
1424 m_scrollingContentsLayer->setPaintingPhase(paintPhase);
1425 m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
1426 } else {
jhoneycutt@apple.com84b8a852014-07-03 04:25:27 +00001427 compositor().willRemoveScrollingLayerWithBacking(m_owningLayer, *this);
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001428
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00001429 willDestroyLayer(m_scrollingLayer.get());
1430 willDestroyLayer(m_scrollingContentsLayer.get());
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001431 m_scrollingLayer = nullptr;
1432 m_scrollingContentsLayer = nullptr;
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001433 }
1434
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +00001435 m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1436 m_graphicsLayer->setNeedsDisplay(); // Because painting phases changed.
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001437
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +00001438 if (m_scrollingLayer)
1439 compositor().didAddScrollingLayer(m_owningLayer);
1440
1441 return true;
bdakin@apple.com0643c9f2012-10-09 18:47:49 +00001442}
1443
1444void RenderLayerBacking::detachFromScrollingCoordinator()
1445{
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +00001446 if (!m_scrollingNodeID && !m_viewportConstrainedNodeID)
bdakin@apple.com0643c9f2012-10-09 18:47:49 +00001447 return;
1448
simon.fraser@apple.come6ad1f62013-01-15 23:46:18 +00001449 ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
bdakin@apple.com0643c9f2012-10-09 18:47:49 +00001450 if (!scrollingCoordinator)
1451 return;
1452
simon.fraser@apple.com2cd0f452014-02-27 01:04:23 +00001453 if (m_scrollingNodeID)
1454 scrollingCoordinator->detachFromStateTree(m_scrollingNodeID);
1455
1456 if (m_viewportConstrainedNodeID)
1457 scrollingCoordinator->detachFromStateTree(m_viewportConstrainedNodeID);
1458
1459 m_scrollingNodeID = 0;
1460 m_viewportConstrainedNodeID = 0;
bdakin@apple.com0643c9f2012-10-09 18:47:49 +00001461}
1462
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001463GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
1464{
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00001465 unsigned phase = 0;
1466 if (!m_backgroundLayer)
1467 phase |= GraphicsLayerPaintBackground;
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001468 if (!m_foregroundLayer)
1469 phase |= GraphicsLayerPaintForeground;
1470 if (!m_maskLayer)
1471 phase |= GraphicsLayerPaintMask;
1472
vollick@chromium.org0015c122013-03-07 14:00:57 +00001473 if (m_scrollingContentsLayer) {
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001474 phase &= ~GraphicsLayerPaintForeground;
vollick@chromium.org0015c122013-03-07 14:00:57 +00001475 phase |= GraphicsLayerPaintCompositedScroll;
1476 }
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001477
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00001478 return static_cast<GraphicsLayerPaintingPhase>(phase);
1479}
1480
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001481float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
1482{
1483 float finalOpacity = rendererOpacity;
1484
akling@apple.comc68fe752013-10-13 18:39:27 +00001485 for (RenderLayer* curr = m_owningLayer.parent(); curr; curr = curr->parent()) {
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001486 // We only care about parents that are stacking contexts.
1487 // Recall that opacity creates stacking context.
vollick@chromium.org04ba77c2013-01-24 01:42:08 +00001488 if (!curr->isStackingContainer())
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001489 continue;
1490
1491 // If we found a compositing layer, we want to compute opacity
1492 // relative to it. So we can break here.
1493 if (curr->isComposited())
1494 break;
1495
akling@apple.comc34ed272013-08-26 01:02:34 +00001496 finalOpacity *= curr->renderer().opacity();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001497 }
1498
1499 return finalOpacity;
1500}
1501
simon.fraser@apple.come6e085e2014-09-02 18:30:06 +00001502// FIXME: Code is duplicated in RenderLayer. Also, we should probably not consider filters a box decoration here.
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001503static inline bool hasBoxDecorations(const RenderStyle& style)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001504{
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001505 return style.hasBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001506}
1507
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001508static bool canCreateTiledImage(const RenderStyle& style)
1509{
1510 const FillLayer* fillLayer = style.backgroundLayers();
1511 if (fillLayer->next())
1512 return false;
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001513
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001514 if (!fillLayer->imagesAreLoaded())
1515 return false;
1516
1517 if (fillLayer->attachment() != ScrollBackgroundAttachment)
1518 return false;
1519
1520 Color color = style.visitedDependentColor(CSSPropertyBackgroundColor);
1521
1522 // FIXME: Allow color+image compositing when it makes sense.
1523 // For now bailing out.
1524 if (color.isValid() && color.alpha())
1525 return false;
1526
1527 StyleImage* styleImage = fillLayer->image();
1528
1529 // FIXME: support gradients with isGeneratedImage.
1530 if (!styleImage->isCachedImage())
1531 return false;
1532
1533 Image* image = styleImage->cachedImage()->image();
1534 if (!image->isBitmapImage())
1535 return false;
1536
1537 return true;
1538}
1539
1540static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle& style)
simon.fraser@apple.com3368e1c2009-03-27 01:12:01 +00001541{
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001542 if (hasBoxDecorations(style))
1543 return true;
1544
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001545 if (!style.hasBackgroundImage())
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001546 return false;
1547
1548 return !GraphicsLayer::supportsContentsTiling() || !canCreateTiledImage(style);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001549}
1550
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001551static inline bool hasPerspectiveOrPreserves3D(const RenderStyle& style)
dino@apple.comb0b80c02013-08-03 00:06:31 +00001552{
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001553 return style.hasPerspective() || style.preserves3D();
dino@apple.comb0b80c02013-08-03 00:06:31 +00001554}
1555
andreas.kling@nokia.com8bdba5972011-10-07 16:42:54 +00001556Color RenderLayerBacking::rendererBackgroundColor() const
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001557{
akling@apple.com227f10f2013-12-14 12:39:40 +00001558 const auto& backgroundRenderer = renderer().isRoot() ? renderer().rendererForRootBackground() : renderer();
1559 return backgroundRenderer.style().visitedDependentColor(CSSPropertyBackgroundColor);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001560}
1561
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001562void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(bool isSimpleContainer, bool& didUpdateContentsRect)
jer.noble@apple.com3352b632011-06-13 18:02:13 +00001563{
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001564 if (!isSimpleContainer) {
1565 m_graphicsLayer->setContentsToSolidColor(Color());
1566 return;
1567 }
1568
1569 Color backgroundColor = rendererBackgroundColor();
simon.fraser@apple.comfdfcc112012-12-15 19:11:44 +00001570
1571 // An unset (invalid) color will remove the solid color.
1572 m_graphicsLayer->setContentsToSolidColor(backgroundColor);
zalan@apple.com5b735c02014-03-09 00:14:00 +00001573 FloatRect contentsRect = backgroundBoxForPainting();
simon.fraser@apple.coma0dfed962013-08-31 00:14:41 +00001574 m_graphicsLayer->setContentsRect(contentsRect);
1575 m_graphicsLayer->setContentsClippingRect(contentsRect);
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001576 didUpdateContentsRect = true;
1577}
1578
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001579void RenderLayerBacking::updateDirectlyCompositedBackgroundImage(bool isSimpleContainer, bool& didUpdateContentsRect)
1580{
1581 if (!GraphicsLayer::supportsContentsTiling())
1582 return;
1583
commit-queue@webkit.orga68a54b2013-04-19 16:01:25 +00001584 if (isDirectlyCompositedImage())
1585 return;
1586
akling@apple.com827be9c2013-10-29 02:58:43 +00001587 const RenderStyle& style = renderer().style();
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001588
akling@apple.com827be9c2013-10-29 02:58:43 +00001589 if (!isSimpleContainer || !style.hasBackgroundImage()) {
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001590 m_graphicsLayer->setContentsToImage(0);
1591 return;
1592 }
1593
zalan@apple.comaa00cbd2014-04-04 16:30:18 +00001594 FloatRect destRect = backgroundBoxForPainting();
1595 FloatPoint phase;
1596 FloatSize tileSize;
commit-queue@webkit.org845ae1d2013-05-24 16:34:46 +00001597
akling@apple.com827be9c2013-10-29 02:58:43 +00001598 RefPtr<Image> image = style.backgroundLayers()->image()->cachedImage()->image();
cdumez@apple.com0abff8b2014-10-17 21:25:10 +00001599 downcast<RenderBox>(renderer()).getGeometryForBackgroundImage(&renderer(), destRect, phase, tileSize);
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001600 m_graphicsLayer->setContentsTileSize(tileSize);
1601 m_graphicsLayer->setContentsTilePhase(phase);
1602 m_graphicsLayer->setContentsRect(destRect);
simon.fraser@apple.coma0dfed962013-08-31 00:14:41 +00001603 m_graphicsLayer->setContentsClippingRect(destRect);
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001604 m_graphicsLayer->setContentsToImage(image.get());
1605 didUpdateContentsRect = true;
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001606}
1607
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00001608void RenderLayerBacking::updateRootLayerConfiguration()
1609{
1610 if (!m_usingTiledCacheLayer)
1611 return;
1612
1613 Color backgroundColor;
akling@apple.comc3466042013-08-24 18:27:32 +00001614 bool viewIsTransparent = compositor().viewHasTransparentBackground(&backgroundColor);
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00001615
1616 if (m_backgroundLayerPaintsFixedRootBackground && m_backgroundLayer) {
1617 m_backgroundLayer->setBackgroundColor(backgroundColor);
1618 m_backgroundLayer->setContentsOpaque(!viewIsTransparent);
1619
1620 m_graphicsLayer->setBackgroundColor(Color());
1621 m_graphicsLayer->setContentsOpaque(false);
1622 } else {
1623 m_graphicsLayer->setBackgroundColor(backgroundColor);
1624 m_graphicsLayer->setContentsOpaque(!viewIsTransparent);
1625 }
1626}
1627
akling@apple.comac253b12013-12-26 17:58:56 +00001628static bool supportsDirectBoxDecorationsComposition(const RenderLayerModelObject& renderer)
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001629{
1630 if (!GraphicsLayer::supportsBackgroundColorContent())
1631 return false;
1632
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001633 const RenderStyle& style = renderer.style();
akling@apple.com32c7a6e2013-08-26 02:21:32 +00001634 if (renderer.hasClip())
commit-queue@webkit.org38aff5602012-12-11 06:44:15 +00001635 return false;
1636
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001637 if (hasBoxDecorationsOrBackgroundImage(style))
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001638 return false;
1639
dino@apple.comb0b80c02013-08-03 00:06:31 +00001640 // FIXME: We can't create a directly composited background if this
1641 // layer will have children that intersect with the background layer.
1642 // A better solution might be to introduce a flattening layer if
1643 // we do direct box decoration composition.
1644 // https://bugs.webkit.org/show_bug.cgi?id=119461
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001645 if (hasPerspectiveOrPreserves3D(style))
dino@apple.comb0b80c02013-08-03 00:06:31 +00001646 return false;
1647
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001648 // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001649 if (style.backgroundComposite() != CompositeSourceOver)
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001650 return false;
1651
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001652 if (style.backgroundClip() == TextFillBox)
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001653 return false;
1654
1655 return true;
jer.noble@apple.com3352b632011-06-13 18:02:13 +00001656}
1657
simon.fraser@apple.com7cfe7612012-03-13 20:59:59 +00001658bool RenderLayerBacking::paintsBoxDecorations() const
1659{
akling@apple.comc68fe752013-10-13 18:39:27 +00001660 if (!m_owningLayer.hasVisibleBoxDecorations())
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001661 return false;
1662
1663 if (!supportsDirectBoxDecorationsComposition(renderer()))
simon.fraser@apple.com7cfe7612012-03-13 20:59:59 +00001664 return true;
1665
simon.fraser@apple.com7cfe7612012-03-13 20:59:59 +00001666 return false;
1667}
1668
1669bool RenderLayerBacking::paintsChildren() const
1670{
akling@apple.comc68fe752013-10-13 18:39:27 +00001671 if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers())
simon.fraser@apple.com7cfe7612012-03-13 20:59:59 +00001672 return true;
commit-queue@webkit.org845ae1d2013-05-24 16:34:46 +00001673
simon.fraser@apple.comd305a892014-05-19 18:33:26 +00001674 if (isPaintDestinationForDescendentLayers())
simon.fraser@apple.com7cfe7612012-03-13 20:59:59 +00001675 return true;
1676
1677 return false;
1678}
1679
cdumez@apple.com3abcc792014-10-20 03:42:03 +00001680static bool isRestartedPlugin(RenderObject& renderer)
dino@apple.com2e06ec82013-04-03 20:13:20 +00001681{
cdumez@apple.com3abcc792014-10-20 03:42:03 +00001682 if (!is<RenderEmbeddedObject>(renderer))
dino@apple.com2e06ec82013-04-03 20:13:20 +00001683 return false;
1684
cdumez@apple.com3abcc792014-10-20 03:42:03 +00001685 HTMLFrameOwnerElement& element = downcast<RenderEmbeddedObject>(renderer).frameOwnerElement();
cdumez@apple.coma9c60c92014-10-02 19:39:41 +00001686 if (!is<HTMLPlugInElement>(element))
dino@apple.com2e06ec82013-04-03 20:13:20 +00001687 return false;
1688
cdumez@apple.com3abcc792014-10-20 03:42:03 +00001689 return downcast<HTMLPlugInElement>(element).isRestartedPlugin();
dino@apple.com2e06ec82013-04-03 20:13:20 +00001690}
1691
cdumez@apple.com3abcc792014-10-20 03:42:03 +00001692static bool isCompositedPlugin(RenderObject& renderer)
simon.fraser@apple.com25a526b2012-08-08 22:17:34 +00001693{
cdumez@apple.com3abcc792014-10-20 03:42:03 +00001694 return is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing();
simon.fraser@apple.com25a526b2012-08-08 22:17:34 +00001695}
1696
simon.fraser@apple.com699dc0b2009-04-07 17:45:00 +00001697// A "simple container layer" is a RenderLayer which has no visible content to render.
1698// It may have no children, or all its children may be themselves composited.
1699// This is a useful optimization, because it allows us to avoid allocating backing store.
1700bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001701{
cdumez@apple.com3abcc792014-10-20 03:42:03 +00001702 if (renderer().isRenderReplaced() && (!isCompositedPlugin(renderer()) || isRestartedPlugin(renderer())))
simon.fraser@apple.com90b35d82013-01-29 04:16:56 +00001703 return false;
dino@apple.com2e06ec82013-04-03 20:13:20 +00001704
simon.fraser@apple.com7cfe7612012-03-13 20:59:59 +00001705 if (paintsBoxDecorations() || paintsChildren())
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001706 return false;
mihnea@adobe.coma8c95772013-02-15 13:00:03 +00001707
commit-queue@webkit.org83e19482013-10-21 19:38:30 +00001708 if (renderer().isRenderNamedFlowFragmentContainer())
mihnea@adobe.coma8c95772013-02-15 13:00:03 +00001709 return false;
1710
rosca@adobe.com43145d52014-09-23 07:47:21 +00001711 if (renderer().isRoot() && m_owningLayer.isolatesCompositedBlending())
1712 return false;
1713
antti@apple.com053c3c22013-09-09 19:21:53 +00001714 if (renderer().isRenderView()) {
simon.fraser@apple.comf757b382012-01-20 02:41:06 +00001715 // Look to see if the root object has a non-simple background
akling@apple.com32c7a6e2013-08-26 02:21:32 +00001716 RenderObject* rootObject = renderer().document().documentElement() ? renderer().document().documentElement()->renderer() : 0;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001717 if (!rootObject)
1718 return false;
1719
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001720 // Reject anything that has a border, a border-radius or outline,
1721 // or is not a simple background (no background, or solid color).
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001722 if (hasBoxDecorationsOrBackgroundImage(rootObject->style()))
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001723 return false;
1724
1725 // Now look at the body's renderer.
akling@apple.com32c7a6e2013-08-26 02:21:32 +00001726 HTMLElement* body = renderer().document().body();
darin@apple.com15708b12014-03-16 16:38:58 +00001727 RenderObject* bodyObject = (body && body->hasTagName(bodyTag)) ? body->renderer() : 0;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001728 if (!bodyObject)
1729 return false;
1730
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001731 if (hasBoxDecorationsOrBackgroundImage(bodyObject->style()))
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001732 return false;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001733 }
1734
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001735 return true;
1736}
1737
simon.fraser@apple.comd305a892014-05-19 18:33:26 +00001738static bool compositedWithOwnBackingStore(const RenderLayer* layer)
1739{
1740 return layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor();
1741}
1742
1743static bool descendentLayerPaintsIntoAncestor(RenderLayer& parent)
shawnsingh@chromium.org3a3ba162013-02-06 19:35:21 +00001744{
shawnsingh@chromium.orgc6911802013-02-13 23:43:01 +00001745 // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
akling@apple.comc68fe752013-10-13 18:39:27 +00001746 parent.updateLayerListsIfNeeded();
shawnsingh@chromium.orgc6911802013-02-13 23:43:01 +00001747
1748#if !ASSERT_DISABLED
akling@apple.comc68fe752013-10-13 18:39:27 +00001749 LayerListMutationDetector mutationChecker(&parent);
shawnsingh@chromium.orgc6911802013-02-13 23:43:01 +00001750#endif
1751
akling@apple.comc68fe752013-10-13 18:39:27 +00001752 if (Vector<RenderLayer*>* normalFlowList = parent.normalFlowList()) {
shawnsingh@chromium.org3a3ba162013-02-06 19:35:21 +00001753 size_t listSize = normalFlowList->size();
1754 for (size_t i = 0; i < listSize; ++i) {
1755 RenderLayer* curLayer = normalFlowList->at(i);
simon.fraser@apple.comd305a892014-05-19 18:33:26 +00001756 if (!compositedWithOwnBackingStore(curLayer)
simon.fraser@apple.come6e085e2014-09-02 18:30:06 +00001757 && (curLayer->isVisuallyNonEmpty() || descendentLayerPaintsIntoAncestor(*curLayer)))
shawnsingh@chromium.org3a3ba162013-02-06 19:35:21 +00001758 return true;
1759 }
1760 }
1761
akling@apple.comc68fe752013-10-13 18:39:27 +00001762 if (parent.isStackingContainer()) {
1763 if (!parent.hasVisibleDescendant())
shawnsingh@chromium.org3a3ba162013-02-06 19:35:21 +00001764 return false;
1765
1766 // Use the m_hasCompositingDescendant bit to optimize?
akling@apple.comc68fe752013-10-13 18:39:27 +00001767 if (Vector<RenderLayer*>* negZOrderList = parent.negZOrderList()) {
shawnsingh@chromium.org3a3ba162013-02-06 19:35:21 +00001768 size_t listSize = negZOrderList->size();
1769 for (size_t i = 0; i < listSize; ++i) {
1770 RenderLayer* curLayer = negZOrderList->at(i);
simon.fraser@apple.comd305a892014-05-19 18:33:26 +00001771 if (!compositedWithOwnBackingStore(curLayer)
simon.fraser@apple.come6e085e2014-09-02 18:30:06 +00001772 && (curLayer->isVisuallyNonEmpty() || descendentLayerPaintsIntoAncestor(*curLayer)))
shawnsingh@chromium.org3a3ba162013-02-06 19:35:21 +00001773 return true;
1774 }
1775 }
1776
akling@apple.comc68fe752013-10-13 18:39:27 +00001777 if (Vector<RenderLayer*>* posZOrderList = parent.posZOrderList()) {
shawnsingh@chromium.org3a3ba162013-02-06 19:35:21 +00001778 size_t listSize = posZOrderList->size();
1779 for (size_t i = 0; i < listSize; ++i) {
1780 RenderLayer* curLayer = posZOrderList->at(i);
simon.fraser@apple.comd305a892014-05-19 18:33:26 +00001781 if (!compositedWithOwnBackingStore(curLayer)
simon.fraser@apple.come6e085e2014-09-02 18:30:06 +00001782 && (curLayer->isVisuallyNonEmpty() || descendentLayerPaintsIntoAncestor(*curLayer)))
shawnsingh@chromium.org3a3ba162013-02-06 19:35:21 +00001783 return true;
1784 }
1785 }
1786 }
1787
1788 return false;
1789}
1790
simon.fraser@apple.comf757b382012-01-20 02:41:06 +00001791// Conservative test for having no rendered children.
simon.fraser@apple.comd305a892014-05-19 18:33:26 +00001792bool RenderLayerBacking::isPaintDestinationForDescendentLayers() const
simon.fraser@apple.comf757b382012-01-20 02:41:06 +00001793{
simon.fraser@apple.comd305a892014-05-19 18:33:26 +00001794 return descendentLayerPaintsIntoAncestor(m_owningLayer);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001795}
1796
simon.fraser@apple.com9ca8cf72013-06-29 20:22:19 +00001797bool RenderLayerBacking::containsPaintedContent(bool isSimpleContainer) const
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +00001798{
akling@apple.comc68fe752013-10-13 18:39:27 +00001799 if (isSimpleContainer || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer.isReflection())
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +00001800 return false;
1801
1802 if (isDirectlyCompositedImage())
1803 return false;
1804
1805 // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
1806 // and set background color on the layer in that case, instead of allocating backing store and painting.
eric.carlson@apple.com402b2c02010-08-06 23:47:54 +00001807#if ENABLE(VIDEO)
cdumez@apple.com3abcc792014-10-20 03:42:03 +00001808 if (is<RenderVideo>(renderer()) && downcast<RenderVideo>(renderer()).shouldDisplayVideo())
akling@apple.comc68fe752013-10-13 18:39:27 +00001809 return m_owningLayer.hasBoxDecorationsOrBackground();
eric.carlson@apple.com402b2c02010-08-06 23:47:54 +00001810#endif
simon.fraser@apple.comefaa4122013-12-20 03:48:10 +00001811
1812#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
cdumez@apple.com3abcc792014-10-20 03:42:03 +00001813 if (is<RenderHTMLCanvas>(renderer()) && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents)
akling@apple.comc68fe752013-10-13 18:39:27 +00001814 return m_owningLayer.hasBoxDecorationsOrBackground();
jamesr@google.comd8c61572010-08-06 21:49:20 +00001815#endif
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +00001816
1817 return true;
1818}
1819
1820// An image can be directly compositing if it's the sole content of the layer, and has no box decorations
1821// that require painting. Direct compositing saves backing store.
1822bool RenderLayerBacking::isDirectlyCompositedImage() const
dino@apple.comce3a4e02009-03-26 01:38:52 +00001823{
cdumez@apple.com1b3800a2014-10-21 18:09:49 +00001824 if (!is<RenderImage>(renderer()) || m_owningLayer.hasBoxDecorationsOrBackground() || renderer().hasClip())
simon.fraser@apple.coma54b1e82010-09-21 00:42:52 +00001825 return false;
1826
cdumez@apple.com1b3800a2014-10-21 18:09:49 +00001827#if ENABLE(VIDEO)
1828 if (is<RenderMedia>(renderer()))
1829 return false;
1830#endif
1831
cdumez@apple.comcda2b9c2014-10-14 09:07:21 +00001832 auto& imageRenderer = downcast<RenderImage>(renderer());
akling@apple.com4c166d62013-09-01 05:29:00 +00001833 if (CachedImage* cachedImage = imageRenderer.cachedImage()) {
noam.rosenthal@nokia.com05334b32012-11-10 04:49:08 +00001834 if (!cachedImage->hasImage())
1835 return false;
1836
akling@apple.com4c166d62013-09-01 05:29:00 +00001837 Image* image = cachedImage->imageForRenderer(&imageRenderer);
noam.rosenthal@nokia.com05334b32012-11-10 04:49:08 +00001838 if (!image->isBitmapImage())
1839 return false;
1840
timothy_horton@apple.com9e3d9c82013-08-07 19:52:37 +00001841 if (image->orientationForCurrentFrame() != DefaultImageOrientation)
1842 return false;
1843
noam.rosenthal@nokia.com05334b32012-11-10 04:49:08 +00001844 return m_graphicsLayer->shouldDirectlyCompositeImage(image);
simon.fraser@apple.coma54b1e82010-09-21 00:42:52 +00001845 }
1846
1847 return false;
dino@apple.comce3a4e02009-03-26 01:38:52 +00001848}
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +00001849
jchaffraix@webkit.org363c3872012-04-17 21:51:22 +00001850void RenderLayerBacking::contentChanged(ContentChangeType changeType)
dino@apple.comce3a4e02009-03-26 01:38:52 +00001851{
jchaffraix@webkit.org363c3872012-04-17 21:51:22 +00001852 if ((changeType == ImageChanged) && isDirectlyCompositedImage()) {
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +00001853 updateImageContents();
1854 return;
cmarrin@apple.com4e7728f2009-08-27 23:55:44 +00001855 }
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001856
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00001857 if ((changeType == BackgroundImageChanged) && canCreateTiledImage(renderer().style()))
simon.fraser@apple.come33dc482014-05-19 15:53:32 +00001858 updateGeometry();
commit-queue@webkit.orge82edbf2013-04-11 05:47:44 +00001859
jchaffraix@webkit.org363c3872012-04-17 21:51:22 +00001860 if ((changeType == MaskImageChanged) && m_maskLayer) {
simon.fraser@apple.com2f5f5c82010-12-15 00:09:58 +00001861 // The composited layer bounds relies on box->maskClipRect(), which changes
1862 // when the mask image becomes available.
simon.fraser@apple.comfc750292012-12-15 22:11:27 +00001863 updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot);
simon.fraser@apple.com2f5f5c82010-12-15 00:09:58 +00001864 }
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +00001865
cmarrin@apple.com8b28bbc2011-01-25 17:27:30 +00001866#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
simon.fraser@apple.comefaa4122013-12-20 03:48:10 +00001867 if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
cmarrin@apple.comc924a5c2010-06-22 22:23:57 +00001868 m_graphicsLayer->setContentsNeedsDisplay();
simon.fraser@apple.comaafddd82010-01-09 04:07:52 +00001869 return;
1870 }
1871#endif
simon.fraser@apple.com3368e1c2009-03-27 01:12:01 +00001872}
1873
1874void RenderLayerBacking::updateImageContents()
1875{
cdumez@apple.comcda2b9c2014-10-14 09:07:21 +00001876 auto& imageRenderer = downcast<RenderImage>(renderer());
simon.fraser@apple.com3368e1c2009-03-27 01:12:01 +00001877
akling@apple.com4c166d62013-09-01 05:29:00 +00001878 CachedImage* cachedImage = imageRenderer.cachedImage();
simon.fraser@apple.com3368e1c2009-03-27 01:12:01 +00001879 if (!cachedImage)
1880 return;
1881
akling@apple.com4c166d62013-09-01 05:29:00 +00001882 Image* image = cachedImage->imageForRenderer(&imageRenderer);
simon.fraser@apple.com3368e1c2009-03-27 01:12:01 +00001883 if (!image)
1884 return;
1885
1886 // We have to wait until the image is fully loaded before setting it on the layer.
1887 if (!cachedImage->isLoaded())
1888 return;
1889
1890 // This is a no-op if the layer doesn't have an inner layer for the image.
zalan@apple.com376339c2014-08-28 04:24:31 +00001891 m_graphicsLayer->setContentsRect(snappedIntRect(contentsBox()));
simon.fraser@apple.coma0dfed962013-08-31 00:14:41 +00001892
akling@apple.com4c166d62013-09-01 05:29:00 +00001893 LayoutRect contentsClippingRect = imageRenderer.contentBoxRect();
simon.fraser@apple.coma0dfed962013-08-31 00:14:41 +00001894 contentsClippingRect.move(contentOffsetInCompostingLayer());
zalan@apple.com376339c2014-08-28 04:24:31 +00001895 m_graphicsLayer->setContentsClippingRect(snappedIntRect(contentsClippingRect));
simon.fraser@apple.coma0dfed962013-08-31 00:14:41 +00001896
simon.fraser@apple.com3368e1c2009-03-27 01:12:01 +00001897 m_graphicsLayer->setContentsToImage(image);
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001898 bool isSimpleContainer = false;
1899 updateDrawsContent(isSimpleContainer);
simon.fraser@apple.com3368e1c2009-03-27 01:12:01 +00001900
1901 // Image animation is "lazy", in that it automatically stops unless someone is drawing
1902 // the image. So we have to kick the animation each time; this has the downside that the
1903 // image will keep animating, even if its layer is not visible.
1904 image->startAnimation();
dino@apple.comce3a4e02009-03-26 01:38:52 +00001905}
1906
zalan@apple.com88965072014-03-19 14:25:34 +00001907FloatPoint3D RenderLayerBacking::computeTransformOriginForPainting(const LayoutRect& borderBox) const
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001908{
akling@apple.com827be9c2013-10-29 02:58:43 +00001909 const RenderStyle& style = renderer().style();
zalan@apple.com93a3f392014-07-23 22:55:37 +00001910 float deviceScaleFactor = this->deviceScaleFactor();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001911
simon.fraser@apple.com61cf5eb2009-02-13 05:10:12 +00001912 FloatPoint3D origin;
zalan@apple.com88965072014-03-19 14:25:34 +00001913 origin.setX(roundToDevicePixel(floatValueForLength(style.transformOriginX(), borderBox.width()), deviceScaleFactor));
1914 origin.setY(roundToDevicePixel(floatValueForLength(style.transformOriginY(), borderBox.height()), deviceScaleFactor));
akling@apple.com827be9c2013-10-29 02:58:43 +00001915 origin.setZ(style.transformOriginZ());
simon.fraser@apple.com61cf5eb2009-02-13 05:10:12 +00001916
1917 return origin;
1918}
1919
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001920// Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
allan.jensen@digia.comd5cbc752013-08-13 17:08:19 +00001921LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001922{
zalan@apple.com5b735c02014-03-09 00:14:00 +00001923 return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y()) + m_devicePixelFractionFromRenderer;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001924}
1925
allan.jensen@digia.comd5cbc752013-08-13 17:08:19 +00001926LayoutRect RenderLayerBacking::contentsBox() const
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001927{
cdumez@apple.com2601e052014-10-10 18:02:32 +00001928 if (!is<RenderBox>(renderer()))
allan.jensen@digia.comd5cbc752013-08-13 17:08:19 +00001929 return LayoutRect();
simon.fraser@apple.com443915d2009-02-06 04:30:51 +00001930
cdumez@apple.com0abff8b2014-10-17 21:25:10 +00001931 auto& renderBox = downcast<RenderBox>(renderer());
allan.jensen@digia.comd5cbc752013-08-13 17:08:19 +00001932 LayoutRect contentsRect;
simon.fraser@apple.com98df11b2009-06-18 18:52:09 +00001933#if ENABLE(VIDEO)
cdumez@apple.com2601e052014-10-10 18:02:32 +00001934 if (is<RenderVideo>(renderBox))
1935 contentsRect = downcast<RenderVideo>(renderBox).videoBox();
akling@apple.com4c166d62013-09-01 05:29:00 +00001936 else
simon.fraser@apple.com98df11b2009-06-18 18:52:09 +00001937#endif
cdumez@apple.com2601e052014-10-10 18:02:32 +00001938 if (is<RenderReplaced>(renderBox)) {
1939 RenderReplaced& renderReplaced = downcast<RenderReplaced>(renderBox);
simon.fraser@apple.coma0dfed962013-08-31 00:14:41 +00001940 contentsRect = renderReplaced.replacedContentRect(renderBox.intrinsicSize());
1941 } else
1942 contentsRect = renderBox.contentBoxRect();
simon.fraser@apple.com98df11b2009-06-18 18:52:09 +00001943
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001944 contentsRect.move(contentOffsetInCompostingLayer());
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00001945 return contentsRect;
1946}
1947
akling@apple.com4c166d62013-09-01 05:29:00 +00001948static LayoutRect backgroundRectForBox(const RenderBox& box)
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001949{
akling@apple.com827be9c2013-10-29 02:58:43 +00001950 switch (box.style().backgroundClip()) {
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001951 case BorderFillBox:
akling@apple.com4c166d62013-09-01 05:29:00 +00001952 return box.borderBoxRect();
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001953 case PaddingFillBox:
akling@apple.com4c166d62013-09-01 05:29:00 +00001954 return box.paddingBoxRect();
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001955 case ContentFillBox:
akling@apple.com4c166d62013-09-01 05:29:00 +00001956 return box.contentBoxRect();
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001957 case TextFillBox:
1958 break;
1959 }
1960
1961 ASSERT_NOT_REACHED();
1962 return LayoutRect();
1963}
1964
zalan@apple.com5b735c02014-03-09 00:14:00 +00001965FloatRect RenderLayerBacking::backgroundBoxForPainting() const
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001966{
cdumez@apple.com0abff8b2014-10-17 21:25:10 +00001967 if (!is<RenderBox>(renderer()))
zalan@apple.com5b735c02014-03-09 00:14:00 +00001968 return FloatRect();
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001969
cdumez@apple.com0abff8b2014-10-17 21:25:10 +00001970 LayoutRect backgroundBox = backgroundRectForBox(downcast<RenderBox>(renderer()));
allan.jensen@digia.comd5cbc752013-08-13 17:08:19 +00001971 backgroundBox.move(contentOffsetInCompostingLayer());
zalan@apple.com376339c2014-08-28 04:24:31 +00001972 return snapRectToDevicePixels(backgroundBox, deviceScaleFactor());
commit-queue@webkit.org90f15662012-12-08 23:46:05 +00001973}
1974
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001975GraphicsLayer* RenderLayerBacking::parentForSublayers() const
1976{
1977 if (m_scrollingContentsLayer)
1978 return m_scrollingContentsLayer.get();
1979
dbates@webkit.org395fca72013-12-06 19:59:38 +00001980#if PLATFORM(IOS)
1981 // FIXME: Can we remove this iOS-specific code path?
1982 if (GraphicsLayer* clippingLayer = this->clippingLayer())
1983 return clippingLayer;
1984 return m_graphicsLayer.get();
1985#else
simon.fraser@apple.com632ced12013-01-15 23:17:01 +00001986 return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
dbates@webkit.org395fca72013-12-06 19:59:38 +00001987#endif
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00001988}
1989
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00001990GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
1991{
1992 if (m_ancestorClippingLayer)
1993 return m_ancestorClippingLayer.get();
1994
1995 if (m_contentsContainmentLayer)
1996 return m_contentsContainmentLayer.get();
1997
1998 return m_graphicsLayer.get();
1999}
2000
simon.fraser@apple.com655ac7f2012-04-06 22:55:45 +00002001bool RenderLayerBacking::paintsIntoWindow() const
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002002{
simon.fraser@apple.com5429b7f2011-12-13 01:05:32 +00002003 if (m_usingTiledCacheLayer)
2004 return false;
2005
akling@apple.comc68fe752013-10-13 18:39:27 +00002006 if (m_owningLayer.isRootLayer()) {
benjamin@webkit.org049d8b32014-01-10 20:41:20 +00002007#if PLATFORM(IOS) || USE(COORDINATED_GRAPHICS)
akling@apple.comc3466042013-08-24 18:27:32 +00002008 if (compositor().inForcedCompositingMode())
commit-queue@webkit.org3c453c42012-04-05 16:10:40 +00002009 return false;
2010#endif
2011
akling@apple.comc3466042013-08-24 18:27:32 +00002012 return compositor().rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
commit-queue@webkit.org3c453c42012-04-05 16:10:40 +00002013 }
simon.fraser@apple.comed063f42010-05-11 05:34:48 +00002014
2015 return false;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002016}
2017
simon.fraser@apple.com9d127902012-05-29 20:49:15 +00002018void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking)
simon.fraser@apple.com297a0fb2012-05-25 21:17:33 +00002019{
simon.fraser@apple.com9d127902012-05-29 20:49:15 +00002020 if (requiresOwnBacking == m_requiresOwnBackingStore)
simon.fraser@apple.com297a0fb2012-05-25 21:17:33 +00002021 return;
2022
simon.fraser@apple.com0afaa9d2012-10-16 18:29:38 +00002023 m_requiresOwnBackingStore = requiresOwnBacking;
2024
simon.fraser@apple.com297a0fb2012-05-25 21:17:33 +00002025 // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects
2026 // cached clip rects, so when it changes we have to clear clip rects on descendants.
akling@apple.comc68fe752013-10-13 18:39:27 +00002027 m_owningLayer.clearClipRectsIncludingDescendants(PaintingClipRects);
2028 m_owningLayer.computeRepaintRectsIncludingDescendants();
simon.fraser@apple.com9d127902012-05-29 20:49:15 +00002029
akling@apple.comc68fe752013-10-13 18:39:27 +00002030 compositor().repaintInCompositedAncestor(m_owningLayer, compositedBounds());
simon.fraser@apple.com297a0fb2012-05-25 21:17:33 +00002031}
2032
bdakin@apple.com6e3f3f22014-01-09 20:20:26 +00002033void RenderLayerBacking::setContentsNeedDisplay(GraphicsLayer::ShouldClipToLayer shouldClip)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002034{
simon.fraser@apple.comb7cec682012-04-16 18:32:13 +00002035 ASSERT(!paintsIntoCompositedAncestor());
timothy_horton@apple.com5251cbd2013-10-02 21:14:26 +00002036
akling@apple.comc68fe752013-10-13 18:39:27 +00002037 FrameView& frameView = owningLayer().renderer().view().frameView();
timothy_horton@apple.com5251cbd2013-10-02 21:14:26 +00002038 if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
zalan@apple.com268e9482014-03-05 05:30:25 +00002039 frameView.addTrackedRepaintRect(owningLayer().absoluteBoundingBoxForPainting());
simon.fraser@apple.comb7cec682012-04-16 18:32:13 +00002040
bdakin@apple.com6e3f3f22014-01-09 20:20:26 +00002041 if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2042 // By default, setNeedsDisplay will clip to the size of the GraphicsLayer, which does not include margin tiles.
2043 // So if the TiledBacking has a margin that needs to be invalidated, we need to send in a rect to setNeedsDisplayInRect
2044 // that is large enough to include the margin. TiledBacking::bounds() includes the margin.
2045 TiledBacking* tiledBacking = this->tiledBacking();
2046 FloatRect rectToRepaint = tiledBacking ? tiledBacking->bounds() : FloatRect(FloatPoint(0, 0), m_graphicsLayer->size());
2047 m_graphicsLayer->setNeedsDisplayInRect(rectToRepaint, shouldClip);
2048 }
simon.fraser@apple.combb04c2d2009-06-25 01:07:08 +00002049
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00002050 if (m_foregroundLayer && m_foregroundLayer->drawsContent())
2051 m_foregroundLayer->setNeedsDisplay();
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00002052
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002053 if (m_backgroundLayer && m_backgroundLayer->drawsContent())
2054 m_backgroundLayer->setNeedsDisplay();
2055
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00002056 if (m_maskLayer && m_maskLayer->drawsContent())
2057 m_maskLayer->setNeedsDisplay();
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00002058
2059 if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
2060 m_scrollingContentsLayer->setNeedsDisplay();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002061}
2062
2063// r is in the coordinate space of the layer's render object
zalan@apple.comc7b20b12014-02-12 04:50:55 +00002064void RenderLayerBacking::setContentsNeedDisplayInRect(const LayoutRect& r, GraphicsLayer::ShouldClipToLayer shouldClip)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002065{
simon.fraser@apple.comb7cec682012-04-16 18:32:13 +00002066 ASSERT(!paintsIntoCompositedAncestor());
2067
zalan@apple.com376339c2014-08-28 04:24:31 +00002068 FloatRect pixelSnappedRectForPainting = snapRectToDevicePixels(r, deviceScaleFactor());
akling@apple.comc68fe752013-10-13 18:39:27 +00002069 FrameView& frameView = owningLayer().renderer().view().frameView();
timothy_horton@apple.com5251cbd2013-10-02 21:14:26 +00002070 if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
zalan@apple.com268e9482014-03-05 05:30:25 +00002071 frameView.addTrackedRepaintRect(pixelSnappedRectForPainting);
timothy_horton@apple.com5251cbd2013-10-02 21:14:26 +00002072
simon.fraser@apple.combb04c2d2009-06-25 01:07:08 +00002073 if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
zalan@apple.comc7b20b12014-02-12 04:50:55 +00002074 FloatRect layerDirtyRect = pixelSnappedRectForPainting;
zalan@apple.comdc9c8402014-03-04 16:17:46 +00002075 layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
bdakin@apple.com8ce430b2014-01-15 23:51:25 +00002076 m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002077 }
2078
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00002079 if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
zalan@apple.comc7b20b12014-02-12 04:50:55 +00002080 FloatRect layerDirtyRect = pixelSnappedRectForPainting;
zalan@apple.comdc9c8402014-03-04 16:17:46 +00002081 layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
bdakin@apple.com8ce430b2014-01-15 23:51:25 +00002082 m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002083 }
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00002084
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002085 // FIXME: need to split out repaints for the background.
2086 if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
zalan@apple.comc7b20b12014-02-12 04:50:55 +00002087 FloatRect layerDirtyRect = pixelSnappedRectForPainting;
zalan@apple.comdc9c8402014-03-04 16:17:46 +00002088 layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
bdakin@apple.com8ce430b2014-01-15 23:51:25 +00002089 m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002090 }
2091
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00002092 if (m_maskLayer && m_maskLayer->drawsContent()) {
zalan@apple.comc7b20b12014-02-12 04:50:55 +00002093 FloatRect layerDirtyRect = pixelSnappedRectForPainting;
zalan@apple.comdc9c8402014-03-04 16:17:46 +00002094 layerDirtyRect.move(-m_maskLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
bdakin@apple.com8ce430b2014-01-15 23:51:25 +00002095 m_maskLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
simon.fraser@apple.com9d9e2982009-08-18 03:57:08 +00002096 }
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00002097
2098 if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
zalan@apple.comc7b20b12014-02-12 04:50:55 +00002099 FloatRect layerDirtyRect = pixelSnappedRectForPainting;
zalan@apple.comdc9c8402014-03-04 16:17:46 +00002100 layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
dbates@webkit.org395fca72013-12-06 19:59:38 +00002101#if PLATFORM(IOS)
simon.fraser@apple.come33dc482014-05-19 15:53:32 +00002102 // Account for the fact that RenderLayerBacking::updateGeometry() bakes scrollOffset into offsetFromRenderer on iOS.
zalan@apple.comdc9c8402014-03-04 16:17:46 +00002103 layerDirtyRect.move(-m_owningLayer.scrollOffset() + m_devicePixelFractionFromRenderer);
dbates@webkit.org395fca72013-12-06 19:59:38 +00002104#endif
bdakin@apple.com8ce430b2014-01-15 23:51:25 +00002105 m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00002106 }
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002107}
2108
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002109void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext* context,
zalan@apple.coma95fd6f2014-02-22 07:24:45 +00002110 const IntRect& paintDirtyRect, // In the coords of rootLayer.
zalan@apple.comd1e3a0f2014-02-12 03:28:43 +00002111 PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002112{
simon.fraser@apple.comb7cec682012-04-16 18:32:13 +00002113 if (paintsIntoWindow() || paintsIntoCompositedAncestor()) {
dbates@webkit.org395fca72013-12-06 19:59:38 +00002114#if !PLATFORM(IOS)
2115 // FIXME: Looks like the CALayer tree is out of sync with the GraphicsLayer heirarchy
2116 // when pages are restored from the PageCache.
2117 // <rdar://problem/8712587> ASSERT: When Going Back to Page with Plugins in PageCache
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002118 ASSERT_NOT_REACHED();
dbates@webkit.org395fca72013-12-06 19:59:38 +00002119#endif
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002120 return;
2121 }
simon.fraser@apple.coma43acab32011-11-02 21:02:07 +00002122
2123 FontCachePurgePreventer fontCachePurgePreventer;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002124
achicu@adobe.comb64dbce2012-01-13 09:05:22 +00002125 RenderLayer::PaintLayerFlags paintFlags = 0;
2126 if (paintingPhase & GraphicsLayerPaintBackground)
2127 paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
2128 if (paintingPhase & GraphicsLayerPaintForeground)
2129 paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
2130 if (paintingPhase & GraphicsLayerPaintMask)
2131 paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00002132 if (paintingPhase & GraphicsLayerPaintOverflowContents)
2133 paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents;
vollick@chromium.org0015c122013-03-07 14:00:57 +00002134 if (paintingPhase & GraphicsLayerPaintCompositedScroll)
2135 paintFlags |= RenderLayer::PaintLayerPaintingCompositingScrollingPhase;
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002136
andersca@apple.comcc3b2dc2013-09-27 18:38:51 +00002137 if (graphicsLayer == m_backgroundLayer.get())
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002138 paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
akling@apple.comc3466042013-08-24 18:27:32 +00002139 else if (compositor().fixedRootBackgroundLayer())
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002140 paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
simon.fraser@apple.com57f81ee2014-03-20 23:14:31 +00002141
2142#ifndef NDEBUG
mihnea@adobe.com388bf222014-09-22 07:51:54 +00002143 RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&renderer());
simon.fraser@apple.com57f81ee2014-03-20 23:14:31 +00002144#endif
2145
2146 FrameView::PaintingState paintingState;
2147 if (m_owningLayer.isRootLayer())
mihnea@adobe.com388bf222014-09-22 07:51:54 +00002148 renderer().view().frameView().willPaintContents(context, paintDirtyRect, paintingState);
simon.fraser@apple.com57f81ee2014-03-20 23:14:31 +00002149
achicu@adobe.comb64dbce2012-01-13 09:05:22 +00002150 // FIXME: GraphicsLayers need a way to split for RenderRegions.
zalan@apple.com5e034f62014-02-20 23:04:20 +00002151 RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, m_devicePixelFractionFromRenderer);
akling@apple.comc68fe752013-10-13 18:39:27 +00002152 m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002153
akling@apple.comc68fe752013-10-13 18:39:27 +00002154 if (m_owningLayer.containsDirtyOverlayScrollbars())
2155 m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
bdakin@apple.comb7b54842012-05-11 00:31:30 +00002156
simon.fraser@apple.com57f81ee2014-03-20 23:14:31 +00002157 if (m_owningLayer.isRootLayer())
mihnea@adobe.com388bf222014-09-22 07:51:54 +00002158 renderer().view().frameView().didPaintContents(context, paintDirtyRect, paintingState);
simon.fraser@apple.com57f81ee2014-03-20 23:14:31 +00002159
akling@apple.comc3466042013-08-24 18:27:32 +00002160 compositor().didPaintBacking(this);
simon.fraser@apple.com6f987a72013-05-29 16:04:12 +00002161
akling@apple.comc68fe752013-10-13 18:39:27 +00002162 ASSERT(!m_owningLayer.m_usedTransparency);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002163}
2164
leviw@chromium.orgdac251e2012-02-15 01:20:32 +00002165static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
jamesr@google.come53ce642011-04-14 06:51:50 +00002166{
2167 if (!scrollbar)
2168 return;
2169
2170 context.save();
leviw@chromium.orgdac251e2012-02-15 01:20:32 +00002171 const IntRect& scrollbarRect = scrollbar->frameRect();
jamesr@google.come53ce642011-04-14 06:51:50 +00002172 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
leviw@chromium.orgdac251e2012-02-15 01:20:32 +00002173 IntRect transformedClip = clip;
leviw@chromium.org35e01312011-06-03 02:41:09 +00002174 transformedClip.moveBy(scrollbarRect.location());
leviw@chromium.orgdac251e2012-02-15 01:20:32 +00002175 scrollbar->paint(&context, transformedClip);
jamesr@google.come53ce642011-04-14 06:51:50 +00002176 context.restore();
2177}
2178
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002179// Up-call from compositing layer drawing callback.
zalan@apple.comd1e3a0f2014-02-12 03:28:43 +00002180void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const FloatRect& clip)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002181{
fsamuel@chromium.org10dcfd82012-03-27 00:09:12 +00002182#ifndef NDEBUG
akling@apple.com32c7a6e2013-08-26 02:21:32 +00002183 if (Page* page = renderer().frame().page())
fsamuel@chromium.org10dcfd82012-03-27 00:09:12 +00002184 page->setIsPainting(true);
2185#endif
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00002186
zalan@apple.comd1e3a0f2014-02-12 03:28:43 +00002187 // The dirtyRect is in the coords of the painting root.
zalan@apple.comb2ef5cb2014-07-17 01:47:10 +00002188 FloatRect adjustedClipRect = clip;
2189 adjustedClipRect.move(-m_devicePixelFractionFromRenderer);
2190 IntRect dirtyRect = enclosingIntRect(adjustedClipRect);
zalan@apple.comd1e3a0f2014-02-12 03:28:43 +00002191
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002192 if (graphicsLayer == m_graphicsLayer.get()
2193 || graphicsLayer == m_foregroundLayer.get()
2194 || graphicsLayer == m_backgroundLayer.get()
2195 || graphicsLayer == m_maskLayer.get()
2196 || graphicsLayer == m_scrollingContentsLayer.get()) {
akling@apple.com32c7a6e2013-08-26 02:21:32 +00002197 InspectorInstrumentation::willPaint(&renderer());
simon.fraser@apple.com8afbff12009-11-19 19:03:02 +00002198
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00002199 if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
bdakin@apple.com8af619c2013-11-21 21:57:53 +00002200 dirtyRect.intersect(enclosingIntRect(compositedBoundsIncludingMargin()));
simon.fraser@apple.com8afbff12009-11-19 19:03:02 +00002201
jamesr@google.come53ce642011-04-14 06:51:50 +00002202 // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002203 paintIntoLayer(graphicsLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase);
jamesr@google.come53ce642011-04-14 06:51:50 +00002204
simon.fraser@apple.com159ad602014-08-22 19:07:17 +00002205 InspectorInstrumentation::didPaint(&renderer(), dirtyRect);
jamesr@google.come53ce642011-04-14 06:51:50 +00002206 } else if (graphicsLayer == layerForHorizontalScrollbar()) {
zalan@apple.coma95fd6f2014-02-22 07:24:45 +00002207 paintScrollbar(m_owningLayer.horizontalScrollbar(), context, dirtyRect);
jamesr@google.come53ce642011-04-14 06:51:50 +00002208 } else if (graphicsLayer == layerForVerticalScrollbar()) {
zalan@apple.coma95fd6f2014-02-22 07:24:45 +00002209 paintScrollbar(m_owningLayer.verticalScrollbar(), context, dirtyRect);
jamesr@google.come53ce642011-04-14 06:51:50 +00002210 } else if (graphicsLayer == layerForScrollCorner()) {
zalan@apple.com5f08e992014-01-24 23:35:07 +00002211 const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
jamesr@google.come53ce642011-04-14 06:51:50 +00002212 context.save();
2213 context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
zalan@apple.comd1e3a0f2014-02-12 03:28:43 +00002214 LayoutRect transformedClip = LayoutRect(clip);
leviw@chromium.orgdac251e2012-02-15 01:20:32 +00002215 transformedClip.moveBy(scrollCornerAndResizer.location());
zalan@apple.com376339c2014-08-28 04:24:31 +00002216 m_owningLayer.paintScrollCorner(&context, IntPoint(), snappedIntRect(transformedClip));
akling@apple.comc68fe752013-10-13 18:39:27 +00002217 m_owningLayer.paintResizer(&context, IntPoint(), transformedClip);
jamesr@google.come53ce642011-04-14 06:51:50 +00002218 context.restore();
2219 }
fsamuel@chromium.org10dcfd82012-03-27 00:09:12 +00002220#ifndef NDEBUG
akling@apple.com32c7a6e2013-08-26 02:21:32 +00002221 if (Page* page = renderer().frame().page())
fsamuel@chromium.org10dcfd82012-03-27 00:09:12 +00002222 page->setIsPainting(false);
2223#endif
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002224}
2225
simon.fraser@apple.com53dd08d2011-07-16 01:30:13 +00002226float RenderLayerBacking::pageScaleFactor() const
2227{
akling@apple.comc3466042013-08-24 18:27:32 +00002228 return compositor().pageScaleFactor();
simon.fraser@apple.com53dd08d2011-07-16 01:30:13 +00002229}
2230
antti@apple.com317ff432014-04-11 18:58:07 +00002231float RenderLayerBacking::zoomedOutPageScaleFactor() const
2232{
2233 return compositor().zoomedOutPageScaleFactor();
2234}
2235
aroben@apple.com631cb902011-08-15 13:43:29 +00002236float RenderLayerBacking::deviceScaleFactor() const
simon.fraser@apple.com53dd08d2011-07-16 01:30:13 +00002237{
akling@apple.comc3466042013-08-24 18:27:32 +00002238 return compositor().deviceScaleFactor();
simon.fraser@apple.com53dd08d2011-07-16 01:30:13 +00002239}
2240
simon.fraser@apple.comc529da02013-11-07 19:34:01 +00002241float RenderLayerBacking::contentsScaleMultiplierForNewTiles(const GraphicsLayer* layer) const
2242{
2243 return compositor().contentsScaleMultiplierForNewTiles(layer);
2244}
2245
timothy_horton@apple.com2aa04e42014-03-19 01:51:56 +00002246bool RenderLayerBacking::paintsOpaquelyAtNonIntegralScales(const GraphicsLayer*) const
2247{
2248 return m_isMainFrameRenderViewLayer;
2249}
2250
simon.fraser@apple.coma5614962013-01-19 01:20:32 +00002251void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer* layer) const
simon.fraser@apple.com53dd08d2011-07-16 01:30:13 +00002252{
akling@apple.comc68fe752013-10-13 18:39:27 +00002253 compositor().didFlushChangesForLayer(m_owningLayer, layer);
simon.fraser@apple.com53dd08d2011-07-16 01:30:13 +00002254}
2255
simon.fraser@apple.com5cabb322012-10-17 18:20:31 +00002256bool RenderLayerBacking::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
2257{
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00002258 GraphicsLayer* transformedLayer = m_contentsContainmentLayer.get() ? m_contentsContainmentLayer.get() : m_graphicsLayer.get();
2259 if (graphicsLayer != transformedLayer)
simon.fraser@apple.com5cabb322012-10-17 18:20:31 +00002260 return false;
2261
akling@apple.comc68fe752013-10-13 18:39:27 +00002262 if (m_owningLayer.hasTransform()) {
2263 transform = m_owningLayer.currentTransform(RenderStyle::ExcludeTransformOrigin);
simon.fraser@apple.com5cabb322012-10-17 18:20:31 +00002264 return true;
2265 }
2266 return false;
2267}
2268
vollick@chromium.orgb992fd32012-11-02 19:58:52 +00002269bool RenderLayerBacking::isTrackingRepaints() const
2270{
akling@apple.comc3466042013-08-24 18:27:32 +00002271 return static_cast<GraphicsLayerClient&>(compositor()).isTrackingRepaints();
vollick@chromium.orgb992fd32012-11-02 19:58:52 +00002272}
2273
timothy_horton@apple.com2304bd52014-10-04 08:47:04 +00002274bool RenderLayerBacking::shouldSkipLayerInDump(const GraphicsLayer* layer, LayerTreeAsTextBehavior) const
timothy_horton@apple.com203cdfa2013-10-01 23:42:50 +00002275{
2276 // Skip the root tile cache's flattening layer.
2277 return m_isMainFrameRenderViewLayer && layer && layer == m_childContainmentLayer.get();
2278}
2279
2280bool RenderLayerBacking::shouldDumpPropertyForLayer(const GraphicsLayer* layer, const char* propertyName) const
2281{
2282 // For backwards compatibility with WebKit1 and other platforms,
2283 // skip some properties on the root tile cache.
2284 if (m_isMainFrameRenderViewLayer && layer == m_graphicsLayer.get()) {
2285 if (!strcmp(propertyName, "drawsContent"))
2286 return false;
2287
2288 // Background color could be of interest to tests or other dumpers if it's non-white.
2289 if (!strcmp(propertyName, "backgroundColor") && layer->backgroundColor() == Color::white)
2290 return false;
timothy_horton@apple.com5251cbd2013-10-02 21:14:26 +00002291
2292 // The root tile cache's repaints will show up at the top with FrameView's,
2293 // so don't dump them twice.
2294 if (!strcmp(propertyName, "repaintRects"))
2295 return false;
timothy_horton@apple.com203cdfa2013-10-01 23:42:50 +00002296 }
2297
2298 return true;
2299}
2300
timothy_horton@apple.com80ec5612014-03-31 19:37:30 +00002301bool RenderLayerBacking::shouldAggressivelyRetainTiles(const GraphicsLayer*) const
2302{
2303 // Only the main frame TileController has enough information about in-window state to
2304 // correctly implement aggressive tile retention.
2305 if (!m_isMainFrameRenderViewLayer)
2306 return false;
2307
2308 if (Page* page = renderer().frame().page())
2309 return page->settings().aggressiveTileRetentionEnabled();
2310 return false;
2311}
2312
2313bool RenderLayerBacking::shouldTemporarilyRetainTileCohorts(const GraphicsLayer*) const
2314{
2315 if (Page* page = renderer().frame().page())
2316 return page->settings().temporaryTileCohortRetentionEnabled();
2317 return true;
2318}
2319
fsamuel@chromium.org10dcfd82012-03-27 00:09:12 +00002320#ifndef NDEBUG
2321void RenderLayerBacking::verifyNotPainting()
2322{
akling@apple.com32c7a6e2013-08-26 02:21:32 +00002323 ASSERT(!renderer().frame().page() || !renderer().frame().page()->isPainting());
fsamuel@chromium.org10dcfd82012-03-27 00:09:12 +00002324}
2325#endif
2326
simon.fraser@apple.comd2fbbe12009-12-11 20:57:27 +00002327bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002328{
2329 bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
akling@apple.com32c7a6e2013-08-26 02:21:32 +00002330 bool hasTransform = renderer().isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002331 bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002332
2333 if (!hasOpacity && !hasTransform && !hasFilter)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002334 return false;
2335
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00002336 KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
2337 KeyframeValueList opacityVector(AnimatedPropertyOpacity);
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002338 KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002339
simon.fraser@apple.comc0065e02010-08-28 17:38:59 +00002340 size_t numKeyframes = keyframes.size();
2341 for (size_t i = 0; i < numKeyframes; ++i) {
2342 const KeyframeValue& currentKeyframe = keyframes[i];
2343 const RenderStyle* keyframeStyle = currentKeyframe.style();
dino@apple.com3b2749f2013-08-30 21:32:17 +00002344 double key = currentKeyframe.key();
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002345
2346 if (!keyframeStyle)
2347 continue;
2348
bfulgham@apple.com55c6e0b2014-04-18 00:44:53 +00002349 TimingFunction* tf = currentKeyframe.timingFunction(keyframes.animationName());
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002350
simon.fraser@apple.com4c723aa2010-10-27 16:47:46 +00002351 bool isFirstOrLastKeyframe = key == 0 || key == 1;
2352 if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitTransform))
andersca@apple.com963e45b2013-05-07 22:04:01 +00002353 transformVector.insert(TransformAnimationValue::create(key, keyframeStyle->transform(), tf));
2354
simon.fraser@apple.com4c723aa2010-10-27 16:47:46 +00002355 if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
andersca@apple.com963e45b2013-05-07 22:04:01 +00002356 opacityVector.insert(FloatAnimationValue::create(key, keyframeStyle->opacity(), tf));
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002357
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002358 if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
commit-queue@webkit.org424b0fc2013-06-18 23:39:44 +00002359 filterVector.insert(FilterAnimationValue::create(key, keyframeStyle->filter(), tf));
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002360 }
2361
dino@apple.com62700e42013-09-26 22:29:07 +00002362 if (renderer().frame().page() && !renderer().frame().page()->settings().acceleratedCompositedAnimationsEnabled())
2363 return false;
2364
darin@apple.comac48be72013-05-07 04:31:35 +00002365 bool didAnimate = false;
dino@apple.com62700e42013-09-26 22:29:07 +00002366
cdumez@apple.com0abff8b2014-10-17 21:25:10 +00002367 if (hasTransform && m_graphicsLayer->addAnimation(transformVector, downcast<RenderBox>(renderer()).pixelSnappedBorderBoxRect().size(), anim, keyframes.animationName(), timeOffset))
darin@apple.comac48be72013-05-07 04:31:35 +00002368 didAnimate = true;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002369
simon.fraser@apple.com73b28912012-05-03 18:15:41 +00002370 if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
darin@apple.comac48be72013-05-07 04:31:35 +00002371 didAnimate = true;
simon.fraser@apple.com02f40492009-07-07 17:15:16 +00002372
simon.fraser@apple.com73b28912012-05-03 18:15:41 +00002373 if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
darin@apple.comac48be72013-05-07 04:31:35 +00002374 didAnimate = true;
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002375
darin@apple.comac48be72013-05-07 04:31:35 +00002376 return didAnimate;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002377}
2378
simon.fraser@apple.com1ae63fb2010-09-24 04:17:03 +00002379void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
2380{
2381 m_graphicsLayer->pauseAnimation(animationName, timeOffset);
2382}
2383
2384void RenderLayerBacking::animationFinished(const String& animationName)
2385{
2386 m_graphicsLayer->removeAnimation(animationName);
2387}
2388
alexis.menard@openbossa.org37efa872012-04-04 19:33:22 +00002389bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002390{
darin@apple.comac48be72013-05-07 04:31:35 +00002391 bool didAnimate = false;
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002392
alexis.menard@openbossa.org37efa872012-04-04 19:33:22 +00002393 ASSERT(property != CSSPropertyInvalid);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002394
alexis.menard@openbossa.org37efa872012-04-04 19:33:22 +00002395 if (property == CSSPropertyOpacity) {
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002396 const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
2397 if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00002398 KeyframeValueList opacityVector(AnimatedPropertyOpacity);
andersca@apple.com963e45b2013-05-07 22:04:01 +00002399 opacityVector.insert(FloatAnimationValue::create(0, compositingOpacity(fromStyle->opacity())));
2400 opacityVector.insert(FloatAnimationValue::create(1, compositingOpacity(toStyle->opacity())));
simon.fraser@apple.comf159ab02009-09-17 20:12:50 +00002401 // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
zalan@apple.com1bc188e2014-03-09 20:27:31 +00002402 if (m_graphicsLayer->addAnimation(opacityVector, FloatSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
simon.fraser@apple.com99d1c052009-10-20 00:38:26 +00002403 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00002404 updateOpacity(*toStyle);
darin@apple.comac48be72013-05-07 04:31:35 +00002405 didAnimate = true;
simon.fraser@apple.com99d1c052009-10-20 00:38:26 +00002406 }
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002407 }
2408 }
2409
akling@apple.comc68fe752013-10-13 18:39:27 +00002410 if (property == CSSPropertyWebkitTransform && m_owningLayer.hasTransform()) {
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002411 const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform);
2412 if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00002413 KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
andersca@apple.com963e45b2013-05-07 22:04:01 +00002414 transformVector.insert(TransformAnimationValue::create(0, fromStyle->transform()));
2415 transformVector.insert(TransformAnimationValue::create(1, toStyle->transform()));
cdumez@apple.com0abff8b2014-10-17 21:25:10 +00002416 if (m_graphicsLayer->addAnimation(transformVector, downcast<RenderBox>(renderer()).pixelSnappedBorderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002417 // To ensure that the correct transform is visible when the animation ends, also set the final transform.
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00002418 updateTransform(*toStyle);
darin@apple.comac48be72013-05-07 04:31:35 +00002419 didAnimate = true;
simon.fraser@apple.com99d1c052009-10-20 00:38:26 +00002420 }
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002421 }
2422 }
simon.fraser@apple.com02f40492009-07-07 17:15:16 +00002423
akling@apple.comc68fe752013-10-13 18:39:27 +00002424 if (property == CSSPropertyWebkitFilter && m_owningLayer.hasFilter()) {
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002425 const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter);
2426 if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
2427 KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
commit-queue@webkit.org424b0fc2013-06-18 23:39:44 +00002428 filterVector.insert(FilterAnimationValue::create(0, fromStyle->filter()));
2429 filterVector.insert(FilterAnimationValue::create(1, toStyle->filter()));
zalan@apple.com1bc188e2014-03-09 20:27:31 +00002430 if (m_graphicsLayer->addAnimation(filterVector, FloatSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset)) {
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002431 // To ensure that the correct filter is visible when the animation ends, also set the final filter.
simon.fraser@apple.com33e25452014-05-19 15:53:37 +00002432 updateFilters(*toStyle);
darin@apple.comac48be72013-05-07 04:31:35 +00002433 didAnimate = true;
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002434 }
2435 }
2436 }
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002437
darin@apple.comac48be72013-05-07 04:31:35 +00002438 return didAnimate;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002439}
2440
alexis.menard@openbossa.org8fb368f2012-04-05 03:08:10 +00002441void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID property)
simon.fraser@apple.com1ae63fb2010-09-24 04:17:03 +00002442{
2443 AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2444 if (animatedProperty != AnimatedPropertyInvalid)
2445 m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
2446}
2447
alexis.menard@openbossa.org8fb368f2012-04-05 03:08:10 +00002448void RenderLayerBacking::transitionFinished(CSSPropertyID property)
simon.fraser@apple.com1ae63fb2010-09-24 04:17:03 +00002449{
2450 AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2451 if (animatedProperty != AnimatedPropertyInvalid)
2452 m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
2453}
2454
simon.fraser@apple.coma30c96f2014-08-21 22:43:18 +00002455void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, const String&, double time)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002456{
cdumez@apple.combc6f7402014-10-17 01:53:09 +00002457 renderer().animation().notifyAnimationStarted(renderer(), time);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002458}
2459
antti@apple.coma6775c12013-04-05 21:19:56 +00002460void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer* layer)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002461{
akling@apple.com32c7a6e2013-08-26 02:21:32 +00002462 if (renderer().documentBeingDestroyed())
antti@apple.coma6775c12013-04-05 21:19:56 +00002463 return;
akling@apple.comc3466042013-08-24 18:27:32 +00002464 compositor().scheduleLayerFlush(layer->canThrottleLayerFlush());
simon.fraser@apple.com8717fee2009-07-31 23:03:25 +00002465}
2466
simon.fraser@apple.com90274bf2012-10-18 00:42:05 +00002467void RenderLayerBacking::notifyFlushBeforeDisplayRefresh(const GraphicsLayer* layer)
2468{
akling@apple.comc3466042013-08-24 18:27:32 +00002469 compositor().notifyFlushBeforeDisplayRefresh(layer);
simon.fraser@apple.com90274bf2012-10-18 00:42:05 +00002470}
2471
simon.fraser@apple.com1ae63fb2010-09-24 04:17:03 +00002472// This is used for the 'freeze' API, for testing only.
simon.fraser@apple.com6510a132009-08-03 19:40:12 +00002473void RenderLayerBacking::suspendAnimations(double time)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002474{
simon.fraser@apple.com6510a132009-08-03 19:40:12 +00002475 m_graphicsLayer->suspendAnimations(time);
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002476}
2477
2478void RenderLayerBacking::resumeAnimations()
2479{
2480 m_graphicsLayer->resumeAnimations();
2481}
2482
allan.jensen@digia.comd5cbc752013-08-13 17:08:19 +00002483LayoutRect RenderLayerBacking::compositedBounds() const
simon.fraser@apple.comb2fc99c2009-06-22 22:45:24 +00002484{
2485 return m_compositedBounds;
2486}
2487
allan.jensen@digia.comd5cbc752013-08-13 17:08:19 +00002488void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
simon.fraser@apple.comb2fc99c2009-06-22 22:45:24 +00002489{
2490 m_compositedBounds = bounds;
simon.fraser@apple.comb2fc99c2009-06-22 22:45:24 +00002491}
simon.fraser@apple.comce9b3f02012-05-03 17:50:03 +00002492
bdakin@apple.com8af619c2013-11-21 21:57:53 +00002493LayoutRect RenderLayerBacking::compositedBoundsIncludingMargin() const
2494{
2495 TiledBacking* tiledBacking = this->tiledBacking();
2496 if (!tiledBacking || !tiledBacking->hasMargins())
2497 return compositedBounds();
2498
2499 LayoutRect boundsIncludingMargin = compositedBounds();
2500 LayoutUnit leftMarginWidth = tiledBacking->leftMarginWidth();
2501 LayoutUnit topMarginHeight = tiledBacking->topMarginHeight();
2502
zalan@apple.coma95fd6f2014-02-22 07:24:45 +00002503 boundsIncludingMargin.moveBy(LayoutPoint(-leftMarginWidth, -topMarginHeight));
2504 boundsIncludingMargin.expand(leftMarginWidth + tiledBacking->rightMarginWidth(), topMarginHeight + tiledBacking->bottomMarginHeight());
bdakin@apple.com8af619c2013-11-21 21:57:53 +00002505
2506 return boundsIncludingMargin;
2507}
2508
alexis.menard@openbossa.org8fb368f2012-04-05 03:08:10 +00002509CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002510{
alexis.menard@openbossa.org8fb368f2012-04-05 03:08:10 +00002511 CSSPropertyID cssProperty = CSSPropertyInvalid;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002512 switch (property) {
2513 case AnimatedPropertyWebkitTransform:
2514 cssProperty = CSSPropertyWebkitTransform;
2515 break;
2516 case AnimatedPropertyOpacity:
2517 cssProperty = CSSPropertyOpacity;
2518 break;
2519 case AnimatedPropertyBackgroundColor:
2520 cssProperty = CSSPropertyBackgroundColor;
2521 break;
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002522 case AnimatedPropertyWebkitFilter:
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002523 cssProperty = CSSPropertyWebkitFilter;
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002524 break;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002525 case AnimatedPropertyInvalid:
2526 ASSERT_NOT_REACHED();
2527 }
2528 return cssProperty;
2529}
2530
alexis.menard@openbossa.org8fb368f2012-04-05 03:08:10 +00002531AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002532{
2533 switch (cssProperty) {
2534 case CSSPropertyWebkitTransform:
2535 return AnimatedPropertyWebkitTransform;
2536 case CSSPropertyOpacity:
2537 return AnimatedPropertyOpacity;
2538 case CSSPropertyBackgroundColor:
2539 return AnimatedPropertyBackgroundColor;
cmarrin@apple.com5b6f59f2012-02-10 19:41:35 +00002540 case CSSPropertyWebkitFilter:
2541 return AnimatedPropertyWebkitFilter;
alexis.menard@openbossa.org8fb368f2012-04-05 03:08:10 +00002542 default:
2543 // It's fine if we see other css properties here; they are just not accelerated.
2544 break;
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002545 }
2546 return AnimatedPropertyInvalid;
2547}
2548
simon.fraser@apple.comb73688b2010-07-14 23:17:20 +00002549CompositingLayerType RenderLayerBacking::compositingLayerType() const
2550{
simon.fraser@apple.comff549312014-04-19 05:31:39 +00002551 if (m_graphicsLayer->usesContentsLayer())
simon.fraser@apple.comb73688b2010-07-14 23:17:20 +00002552 return MediaCompositingLayer;
2553
2554 if (m_graphicsLayer->drawsContent())
simon.fraser@apple.comfb15c722013-03-12 17:54:44 +00002555 return m_graphicsLayer->usingTiledBacking() ? TiledCompositingLayer : NormalCompositingLayer;
simon.fraser@apple.comb73688b2010-07-14 23:17:20 +00002556
2557 return ContainerCompositingLayer;
2558}
2559
simon.fraser@apple.coma46313b2012-06-28 20:28:42 +00002560double RenderLayerBacking::backingStoreMemoryEstimate() const
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002561{
simon.fraser@apple.coma46313b2012-06-28 20:28:42 +00002562 double backingMemory;
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002563
simon.fraser@apple.comce5450e2013-01-16 02:01:39 +00002564 // m_ancestorClippingLayer, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
simon.fraser@apple.coma46313b2012-06-28 20:28:42 +00002565 backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002566 if (m_foregroundLayer)
simon.fraser@apple.coma46313b2012-06-28 20:28:42 +00002567 backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
simon.fraser@apple.comee9213c2013-01-18 00:10:53 +00002568 if (m_backgroundLayer)
2569 backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002570 if (m_maskLayer)
simon.fraser@apple.coma46313b2012-06-28 20:28:42 +00002571 backingMemory += m_maskLayer->backingStoreMemoryEstimate();
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002572
commit-queue@webkit.org45a7e932012-08-25 00:35:34 +00002573 if (m_scrollingContentsLayer)
2574 backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
2575
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002576 if (m_layerForHorizontalScrollbar)
simon.fraser@apple.coma46313b2012-06-28 20:28:42 +00002577 backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002578
2579 if (m_layerForVerticalScrollbar)
simon.fraser@apple.coma46313b2012-06-28 20:28:42 +00002580 backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002581
2582 if (m_layerForScrollCorner)
simon.fraser@apple.coma46313b2012-06-28 20:28:42 +00002583 backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002584
simon.fraser@apple.coma46313b2012-06-28 20:28:42 +00002585 return backingMemory;
simon.fraser@apple.coma7f01bd2012-04-25 04:30:13 +00002586}
2587
simon.fraser@apple.com6d640a02009-01-31 01:47:49 +00002588} // namespace WebCore