| 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 "config.h" | |
| 27 | |
| 28 #include "core/layout/compositing/RenderLayerCompositor.h" | |
| 29 | |
| 30 #include "core/animation/DocumentAnimations.h" | |
| 31 #include "core/dom/Fullscreen.h" | |
| 32 #include "core/editing/FrameSelection.h" | |
| 33 #include "core/frame/FrameHost.h" | |
| 34 #include "core/frame/FrameView.h" | |
| 35 #include "core/frame/LocalFrame.h" | |
| 36 #include "core/frame/Settings.h" | |
| 37 #include "core/html/HTMLIFrameElement.h" | |
| 38 #include "core/inspector/InspectorInstrumentation.h" | |
| 39 #include "core/inspector/InspectorNodeIds.h" | |
| 40 #include "core/layout/compositing/CompositedLayerMapping.h" | |
| 41 #include "core/layout/compositing/CompositingInputsUpdater.h" | |
| 42 #include "core/layout/compositing/CompositingLayerAssigner.h" | |
| 43 #include "core/layout/compositing/CompositingRequirementsUpdater.h" | |
| 44 #include "core/layout/compositing/GraphicsLayerTreeBuilder.h" | |
| 45 #include "core/layout/compositing/GraphicsLayerUpdater.h" | |
| 46 #include "core/loader/FrameLoaderClient.h" | |
| 47 #include "core/page/Chrome.h" | |
| 48 #include "core/page/ChromeClient.h" | |
| 49 #include "core/page/Page.h" | |
| 50 #include "core/page/scrolling/ScrollingCoordinator.h" | |
| 51 #include "core/paint/FramePainter.h" | |
| 52 #include "core/paint/TransformRecorder.h" | |
| 53 #include "core/rendering/RenderEmbeddedObject.h" | |
| 54 #include "core/rendering/RenderLayerStackingNode.h" | |
| 55 #include "core/rendering/RenderLayerStackingNodeIterator.h" | |
| 56 #include "core/rendering/RenderPart.h" | |
| 57 #include "core/rendering/RenderVideo.h" | |
| 58 #include "core/rendering/RenderView.h" | |
| 59 #include "platform/RuntimeEnabledFeatures.h" | |
| 60 #include "platform/ScriptForbiddenScope.h" | |
| 61 #include "platform/TraceEvent.h" | |
| 62 #include "platform/graphics/GraphicsLayer.h" | |
| 63 #include "platform/graphics/paint/DisplayItemList.h" | |
| 64 #include "platform/graphics/paint/DrawingRecorder.h" | |
| 65 #include "platform/graphics/paint/TransformDisplayItem.h" | |
| 66 #include "public/platform/Platform.h" | |
| 67 | |
| 68 namespace blink { | |
| 69 | |
| 70 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView) | |
| 71 : m_renderView(renderView) | |
| 72 , m_compositingReasonFinder(renderView) | |
| 73 , m_pendingUpdateType(CompositingUpdateNone) | |
| 74 , m_hasAcceleratedCompositing(true) | |
| 75 , m_compositing(false) | |
| 76 , m_rootShouldAlwaysCompositeDirty(true) | |
| 77 , m_needsUpdateFixedBackground(false) | |
| 78 , m_isTrackingPaintInvalidations(false) | |
| 79 , m_rootLayerAttachment(RootLayerUnattached) | |
| 80 , m_inOverlayFullscreenVideo(false) | |
| 81 { | |
| 82 updateAcceleratedCompositingSettings(); | |
| 83 } | |
| 84 | |
| 85 RenderLayerCompositor::~RenderLayerCompositor() | |
| 86 { | |
| 87 ASSERT(m_rootLayerAttachment == RootLayerUnattached); | |
| 88 } | |
| 89 | |
| 90 bool RenderLayerCompositor::inCompositingMode() const | |
| 91 { | |
| 92 // FIXME: This should assert that lifecycle is >= CompositingClean since | |
| 93 // the last step of updateIfNeeded can set this bit to false. | |
| 94 ASSERT(m_renderView.layer()->isAllowedToQueryCompositingState()); | |
| 95 return m_compositing; | |
| 96 } | |
| 97 | |
| 98 bool RenderLayerCompositor::staleInCompositingMode() const | |
| 99 { | |
| 100 return m_compositing; | |
| 101 } | |
| 102 | |
| 103 void RenderLayerCompositor::setCompositingModeEnabled(bool enable) | |
| 104 { | |
| 105 if (enable == m_compositing) | |
| 106 return; | |
| 107 | |
| 108 m_compositing = enable; | |
| 109 | |
| 110 // RenderPart::requiresAcceleratedCompositing is used to determine self-pain
tingness | |
| 111 // and bases it's return value for frames on the m_compositing bit here. | |
| 112 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerEleme
nt()) { | |
| 113 if (RenderPart* renderer = ownerElement->renderPart()) | |
| 114 renderer->layer()->updateSelfPaintingLayer(); | |
| 115 } | |
| 116 | |
| 117 if (m_compositing) | |
| 118 ensureRootLayer(); | |
| 119 else | |
| 120 destroyRootLayer(); | |
| 121 | |
| 122 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedC
ompositing(), so | |
| 123 // we need to schedule a style recalc in our parent document. | |
| 124 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerEleme
nt()) | |
| 125 ownerElement->setNeedsCompositingUpdate(); | |
| 126 } | |
| 127 | |
| 128 void RenderLayerCompositor::enableCompositingModeIfNeeded() | |
| 129 { | |
| 130 if (!m_rootShouldAlwaysCompositeDirty) | |
| 131 return; | |
| 132 | |
| 133 m_rootShouldAlwaysCompositeDirty = false; | |
| 134 if (m_compositing) | |
| 135 return; | |
| 136 | |
| 137 if (rootShouldAlwaysComposite()) { | |
| 138 // FIXME: Is this needed? It was added in https://bugs.webkit.org/show_b
ug.cgi?id=26651. | |
| 139 // No tests fail if it's deleted. | |
| 140 setNeedsCompositingUpdate(CompositingUpdateRebuildTree); | |
| 141 setCompositingModeEnabled(true); | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 bool RenderLayerCompositor::rootShouldAlwaysComposite() const | |
| 146 { | |
| 147 if (!m_hasAcceleratedCompositing) | |
| 148 return false; | |
| 149 return m_renderView.frame()->isLocalRoot() || m_compositingReasonFinder.requ
iresCompositingForScrollableFrame(); | |
| 150 } | |
| 151 | |
| 152 void RenderLayerCompositor::updateAcceleratedCompositingSettings() | |
| 153 { | |
| 154 m_compositingReasonFinder.updateTriggers(); | |
| 155 m_hasAcceleratedCompositing = m_renderView.document().settings()->accelerate
dCompositingEnabled(); | |
| 156 m_rootShouldAlwaysCompositeDirty = true; | |
| 157 if (m_rootLayerAttachment != RootLayerUnattached) | |
| 158 rootRenderLayer()->setNeedsCompositingInputsUpdate(); | |
| 159 } | |
| 160 | |
| 161 bool RenderLayerCompositor::preferCompositingToLCDTextEnabled() const | |
| 162 { | |
| 163 return m_compositingReasonFinder.hasOverflowScrollTrigger(); | |
| 164 } | |
| 165 | |
| 166 static RenderVideo* findFullscreenVideoRenderer(Document& document) | |
| 167 { | |
| 168 // Recursively find the document that is in fullscreen. | |
| 169 Element* fullscreenElement = Fullscreen::fullscreenElementFrom(document); | |
| 170 Document* contentDocument = &document; | |
| 171 while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) { | |
| 172 contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDoc
ument(); | |
| 173 if (!contentDocument) | |
| 174 return 0; | |
| 175 fullscreenElement = Fullscreen::fullscreenElementFrom(*contentDocument); | |
| 176 } | |
| 177 // Get the current fullscreen element from the document. | |
| 178 fullscreenElement = Fullscreen::currentFullScreenElementFrom(*contentDocumen
t); | |
| 179 if (!isHTMLVideoElement(fullscreenElement)) | |
| 180 return 0; | |
| 181 RenderObject* renderer = fullscreenElement->renderer(); | |
| 182 if (!renderer) | |
| 183 return 0; | |
| 184 return toRenderVideo(renderer); | |
| 185 } | |
| 186 | |
| 187 void RenderLayerCompositor::updateIfNeededRecursive() | |
| 188 { | |
| 189 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); c
hild; child = child->tree().nextSibling()) { | |
| 190 if (child->isLocalFrame()) | |
| 191 toLocalFrame(child)->contentRenderer()->compositor()->updateIfNeeded
Recursive(); | |
| 192 } | |
| 193 | |
| 194 TRACE_EVENT0("blink", "RenderLayerCompositor::updateIfNeededRecursive"); | |
| 195 | |
| 196 ASSERT(!m_renderView.needsLayout()); | |
| 197 | |
| 198 ScriptForbiddenScope forbidScript; | |
| 199 | |
| 200 // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebui
ldTree, | |
| 201 // which asserts that it's not InCompositingUpdate. | |
| 202 enableCompositingModeIfNeeded(); | |
| 203 | |
| 204 rootRenderLayer()->updateDescendantDependentFlagsForEntireSubtree(); | |
| 205 m_renderView.commitPendingSelection(); | |
| 206 | |
| 207 lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate); | |
| 208 updateIfNeeded(); | |
| 209 lifecycle().advanceTo(DocumentLifecycle::CompositingClean); | |
| 210 | |
| 211 DocumentAnimations::startPendingAnimations(m_renderView.document()); | |
| 212 | |
| 213 m_renderView.frameView()->updateCompositorScrollAnimations(); | |
| 214 if (const FrameView::ScrollableAreaSet* animatingScrollableAreas = m_renderV
iew.frameView()->animatingScrollableAreas()) { | |
| 215 for (ScrollableArea* scrollableArea : *animatingScrollableAreas) | |
| 216 scrollableArea->updateCompositorScrollAnimations(); | |
| 217 } | |
| 218 | |
| 219 #if ENABLE(ASSERT) | |
| 220 ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean); | |
| 221 assertNoUnresolvedDirtyBits(); | |
| 222 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); c
hild; child = child->tree().nextSibling()) { | |
| 223 if (child->isLocalFrame()) | |
| 224 toLocalFrame(child)->contentRenderer()->compositor()->assertNoUnreso
lvedDirtyBits(); | |
| 225 } | |
| 226 #endif | |
| 227 } | |
| 228 | |
| 229 void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType upda
teType) | |
| 230 { | |
| 231 ASSERT(updateType != CompositingUpdateNone); | |
| 232 m_pendingUpdateType = std::max(m_pendingUpdateType, updateType); | |
| 233 page()->animator().scheduleVisualUpdate(m_renderView.frame()); | |
| 234 lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean); | |
| 235 } | |
| 236 | |
| 237 void RenderLayerCompositor::didLayout() | |
| 238 { | |
| 239 // FIXME: Technically we only need to do this when the FrameView's | |
| 240 // isScrollable method would return a different value. | |
| 241 m_rootShouldAlwaysCompositeDirty = true; | |
| 242 enableCompositingModeIfNeeded(); | |
| 243 | |
| 244 // FIXME: Rather than marking the entire RenderView as dirty, we should | |
| 245 // track which RenderLayers moved during layout and only dirty those | |
| 246 // specific RenderLayers. | |
| 247 rootRenderLayer()->setNeedsCompositingInputsUpdate(); | |
| 248 } | |
| 249 | |
| 250 #if ENABLE(ASSERT) | |
| 251 | |
| 252 void RenderLayerCompositor::assertNoUnresolvedDirtyBits() | |
| 253 { | |
| 254 ASSERT(m_pendingUpdateType == CompositingUpdateNone); | |
| 255 ASSERT(!m_rootShouldAlwaysCompositeDirty); | |
| 256 } | |
| 257 | |
| 258 #endif | |
| 259 | |
| 260 void RenderLayerCompositor::applyOverlayFullscreenVideoAdjustment() | |
| 261 { | |
| 262 m_inOverlayFullscreenVideo = false; | |
| 263 if (!m_rootContentLayer) | |
| 264 return; | |
| 265 | |
| 266 bool isLocalRoot = m_renderView.frame()->isLocalRoot(); | |
| 267 RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document()); | |
| 268 if (!video || !video->layer()->hasCompositedLayerMapping()) { | |
| 269 if (isLocalRoot) { | |
| 270 GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer(); | |
| 271 if (backgroundLayer && !backgroundLayer->parent()) | |
| 272 rootFixedBackgroundsChanged(); | |
| 273 } | |
| 274 return; | |
| 275 } | |
| 276 | |
| 277 GraphicsLayer* videoLayer = video->layer()->compositedLayerMapping()->mainGr
aphicsLayer(); | |
| 278 | |
| 279 // The fullscreen video has layer position equal to its enclosing frame's sc
roll position because fullscreen container is fixed-positioned. | |
| 280 // We should reset layer position here since we are going to reattach the la
yer at the very top level. | |
| 281 videoLayer->setPosition(IntPoint()); | |
| 282 | |
| 283 // Only steal fullscreen video layer and clear all other layers if we are th
e main frame. | |
| 284 if (!isLocalRoot) | |
| 285 return; | |
| 286 | |
| 287 m_rootContentLayer->removeAllChildren(); | |
| 288 m_overflowControlsHostLayer->addChild(videoLayer); | |
| 289 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer()) | |
| 290 backgroundLayer->removeFromParent(); | |
| 291 m_inOverlayFullscreenVideo = true; | |
| 292 } | |
| 293 | |
| 294 void RenderLayerCompositor::updateWithoutAcceleratedCompositing(CompositingUpdat
eType updateType) | |
| 295 { | |
| 296 ASSERT(!hasAcceleratedCompositing()); | |
| 297 | |
| 298 if (updateType >= CompositingUpdateAfterCompositingInputChange) | |
| 299 CompositingInputsUpdater(rootRenderLayer()).update(); | |
| 300 | |
| 301 #if ENABLE(ASSERT) | |
| 302 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(root
RenderLayer()); | |
| 303 #endif | |
| 304 } | |
| 305 | |
| 306 static void forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendan
ts(RenderObject* renderer) | |
| 307 { | |
| 308 // We clear the previous paint invalidation rect as it's wrong (paint invali
ation container | |
| 309 // changed, ...). Forcing a full invalidation will make us recompute it. Als
o we are not | |
| 310 // changing the previous position from our paint invalidation container, whi
ch is fine as | |
| 311 // we want a full paint invalidation anyway. | |
| 312 renderer->setPreviousPaintInvalidationRect(LayoutRect()); | |
| 313 renderer->setShouldDoFullPaintInvalidation(); | |
| 314 | |
| 315 for (RenderObject* child = renderer->slowFirstChild(); child; child = child-
>nextSibling()) { | |
| 316 if (!child->isPaintInvalidationContainer()) | |
| 317 forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendan
ts(child); | |
| 318 } | |
| 319 } | |
| 320 | |
| 321 | |
| 322 void RenderLayerCompositor::updateIfNeeded() | |
| 323 { | |
| 324 CompositingUpdateType updateType = m_pendingUpdateType; | |
| 325 m_pendingUpdateType = CompositingUpdateNone; | |
| 326 | |
| 327 if (!hasAcceleratedCompositing()) { | |
| 328 updateWithoutAcceleratedCompositing(updateType); | |
| 329 return; | |
| 330 } | |
| 331 | |
| 332 if (updateType == CompositingUpdateNone) | |
| 333 return; | |
| 334 | |
| 335 RenderLayer* updateRoot = rootRenderLayer(); | |
| 336 | |
| 337 Vector<RenderLayer*> layersNeedingPaintInvalidation; | |
| 338 | |
| 339 if (updateType >= CompositingUpdateAfterCompositingInputChange) { | |
| 340 CompositingInputsUpdater(updateRoot).update(); | |
| 341 | |
| 342 #if ENABLE(ASSERT) | |
| 343 // FIXME: Move this check to the end of the compositing update. | |
| 344 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(
updateRoot); | |
| 345 #endif | |
| 346 | |
| 347 CompositingRequirementsUpdater(m_renderView, m_compositingReasonFinder).
update(updateRoot); | |
| 348 | |
| 349 CompositingLayerAssigner layerAssigner(this); | |
| 350 layerAssigner.assign(updateRoot, layersNeedingPaintInvalidation); | |
| 351 | |
| 352 bool layersChanged = layerAssigner.layersChanged(); | |
| 353 | |
| 354 { | |
| 355 TRACE_EVENT0("blink", "RenderLayerCompositor::updateAfterCompositing
Change"); | |
| 356 if (const FrameView::ScrollableAreaSet* scrollableAreas = m_renderVi
ew.frameView()->scrollableAreas()) { | |
| 357 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas
->begin(); it != scrollableAreas->end(); ++it) | |
| 358 layersChanged |= (*it)->updateAfterCompositingChange(); | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 if (layersChanged) | |
| 363 updateType = std::max(updateType, CompositingUpdateRebuildTree); | |
| 364 } | |
| 365 | |
| 366 if (updateType != CompositingUpdateNone) { | |
| 367 GraphicsLayerUpdater updater; | |
| 368 updater.update(*updateRoot, layersNeedingPaintInvalidation); | |
| 369 | |
| 370 if (updater.needsRebuildTree()) | |
| 371 updateType = std::max(updateType, CompositingUpdateRebuildTree); | |
| 372 | |
| 373 #if ENABLE(ASSERT) | |
| 374 // FIXME: Move this check to the end of the compositing update. | |
| 375 GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(*updat
eRoot); | |
| 376 #endif | |
| 377 } | |
| 378 | |
| 379 if (updateType >= CompositingUpdateRebuildTree) { | |
| 380 GraphicsLayerTreeBuilder::AncestorInfo ancestorInfo; | |
| 381 GraphicsLayerVector childList; | |
| 382 ancestorInfo.childLayersOfEnclosingCompositedLayer = &childList; | |
| 383 { | |
| 384 TRACE_EVENT0("blink", "GraphicsLayerTreeBuilder::rebuild"); | |
| 385 GraphicsLayerTreeBuilder().rebuild(*updateRoot, ancestorInfo); | |
| 386 } | |
| 387 | |
| 388 if (childList.isEmpty()) | |
| 389 destroyRootLayer(); | |
| 390 else | |
| 391 m_rootContentLayer->setChildren(childList); | |
| 392 | |
| 393 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled()) | |
| 394 applyOverlayFullscreenVideoAdjustment(); | |
| 395 } | |
| 396 | |
| 397 if (m_needsUpdateFixedBackground) { | |
| 398 rootFixedBackgroundsChanged(); | |
| 399 m_needsUpdateFixedBackground = false; | |
| 400 } | |
| 401 | |
| 402 for (unsigned i = 0; i < layersNeedingPaintInvalidation.size(); i++) | |
| 403 forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(l
ayersNeedingPaintInvalidation[i]->renderer()); | |
| 404 | |
| 405 // Inform the inspector that the layer tree has changed. | |
| 406 if (m_renderView.frame()->isMainFrame()) | |
| 407 InspectorInstrumentation::layerTreeDidChange(m_renderView.frame()); | |
| 408 } | |
| 409 | |
| 410 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* l
ayer, const CompositingStateTransitionType compositedLayerUpdate) | |
| 411 { | |
| 412 bool compositedLayerMappingChanged = false; | |
| 413 | |
| 414 // FIXME: It would be nice to directly use the layer's compositing reason, | |
| 415 // but allocateOrClearCompositedLayerMapping also gets called without having
updated compositing | |
| 416 // requirements fully. | |
| 417 switch (compositedLayerUpdate) { | |
| 418 case AllocateOwnCompositedLayerMapping: | |
| 419 ASSERT(!layer->hasCompositedLayerMapping()); | |
| 420 setCompositingModeEnabled(true); | |
| 421 | |
| 422 // If we need to issue paint invalidations, do so before allocating the
compositedLayerMapping and clearing out the groupedMapping. | |
| 423 paintInvalidationOnCompositingChange(layer); | |
| 424 | |
| 425 // If this layer was previously squashed, we need to remove its referenc
e to a groupedMapping right away, so | |
| 426 // that computing paint invalidation rects will know the layer's correct
compositingState. | |
| 427 // FIXME: do we need to also remove the layer from it's location in the
squashing list of its groupedMapping? | |
| 428 // Need to create a test where a squashed layer pops into compositing. A
nd also to cover all other | |
| 429 // sorts of compositingState transitions. | |
| 430 layer->setLostGroupedMapping(false); | |
| 431 layer->setGroupedMapping(0); | |
| 432 | |
| 433 layer->ensureCompositedLayerMapping(); | |
| 434 compositedLayerMappingChanged = true; | |
| 435 | |
| 436 // At this time, the ScrollingCooridnator only supports the top-level fr
ame. | |
| 437 if (layer->isRootLayer() && m_renderView.frame()->isLocalRoot()) { | |
| 438 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoor
dinator()) | |
| 439 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.f
rameView()); | |
| 440 } | |
| 441 break; | |
| 442 case RemoveOwnCompositedLayerMapping: | |
| 443 // PutInSquashingLayer means you might have to remove the composited layer m
apping first. | |
| 444 case PutInSquashingLayer: | |
| 445 if (layer->hasCompositedLayerMapping()) { | |
| 446 // If we're removing the compositedLayerMapping from a reflection, c
lear the source GraphicsLayer's pointer to | |
| 447 // its replica GraphicsLayer. In practice this should never happen b
ecause reflectee and reflection | |
| 448 // are both either composited, or not composited. | |
| 449 if (layer->isReflection()) { | |
| 450 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->rende
rer()->parent())->layer(); | |
| 451 if (sourceLayer->hasCompositedLayerMapping()) { | |
| 452 ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLa
yer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer()); | |
| 453 sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->
setReplicatedByLayer(0); | |
| 454 } | |
| 455 } | |
| 456 | |
| 457 layer->clearCompositedLayerMapping(); | |
| 458 compositedLayerMappingChanged = true; | |
| 459 } | |
| 460 | |
| 461 break; | |
| 462 case RemoveFromSquashingLayer: | |
| 463 case NoCompositingStateChange: | |
| 464 // Do nothing. | |
| 465 break; | |
| 466 } | |
| 467 | |
| 468 if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) { | |
| 469 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRende
rPart(layer->renderer())); | |
| 470 if (innerCompositor && innerCompositor->staleInCompositingMode()) | |
| 471 innerCompositor->updateRootLayerAttachment(); | |
| 472 } | |
| 473 | |
| 474 if (compositedLayerMappingChanged) | |
| 475 layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects); | |
| 476 | |
| 477 // If a fixed position layer gained/lost a compositedLayerMapping or the rea
son not compositing it changed, | |
| 478 // the scrolling coordinator needs to recalculate whether it can do fast scr
olling. | |
| 479 if (compositedLayerMappingChanged) { | |
| 480 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
| 481 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.fr
ameView()); | |
| 482 } | |
| 483 | |
| 484 return compositedLayerMappingChanged; | |
| 485 } | |
| 486 | |
| 487 void RenderLayerCompositor::paintInvalidationOnCompositingChange(RenderLayer* la
yer) | |
| 488 { | |
| 489 // If the renderer is not attached yet, no need to issue paint invalidations
. | |
| 490 if (layer->renderer() != &m_renderView && !layer->renderer()->parent()) | |
| 491 return; | |
| 492 | |
| 493 // For querying RenderLayer::compositingState() | |
| 494 // Eager invalidation here is correct, since we are invalidating with respec
t to the previous frame's | |
| 495 // compositing state when changing the compositing backing of the layer. | |
| 496 DisableCompositingQueryAsserts disabler; | |
| 497 | |
| 498 layer->renderer()->invalidatePaintIncludingNonCompositingDescendants(); | |
| 499 } | |
| 500 | |
| 501 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsO
ffset) | |
| 502 { | |
| 503 if (m_overflowControlsHostLayer) | |
| 504 m_overflowControlsHostLayer->setPosition(contentsOffset); | |
| 505 } | |
| 506 | |
| 507 void RenderLayerCompositor::frameViewDidChangeSize() | |
| 508 { | |
| 509 if (m_containerLayer) { | |
| 510 FrameView* frameView = m_renderView.frameView(); | |
| 511 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); | |
| 512 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSi
ze(IncludeScrollbars)); | |
| 513 | |
| 514 frameViewDidScroll(); | |
| 515 updateOverflowControlsLayers(); | |
| 516 } | |
| 517 } | |
| 518 | |
| 519 enum AcceleratedFixedRootBackgroundHistogramBuckets { | |
| 520 ScrolledMainFrameBucket = 0, | |
| 521 ScrolledMainFrameWithAcceleratedFixedRootBackground = 1, | |
| 522 ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2, | |
| 523 AcceleratedFixedRootBackgroundHistogramMax = 3 | |
| 524 }; | |
| 525 | |
| 526 void RenderLayerCompositor::frameViewDidScroll() | |
| 527 { | |
| 528 FrameView* frameView = m_renderView.frameView(); | |
| 529 IntPoint scrollPosition = frameView->scrollPosition(); | |
| 530 | |
| 531 if (!m_scrollLayer) | |
| 532 return; | |
| 533 | |
| 534 bool scrollingCoordinatorHandlesOffset = false; | |
| 535 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator(
)) { | |
| 536 if (Settings* settings = m_renderView.document().settings()) { | |
| 537 if (m_renderView.frame()->isLocalRoot() || settings->preferCompositi
ngToLCDTextEnabled()) | |
| 538 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scroll
ableAreaScrollLayerDidChange(frameView); | |
| 539 } | |
| 540 } | |
| 541 | |
| 542 // Scroll position = scroll minimum + scroll offset. Adjust the layer's | |
| 543 // position to handle whatever the scroll coordinator isn't handling. | |
| 544 // The minimum scroll position is non-zero for RTL pages with overflow. | |
| 545 if (scrollingCoordinatorHandlesOffset) | |
| 546 m_scrollLayer->setPosition(-frameView->minimumScrollPosition()); | |
| 547 else | |
| 548 m_scrollLayer->setPosition(-scrollPosition); | |
| 549 | |
| 550 | |
| 551 Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBack
ground", | |
| 552 ScrolledMainFrameBucket, | |
| 553 AcceleratedFixedRootBackgroundHistogramMax); | |
| 554 } | |
| 555 | |
| 556 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange() | |
| 557 { | |
| 558 if (m_containerLayer) | |
| 559 updateOverflowControlsLayers(); | |
| 560 } | |
| 561 | |
| 562 void RenderLayerCompositor::rootFixedBackgroundsChanged() | |
| 563 { | |
| 564 if (!supportsFixedRootBackgroundCompositing()) | |
| 565 return; | |
| 566 | |
| 567 // To avoid having to make the fixed root background layer fixed positioned
to | |
| 568 // stay put, we position it in the layer tree as follows: | |
| 569 // | |
| 570 // + Overflow controls host | |
| 571 // + LocalFrame clip | |
| 572 // + (Fixed root background) <-- Here. | |
| 573 // + LocalFrame scroll | |
| 574 // + Root content layer | |
| 575 // + Scrollbars | |
| 576 // | |
| 577 // That is, it needs to be the first child of the frame clip, the sibling of | |
| 578 // the frame scroll layer. The compositor does not own the background layer,
it | |
| 579 // just positions it (like the foreground layer). | |
| 580 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer()) | |
| 581 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get()); | |
| 582 } | |
| 583 | |
| 584 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer) | |
| 585 { | |
| 586 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator(
)) | |
| 587 return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->s
crollableArea()); | |
| 588 return false; | |
| 589 } | |
| 590 | |
| 591 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags) | |
| 592 { | |
| 593 ASSERT(lifecycle().state() >= DocumentLifecycle::PaintInvalidationClean); | |
| 594 | |
| 595 if (!m_rootContentLayer) | |
| 596 return String(); | |
| 597 | |
| 598 // We skip dumping the scroll and clip layers to keep layerTreeAsText output | |
| 599 // similar between platforms (unless we explicitly request dumping from the | |
| 600 // root. | |
| 601 GraphicsLayer* rootLayer = m_rootContentLayer.get(); | |
| 602 if (flags & LayerTreeIncludesRootLayer) | |
| 603 rootLayer = rootGraphicsLayer(); | |
| 604 | |
| 605 String layerTreeText = rootLayer->layerTreeAsText(flags); | |
| 606 | |
| 607 // The true root layer is not included in the dump, so if we want to report | |
| 608 // its paint invalidation rects, they must be included here. | |
| 609 if (flags & LayerTreeIncludesPaintInvalidationRects) | |
| 610 return m_renderView.frameView()->trackedPaintInvalidationRectsAsText() +
layerTreeText; | |
| 611 | |
| 612 return layerTreeText; | |
| 613 } | |
| 614 | |
| 615 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart
* renderer) | |
| 616 { | |
| 617 if (!renderer->node()->isFrameOwnerElement()) | |
| 618 return 0; | |
| 619 | |
| 620 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node()); | |
| 621 if (Document* contentDocument = element->contentDocument()) { | |
| 622 if (RenderView* view = contentDocument->renderView()) | |
| 623 return view->compositor(); | |
| 624 } | |
| 625 return 0; | |
| 626 } | |
| 627 | |
| 628 // FIXME: What does this function do? It needs a clearer name. | |
| 629 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer) | |
| 630 { | |
| 631 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer); | |
| 632 if (!innerCompositor || !innerCompositor->staleInCompositingMode() || innerC
ompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame) | |
| 633 return false; | |
| 634 | |
| 635 RenderLayer* layer = renderer->layer(); | |
| 636 if (!layer->hasCompositedLayerMapping()) | |
| 637 return false; | |
| 638 | |
| 639 CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMappi
ng(); | |
| 640 GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers(); | |
| 641 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer(); | |
| 642 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != r
ootLayer) { | |
| 643 hostingLayer->removeAllChildren(); | |
| 644 hostingLayer->addChild(rootLayer); | |
| 645 } | |
| 646 return true; | |
| 647 } | |
| 648 | |
| 649 static void fullyInvalidatePaintRecursive(RenderLayer* layer) | |
| 650 { | |
| 651 if (layer->compositingState() == PaintsIntoOwnBacking) { | |
| 652 layer->compositedLayerMapping()->setContentsNeedDisplay(); | |
| 653 layer->compositedLayerMapping()->setSquashingContentsNeedDisplay(); | |
| 654 } | |
| 655 | |
| 656 for (RenderLayer* child = layer->firstChild(); child; child = child->nextSib
ling()) | |
| 657 fullyInvalidatePaintRecursive(child); | |
| 658 } | |
| 659 | |
| 660 void RenderLayerCompositor::fullyInvalidatePaint() | |
| 661 { | |
| 662 // We're walking all compositing layers and invalidating them, so there's | |
| 663 // no need to have up-to-date compositing state. | |
| 664 DisableCompositingQueryAsserts disabler; | |
| 665 fullyInvalidatePaintRecursive(rootRenderLayer()); | |
| 666 } | |
| 667 | |
| 668 RenderLayer* RenderLayerCompositor::rootRenderLayer() const | |
| 669 { | |
| 670 return m_renderView.layer(); | |
| 671 } | |
| 672 | |
| 673 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const | |
| 674 { | |
| 675 if (m_overflowControlsHostLayer) | |
| 676 return m_overflowControlsHostLayer.get(); | |
| 677 return m_rootContentLayer.get(); | |
| 678 } | |
| 679 | |
| 680 GraphicsLayer* RenderLayerCompositor::frameScrollLayer() const | |
| 681 { | |
| 682 return m_scrollLayer.get(); | |
| 683 } | |
| 684 | |
| 685 GraphicsLayer* RenderLayerCompositor::scrollLayer() const | |
| 686 { | |
| 687 if (ScrollableArea* scrollableArea = m_renderView.frameView()->scrollableAre
a()) | |
| 688 return scrollableArea->layerForScrolling(); | |
| 689 return nullptr; | |
| 690 } | |
| 691 | |
| 692 GraphicsLayer* RenderLayerCompositor::containerLayer() const | |
| 693 { | |
| 694 return m_containerLayer.get(); | |
| 695 } | |
| 696 | |
| 697 GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer() | |
| 698 { | |
| 699 ASSERT(rootGraphicsLayer()); | |
| 700 | |
| 701 if (!m_rootTransformLayer.get()) { | |
| 702 m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), thi
s); | |
| 703 m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get()); | |
| 704 m_rootTransformLayer->addChild(m_containerLayer.get()); | |
| 705 updateOverflowControlsLayers(); | |
| 706 } | |
| 707 | |
| 708 return m_rootTransformLayer.get(); | |
| 709 } | |
| 710 | |
| 711 void RenderLayerCompositor::setIsInWindow(bool isInWindow) | |
| 712 { | |
| 713 if (!staleInCompositingMode()) | |
| 714 return; | |
| 715 | |
| 716 if (isInWindow) { | |
| 717 if (m_rootLayerAttachment != RootLayerUnattached) | |
| 718 return; | |
| 719 | |
| 720 RootLayerAttachment attachment = m_renderView.frame()->isLocalRoot() ? R
ootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; | |
| 721 attachRootLayer(attachment); | |
| 722 } else { | |
| 723 if (m_rootLayerAttachment == RootLayerUnattached) | |
| 724 return; | |
| 725 | |
| 726 detachRootLayer(); | |
| 727 } | |
| 728 } | |
| 729 | |
| 730 void RenderLayerCompositor::updateRootLayerPosition() | |
| 731 { | |
| 732 if (m_rootContentLayer) { | |
| 733 const IntRect& documentRect = m_renderView.documentRect(); | |
| 734 m_rootContentLayer->setSize(documentRect.size()); | |
| 735 m_rootContentLayer->setPosition(documentRect.location()); | |
| 736 } | |
| 737 if (m_containerLayer) { | |
| 738 FrameView* frameView = m_renderView.frameView(); | |
| 739 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); | |
| 740 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSi
ze(IncludeScrollbars)); | |
| 741 } | |
| 742 } | |
| 743 | |
| 744 void RenderLayerCompositor::updatePotentialCompositingReasonsFromStyle(RenderLay
er* layer) | |
| 745 { | |
| 746 layer->setPotentialCompositingReasonsFromStyle(m_compositingReasonFinder.pot
entialCompositingReasonsFromStyle(layer->renderer())); | |
| 747 } | |
| 748 | |
| 749 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer) | |
| 750 { | |
| 751 layer->setCompositingReasons(m_compositingReasonFinder.directReasons(layer),
CompositingReasonComboAllDirectReasons); | |
| 752 } | |
| 753 | |
| 754 void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer) | |
| 755 { | |
| 756 ASSERT(rootGraphicsLayer()); | |
| 757 | |
| 758 if (layer->parent() != m_overflowControlsHostLayer.get()) | |
| 759 m_overflowControlsHostLayer->addChild(layer); | |
| 760 } | |
| 761 | |
| 762 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const | |
| 763 { | |
| 764 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer
->subtreeIsInvisible(); | |
| 765 } | |
| 766 | |
| 767 // Return true if the given layer is a stacking context and has compositing chil
d | |
| 768 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer | |
| 769 // into the hierarchy between this layer and its children in the z-order hierarc
hy. | |
| 770 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer
) const | |
| 771 { | |
| 772 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOver
flowClip(); | |
| 773 } | |
| 774 | |
| 775 // If an element has composited negative z-index children, those children render
in front of the | |
| 776 // layer background, so we need an extra 'contents' layer for the foreground of
the layer | |
| 777 // object. | |
| 778 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* lay
er) const | |
| 779 { | |
| 780 if (!layer->hasCompositingDescendant()) | |
| 781 return false; | |
| 782 return layer->stackingNode()->hasNegativeZOrderList(); | |
| 783 } | |
| 784 | |
| 785 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const
IntRect& clip) | |
| 786 { | |
| 787 if (!scrollbar) | |
| 788 return; | |
| 789 | |
| 790 // Frame scrollbars are painted in the space of the containing frame, not th
e local space of the scrollbar. | |
| 791 const IntPoint& paintOffset = scrollbar->frameRect().location(); | |
| 792 IntRect transformedClip = clip; | |
| 793 transformedClip.moveBy(paintOffset); | |
| 794 | |
| 795 AffineTransform translation; | |
| 796 translation.translate(-paintOffset.x(), -paintOffset.y()); | |
| 797 TransformRecorder transformRecorder(context, scrollbar->displayItemClient(),
translation); | |
| 798 | |
| 799 scrollbar->paint(&context, transformedClip); | |
| 800 } | |
| 801 | |
| 802 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, Gr
aphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip) | |
| 803 { | |
| 804 if (graphicsLayer == layerForHorizontalScrollbar()) | |
| 805 paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context,
clip); | |
| 806 else if (graphicsLayer == layerForVerticalScrollbar()) | |
| 807 paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, c
lip); | |
| 808 else if (graphicsLayer == layerForScrollCorner()) | |
| 809 FramePainter(*m_renderView.frameView()).paintScrollCorner(&context, clip
); | |
| 810 } | |
| 811 | |
| 812 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const | |
| 813 { | |
| 814 if (Settings* settings = m_renderView.document().settings()) | |
| 815 return settings->preferCompositingToLCDTextEnabled(); | |
| 816 return false; | |
| 817 } | |
| 818 | |
| 819 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* lay
er) const | |
| 820 { | |
| 821 if (layer != m_renderView.layer()) | |
| 822 return false; | |
| 823 | |
| 824 return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgrou
ndIsEntirelyFixed(); | |
| 825 } | |
| 826 | |
| 827 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const | |
| 828 { | |
| 829 // Get the fixed root background from the RenderView layer's compositedLayer
Mapping. | |
| 830 RenderLayer* viewLayer = m_renderView.layer(); | |
| 831 if (!viewLayer) | |
| 832 return 0; | |
| 833 | |
| 834 if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->comp
ositedLayerMapping()->backgroundLayerPaintsFixedRootBackground()) | |
| 835 return viewLayer->compositedLayerMapping()->backgroundLayer(); | |
| 836 | |
| 837 return 0; | |
| 838 } | |
| 839 | |
| 840 static void resetTrackedPaintInvalidationRectsRecursive(GraphicsLayer* graphicsL
ayer) | |
| 841 { | |
| 842 if (!graphicsLayer) | |
| 843 return; | |
| 844 | |
| 845 graphicsLayer->resetTrackedPaintInvalidations(); | |
| 846 | |
| 847 for (size_t i = 0; i < graphicsLayer->children().size(); ++i) | |
| 848 resetTrackedPaintInvalidationRectsRecursive(graphicsLayer->children()[i]
); | |
| 849 | |
| 850 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer()) | |
| 851 resetTrackedPaintInvalidationRectsRecursive(replicaLayer); | |
| 852 | |
| 853 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer()) | |
| 854 resetTrackedPaintInvalidationRectsRecursive(maskLayer); | |
| 855 | |
| 856 if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLa
yer()) | |
| 857 resetTrackedPaintInvalidationRectsRecursive(clippingMaskLayer); | |
| 858 } | |
| 859 | |
| 860 void RenderLayerCompositor::resetTrackedPaintInvalidationRects() | |
| 861 { | |
| 862 if (GraphicsLayer* rootLayer = rootGraphicsLayer()) | |
| 863 resetTrackedPaintInvalidationRectsRecursive(rootLayer); | |
| 864 } | |
| 865 | |
| 866 void RenderLayerCompositor::setTracksPaintInvalidations(bool tracksPaintInvalida
tions) | |
| 867 { | |
| 868 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationClean); | |
| 869 m_isTrackingPaintInvalidations = tracksPaintInvalidations; | |
| 870 } | |
| 871 | |
| 872 bool RenderLayerCompositor::isTrackingPaintInvalidations() const | |
| 873 { | |
| 874 return m_isTrackingPaintInvalidations; | |
| 875 } | |
| 876 | |
| 877 static bool shouldCompositeOverflowControls(FrameView* view) | |
| 878 { | |
| 879 if (Page* page = view->frame().page()) { | |
| 880 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordina
tor()) { | |
| 881 if (scrollingCoordinator->coordinatesScrollingForFrameView(view)) | |
| 882 return true; | |
| 883 } | |
| 884 } | |
| 885 | |
| 886 return true; | |
| 887 } | |
| 888 | |
| 889 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const | |
| 890 { | |
| 891 FrameView* view = m_renderView.frameView(); | |
| 892 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar(); | |
| 893 } | |
| 894 | |
| 895 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const | |
| 896 { | |
| 897 FrameView* view = m_renderView.frameView(); | |
| 898 return shouldCompositeOverflowControls(view) && view->verticalScrollbar(); | |
| 899 } | |
| 900 | |
| 901 bool RenderLayerCompositor::requiresScrollCornerLayer() const | |
| 902 { | |
| 903 FrameView* view = m_renderView.frameView(); | |
| 904 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible(
); | |
| 905 } | |
| 906 | |
| 907 void RenderLayerCompositor::updateOverflowControlsLayers() | |
| 908 { | |
| 909 GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransform
Layer.get() : m_overflowControlsHostLayer.get(); | |
| 910 // On Mac, main frame scrollbars should always be stuck to the sides of the
screen (in overscroll and in pinch-zoom), so | |
| 911 // make the parent for the scrollbars be the viewport container layer. | |
| 912 #if OS(MACOSX) | |
| 913 if (m_renderView.frame()->isMainFrame() && m_renderView.frame()->settings()-
>pinchVirtualViewportEnabled()) { | |
| 914 PinchViewport& pinchViewport = m_renderView.frameView()->page()->frameHo
st().pinchViewport(); | |
| 915 controlsParent = pinchViewport.containerLayer(); | |
| 916 } | |
| 917 #endif | |
| 918 | |
| 919 if (requiresHorizontalScrollbarLayer()) { | |
| 920 if (!m_layerForHorizontalScrollbar) { | |
| 921 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerF
actory(), this); | |
| 922 } | |
| 923 | |
| 924 if (m_layerForHorizontalScrollbar->parent() != controlsParent) { | |
| 925 controlsParent->addChild(m_layerForHorizontalScrollbar.get()); | |
| 926 | |
| 927 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoor
dinator()) | |
| 928 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_re
nderView.frameView(), HorizontalScrollbar); | |
| 929 } | |
| 930 } else if (m_layerForHorizontalScrollbar) { | |
| 931 m_layerForHorizontalScrollbar->removeFromParent(); | |
| 932 m_layerForHorizontalScrollbar = nullptr; | |
| 933 | |
| 934 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
| 935 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_render
View.frameView(), HorizontalScrollbar); | |
| 936 } | |
| 937 | |
| 938 if (requiresVerticalScrollbarLayer()) { | |
| 939 if (!m_layerForVerticalScrollbar) { | |
| 940 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFac
tory(), this); | |
| 941 } | |
| 942 | |
| 943 if (m_layerForVerticalScrollbar->parent() != controlsParent) { | |
| 944 controlsParent->addChild(m_layerForVerticalScrollbar.get()); | |
| 945 | |
| 946 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoor
dinator()) | |
| 947 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_re
nderView.frameView(), VerticalScrollbar); | |
| 948 } | |
| 949 } else if (m_layerForVerticalScrollbar) { | |
| 950 m_layerForVerticalScrollbar->removeFromParent(); | |
| 951 m_layerForVerticalScrollbar = nullptr; | |
| 952 | |
| 953 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
| 954 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_render
View.frameView(), VerticalScrollbar); | |
| 955 } | |
| 956 | |
| 957 if (requiresScrollCornerLayer()) { | |
| 958 if (!m_layerForScrollCorner) { | |
| 959 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(
), this); | |
| 960 controlsParent->addChild(m_layerForScrollCorner.get()); | |
| 961 } | |
| 962 } else if (m_layerForScrollCorner) { | |
| 963 m_layerForScrollCorner->removeFromParent(); | |
| 964 m_layerForScrollCorner = nullptr; | |
| 965 } | |
| 966 | |
| 967 m_renderView.frameView()->positionScrollbarLayers(); | |
| 968 } | |
| 969 | |
| 970 void RenderLayerCompositor::ensureRootLayer() | |
| 971 { | |
| 972 RootLayerAttachment expectedAttachment = m_renderView.frame()->isLocalRoot()
? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; | |
| 973 if (expectedAttachment == m_rootLayerAttachment) | |
| 974 return; | |
| 975 | |
| 976 Settings* settings = m_renderView.document().settings(); | |
| 977 if (!m_rootContentLayer) { | |
| 978 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this)
; | |
| 979 IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect(); | |
| 980 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.
maxY())); | |
| 981 m_rootContentLayer->setPosition(FloatPoint()); | |
| 982 m_rootContentLayer->setOwnerNodeId(InspectorNodeIds::idForNode(m_renderV
iew.generatingNode())); | |
| 983 | |
| 984 // FIXME: with rootLayerScrolls, we probably don't even need m_rootConte
ntLayer? | |
| 985 if (!(settings && settings->rootLayerScrolls())) { | |
| 986 // Need to clip to prevent transformed content showing outside this
frame | |
| 987 m_rootContentLayer->setMasksToBounds(true); | |
| 988 } | |
| 989 } | |
| 990 | |
| 991 if (!m_overflowControlsHostLayer) { | |
| 992 ASSERT(!m_scrollLayer); | |
| 993 ASSERT(!m_containerLayer); | |
| 994 | |
| 995 // Create a layer to host the clipping layer and the overflow controls l
ayers. | |
| 996 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory
(), this); | |
| 997 | |
| 998 // Clip iframe's overflow controls layer. | |
| 999 bool containerMasksToBounds = !m_renderView.frame()->isLocalRoot(); | |
| 1000 m_overflowControlsHostLayer->setMasksToBounds(containerMasksToBounds); | |
| 1001 | |
| 1002 // Create a clipping layer if this is an iframe or settings require to c
lip. | |
| 1003 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this); | |
| 1004 if (Settings* settings = m_renderView.document().settings()) { | |
| 1005 if (settings->mainFrameClipsContent()) | |
| 1006 containerMasksToBounds = true; | |
| 1007 } | |
| 1008 m_containerLayer->setMasksToBounds(containerMasksToBounds); | |
| 1009 | |
| 1010 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this); | |
| 1011 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
| 1012 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_sc
rollLayer.get(), true); | |
| 1013 | |
| 1014 // Hook them up | |
| 1015 m_overflowControlsHostLayer->addChild(m_containerLayer.get()); | |
| 1016 m_containerLayer->addChild(m_scrollLayer.get()); | |
| 1017 m_scrollLayer->addChild(m_rootContentLayer.get()); | |
| 1018 | |
| 1019 frameViewDidChangeSize(); | |
| 1020 } | |
| 1021 | |
| 1022 // Check to see if we have to change the attachment | |
| 1023 if (m_rootLayerAttachment != RootLayerUnattached) | |
| 1024 detachRootLayer(); | |
| 1025 | |
| 1026 attachRootLayer(expectedAttachment); | |
| 1027 } | |
| 1028 | |
| 1029 void RenderLayerCompositor::destroyRootLayer() | |
| 1030 { | |
| 1031 if (!m_rootContentLayer) | |
| 1032 return; | |
| 1033 | |
| 1034 detachRootLayer(); | |
| 1035 | |
| 1036 if (m_layerForHorizontalScrollbar) { | |
| 1037 m_layerForHorizontalScrollbar->removeFromParent(); | |
| 1038 m_layerForHorizontalScrollbar = nullptr; | |
| 1039 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
| 1040 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_render
View.frameView(), HorizontalScrollbar); | |
| 1041 if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalS
crollbar()) | |
| 1042 m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, I
ntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size())); | |
| 1043 } | |
| 1044 | |
| 1045 if (m_layerForVerticalScrollbar) { | |
| 1046 m_layerForVerticalScrollbar->removeFromParent(); | |
| 1047 m_layerForVerticalScrollbar = nullptr; | |
| 1048 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
| 1049 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_render
View.frameView(), VerticalScrollbar); | |
| 1050 if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScr
ollbar()) | |
| 1051 m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, Int
Rect(IntPoint(0, 0), verticalScrollbar->frameRect().size())); | |
| 1052 } | |
| 1053 | |
| 1054 if (m_layerForScrollCorner) { | |
| 1055 m_layerForScrollCorner = nullptr; | |
| 1056 m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView(
)->scrollCornerRect()); | |
| 1057 } | |
| 1058 | |
| 1059 if (m_overflowControlsHostLayer) { | |
| 1060 m_overflowControlsHostLayer = nullptr; | |
| 1061 m_containerLayer = nullptr; | |
| 1062 m_scrollLayer = nullptr; | |
| 1063 } | |
| 1064 ASSERT(!m_scrollLayer); | |
| 1065 m_rootContentLayer = nullptr; | |
| 1066 m_rootTransformLayer = nullptr; | |
| 1067 } | |
| 1068 | |
| 1069 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment) | |
| 1070 { | |
| 1071 if (!m_rootContentLayer) | |
| 1072 return; | |
| 1073 | |
| 1074 switch (attachment) { | |
| 1075 case RootLayerUnattached: | |
| 1076 ASSERT_NOT_REACHED(); | |
| 1077 break; | |
| 1078 case RootLayerAttachedViaChromeClient: { | |
| 1079 LocalFrame& frame = m_renderView.frameView()->frame(); | |
| 1080 Page* page = frame.page(); | |
| 1081 if (!page) | |
| 1082 return; | |
| 1083 page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer(), &fr
ame); | |
| 1084 break; | |
| 1085 } | |
| 1086 case RootLayerAttachedViaEnclosingFrame: { | |
| 1087 HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerEleme
nt(); | |
| 1088 ASSERT(ownerElement); | |
| 1089 // The layer will get hooked up via CompositedLayerMapping::updateGraphi
csLayerConfiguration() | |
| 1090 // for the frame's renderer in the parent document. | |
| 1091 ownerElement->setNeedsCompositingUpdate(); | |
| 1092 break; | |
| 1093 } | |
| 1094 } | |
| 1095 | |
| 1096 m_rootLayerAttachment = attachment; | |
| 1097 } | |
| 1098 | |
| 1099 void RenderLayerCompositor::detachRootLayer() | |
| 1100 { | |
| 1101 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached) | |
| 1102 return; | |
| 1103 | |
| 1104 switch (m_rootLayerAttachment) { | |
| 1105 case RootLayerAttachedViaEnclosingFrame: { | |
| 1106 // The layer will get unhooked up via CompositedLayerMapping::updateGrap
hicsLayerConfiguration() | |
| 1107 // for the frame's renderer in the parent document. | |
| 1108 if (m_overflowControlsHostLayer) | |
| 1109 m_overflowControlsHostLayer->removeFromParent(); | |
| 1110 else | |
| 1111 m_rootContentLayer->removeFromParent(); | |
| 1112 | |
| 1113 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerE
lement()) | |
| 1114 ownerElement->setNeedsCompositingUpdate(); | |
| 1115 break; | |
| 1116 } | |
| 1117 case RootLayerAttachedViaChromeClient: { | |
| 1118 LocalFrame& frame = m_renderView.frameView()->frame(); | |
| 1119 Page* page = frame.page(); | |
| 1120 if (!page) | |
| 1121 return; | |
| 1122 page->chrome().client().attachRootGraphicsLayer(0, &frame); | |
| 1123 break; | |
| 1124 } | |
| 1125 case RootLayerUnattached: | |
| 1126 break; | |
| 1127 } | |
| 1128 | |
| 1129 m_rootLayerAttachment = RootLayerUnattached; | |
| 1130 } | |
| 1131 | |
| 1132 void RenderLayerCompositor::updateRootLayerAttachment() | |
| 1133 { | |
| 1134 ensureRootLayer(); | |
| 1135 } | |
| 1136 | |
| 1137 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const | |
| 1138 { | |
| 1139 if (Page* page = this->page()) | |
| 1140 return page->scrollingCoordinator(); | |
| 1141 | |
| 1142 return 0; | |
| 1143 } | |
| 1144 | |
| 1145 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const | |
| 1146 { | |
| 1147 if (Page* page = this->page()) | |
| 1148 return page->chrome().client().graphicsLayerFactory(); | |
| 1149 return 0; | |
| 1150 } | |
| 1151 | |
| 1152 Page* RenderLayerCompositor::page() const | |
| 1153 { | |
| 1154 return m_renderView.frameView()->frame().page(); | |
| 1155 } | |
| 1156 | |
| 1157 DocumentLifecycle& RenderLayerCompositor::lifecycle() const | |
| 1158 { | |
| 1159 return m_renderView.document().lifecycle(); | |
| 1160 } | |
| 1161 | |
| 1162 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer) | |
| 1163 { | |
| 1164 String name; | |
| 1165 if (graphicsLayer == m_rootContentLayer.get()) { | |
| 1166 name = "Content Root Layer"; | |
| 1167 } else if (graphicsLayer == m_rootTransformLayer.get()) { | |
| 1168 name = "Root Transform Layer"; | |
| 1169 } else if (graphicsLayer == m_overflowControlsHostLayer.get()) { | |
| 1170 name = "Overflow Controls Host Layer"; | |
| 1171 } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) { | |
| 1172 name = "Horizontal Scrollbar Layer"; | |
| 1173 } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) { | |
| 1174 name = "Vertical Scrollbar Layer"; | |
| 1175 } else if (graphicsLayer == m_layerForScrollCorner.get()) { | |
| 1176 name = "Scroll Corner Layer"; | |
| 1177 } else if (graphicsLayer == m_containerLayer.get()) { | |
| 1178 name = "LocalFrame Clipping Layer"; | |
| 1179 } else if (graphicsLayer == m_scrollLayer.get()) { | |
| 1180 name = "LocalFrame Scrolling Layer"; | |
| 1181 } else { | |
| 1182 ASSERT_NOT_REACHED(); | |
| 1183 } | |
| 1184 | |
| 1185 return name; | |
| 1186 } | |
| 1187 | |
| 1188 } // namespace blink | |
| OLD | NEW |