| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. | |
| 3 * | |
| 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 | |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
| 17 * 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 "sky/engine/config.h" | |
| 27 | |
| 28 #include "sky/engine/core/rendering/compositing/RenderLayerCompositor.h" | |
| 29 | |
| 30 #include "gen/sky/platform/RuntimeEnabledFeatures.h" | |
| 31 #include "sky/engine/core/animation/DocumentAnimations.h" | |
| 32 #include "sky/engine/core/frame/FrameView.h" | |
| 33 #include "sky/engine/core/frame/LocalFrame.h" | |
| 34 #include "sky/engine/core/frame/Settings.h" | |
| 35 #include "sky/engine/core/inspector/InspectorNodeIds.h" | |
| 36 #include "sky/engine/core/page/Chrome.h" | |
| 37 #include "sky/engine/core/page/ChromeClient.h" | |
| 38 #include "sky/engine/core/page/Page.h" | |
| 39 #include "sky/engine/core/rendering/RenderLayerStackingNode.h" | |
| 40 #include "sky/engine/core/rendering/RenderLayerStackingNodeIterator.h" | |
| 41 #include "sky/engine/core/rendering/RenderView.h" | |
| 42 #include "sky/engine/platform/ScriptForbiddenScope.h" | |
| 43 #include "sky/engine/platform/TraceEvent.h" | |
| 44 #include "sky/engine/platform/graphics/GraphicsLayer.h" | |
| 45 #include "sky/engine/public/platform/Platform.h" | |
| 46 | |
| 47 namespace blink { | |
| 48 | |
| 49 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView) | |
| 50 : m_renderView(renderView) | |
| 51 , m_compositingReasonFinder(renderView) | |
| 52 , m_pendingUpdateType(CompositingUpdateNone) | |
| 53 , m_compositing(false) | |
| 54 , m_rootShouldAlwaysCompositeDirty(true) | |
| 55 , m_needsUpdateFixedBackground(false) | |
| 56 , m_isTrackingPaintInvalidations(false) | |
| 57 , m_rootLayerAttachment(RootLayerUnattached) | |
| 58 { | |
| 59 updateAcceleratedCompositingSettings(); | |
| 60 } | |
| 61 | |
| 62 RenderLayerCompositor::~RenderLayerCompositor() | |
| 63 { | |
| 64 ASSERT(m_rootLayerAttachment == RootLayerUnattached); | |
| 65 } | |
| 66 | |
| 67 bool RenderLayerCompositor::inCompositingMode() const | |
| 68 { | |
| 69 // FIXME: This should assert that lificycle is >= CompositingClean since | |
| 70 // the last step of updateIfNeeded can set this bit to false. | |
| 71 ASSERT(!m_rootShouldAlwaysCompositeDirty); | |
| 72 return m_compositing; | |
| 73 } | |
| 74 | |
| 75 bool RenderLayerCompositor::staleInCompositingMode() const | |
| 76 { | |
| 77 return m_compositing; | |
| 78 } | |
| 79 | |
| 80 void RenderLayerCompositor::setCompositingModeEnabled(bool enable) | |
| 81 { | |
| 82 if (enable == m_compositing) | |
| 83 return; | |
| 84 | |
| 85 m_compositing = enable; | |
| 86 | |
| 87 if (m_compositing) | |
| 88 ensureRootLayer(); | |
| 89 else | |
| 90 destroyRootLayer(); | |
| 91 } | |
| 92 | |
| 93 void RenderLayerCompositor::enableCompositingModeIfNeeded() | |
| 94 { | |
| 95 if (!m_rootShouldAlwaysCompositeDirty) | |
| 96 return; | |
| 97 | |
| 98 m_rootShouldAlwaysCompositeDirty = false; | |
| 99 if (m_compositing) | |
| 100 return; | |
| 101 | |
| 102 if (rootShouldAlwaysComposite()) { | |
| 103 // FIXME: Is this needed? It was added in https://bugs.webkit.org/show_b
ug.cgi?id=26651. | |
| 104 // No tests fail if it's deleted. | |
| 105 setNeedsCompositingUpdate(CompositingUpdateRebuildTree); | |
| 106 setCompositingModeEnabled(true); | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 bool RenderLayerCompositor::rootShouldAlwaysComposite() const | |
| 111 { | |
| 112 return false; | |
| 113 } | |
| 114 | |
| 115 void RenderLayerCompositor::updateAcceleratedCompositingSettings() | |
| 116 { | |
| 117 m_compositingReasonFinder.updateTriggers(); | |
| 118 m_rootShouldAlwaysCompositeDirty = true; | |
| 119 } | |
| 120 | |
| 121 bool RenderLayerCompositor::hasAcceleratedCompositing() const | |
| 122 { | |
| 123 return false; | |
| 124 } | |
| 125 | |
| 126 bool RenderLayerCompositor::layerSquashingEnabled() const | |
| 127 { | |
| 128 if (!RuntimeEnabledFeatures::layerSquashingEnabled()) | |
| 129 return false; | |
| 130 return true; | |
| 131 } | |
| 132 | |
| 133 bool RenderLayerCompositor::preferCompositingToLCDTextEnabled() const | |
| 134 { | |
| 135 return m_compositingReasonFinder.hasOverflowScrollTrigger(); | |
| 136 } | |
| 137 | |
| 138 void RenderLayerCompositor::updateIfNeededRecursive() | |
| 139 { | |
| 140 TRACE_EVENT0("blink", "RenderLayerCompositor::updateIfNeededRecursive"); | |
| 141 | |
| 142 ASSERT(!m_renderView.needsLayout()); | |
| 143 | |
| 144 ScriptForbiddenScope forbidScript; | |
| 145 | |
| 146 // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebui
ldTree, | |
| 147 // which asserts that it's not InCompositingUpdate. | |
| 148 enableCompositingModeIfNeeded(); | |
| 149 | |
| 150 lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate); | |
| 151 updateIfNeeded(); | |
| 152 lifecycle().advanceTo(DocumentLifecycle::CompositingClean); | |
| 153 | |
| 154 DocumentAnimations::startPendingAnimations(m_renderView.document()); | |
| 155 | |
| 156 #if ENABLE(ASSERT) | |
| 157 ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean); | |
| 158 assertNoUnresolvedDirtyBits(); | |
| 159 #endif | |
| 160 } | |
| 161 | |
| 162 void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType upda
teType) | |
| 163 { | |
| 164 ASSERT(updateType != CompositingUpdateNone); | |
| 165 m_pendingUpdateType = std::max(m_pendingUpdateType, updateType); | |
| 166 page()->animator().scheduleVisualUpdate(); | |
| 167 lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean); | |
| 168 } | |
| 169 | |
| 170 void RenderLayerCompositor::didLayout() | |
| 171 { | |
| 172 // FIXME: Technically we only need to do this when the FrameView's | |
| 173 // isScrollable method would return a different value. | |
| 174 m_rootShouldAlwaysCompositeDirty = true; | |
| 175 enableCompositingModeIfNeeded(); | |
| 176 | |
| 177 // FIXME: Rather than marking the entire RenderView as dirty, we should | |
| 178 // track which RenderLayers moved during layout and only dirty those | |
| 179 // specific RenderLayers. | |
| 180 rootRenderLayer()->setNeedsCompositingInputsUpdate(); | |
| 181 } | |
| 182 | |
| 183 #if ENABLE(ASSERT) | |
| 184 | |
| 185 void RenderLayerCompositor::assertNoUnresolvedDirtyBits() | |
| 186 { | |
| 187 ASSERT(m_pendingUpdateType == CompositingUpdateNone); | |
| 188 ASSERT(!m_rootShouldAlwaysCompositeDirty); | |
| 189 } | |
| 190 | |
| 191 #endif | |
| 192 | |
| 193 void RenderLayerCompositor::updateWithoutAcceleratedCompositing(CompositingUpdat
eType updateType) | |
| 194 { | |
| 195 } | |
| 196 | |
| 197 void RenderLayerCompositor::updateIfNeeded() | |
| 198 { | |
| 199 m_pendingUpdateType = CompositingUpdateNone; | |
| 200 } | |
| 201 | |
| 202 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer*,
const CompositingStateTransitionType) | |
| 203 { | |
| 204 return false; | |
| 205 } | |
| 206 | |
| 207 void RenderLayerCompositor::paintInvalidationOnCompositingChange(RenderLayer* la
yer) | |
| 208 { | |
| 209 // If the renderer is not attached yet, no need to issue paint invalidations
. | |
| 210 if (layer->renderer() != &m_renderView && !layer->renderer()->parent()) | |
| 211 return; | |
| 212 | |
| 213 // For querying RenderLayer::compositingState() | |
| 214 // Eager invalidation here is correct, since we are invalidating with respec
t to the previous frame's | |
| 215 // compositing state when changing the compositing backing of the layer. | |
| 216 DisableCompositingQueryAsserts disabler; | |
| 217 | |
| 218 layer->paintInvalidator().paintInvalidationIncludingNonCompositingDescendant
s(); | |
| 219 } | |
| 220 | |
| 221 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsO
ffset) | |
| 222 { | |
| 223 if (m_overflowControlsHostLayer) | |
| 224 m_overflowControlsHostLayer->setPosition(contentsOffset); | |
| 225 } | |
| 226 | |
| 227 void RenderLayerCompositor::frameViewDidChangeSize() | |
| 228 { | |
| 229 if (m_containerLayer) { | |
| 230 FrameView* frameView = m_renderView.frameView(); | |
| 231 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 void RenderLayerCompositor::rootFixedBackgroundsChanged() | |
| 236 { | |
| 237 if (!supportsFixedRootBackgroundCompositing()) | |
| 238 return; | |
| 239 | |
| 240 // To avoid having to make the fixed root background layer fixed positioned
to | |
| 241 // stay put, we position it in the layer tree as follows: | |
| 242 // | |
| 243 // + Overflow controls host | |
| 244 // + LocalFrame clip | |
| 245 // + (Fixed root background) <-- Here. | |
| 246 // + LocalFrame scroll | |
| 247 // + Root content layer | |
| 248 // + Scrollbars | |
| 249 // | |
| 250 // That is, it needs to be the first child of the frame clip, the sibling of | |
| 251 // the frame scroll layer. The compositor does not own the background layer,
it | |
| 252 // just positions it (like the foreground layer). | |
| 253 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer()) | |
| 254 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get()); | |
| 255 } | |
| 256 | |
| 257 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags) | |
| 258 { | |
| 259 ASSERT(lifecycle().state() >= DocumentLifecycle::PaintInvalidationClean); | |
| 260 | |
| 261 if (!m_rootContentLayer) | |
| 262 return String(); | |
| 263 | |
| 264 // We skip dumping the scroll and clip layers to keep layerTreeAsText output | |
| 265 // similar between platforms (unless we explicitly request dumping from the | |
| 266 // root. | |
| 267 GraphicsLayer* rootLayer = m_rootContentLayer.get(); | |
| 268 if (flags & LayerTreeIncludesRootLayer) | |
| 269 rootLayer = rootGraphicsLayer(); | |
| 270 | |
| 271 String layerTreeText = rootLayer->layerTreeAsText(flags); | |
| 272 | |
| 273 // The true root layer is not included in the dump, so if we want to report | |
| 274 // its paint invalidation rects, they must be included here. | |
| 275 if (flags & LayerTreeIncludesPaintInvalidationRects) | |
| 276 return m_renderView.frameView()->trackedPaintInvalidationRectsAsText() +
layerTreeText; | |
| 277 | |
| 278 return layerTreeText; | |
| 279 } | |
| 280 | |
| 281 static void fullyInvalidatePaintRecursive(RenderLayer* layer) | |
| 282 { | |
| 283 for (RenderLayer* child = layer->firstChild(); child; child = child->nextSib
ling()) | |
| 284 fullyInvalidatePaintRecursive(child); | |
| 285 } | |
| 286 | |
| 287 void RenderLayerCompositor::fullyInvalidatePaint() | |
| 288 { | |
| 289 // We're walking all compositing layers and invalidating them, so there's | |
| 290 // no need to have up-to-date compositing state. | |
| 291 DisableCompositingQueryAsserts disabler; | |
| 292 fullyInvalidatePaintRecursive(rootRenderLayer()); | |
| 293 } | |
| 294 | |
| 295 RenderLayer* RenderLayerCompositor::rootRenderLayer() const | |
| 296 { | |
| 297 return m_renderView.layer(); | |
| 298 } | |
| 299 | |
| 300 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const | |
| 301 { | |
| 302 if (m_overflowControlsHostLayer) | |
| 303 return m_overflowControlsHostLayer.get(); | |
| 304 return m_rootContentLayer.get(); | |
| 305 } | |
| 306 | |
| 307 GraphicsLayer* RenderLayerCompositor::scrollLayer() const | |
| 308 { | |
| 309 return m_scrollLayer.get(); | |
| 310 } | |
| 311 | |
| 312 GraphicsLayer* RenderLayerCompositor::containerLayer() const | |
| 313 { | |
| 314 return m_containerLayer.get(); | |
| 315 } | |
| 316 | |
| 317 GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer() | |
| 318 { | |
| 319 ASSERT(rootGraphicsLayer()); | |
| 320 | |
| 321 if (!m_rootTransformLayer.get()) { | |
| 322 m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), thi
s); | |
| 323 m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get()); | |
| 324 m_rootTransformLayer->addChild(m_containerLayer.get()); | |
| 325 } | |
| 326 | |
| 327 return m_rootTransformLayer.get(); | |
| 328 } | |
| 329 | |
| 330 void RenderLayerCompositor::setIsInWindow(bool isInWindow) | |
| 331 { | |
| 332 if (!staleInCompositingMode()) | |
| 333 return; | |
| 334 | |
| 335 if (isInWindow) { | |
| 336 if (m_rootLayerAttachment != RootLayerUnattached) | |
| 337 return; | |
| 338 | |
| 339 RootLayerAttachment attachment = RootLayerAttachedViaChromeClient; | |
| 340 attachRootLayer(attachment); | |
| 341 } else { | |
| 342 if (m_rootLayerAttachment == RootLayerUnattached) | |
| 343 return; | |
| 344 | |
| 345 detachRootLayer(); | |
| 346 } | |
| 347 } | |
| 348 | |
| 349 void RenderLayerCompositor::updateRootLayerPosition() | |
| 350 { | |
| 351 if (m_rootContentLayer) { | |
| 352 const IntRect& documentRect = m_renderView.documentRect(); | |
| 353 m_rootContentLayer->setSize(documentRect.size()); | |
| 354 m_rootContentLayer->setPosition(documentRect.location()); | |
| 355 } | |
| 356 if (m_containerLayer) { | |
| 357 FrameView* frameView = m_renderView.frameView(); | |
| 358 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 void RenderLayerCompositor::updatePotentialCompositingReasonsFromStyle(RenderLay
er* layer) | |
| 363 { | |
| 364 layer->setPotentialCompositingReasonsFromStyle(m_compositingReasonFinder.pot
entialCompositingReasonsFromStyle(layer->renderer())); | |
| 365 } | |
| 366 | |
| 367 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer) | |
| 368 { | |
| 369 layer->setCompositingReasons(m_compositingReasonFinder.directReasons(layer),
CompositingReasonComboAllDirectReasons); | |
| 370 } | |
| 371 | |
| 372 void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer) | |
| 373 { | |
| 374 ASSERT(rootGraphicsLayer()); | |
| 375 | |
| 376 if (layer->parent() != m_overflowControlsHostLayer.get()) | |
| 377 m_overflowControlsHostLayer->addChild(layer); | |
| 378 } | |
| 379 | |
| 380 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const | |
| 381 { | |
| 382 // FIXME: We disable accelerated compositing for elements in a RenderFlowThr
ead as it doesn't work properly. | |
| 383 // See http://webkit.org/b/84900 to re-enable it. | |
| 384 return layer->isSelfPaintingLayer(); | |
| 385 } | |
| 386 | |
| 387 // Return true if the given layer is a stacking context and has compositing chil
d | |
| 388 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer | |
| 389 // into the hierarchy between this layer and its children in the z-order hierarc
hy. | |
| 390 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer
) const | |
| 391 { | |
| 392 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOver
flowClip(); | |
| 393 } | |
| 394 | |
| 395 // If an element has negative z-index children, those children render in front o
f the | |
| 396 // layer background, so we need an extra 'contents' layer for the foreground of
the layer | |
| 397 // object. | |
| 398 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* lay
er) const | |
| 399 { | |
| 400 return layer->stackingNode()->hasNegativeZOrderList(); | |
| 401 } | |
| 402 | |
| 403 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, Gr
aphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip) | |
| 404 { | |
| 405 // FIXME(sky): Remove. | |
| 406 } | |
| 407 | |
| 408 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const | |
| 409 { | |
| 410 if (Settings* settings = m_renderView.document().settings()) | |
| 411 return settings->preferCompositingToLCDTextEnabled(); | |
| 412 return false; | |
| 413 } | |
| 414 | |
| 415 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* lay
er) const | |
| 416 { | |
| 417 if (layer != m_renderView.layer()) | |
| 418 return false; | |
| 419 | |
| 420 return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgrou
ndIsEntirelyFixed(); | |
| 421 } | |
| 422 | |
| 423 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const | |
| 424 { | |
| 425 return 0; | |
| 426 } | |
| 427 | |
| 428 static void resetTrackedPaintInvalidationRectsRecursive(GraphicsLayer* graphicsL
ayer) | |
| 429 { | |
| 430 if (!graphicsLayer) | |
| 431 return; | |
| 432 | |
| 433 graphicsLayer->resetTrackedPaintInvalidations(); | |
| 434 | |
| 435 for (size_t i = 0; i < graphicsLayer->children().size(); ++i) | |
| 436 resetTrackedPaintInvalidationRectsRecursive(graphicsLayer->children()[i]
); | |
| 437 | |
| 438 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer()) | |
| 439 resetTrackedPaintInvalidationRectsRecursive(maskLayer); | |
| 440 | |
| 441 if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLa
yer()) | |
| 442 resetTrackedPaintInvalidationRectsRecursive(clippingMaskLayer); | |
| 443 } | |
| 444 | |
| 445 void RenderLayerCompositor::resetTrackedPaintInvalidationRects() | |
| 446 { | |
| 447 if (GraphicsLayer* rootLayer = rootGraphicsLayer()) | |
| 448 resetTrackedPaintInvalidationRectsRecursive(rootLayer); | |
| 449 } | |
| 450 | |
| 451 void RenderLayerCompositor::setTracksPaintInvalidations(bool tracksPaintInvalida
tions) | |
| 452 { | |
| 453 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationClean); | |
| 454 m_isTrackingPaintInvalidations = tracksPaintInvalidations; | |
| 455 } | |
| 456 | |
| 457 bool RenderLayerCompositor::isTrackingPaintInvalidations() const | |
| 458 { | |
| 459 return m_isTrackingPaintInvalidations; | |
| 460 } | |
| 461 | |
| 462 void RenderLayerCompositor::ensureRootLayer() | |
| 463 { | |
| 464 RootLayerAttachment expectedAttachment = RootLayerAttachedViaChromeClient; | |
| 465 if (expectedAttachment == m_rootLayerAttachment) | |
| 466 return; | |
| 467 | |
| 468 if (!m_rootContentLayer) { | |
| 469 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this)
; | |
| 470 IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect(); | |
| 471 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.
maxY())); | |
| 472 m_rootContentLayer->setPosition(FloatPoint()); | |
| 473 m_rootContentLayer->setOwnerNodeId(InspectorNodeIds::idForNode(m_renderV
iew.node())); | |
| 474 | |
| 475 // Need to clip to prevent transformed content showing outside this fram
e | |
| 476 m_rootContentLayer->setMasksToBounds(true); | |
| 477 } | |
| 478 | |
| 479 if (!m_overflowControlsHostLayer) { | |
| 480 ASSERT(!m_scrollLayer); | |
| 481 ASSERT(!m_containerLayer); | |
| 482 | |
| 483 // Create a layer to host the clipping layer and the overflow controls l
ayers. | |
| 484 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory
(), this); | |
| 485 | |
| 486 // Create a clipping layer if this is an iframe or settings require to c
lip. | |
| 487 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this); | |
| 488 bool containerMasksToBounds = false; | |
| 489 if (Settings* settings = m_renderView.document().settings()) { | |
| 490 if (settings->mainFrameClipsContent()) | |
| 491 containerMasksToBounds = true; | |
| 492 } | |
| 493 m_containerLayer->setMasksToBounds(containerMasksToBounds); | |
| 494 | |
| 495 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this); | |
| 496 | |
| 497 // Hook them up | |
| 498 m_overflowControlsHostLayer->addChild(m_containerLayer.get()); | |
| 499 m_containerLayer->addChild(m_scrollLayer.get()); | |
| 500 m_scrollLayer->addChild(m_rootContentLayer.get()); | |
| 501 | |
| 502 frameViewDidChangeSize(); | |
| 503 } | |
| 504 | |
| 505 // Check to see if we have to change the attachment | |
| 506 if (m_rootLayerAttachment != RootLayerUnattached) | |
| 507 detachRootLayer(); | |
| 508 | |
| 509 attachRootLayer(expectedAttachment); | |
| 510 } | |
| 511 | |
| 512 void RenderLayerCompositor::destroyRootLayer() | |
| 513 { | |
| 514 if (!m_rootContentLayer) | |
| 515 return; | |
| 516 | |
| 517 detachRootLayer(); | |
| 518 | |
| 519 if (m_overflowControlsHostLayer) { | |
| 520 m_overflowControlsHostLayer = nullptr; | |
| 521 m_containerLayer = nullptr; | |
| 522 m_scrollLayer = nullptr; | |
| 523 } | |
| 524 ASSERT(!m_scrollLayer); | |
| 525 m_rootContentLayer = nullptr; | |
| 526 m_rootTransformLayer = nullptr; | |
| 527 } | |
| 528 | |
| 529 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment) | |
| 530 { | |
| 531 if (!m_rootContentLayer) | |
| 532 return; | |
| 533 | |
| 534 switch (attachment) { | |
| 535 case RootLayerUnattached: | |
| 536 ASSERT_NOT_REACHED(); | |
| 537 break; | |
| 538 case RootLayerAttachedViaChromeClient: { | |
| 539 LocalFrame& frame = m_renderView.frameView()->frame(); | |
| 540 Page* page = frame.page(); | |
| 541 if (!page) | |
| 542 return; | |
| 543 page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer())
; | |
| 544 break; | |
| 545 } | |
| 546 case RootLayerAttachedViaEnclosingFrame: { | |
| 547 ASSERT_NOT_REACHED(); | |
| 548 } | |
| 549 } | |
| 550 | |
| 551 m_rootLayerAttachment = attachment; | |
| 552 } | |
| 553 | |
| 554 void RenderLayerCompositor::detachRootLayer() | |
| 555 { | |
| 556 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached) | |
| 557 return; | |
| 558 | |
| 559 switch (m_rootLayerAttachment) { | |
| 560 case RootLayerAttachedViaEnclosingFrame: { | |
| 561 ASSERT_NOT_REACHED(); | |
| 562 } | |
| 563 case RootLayerAttachedViaChromeClient: { | |
| 564 LocalFrame& frame = m_renderView.frameView()->frame(); | |
| 565 Page* page = frame.page(); | |
| 566 if (!page) | |
| 567 return; | |
| 568 page->chrome().client().attachRootGraphicsLayer(0); | |
| 569 } | |
| 570 break; | |
| 571 case RootLayerUnattached: | |
| 572 break; | |
| 573 } | |
| 574 | |
| 575 m_rootLayerAttachment = RootLayerUnattached; | |
| 576 } | |
| 577 | |
| 578 void RenderLayerCompositor::updateRootLayerAttachment() | |
| 579 { | |
| 580 ensureRootLayer(); | |
| 581 } | |
| 582 | |
| 583 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const | |
| 584 { | |
| 585 if (Page* page = this->page()) | |
| 586 return page->chrome().client().graphicsLayerFactory(); | |
| 587 return 0; | |
| 588 } | |
| 589 | |
| 590 Page* RenderLayerCompositor::page() const | |
| 591 { | |
| 592 return m_renderView.frameView()->frame().page(); | |
| 593 } | |
| 594 | |
| 595 DocumentLifecycle& RenderLayerCompositor::lifecycle() const | |
| 596 { | |
| 597 return m_renderView.document().lifecycle(); | |
| 598 } | |
| 599 | |
| 600 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer) | |
| 601 { | |
| 602 String name; | |
| 603 if (graphicsLayer == m_rootContentLayer.get()) { | |
| 604 name = "Content Root Layer"; | |
| 605 } else if (graphicsLayer == m_rootTransformLayer.get()) { | |
| 606 name = "Root Transform Layer"; | |
| 607 } else if (graphicsLayer == m_overflowControlsHostLayer.get()) { | |
| 608 name = "Overflow Controls Host Layer"; | |
| 609 } else if (graphicsLayer == m_containerLayer.get()) { | |
| 610 name = "LocalFrame Clipping Layer"; | |
| 611 } else if (graphicsLayer == m_scrollLayer.get()) { | |
| 612 name = "LocalFrame Scrolling Layer"; | |
| 613 } else { | |
| 614 ASSERT_NOT_REACHED(); | |
| 615 } | |
| 616 | |
| 617 return name; | |
| 618 } | |
| 619 | |
| 620 } // namespace blink | |
| OLD | NEW |