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/rendering/RenderLayerCompositor.h" 29 30 #include "CSSPropertyNames.h" 31 #include "HTMLNames.h" 32 #include "core/dom/NodeList.h" 33 #include "core/html/HTMLCanvasElement.h" 34 #include "core/html/HTMLIFrameElement.h" 35 #include "core/html/canvas/CanvasRenderingContext.h" 36 #include "core/inspector/InspectorInstrumentation.h" 37 #include "core/page/Chrome.h" 38 #include "core/page/ChromeClient.h" 39 #include "core/page/Frame.h" 40 #include "core/page/FrameView.h" 41 #include "core/page/Page.h" 42 #include "core/page/Settings.h" 43 #include "core/page/animation/AnimationController.h" 44 #include "core/page/scrolling/ScrollingConstraints.h" 45 #include "core/page/scrolling/ScrollingCoordinator.h" 46 #include "core/platform/HistogramSupport.h" 47 #include "core/platform/Logging.h" 48 #include "core/platform/ScrollbarTheme.h" 49 #include "core/platform/chromium/TraceEvent.h" 50 #include "core/platform/graphics/GraphicsLayer.h" 51 #include "core/platform/graphics/GraphicsLayerClient.h" 52 #include "core/platform/graphics/transforms/TransformState.h" 53 #include "core/rendering/HitTestResult.h" 54 #include "core/rendering/RenderApplet.h" 55 #include "core/rendering/RenderEmbeddedObject.h" 56 #include "core/rendering/RenderFullScreen.h" 57 #include "core/rendering/RenderGeometryMap.h" 58 #include "core/rendering/RenderIFrame.h" 59 #include "core/rendering/RenderLayerBacking.h" 60 #include "core/rendering/RenderReplica.h" 61 #include "core/rendering/RenderVideo.h" 62 #include "core/rendering/RenderView.h" 63 #include "wtf/TemporaryChange.h" 64 65 #if !LOG_DISABLED 66 #include "wtf/CurrentTime.h" 67 #endif 68 69 #ifndef NDEBUG 70 #include "core/rendering/RenderTreeAsText.h" 71 #endif 72 73 #define WTF_USE_COMPOSITING_FOR_SMALL_CANVASES 1 74 75 static const int canvasAreaThresholdRequiringCompositing = 50 * 100; 76 77 namespace WebCore { 78 79 using namespace HTMLNames; 80 81 class OverlapMapContainer { 82 public: 83 void add(const IntRect& bounds) 84 { 85 m_layerRects.append(bounds); 86 m_boundingBox.unite(bounds); 87 } 88 89 bool overlapsLayers(const IntRect& bounds) const 90 { 91 // Checking with the bounding box will quickly reject cases when 92 // layers are created for lists of items going in one direction and 93 // never overlap with each other. 94 if (!bounds.intersects(m_boundingBox)) 95 return false; 96 for (unsigned i = 0; i < m_layerRects.size(); i++) { 97 if (m_layerRects[i].intersects(bounds)) 98 return true; 99 } 100 return false; 101 } 102 103 void unite(const OverlapMapContainer& otherContainer) 104 { 105 m_layerRects.append(otherContainer.m_layerRects); 106 m_boundingBox.unite(otherContainer.m_boundingBox); 107 } 108 private: 109 Vector<IntRect> m_layerRects; 110 IntRect m_boundingBox; 111 }; 112 113 class RenderLayerCompositor::OverlapMap { 114 WTF_MAKE_NONCOPYABLE(OverlapMap); 115 public: 116 OverlapMap() 117 : m_geometryMap(UseTransforms) 118 { 119 // Begin by assuming the root layer will be composited so that there 120 // is something on the stack. The root layer should also never get a 121 // finishCurrentOverlapTestingContext() call. 122 beginNewOverlapTestingContext(); 123 } 124 125 void add(const RenderLayer* layer, const IntRect& bounds) 126 { 127 // Layers do not contribute to overlap immediately--instead, they will 128 // contribute to overlap as soon as they have been recursively processed 129 // and popped off the stack. 130 ASSERT(m_overlapStack.size() >= 2); 131 m_overlapStack[m_overlapStack.size() - 2].add(bounds); 132 m_layers.add(layer); 133 } 134 135 bool contains(const RenderLayer* layer) 136 { 137 return m_layers.contains(layer); 138 } 139 140 bool overlapsLayers(const IntRect& bounds) const 141 { 142 return m_overlapStack.last().overlapsLayers(bounds); 143 } 144 145 bool isEmpty() 146 { 147 return m_layers.isEmpty(); 148 } 149 150 void beginNewOverlapTestingContext() 151 { 152 // This effectively creates a new "clean slate" for overlap state. 153 // This is used when we know that a subtree or remaining set of 154 // siblings does not need to check overlap with things behind it. 155 m_overlapStack.append(OverlapMapContainer()); 156 } 157 158 void finishCurrentOverlapTestingContext() 159 { 160 // The overlap information on the top of the stack is still necessary 161 // for checking overlap of any layers outside this context that may 162 // overlap things from inside this context. Therefore, we must merge 163 // the information from the top of the stack before popping the stack. 164 // 165 // FIXME: we may be able to avoid this deep copy by rearranging how 166 // overlapMap state is managed. 167 m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last()); 168 m_overlapStack.removeLast(); 169 } 170 171 RenderGeometryMap& geometryMap() { return m_geometryMap; } 172 173 private: 174 Vector<OverlapMapContainer> m_overlapStack; 175 HashSet<const RenderLayer*> m_layers; 176 RenderGeometryMap m_geometryMap; 177 }; 178 179 struct CompositingState { 180 CompositingState(RenderLayer* compAncestor, bool testOverlap) 181 : m_compositingAncestor(compAncestor) 182 , m_subtreeIsCompositing(false) 183 , m_testingOverlap(testOverlap) 184 #ifndef NDEBUG 185 , m_depth(0) 186 #endif 187 { 188 } 189 190 CompositingState(const CompositingState& other) 191 : m_compositingAncestor(other.m_compositingAncestor) 192 , m_subtreeIsCompositing(other.m_subtreeIsCompositing) 193 , m_testingOverlap(other.m_testingOverlap) 194 #ifndef NDEBUG 195 , m_depth(other.m_depth + 1) 196 #endif 197 { 198 } 199 200 RenderLayer* m_compositingAncestor; 201 bool m_subtreeIsCompositing; 202 bool m_testingOverlap; 203 #ifndef NDEBUG 204 int m_depth; 205 #endif 206 }; 207 208 209 static inline bool compositingLogEnabled() 210 { 211 #if !LOG_DISABLED 212 return LogCompositing.state == WTFLogChannelOn; 213 #else 214 return false; 215 #endif 216 } 217 218 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView) 219 : m_renderView(renderView) 220 , m_hasAcceleratedCompositing(true) 221 , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers)) 222 , m_compositedLayerCount(0) 223 , m_showRepaintCounter(false) 224 , m_reevaluateCompositingAfterLayout(false) 225 , m_compositing(false) 226 , m_compositingLayersNeedRebuild(false) 227 , m_forceCompositingMode(false) 228 , m_inPostLayoutUpdate(false) 229 , m_needsUpdateCompositingRequirementsState(false) 230 , m_isTrackingRepaints(false) 231 , m_rootLayerAttachment(RootLayerUnattached) 232 #if !LOG_DISABLED 233 , m_rootLayerUpdateCount(0) 234 , m_obligateCompositedLayerCount(0) 235 , m_secondaryCompositedLayerCount(0) 236 , m_obligatoryBackingStoreBytes(0) 237 , m_secondaryBackingStoreBytes(0) 238 #endif 239 { 240 } 241 242 RenderLayerCompositor::~RenderLayerCompositor() 243 { 244 ASSERT(m_rootLayerAttachment == RootLayerUnattached); 245 } 246 247 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */) 248 { 249 if (enable != m_compositing) { 250 m_compositing = enable; 251 252 if (m_compositing) { 253 ensureRootLayer(); 254 notifyIFramesOfCompositingChange(); 255 } else 256 destroyRootLayer(); 257 } 258 } 259 260 void RenderLayerCompositor::cacheAcceleratedCompositingFlags() 261 { 262 bool hasAcceleratedCompositing = false; 263 bool showRepaintCounter = false; 264 bool forceCompositingMode = false; 265 266 if (Settings* settings = m_renderView->document()->settings()) { 267 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled(); 268 269 // We allow the chrome to override the settings, in case the page is rendered 270 // on a chrome that doesn't allow accelerated compositing. 271 if (hasAcceleratedCompositing) { 272 if (Page* page = this->page()) { 273 ChromeClient* chromeClient = page->chrome().client(); 274 m_compositingTriggers = chromeClient->allowedCompositingTriggers(); 275 hasAcceleratedCompositing = m_compositingTriggers; 276 } 277 } 278 279 showRepaintCounter = settings->showRepaintCounter(); 280 forceCompositingMode = settings->forceCompositingMode() && hasAcceleratedCompositing; 281 282 if (forceCompositingMode && !isMainFrame()) 283 forceCompositingMode = requiresCompositingForScrollableFrame(); 284 } 285 286 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode) 287 setCompositingLayersNeedRebuild(); 288 289 m_hasAcceleratedCompositing = hasAcceleratedCompositing; 290 m_showRepaintCounter = showRepaintCounter; 291 m_forceCompositingMode = forceCompositingMode; 292 } 293 294 bool RenderLayerCompositor::canRender3DTransforms() const 295 { 296 return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger); 297 } 298 299 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild) 300 { 301 if (inCompositingMode()) 302 m_compositingLayersNeedRebuild = needRebuild; 303 } 304 305 void RenderLayerCompositor::didChangeVisibleRect() 306 { 307 GraphicsLayer* rootLayer = rootGraphicsLayer(); 308 if (!rootLayer) 309 return; 310 311 FrameView* frameView = m_renderView ? m_renderView->frameView() : 0; 312 if (!frameView) 313 return; 314 315 IntRect visibleRect = m_containerLayer ? IntRect(IntPoint(), frameView->contentsSize()) : frameView->visibleContentRect(); 316 if (rootLayer->visibleRectChangeRequiresFlush(visibleRect)) { 317 if (Page* page = this->page()) 318 page->chrome().client()->scheduleCompositingLayerFlush(); 319 } 320 } 321 322 bool RenderLayerCompositor::hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const 323 { 324 return m_compositedLayerCount > (rootLayer->isComposited() ? 1 : 0); 325 } 326 327 void RenderLayerCompositor::updateCompositingRequirementsState() 328 { 329 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateCompositingRequirementsState"); 330 331 if (!m_needsUpdateCompositingRequirementsState) 332 return; 333 334 m_needsUpdateCompositingRequirementsState = false; 335 336 if (!rootRenderLayer() || !rootRenderLayer()->acceleratedCompositingForOverflowScrollEnabled()) 337 return; 338 339 const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas(); 340 if (!scrollableAreas) 341 return; 342 343 for (HashSet<RenderLayer*>::iterator it = m_outOfFlowPositionedLayers.begin(); it != m_outOfFlowPositionedLayers.end(); ++it) 344 (*it)->updateHasUnclippedDescendant(); 345 346 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it) 347 (*it)->updateNeedsCompositedScrolling(); 348 } 349 350 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot) 351 { 352 // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished. 353 if (m_renderView->needsLayout()) 354 return; 355 356 if (m_forceCompositingMode && !m_compositing) 357 enableCompositingMode(true); 358 359 if (!m_reevaluateCompositingAfterLayout && !m_compositing) 360 return; 361 362 AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame()->animation()); 363 364 TemporaryChange<bool> postLayoutChange(m_inPostLayoutUpdate, true); 365 366 bool checkForHierarchyUpdate = m_reevaluateCompositingAfterLayout; 367 bool needGeometryUpdate = false; 368 369 switch (updateType) { 370 case CompositingUpdateAfterStyleChange: 371 case CompositingUpdateAfterLayout: 372 checkForHierarchyUpdate = true; 373 break; 374 case CompositingUpdateOnScroll: 375 checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates. 376 needGeometryUpdate = true; 377 break; 378 case CompositingUpdateOnCompositedScroll: 379 needGeometryUpdate = true; 380 break; 381 } 382 383 if (!checkForHierarchyUpdate && !needGeometryUpdate) 384 return; 385 386 bool needHierarchyUpdate = m_compositingLayersNeedRebuild; 387 bool isFullUpdate = !updateRoot; 388 389 // Only clear the flag if we're updating the entire hierarchy. 390 m_compositingLayersNeedRebuild = false; 391 updateRoot = rootRenderLayer(); 392 393 if (isFullUpdate && updateType == CompositingUpdateAfterLayout) 394 m_reevaluateCompositingAfterLayout = false; 395 396 #if !LOG_DISABLED 397 double startTime = 0; 398 if (compositingLogEnabled()) { 399 ++m_rootLayerUpdateCount; 400 startTime = currentTime(); 401 } 402 #endif 403 404 if (checkForHierarchyUpdate) { 405 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers. 406 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex. 407 CompositingState compState(updateRoot, true); 408 bool layersChanged = false; 409 bool saw3DTransform = false; 410 { 411 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::computeCompositingRequirements"); 412 OverlapMap overlapTestRequestMap; 413 computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, compState, layersChanged, saw3DTransform); 414 } 415 needHierarchyUpdate |= layersChanged; 416 } 417 418 #if !LOG_DISABLED 419 if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) { 420 m_obligateCompositedLayerCount = 0; 421 m_secondaryCompositedLayerCount = 0; 422 m_obligatoryBackingStoreBytes = 0; 423 m_secondaryBackingStoreBytes = 0; 424 425 Frame* frame = m_renderView->frameView()->frame(); 426 LOG(Compositing, "\nUpdate %d of %s.\n", m_rootLayerUpdateCount, isMainFrame() ? "main frame" : frame->tree()->uniqueName().string().utf8().data()); 427 } 428 #endif 429 430 if (needHierarchyUpdate) { 431 // Update the hierarchy of the compositing layers. 432 Vector<GraphicsLayer*> childList; 433 { 434 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::rebuildCompositingLayerTree"); 435 rebuildCompositingLayerTree(updateRoot, childList, 0); 436 } 437 438 // Host the document layer in the RenderView's root layer. 439 if (isFullUpdate) { 440 // Even when childList is empty, don't drop out of compositing mode if there are 441 // composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden). 442 if (childList.isEmpty() && !hasAnyAdditionalCompositedLayers(updateRoot)) 443 destroyRootLayer(); 444 else 445 m_rootContentLayer->setChildren(childList); 446 } 447 } else if (needGeometryUpdate) { 448 // We just need to do a geometry update. This is only used for position:fixed scrolling; 449 // most of the time, geometry is updated via RenderLayer::styleChanged(). 450 updateLayerTreeGeometry(updateRoot, 0); 451 } 452 453 #if !LOG_DISABLED 454 if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) { 455 double endTime = currentTime(); 456 LOG(Compositing, "Total layers primary secondary obligatory backing (KB) secondary backing(KB) total backing (KB) update time (ms)\n"); 457 458 LOG(Compositing, "%8d %11d %9d %20.2f %22.2f %22.2f %18.2f\n", 459 m_obligateCompositedLayerCount + m_secondaryCompositedLayerCount, m_obligateCompositedLayerCount, 460 m_secondaryCompositedLayerCount, m_obligatoryBackingStoreBytes / 1024, m_secondaryBackingStoreBytes / 1024, (m_obligatoryBackingStoreBytes + m_secondaryBackingStoreBytes) / 1024, 1000.0 * (endTime - startTime)); 461 } 462 #endif 463 ASSERT(updateRoot || !m_compositingLayersNeedRebuild); 464 465 if (!hasAcceleratedCompositing()) 466 enableCompositingMode(false); 467 468 // Inform the inspector that the layer tree has changed. 469 InspectorInstrumentation::layerTreeDidChange(page()); 470 } 471 472 void RenderLayerCompositor::layerBecameNonComposited(const RenderLayer* renderLayer) 473 { 474 ASSERT(m_compositedLayerCount > 0); 475 --m_compositedLayerCount; 476 } 477 478 static bool requiresCompositing(CompositingReasons reasons) 479 { 480 return reasons != CompositingReasonNone; 481 } 482 483 #if !LOG_DISABLED 484 void RenderLayerCompositor::logLayerInfo(const RenderLayer* layer, int depth) 485 { 486 if (!compositingLogEnabled()) 487 return; 488 489 RenderLayerBacking* backing = layer->backing(); 490 if (requiresCompositing(directReasonsForCompositing(layer)) || layer->isRootLayer()) { 491 ++m_obligateCompositedLayerCount; 492 m_obligatoryBackingStoreBytes += backing->backingStoreMemoryEstimate(); 493 } else { 494 ++m_secondaryCompositedLayerCount; 495 m_secondaryBackingStoreBytes += backing->backingStoreMemoryEstimate(); 496 } 497 498 String layerName; 499 #ifndef NDEBUG 500 layerName = layer->debugName(); 501 #endif 502 503 LOG(Compositing, "%*p %dx%d %.2fKB (%s) %s\n", 12 + depth * 2, layer, backing->compositedBounds().width(), backing->compositedBounds().height(), 504 backing->backingStoreMemoryEstimate() / 1024, 505 logReasonsForCompositing(layer), layerName.utf8().data()); 506 } 507 #endif 508 509 void RenderLayerCompositor::addOutOfFlowPositionedLayer(RenderLayer* layer) 510 { 511 m_outOfFlowPositionedLayers.add(layer); 512 } 513 514 void RenderLayerCompositor::removeOutOfFlowPositionedLayer(RenderLayer* layer) 515 { 516 m_outOfFlowPositionedLayers.remove(layer); 517 } 518 519 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) 520 { 521 bool layerChanged = false; 522 RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason; 523 requiresCompositingForPosition(layer->renderer(), layer, &viewportConstrainedNotCompositedReason); 524 525 // FIXME: It would be nice to directly use the layer's compositing reason, 526 // but updateBacking() also gets called without having updated compositing 527 // requirements fully. 528 if (needsToBeComposited(layer)) { 529 enableCompositingMode(); 530 531 if (!layer->backing()) { 532 // If we need to repaint, do so before making backing 533 if (shouldRepaint == CompositingChangeRepaintNow) 534 repaintOnCompositingChange(layer); 535 536 layer->ensureBacking(); 537 538 // At this time, the ScrollingCooridnator only supports the top-level frame. 539 if (layer->isRootLayer() && !isMainFrame()) { 540 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 541 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView()); 542 } 543 544 // This layer and all of its descendants have cached repaints rects that are relative to 545 // the repaint container, so change when compositing changes; we need to update them here. 546 if (layer->parent()) 547 layer->computeRepaintRectsIncludingDescendants(); 548 549 layerChanged = true; 550 } 551 } else { 552 if (layer->backing()) { 553 // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to 554 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection 555 // are both either composited, or not composited. 556 if (layer->isReflection()) { 557 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer(); 558 if (RenderLayerBacking* backing = sourceLayer->backing()) { 559 ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer()); 560 backing->graphicsLayer()->setReplicatedByLayer(0); 561 } 562 } 563 564 removeViewportConstrainedLayer(layer); 565 566 layer->clearBacking(); 567 layerChanged = true; 568 569 // This layer and all of its descendants have cached repaints rects that are relative to 570 // the repaint container, so change when compositing changes; we need to update them here. 571 layer->computeRepaintRectsIncludingDescendants(); 572 573 // If we need to repaint, do so now that we've removed the backing 574 if (shouldRepaint == CompositingChangeRepaintNow) 575 repaintOnCompositingChange(layer); 576 } 577 } 578 579 if (layerChanged && layer->renderer()->isRenderPart()) { 580 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer())); 581 if (innerCompositor && innerCompositor->inCompositingMode()) 582 innerCompositor->updateRootLayerAttachment(); 583 } 584 585 if (layerChanged) 586 layer->clearClipRectsIncludingDescendants(PaintingClipRects); 587 588 // If a fixed position layer gained/lost a backing or the reason not compositing it changed, 589 // the scrolling coordinator needs to recalculate whether it can do fast scrolling. 590 if (layer->renderer()->style()->position() == FixedPosition) { 591 if (layer->viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) { 592 layer->setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason); 593 layerChanged = true; 594 } 595 if (layerChanged) { 596 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 597 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView->frameView()); 598 } 599 } 600 601 return layerChanged; 602 } 603 604 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) 605 { 606 bool layerChanged = updateBacking(layer, shouldRepaint); 607 608 // See if we need content or clipping layers. Methods called here should assume 609 // that the compositing state of descendant layers has not been updated yet. 610 if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration()) 611 layerChanged = true; 612 613 return layerChanged; 614 } 615 616 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer) 617 { 618 // If the renderer is not attached yet, no need to repaint. 619 if (layer->renderer() != m_renderView && !layer->renderer()->parent()) 620 return; 621 622 RenderLayerModelObject* repaintContainer = layer->renderer()->containerForRepaint(); 623 if (!repaintContainer) 624 repaintContainer = m_renderView; 625 626 layer->repaintIncludingNonCompositingDescendants(repaintContainer); 627 } 628 629 // This method assumes that layout is up-to-date, unlike repaintOnCompositingChange(). 630 void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect) 631 { 632 RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(false /*exclude self*/); 633 if (compositedAncestor) { 634 ASSERT(compositedAncestor->backing()); 635 636 LayoutPoint offset; 637 layer->convertToLayerCoords(compositedAncestor, offset); 638 639 LayoutRect repaintRect = rect; 640 repaintRect.moveBy(offset); 641 642 compositedAncestor->setBackingNeedsRepaintInRect(repaintRect); 643 } 644 } 645 646 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant 647 // RenderLayers that are rendered by the composited RenderLayer. 648 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const 649 { 650 if (!canBeComposited(layer)) 651 return IntRect(); 652 653 RenderLayer::CalculateLayerBoundsFlags flags = RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask; 654 #if HAVE(COMPOSITOR_FILTER_OUTSETS) 655 // If the compositor computes its own filter outsets, don't include them in the composited bounds. 656 if (!layer->paintsWithFilters()) 657 flags &= ~RenderLayer::IncludeLayerFilterOutsets; 658 #endif 659 return layer->calculateLayerBounds(ancestorLayer, 0, flags); 660 } 661 662 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/) 663 { 664 setCompositingLayersNeedRebuild(); 665 } 666 667 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child) 668 { 669 if (!child->isComposited() || parent->renderer()->documentBeingDestroyed()) 670 return; 671 672 removeViewportConstrainedLayer(child); 673 repaintInCompositedAncestor(child, child->backing()->compositedBounds()); 674 675 setCompositingParent(child, 0); 676 setCompositingLayersNeedRebuild(); 677 } 678 679 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const 680 { 681 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) { 682 if (curr->isStackingContainer()) 683 return 0; 684 685 if (curr->renderer()->hasClipOrOverflowClip()) 686 return curr; 687 } 688 return 0; 689 } 690 691 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed) 692 { 693 if (layer->isRootLayer()) 694 return; 695 696 if (!boundsComputed) { 697 // FIXME: If this layer's overlap bounds include its children, we don't need to add its 698 // children's bounds to the overlap map. 699 layerBounds = enclosingIntRect(overlapMap.geometryMap().absoluteRect(layer->overlapBounds())); 700 // Empty rects never intersect, but we need them to for the purposes of overlap testing. 701 if (layerBounds.isEmpty()) 702 layerBounds.setSize(IntSize(1, 1)); 703 boundsComputed = true; 704 } 705 706 IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(RenderLayer::ClipRectsContext(rootRenderLayer(), 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions. 707 clipRect.intersect(layerBounds); 708 overlapMap.add(layer, clipRect); 709 } 710 711 void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, RenderLayer* layer, RenderLayer* ancestorLayer) 712 { 713 if (!canBeComposited(layer) || overlapMap.contains(layer)) 714 return; 715 716 // A null ancestorLayer is an indication that 'layer' has already been pushed. 717 if (ancestorLayer) 718 overlapMap.geometryMap().pushMappingsToAncestor(layer, ancestorLayer); 719 720 IntRect bounds; 721 bool haveComputedBounds = false; 722 addToOverlapMap(overlapMap, layer, bounds, haveComputedBounds); 723 724 #if !ASSERT_DISABLED 725 LayerListMutationDetector mutationChecker(layer); 726 #endif 727 728 if (layer->isStackingContainer()) { 729 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 730 size_t listSize = negZOrderList->size(); 731 for (size_t i = 0; i < listSize; ++i) { 732 RenderLayer* curLayer = negZOrderList->at(i); 733 addToOverlapMapRecursive(overlapMap, curLayer, layer); 734 } 735 } 736 } 737 738 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 739 size_t listSize = normalFlowList->size(); 740 for (size_t i = 0; i < listSize; ++i) { 741 RenderLayer* curLayer = normalFlowList->at(i); 742 addToOverlapMapRecursive(overlapMap, curLayer, layer); 743 } 744 } 745 746 if (layer->isStackingContainer()) { 747 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 748 size_t listSize = posZOrderList->size(); 749 for (size_t i = 0; i < listSize; ++i) { 750 RenderLayer* curLayer = posZOrderList->at(i); 751 addToOverlapMapRecursive(overlapMap, curLayer, layer); 752 } 753 } 754 } 755 756 if (ancestorLayer) 757 overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer); 758 } 759 760 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order) 761 // For the z-order children of a compositing layer: 762 // If a child layers has a compositing layer, then all subsequent layers must 763 // be compositing in order to render above that layer. 764 // 765 // If a child in the negative z-order list is compositing, then the layer itself 766 // must be compositing so that its contents render over that child. 767 // This implies that its positive z-index children must also be compositing. 768 // 769 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged, bool& descendantHas3DTransform) 770 { 771 layer->updateLayerListsIfNeeded(); 772 773 if (overlapMap) 774 overlapMap->geometryMap().pushMappingsToAncestor(layer, ancestorLayer); 775 776 // Clear the flag 777 layer->setHasCompositingDescendant(false); 778 779 // Start by assuming this layer will not need to composite. 780 CompositingReasons reasonsToComposite = CompositingReasonNone; 781 782 // First accumulate the straightforward compositing reasons. 783 CompositingReasons directReasons = directReasonsForCompositing(layer); 784 785 // Video is special. It's the only RenderLayer type that can both have 786 // RenderLayer children and whose children can't use its backing to render 787 // into. These children (the controls) always need to be promoted into their 788 // own layers to draw on top of the accelerated video. 789 if (compositingState.m_compositingAncestor && compositingState.m_compositingAncestor->renderer()->isVideo()) 790 directReasons |= CompositingReasonLayerForVideoOverlay; 791 792 if (canBeComposited(layer)) { 793 reasonsToComposite |= directReasons; 794 reasonsToComposite |= (inCompositingMode() && layer->isRootLayer()) ? CompositingReasonRoot : CompositingReasonNone; 795 } 796 797 // Next, accumulate reasons related to overlap. 798 // If overlap testing is used, this reason will be overridden. If overlap testing is not 799 // used, we must assume we overlap if there is anything composited behind us in paint-order. 800 CompositingReasons overlapCompositingReason = compositingState.m_subtreeIsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone; 801 802 bool haveComputedBounds = false; 803 IntRect absBounds; 804 // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map. 805 if (overlapMap && !overlapMap->isEmpty() && compositingState.m_testingOverlap && !requiresCompositing(directReasons)) { 806 // If we're testing for overlap, we only need to composite if we overlap something that is already composited. 807 absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds())); 808 809 // Empty rects never intersect, but we need them to for the purposes of overlap testing. 810 if (absBounds.isEmpty()) 811 absBounds.setSize(IntSize(1, 1)); 812 haveComputedBounds = true; 813 overlapCompositingReason = overlapMap->overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone; 814 } 815 816 reasonsToComposite |= overlapCompositingReason; 817 818 // The children of this layer don't need to composite, unless there is 819 // a compositing layer among them, so start by inheriting the compositing 820 // ancestor with m_subtreeIsCompositing set to false. 821 CompositingState childState(compositingState); 822 childState.m_subtreeIsCompositing = false; 823 824 bool willBeComposited = canBeComposited(layer) && requiresCompositing(reasonsToComposite); 825 if (willBeComposited) { 826 // Tell the parent it has compositing descendants. 827 compositingState.m_subtreeIsCompositing = true; 828 // This layer now acts as the ancestor for kids. 829 childState.m_compositingAncestor = layer; 830 831 // Here we know that all children and the layer's own contents can blindly paint into 832 // this layer's backing, until a descendant is composited. So, we don't need to check 833 // for overlap with anything behind this layer. 834 if (overlapMap) 835 overlapMap->beginNewOverlapTestingContext(); 836 // This layer is going to be composited, so children can safely ignore the fact that there's an 837 // animation running behind this layer, meaning they can rely on the overlap map testing again. 838 childState.m_testingOverlap = true; 839 } 840 841 #if !ASSERT_DISABLED 842 LayerListMutationDetector mutationChecker(layer); 843 #endif 844 845 bool anyDescendantHas3DTransform = false; 846 bool willHaveForegroundLayer = false; 847 848 if (layer->isStackingContainer()) { 849 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 850 size_t listSize = negZOrderList->size(); 851 for (size_t i = 0; i < listSize; ++i) { 852 RenderLayer* curLayer = negZOrderList->at(i); 853 computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform); 854 855 // If we have to make a layer for this child, make one now so we can have a contents layer 856 // (since we need to ensure that the -ve z-order child renders underneath our contents). 857 if (childState.m_subtreeIsCompositing) { 858 reasonsToComposite |= CompositingReasonNegativeZIndexChildren; 859 860 if (!willBeComposited) { 861 // make layer compositing 862 childState.m_compositingAncestor = layer; 863 overlapMap->beginNewOverlapTestingContext(); 864 willBeComposited = true; 865 willHaveForegroundLayer = true; 866 867 // FIXME: temporary solution for the first negative z-index composited child: 868 // re-compute the absBounds for the child so that we can add the 869 // negative z-index child's bounds to the new overlap context. 870 if (overlapMap) { 871 overlapMap->geometryMap().pushMappingsToAncestor(curLayer, layer); 872 IntRect childAbsBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(curLayer->overlapBounds())); 873 bool boundsComputed = true; 874 overlapMap->beginNewOverlapTestingContext(); 875 addToOverlapMap(*overlapMap, curLayer, childAbsBounds, boundsComputed); 876 overlapMap->finishCurrentOverlapTestingContext(); 877 overlapMap->geometryMap().popMappingsToAncestor(layer); 878 } 879 } 880 } 881 } 882 } 883 } 884 885 if (overlapMap && willHaveForegroundLayer) { 886 ASSERT(willBeComposited); 887 // A foreground layer effectively is a new backing for all subsequent children, so 888 // we don't need to test for overlap with anything behind this. So, we can finish 889 // the previous context that was accumulating rects for the negative z-index 890 // children, and start with a fresh new empty context. 891 overlapMap->finishCurrentOverlapTestingContext(); 892 overlapMap->beginNewOverlapTestingContext(); 893 // This layer is going to be composited, so children can safely ignore the fact that there's an 894 // animation running behind this layer, meaning they can rely on the overlap map testing again 895 childState.m_testingOverlap = true; 896 } 897 898 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 899 size_t listSize = normalFlowList->size(); 900 for (size_t i = 0; i < listSize; ++i) { 901 RenderLayer* curLayer = normalFlowList->at(i); 902 computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform); 903 } 904 } 905 906 if (layer->isStackingContainer()) { 907 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 908 size_t listSize = posZOrderList->size(); 909 for (size_t i = 0; i < listSize; ++i) { 910 RenderLayer* curLayer = posZOrderList->at(i); 911 computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform); 912 } 913 } 914 } 915 916 // Now that the subtree has been traversed, we can check for compositing reasons that depended on the state of the subtree. 917 918 // If we entered compositing mode during the recursion, the root will also need to be composited (as long as accelerated compositing is enabled). 919 if (layer->isRootLayer()) { 920 if (inCompositingMode() && m_hasAcceleratedCompositing) 921 willBeComposited = true; 922 } 923 924 // All layers (even ones that aren't being composited) need to get added to 925 // the overlap map. Layers that do not composite will draw into their 926 // compositing ancestor's backing, and so are still considered for overlap. 927 if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer()) 928 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 929 930 // Now check for reasons to become composited that depend on the state of descendant layers. 931 CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(layer->renderer(), childState.m_subtreeIsCompositing, anyDescendantHas3DTransform); 932 reasonsToComposite |= subtreeCompositingReasons; 933 if (!willBeComposited && canBeComposited(layer) && requiresCompositing(subtreeCompositingReasons)) { 934 childState.m_compositingAncestor = layer; 935 if (overlapMap) { 936 // FIXME: this context push is effectively a no-op but needs to exist for 937 // now, because the code is designed to push overlap information to the 938 // second-from-top context of the stack. 939 overlapMap->beginNewOverlapTestingContext(); 940 addToOverlapMapRecursive(*overlapMap, layer); 941 } 942 willBeComposited = true; 943 } 944 945 // If the original layer is composited, the reflection needs to be, too. 946 if (layer->reflectionLayer()) { 947 // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer? 948 CompositingReasons reflectionCompositingReason = willBeComposited ? CompositingReasonReflectionOfCompositedParent : CompositingReasonNone; 949 layer->reflectionLayer()->setCompositingReasons(layer->reflectionLayer()->compositingReasons() | reflectionCompositingReason); 950 } 951 952 // Subsequent layers in the parent's stacking context may also need to composite. 953 if (childState.m_subtreeIsCompositing) 954 compositingState.m_subtreeIsCompositing = true; 955 956 // Set the flag to say that this SC has compositing children. 957 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing); 958 959 960 // Turn overlap testing off for later layers if it's already off, or if we have an animating transform. 961 // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because 962 // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map. 963 bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposite & CompositingReasonClipsCompositingDescendants); 964 if ((!childState.m_testingOverlap && !isCompositedClippingLayer) || isRunningAcceleratedTransformAnimation(layer->renderer())) 965 compositingState.m_testingOverlap = false; 966 967 if (overlapMap && childState.m_compositingAncestor == layer && !layer->isRootLayer()) 968 overlapMap->finishCurrentOverlapTestingContext(); 969 970 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need 971 // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode 972 // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden). 973 // FIXME: hasAnyAdditionalCompositedLayers() code seems fishy. We need to make root layer logic more obvious. 974 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositing(directReasons) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) { 975 enableCompositingMode(false); 976 willBeComposited = false; 977 reasonsToComposite = CompositingReasonNone; 978 } 979 980 // At this point we have finished collecting all reasons to composite this layer. 981 layer->setCompositingReasons(reasonsToComposite); 982 983 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree(). 984 if (updateBacking(layer, CompositingChangeRepaintNow)) 985 layersChanged = true; 986 987 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow)) 988 layersChanged = true; 989 990 descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform(); 991 992 if (overlapMap) 993 overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer); 994 } 995 996 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer) 997 { 998 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer); 999 ASSERT(childLayer->isComposited()); 1000 1001 // It's possible to be called with a parent that isn't yet composited when we're doing 1002 // partial updates as required by painting or hit testing. Just bail in that case; 1003 // we'll do a full layer update soon. 1004 if (!parentLayer || !parentLayer->isComposited()) 1005 return; 1006 1007 if (parentLayer) { 1008 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers(); 1009 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers(); 1010 1011 hostingLayer->addChild(hostedLayer); 1012 } else 1013 childLayer->backing()->childForSuperlayers()->removeFromParent(); 1014 } 1015 1016 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer) 1017 { 1018 ASSERT(layer->isComposited()); 1019 1020 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers(); 1021 hostingLayer->removeAllChildren(); 1022 } 1023 1024 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const 1025 { 1026 if (!m_hasAcceleratedCompositing) 1027 return false; 1028 1029 return o->supportsAcceleratedRendering(); 1030 } 1031 1032 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth) 1033 { 1034 // Make the layer compositing if necessary, and set up clipping and content layers. 1035 // Note that we can only do work here that is independent of whether the descendant layers 1036 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary. 1037 1038 // Used for gathering UMA data about the effect on memory usage of promoting all layers 1039 // that have a webkit-transition on opacity or transform and intersect the viewport. 1040 static double pixelsWithoutPromotingAllTransitions = 0.0; 1041 static double pixelsAddedByPromotingAllTransitions = 0.0; 1042 1043 if (!depth) { 1044 pixelsWithoutPromotingAllTransitions = 0.0; 1045 pixelsAddedByPromotingAllTransitions = 0.0; 1046 } 1047 1048 RenderLayerBacking* layerBacking = layer->backing(); 1049 if (layerBacking) { 1050 // The compositing state of all our children has been updated already, so now 1051 // we can compute and cache the composited bounds for this layer. 1052 layerBacking->updateCompositedBounds(); 1053 1054 if (RenderLayer* reflection = layer->reflectionLayer()) { 1055 if (reflection->backing()) 1056 reflection->backing()->updateCompositedBounds(); 1057 } 1058 1059 layerBacking->updateGraphicsLayerConfiguration(); 1060 layerBacking->updateGraphicsLayerGeometry(); 1061 1062 if (!layer->parent()) 1063 updateRootLayerPosition(); 1064 1065 #if !LOG_DISABLED 1066 logLayerInfo(layer, depth); 1067 #else 1068 UNUSED_PARAM(depth); 1069 #endif 1070 if (layerBacking->hasUnpositionedOverflowControlsLayers()) 1071 layer->positionNewlyCreatedOverflowControls(); 1072 1073 pixelsWithoutPromotingAllTransitions += layer->size().height() * layer->size().width(); 1074 } else { 1075 if ((layer->renderer()->style()->transitionForProperty(CSSPropertyOpacity) || 1076 layer->renderer()->style()->transitionForProperty(CSSPropertyWebkitTransform)) && 1077 m_renderView->viewRect().intersects(layer->absoluteBoundingBox())) 1078 pixelsAddedByPromotingAllTransitions += layer->size().height() * layer->size().width(); 1079 } 1080 1081 // If this layer has backing, then we are collecting its children, otherwise appending 1082 // to the compositing child list of an enclosing layer. 1083 Vector<GraphicsLayer*> layerChildren; 1084 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer; 1085 1086 #if !ASSERT_DISABLED 1087 LayerListMutationDetector mutationChecker(layer); 1088 #endif 1089 1090 if (layer->isStackingContainer()) { 1091 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1092 size_t listSize = negZOrderList->size(); 1093 for (size_t i = 0; i < listSize; ++i) { 1094 RenderLayer* curLayer = negZOrderList->at(i); 1095 rebuildCompositingLayerTree(curLayer, childList, depth + 1); 1096 } 1097 } 1098 1099 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented. 1100 if (layerBacking && layerBacking->foregroundLayer()) 1101 childList.append(layerBacking->foregroundLayer()); 1102 } 1103 1104 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1105 size_t listSize = normalFlowList->size(); 1106 for (size_t i = 0; i < listSize; ++i) { 1107 RenderLayer* curLayer = normalFlowList->at(i); 1108 rebuildCompositingLayerTree(curLayer, childList, depth + 1); 1109 } 1110 } 1111 1112 if (layer->isStackingContainer()) { 1113 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1114 size_t listSize = posZOrderList->size(); 1115 for (size_t i = 0; i < listSize; ++i) { 1116 RenderLayer* curLayer = posZOrderList->at(i); 1117 rebuildCompositingLayerTree(curLayer, childList, depth + 1); 1118 } 1119 } 1120 } 1121 1122 if (layerBacking) { 1123 bool parented = false; 1124 if (layer->renderer()->isRenderPart()) 1125 parented = parentFrameContentLayers(toRenderPart(layer->renderer())); 1126 1127 if (!parented) 1128 layerBacking->parentForSublayers()->setChildren(layerChildren); 1129 1130 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer. 1131 // Otherwise, the overflow control layers are normal children. 1132 if (!layerBacking->hasClippingLayer() && !layerBacking->hasScrollingLayer()) { 1133 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) { 1134 overflowControlLayer->removeFromParent(); 1135 layerBacking->parentForSublayers()->addChild(overflowControlLayer); 1136 } 1137 1138 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) { 1139 overflowControlLayer->removeFromParent(); 1140 layerBacking->parentForSublayers()->addChild(overflowControlLayer); 1141 } 1142 1143 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) { 1144 overflowControlLayer->removeFromParent(); 1145 layerBacking->parentForSublayers()->addChild(overflowControlLayer); 1146 } 1147 } 1148 1149 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers()); 1150 } 1151 1152 if (!depth) { 1153 int percentageIncreaseInPixels = static_cast<int>(pixelsAddedByPromotingAllTransitions / pixelsWithoutPromotingAllTransitions * 100); 1154 HistogramSupport::histogramCustomCounts("Renderer.PixelIncreaseFromTransitions", percentageIncreaseInPixels, 0, 1000, 50); 1155 } 1156 } 1157 1158 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset) 1159 { 1160 if (m_overflowControlsHostLayer) 1161 m_overflowControlsHostLayer->setPosition(contentsOffset); 1162 } 1163 1164 void RenderLayerCompositor::frameViewDidChangeSize() 1165 { 1166 if (m_containerLayer) { 1167 FrameView* frameView = m_renderView->frameView(); 1168 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); 1169 1170 frameViewDidScroll(); 1171 updateOverflowControlsLayers(); 1172 1173 #if ENABLE(RUBBER_BANDING) 1174 if (m_layerForOverhangAreas) 1175 m_layerForOverhangAreas->setSize(frameView->frameRect().size()); 1176 #endif 1177 } 1178 } 1179 1180 void RenderLayerCompositor::frameViewDidScroll() 1181 { 1182 FrameView* frameView = m_renderView->frameView(); 1183 IntPoint scrollPosition = frameView->scrollPosition(); 1184 1185 if (!m_scrollLayer) 1186 return; 1187 1188 bool scrollingCoordinatorHandlesOffset = false; 1189 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) { 1190 if (Settings* settings = m_renderView->document()->settings()) { 1191 if (isMainFrame() || settings->compositedScrollingForFramesEnabled()) 1192 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView); 1193 } 1194 } 1195 1196 // Scroll position = scroll minimum + scroll offset. Adjust the layer's 1197 // position to handle whatever the scroll coordinator isn't handling. 1198 // The minimum scroll position is non-zero for RTL pages with overflow. 1199 if (scrollingCoordinatorHandlesOffset) 1200 m_scrollLayer->setPosition(-frameView->minimumScrollPosition()); 1201 else 1202 m_scrollLayer->setPosition(-scrollPosition); 1203 } 1204 1205 void RenderLayerCompositor::frameViewDidLayout() 1206 { 1207 } 1208 1209 void RenderLayerCompositor::rootFixedBackgroundsChanged() 1210 { 1211 if (!supportsFixedRootBackgroundCompositing()) 1212 return; 1213 1214 // To avoid having to make the fixed root background layer fixed positioned to 1215 // stay put, we position it in the layer tree as follows: 1216 // 1217 // + Overflow controls host 1218 // + Frame clip 1219 // + (Fixed root background) <-- Here. 1220 // + Frame scroll 1221 // + Root content layer 1222 // + Scrollbars 1223 // 1224 // That is, it needs to be the first child of the frame clip, the sibling of 1225 // the frame scroll layer. The compositor does not own the background layer, it 1226 // just positions it (like the foreground layer). 1227 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer()) 1228 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get()); 1229 } 1230 1231 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer) 1232 { 1233 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 1234 return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer); 1235 return false; 1236 } 1237 1238 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags) 1239 { 1240 updateCompositingLayers(CompositingUpdateAfterLayout); 1241 1242 if (!m_rootContentLayer) 1243 return String(); 1244 1245 // We skip dumping the scroll and clip layers to keep layerTreeAsText output 1246 // similar between platforms (unless we explicitly request dumping from the 1247 // root. 1248 GraphicsLayer* rootLayer = m_rootContentLayer.get(); 1249 if (flags & LayerTreeIncludesRootLayer) 1250 rootLayer = rootGraphicsLayer(); 1251 1252 String layerTreeText = rootLayer->layerTreeAsText(flags); 1253 1254 // The true root layer is not included in the dump, so if we want to report 1255 // its repaint rects, they must be included here. 1256 if (flags & LayerTreeIncludesRepaintRects) { 1257 String layerTreeTextWithRootRepaintRects = m_renderView->frameView()->trackedRepaintRectsAsText(); 1258 layerTreeTextWithRootRepaintRects.append(layerTreeText); 1259 return layerTreeTextWithRootRepaintRects; 1260 } 1261 1262 return layerTreeText; 1263 } 1264 1265 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer) 1266 { 1267 if (!renderer->node()->isFrameOwnerElement()) 1268 return 0; 1269 1270 HTMLFrameOwnerElement* element = toFrameOwnerElement(renderer->node()); 1271 if (Document* contentDocument = element->contentDocument()) { 1272 if (RenderView* view = contentDocument->renderView()) 1273 return view->compositor(); 1274 } 1275 return 0; 1276 } 1277 1278 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer) 1279 { 1280 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer); 1281 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame) 1282 return false; 1283 1284 RenderLayer* layer = renderer->layer(); 1285 if (!layer->isComposited()) 1286 return false; 1287 1288 RenderLayerBacking* backing = layer->backing(); 1289 GraphicsLayer* hostingLayer = backing->parentForSublayers(); 1290 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer(); 1291 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) { 1292 hostingLayer->removeAllChildren(); 1293 hostingLayer->addChild(rootLayer); 1294 } 1295 return true; 1296 } 1297 1298 // This just updates layer geometry without changing the hierarchy. 1299 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer, int depth) 1300 { 1301 if (RenderLayerBacking* layerBacking = layer->backing()) { 1302 // The compositing state of all our children has been updated already, so now 1303 // we can compute and cache the composited bounds for this layer. 1304 layerBacking->updateCompositedBounds(); 1305 1306 if (RenderLayer* reflection = layer->reflectionLayer()) { 1307 if (reflection->backing()) 1308 reflection->backing()->updateCompositedBounds(); 1309 } 1310 1311 layerBacking->updateGraphicsLayerConfiguration(); 1312 layerBacking->updateGraphicsLayerGeometry(); 1313 1314 if (!layer->parent()) 1315 updateRootLayerPosition(); 1316 1317 #if !LOG_DISABLED 1318 logLayerInfo(layer, depth); 1319 #else 1320 UNUSED_PARAM(depth); 1321 #endif 1322 } 1323 1324 #if !ASSERT_DISABLED 1325 LayerListMutationDetector mutationChecker(layer); 1326 #endif 1327 1328 if (layer->isStackingContainer()) { 1329 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1330 size_t listSize = negZOrderList->size(); 1331 for (size_t i = 0; i < listSize; ++i) 1332 updateLayerTreeGeometry(negZOrderList->at(i), depth + 1); 1333 } 1334 } 1335 1336 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1337 size_t listSize = normalFlowList->size(); 1338 for (size_t i = 0; i < listSize; ++i) 1339 updateLayerTreeGeometry(normalFlowList->at(i), depth + 1); 1340 } 1341 1342 if (layer->isStackingContainer()) { 1343 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1344 size_t listSize = posZOrderList->size(); 1345 for (size_t i = 0; i < listSize; ++i) 1346 updateLayerTreeGeometry(posZOrderList->at(i), depth + 1); 1347 } 1348 } 1349 } 1350 1351 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry. 1352 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, bool compositedChildrenOnly) 1353 { 1354 if (layer != compositingAncestor) { 1355 if (RenderLayerBacking* layerBacking = layer->backing()) { 1356 layerBacking->updateCompositedBounds(); 1357 1358 if (RenderLayer* reflection = layer->reflectionLayer()) { 1359 if (reflection->backing()) 1360 reflection->backing()->updateCompositedBounds(); 1361 } 1362 1363 layerBacking->updateGraphicsLayerGeometry(); 1364 if (compositedChildrenOnly) 1365 return; 1366 } 1367 } 1368 1369 if (layer->reflectionLayer()) 1370 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), compositedChildrenOnly); 1371 1372 if (!layer->hasCompositingDescendant()) 1373 return; 1374 1375 #if !ASSERT_DISABLED 1376 LayerListMutationDetector mutationChecker(layer); 1377 #endif 1378 1379 if (layer->isStackingContainer()) { 1380 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1381 size_t listSize = negZOrderList->size(); 1382 for (size_t i = 0; i < listSize; ++i) 1383 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), compositedChildrenOnly); 1384 } 1385 } 1386 1387 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1388 size_t listSize = normalFlowList->size(); 1389 for (size_t i = 0; i < listSize; ++i) 1390 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), compositedChildrenOnly); 1391 } 1392 1393 if (layer->isStackingContainer()) { 1394 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1395 size_t listSize = posZOrderList->size(); 1396 for (size_t i = 0; i < listSize; ++i) 1397 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), compositedChildrenOnly); 1398 } 1399 } 1400 } 1401 1402 1403 void RenderLayerCompositor::repaintCompositedLayers(const IntRect* absRect) 1404 { 1405 recursiveRepaintLayer(rootRenderLayer(), absRect); 1406 } 1407 1408 void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer, const IntRect* rect) 1409 { 1410 // FIXME: This method does not work correctly with transforms. 1411 if (layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor()) { 1412 if (rect) 1413 layer->setBackingNeedsRepaintInRect(*rect); 1414 else 1415 layer->setBackingNeedsRepaint(); 1416 } 1417 1418 #if !ASSERT_DISABLED 1419 LayerListMutationDetector mutationChecker(layer); 1420 #endif 1421 1422 if (layer->hasCompositingDescendant()) { 1423 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1424 size_t listSize = negZOrderList->size(); 1425 for (size_t i = 0; i < listSize; ++i) { 1426 RenderLayer* curLayer = negZOrderList->at(i); 1427 if (rect) { 1428 IntRect childRect(*rect); 1429 curLayer->convertToPixelSnappedLayerCoords(layer, childRect); 1430 recursiveRepaintLayer(curLayer, &childRect); 1431 } else 1432 recursiveRepaintLayer(curLayer); 1433 } 1434 } 1435 1436 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1437 size_t listSize = posZOrderList->size(); 1438 for (size_t i = 0; i < listSize; ++i) { 1439 RenderLayer* curLayer = posZOrderList->at(i); 1440 if (rect) { 1441 IntRect childRect(*rect); 1442 curLayer->convertToPixelSnappedLayerCoords(layer, childRect); 1443 recursiveRepaintLayer(curLayer, &childRect); 1444 } else 1445 recursiveRepaintLayer(curLayer); 1446 } 1447 } 1448 } 1449 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1450 size_t listSize = normalFlowList->size(); 1451 for (size_t i = 0; i < listSize; ++i) { 1452 RenderLayer* curLayer = normalFlowList->at(i); 1453 if (rect) { 1454 IntRect childRect(*rect); 1455 curLayer->convertToPixelSnappedLayerCoords(layer, childRect); 1456 recursiveRepaintLayer(curLayer, &childRect); 1457 } else 1458 recursiveRepaintLayer(curLayer); 1459 } 1460 } 1461 } 1462 1463 RenderLayer* RenderLayerCompositor::rootRenderLayer() const 1464 { 1465 return m_renderView->layer(); 1466 } 1467 1468 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const 1469 { 1470 if (m_overflowControlsHostLayer) 1471 return m_overflowControlsHostLayer.get(); 1472 return m_rootContentLayer.get(); 1473 } 1474 1475 GraphicsLayer* RenderLayerCompositor::scrollLayer() const 1476 { 1477 return m_scrollLayer.get(); 1478 } 1479 1480 void RenderLayerCompositor::setIsInWindow(bool isInWindow) 1481 { 1482 if (!inCompositingMode()) 1483 return; 1484 1485 if (isInWindow) { 1486 if (m_rootLayerAttachment != RootLayerUnattached) 1487 return; 1488 1489 RootLayerAttachment attachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; 1490 attachRootLayer(attachment); 1491 } else { 1492 if (m_rootLayerAttachment == RootLayerUnattached) 1493 return; 1494 1495 detachRootLayer(); 1496 } 1497 } 1498 1499 void RenderLayerCompositor::clearBackingForLayerIncludingDescendants(RenderLayer* layer) 1500 { 1501 if (!layer) 1502 return; 1503 1504 if (layer->isComposited()) { 1505 removeViewportConstrainedLayer(layer); 1506 layer->clearBacking(); 1507 } 1508 1509 for (RenderLayer* currLayer = layer->firstChild(); currLayer; currLayer = currLayer->nextSibling()) 1510 clearBackingForLayerIncludingDescendants(currLayer); 1511 } 1512 1513 void RenderLayerCompositor::clearBackingForAllLayers() 1514 { 1515 clearBackingForLayerIncludingDescendants(m_renderView->layer()); 1516 } 1517 1518 void RenderLayerCompositor::updateRootLayerPosition() 1519 { 1520 if (m_rootContentLayer) { 1521 const IntRect& documentRect = m_renderView->documentRect(); 1522 m_rootContentLayer->setSize(documentRect.size()); 1523 m_rootContentLayer->setPosition(documentRect.location()); 1524 } 1525 if (m_containerLayer) { 1526 FrameView* frameView = m_renderView->frameView(); 1527 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); 1528 } 1529 } 1530 1531 bool RenderLayerCompositor::has3DContent() const 1532 { 1533 return layerHas3DContent(rootRenderLayer()); 1534 } 1535 1536 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const 1537 { 1538 if (!canBeComposited(layer)) 1539 return false; 1540 1541 return requiresCompositing(directReasonsForCompositing(layer)) || requiresCompositing(layer->compositingReasons()) || (inCompositingMode() && layer->isRootLayer()); 1542 } 1543 1544 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const 1545 { 1546 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly. 1547 // See http://webkit.org/b/84900 to re-enable it. 1548 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread; 1549 } 1550 1551 bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer* layer, const RenderLayer* compositingAncestorLayer) const 1552 { 1553 RenderObject* renderer = layer->renderer(); 1554 if (compositingAncestorLayer 1555 && !(compositingAncestorLayer->backing()->graphicsLayer()->drawsContent() 1556 || compositingAncestorLayer->backing()->paintsIntoCompositedAncestor())) 1557 return true; 1558 1559 if (layer->isRootLayer() 1560 || layer->transform() // note: excludes perspective and transformStyle3D. 1561 || requiresCompositingForVideo(renderer) 1562 || requiresCompositingForCanvas(renderer) 1563 || requiresCompositingForPlugin(renderer) 1564 || requiresCompositingForFrame(renderer) 1565 || requiresCompositingForBackfaceVisibilityHidden(renderer) 1566 || requiresCompositingForAnimation(renderer) 1567 || requiresCompositingForTransition(renderer) 1568 || requiresCompositingForFilters(renderer) 1569 || requiresCompositingForBlending(renderer) 1570 || requiresCompositingForPosition(renderer, layer) 1571 || requiresCompositingForOverflowScrolling(layer) 1572 || renderer->isTransparent() 1573 || renderer->hasMask() 1574 || renderer->hasReflection() 1575 || renderer->hasFilter()) 1576 return true; 1577 1578 CompositingReasons indirectReasonsThatNeedBacking = CompositingReasonOverlap 1579 | CompositingReasonAssumedOverlap 1580 | CompositingReasonNegativeZIndexChildren 1581 | CompositingReasonTransformWithCompositedDescendants 1582 | CompositingReasonOpacityWithCompositedDescendants 1583 | CompositingReasonMaskWithCompositedDescendants 1584 | CompositingReasonFilterWithCompositedDescendants 1585 | CompositingReasonBlendingWithCompositedDescendants 1586 | CompositingReasonPreserve3D; // preserve-3d has to create backing store to ensure that 3d-transformed elements intersect. 1587 return layer->compositingReasons() & indirectReasonsThatNeedBacking; 1588 } 1589 1590 CompositingReasons RenderLayerCompositor::directReasonsForCompositing(const RenderLayer* layer) const 1591 { 1592 RenderObject* renderer = layer->renderer(); 1593 CompositingReasons directReasons = CompositingReasonNone; 1594 1595 if (requiresCompositingForTransform(renderer)) 1596 directReasons |= CompositingReason3DTransform; 1597 1598 // Only zero or one of the following conditions will be true for a given RenderLayer. 1599 if (requiresCompositingForVideo(renderer)) 1600 directReasons |= CompositingReasonVideo; 1601 else if (requiresCompositingForCanvas(renderer)) 1602 directReasons |= CompositingReasonCanvas; 1603 else if (requiresCompositingForPlugin(renderer)) 1604 directReasons |= CompositingReasonPlugin; 1605 else if (requiresCompositingForFrame(renderer)) 1606 directReasons |= CompositingReasonIFrame; 1607 1608 if (requiresCompositingForBackfaceVisibilityHidden(renderer)) 1609 directReasons |= CompositingReasonBackfaceVisibilityHidden; 1610 1611 if (requiresCompositingForAnimation(renderer)) 1612 directReasons |= CompositingReasonAnimation; 1613 1614 if (requiresCompositingForTransition(renderer)) 1615 directReasons |= CompositingReasonAnimation; 1616 1617 if (requiresCompositingForFilters(renderer)) 1618 directReasons |= CompositingReasonFilters; 1619 1620 if (requiresCompositingForPosition(renderer, layer)) 1621 directReasons |= renderer->style()->position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky; 1622 1623 if (requiresCompositingForOverflowScrolling(layer)) 1624 directReasons |= CompositingReasonOverflowScrollingTouch; 1625 1626 if (requiresCompositingForBlending(renderer)) 1627 directReasons |= CompositingReasonBlending; 1628 1629 return directReasons; 1630 } 1631 1632 CompositingReasons RenderLayerCompositor::reasonsForCompositing(const RenderLayer* layer) const 1633 { 1634 CompositingReasons reasons = CompositingReasonNone; 1635 1636 if (!layer || !layer->isComposited()) 1637 return reasons; 1638 1639 return layer->compositingReasons(); 1640 } 1641 1642 #if !LOG_DISABLED 1643 const char* RenderLayerCompositor::logReasonsForCompositing(const RenderLayer* layer) 1644 { 1645 CompositingReasons reasons = reasonsForCompositing(layer); 1646 1647 if (reasons & CompositingReason3DTransform) 1648 return "3D transform"; 1649 1650 if (reasons & CompositingReasonVideo) 1651 return "video"; 1652 else if (reasons & CompositingReasonCanvas) 1653 return "canvas"; 1654 else if (reasons & CompositingReasonPlugin) 1655 return "plugin"; 1656 else if (reasons & CompositingReasonIFrame) 1657 return "iframe"; 1658 1659 if (reasons & CompositingReasonBackfaceVisibilityHidden) 1660 return "backface-visibility: hidden"; 1661 1662 if (reasons & CompositingReasonClipsCompositingDescendants) 1663 return "clips compositing descendants"; 1664 1665 if (reasons & CompositingReasonAnimation) 1666 return "animation"; 1667 1668 if (reasons & CompositingReasonFilters) 1669 return "filters"; 1670 1671 if (reasons & CompositingReasonPositionFixed) 1672 return "position: fixed"; 1673 1674 if (reasons & CompositingReasonPositionSticky) 1675 return "position: sticky"; 1676 1677 if (reasons & CompositingReasonOverflowScrollingTouch) 1678 return "-webkit-overflow-scrolling: touch"; 1679 1680 if (reasons & CompositingReasonAssumedOverlap) 1681 return "stacking"; 1682 1683 if (reasons & CompositingReasonOverlap) 1684 return "overlap"; 1685 1686 if (reasons & CompositingReasonNegativeZIndexChildren) 1687 return "negative z-index children"; 1688 1689 if (reasons & CompositingReasonTransformWithCompositedDescendants) 1690 return "transform with composited descendants"; 1691 1692 if (reasons & CompositingReasonOpacityWithCompositedDescendants) 1693 return "opacity with composited descendants"; 1694 1695 if (reasons & CompositingReasonMaskWithCompositedDescendants) 1696 return "mask with composited descendants"; 1697 1698 if (reasons & CompositingReasonReflectionWithCompositedDescendants) 1699 return "reflection with composited descendants"; 1700 1701 if (reasons & CompositingReasonFilterWithCompositedDescendants) 1702 return "filter with composited descendants"; 1703 1704 if (reasons & CompositingReasonBlendingWithCompositedDescendants) 1705 return "blending with composited descendants"; 1706 1707 if (reasons & CompositingReasonPerspective) 1708 return "perspective"; 1709 1710 if (reasons & CompositingReasonPreserve3D) 1711 return "preserve-3d"; 1712 1713 if (reasons & CompositingReasonRoot) 1714 return "root"; 1715 1716 return ""; 1717 } 1718 #endif 1719 1720 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips, 1721 // up to the enclosing compositing ancestor. This is required because compositing layers are parented 1722 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy. 1723 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy, 1724 // but a sibling in the z-order hierarchy. 1725 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const 1726 { 1727 if (!layer->isComposited() || !layer->parent()) 1728 return false; 1729 1730 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer(); 1731 if (!compositingAncestor) 1732 return false; 1733 1734 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(), 1735 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot), 1736 // and layer. 1737 RenderLayer* computeClipRoot = 0; 1738 RenderLayer* curr = layer; 1739 while (curr) { 1740 RenderLayer* next = curr->parent(); 1741 if (next == compositingAncestor) { 1742 computeClipRoot = curr; 1743 break; 1744 } 1745 curr = next; 1746 } 1747 1748 if (!computeClipRoot || computeClipRoot == layer) 1749 return false; 1750 1751 return layer->backgroundClipRect(RenderLayer::ClipRectsContext(computeClipRoot, 0, TemporaryClipRects)).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions. 1752 } 1753 1754 // Return true if the given layer is a stacking context and has compositing child 1755 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer 1756 // into the hierarchy between this layer and its children in the z-order hierarchy. 1757 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const 1758 { 1759 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip(); 1760 } 1761 1762 bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const 1763 { 1764 // Need this done first to determine overflow. 1765 ASSERT(!m_renderView->needsLayout()); 1766 if (isMainFrame()) 1767 return false; 1768 1769 if (!(m_compositingTriggers & ChromeClient::ScrollableInnerFrameTrigger)) 1770 return false; 1771 1772 FrameView* frameView = m_renderView->frameView(); 1773 return frameView->isScrollable(); 1774 } 1775 1776 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const 1777 { 1778 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger)) 1779 return false; 1780 1781 RenderStyle* style = renderer->style(); 1782 // Note that we ask the renderer if it has a transform, because the style may have transforms, 1783 // but the renderer may be an inline that doesn't suppport them. 1784 return renderer->hasTransform() && style->transform().has3DOperation(); 1785 } 1786 1787 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const 1788 { 1789 if (!(m_compositingTriggers & ChromeClient::VideoTrigger)) 1790 return false; 1791 1792 if (renderer->isVideo()) { 1793 RenderVideo* video = toRenderVideo(renderer); 1794 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video); 1795 } 1796 return false; 1797 } 1798 1799 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const 1800 { 1801 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger)) 1802 return false; 1803 1804 if (renderer->isCanvas()) { 1805 HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node()); 1806 #if USE(COMPOSITING_FOR_SMALL_CANVASES) 1807 bool isCanvasLargeEnoughToForceCompositing = true; 1808 #else 1809 bool isCanvasLargeEnoughToForceCompositing = canvas->size().area() >= canvasAreaThresholdRequiringCompositing; 1810 #endif 1811 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated() && (canvas->renderingContext()->is3d() || isCanvasLargeEnoughToForceCompositing); 1812 } 1813 return false; 1814 } 1815 1816 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const 1817 { 1818 if (!(m_compositingTriggers & ChromeClient::PluginTrigger)) 1819 return false; 1820 1821 bool composite = renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing(); 1822 if (!composite) 1823 return false; 1824 1825 m_reevaluateCompositingAfterLayout = true; 1826 1827 RenderWidget* pluginRenderer = toRenderWidget(renderer); 1828 // If we can't reliably know the size of the plugin yet, don't change compositing state. 1829 if (pluginRenderer->needsLayout()) 1830 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited(); 1831 1832 // Don't go into compositing mode if height or width are zero, or size is 1x1. 1833 IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect()); 1834 return contentBox.height() * contentBox.width() > 1; 1835 } 1836 1837 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const 1838 { 1839 if (!renderer->isRenderPart()) 1840 return false; 1841 1842 RenderPart* frameRenderer = toRenderPart(renderer); 1843 1844 if (!frameRenderer->requiresAcceleratedCompositing()) 1845 return false; 1846 1847 m_reevaluateCompositingAfterLayout = true; 1848 1849 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer); 1850 if (!innerCompositor) 1851 return false; 1852 1853 // If we can't reliably know the size of the iframe yet, don't change compositing state. 1854 if (renderer->needsLayout()) 1855 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited(); 1856 1857 // Don't go into compositing mode if height or width are zero. 1858 IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect()); 1859 return contentBox.height() * contentBox.width() > 0; 1860 } 1861 1862 bool RenderLayerCompositor::requiresCompositingForBackfaceVisibilityHidden(RenderObject* renderer) const 1863 { 1864 return canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden; 1865 } 1866 1867 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const 1868 { 1869 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger)) 1870 return false; 1871 1872 if (AnimationController* animController = renderer->animation()) 1873 return animController->isRunningAcceleratableAnimationOnRenderer(renderer); 1874 return false; 1875 } 1876 1877 bool RenderLayerCompositor::requiresCompositingForTransition(RenderObject* renderer) const 1878 { 1879 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger)) 1880 return false; 1881 1882 if (Settings* settings = m_renderView->document()->settings()) { 1883 if (!settings->acceleratedCompositingForTransitionEnabled()) 1884 return false; 1885 } 1886 1887 return renderer->style()->transitionForProperty(CSSPropertyOpacity) 1888 || renderer->style()->transitionForProperty(CSSPropertyWebkitFilter) 1889 || renderer->style()->transitionForProperty(CSSPropertyWebkitTransform); 1890 } 1891 1892 CompositingReasons RenderLayerCompositor::subtreeReasonsForCompositing(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants) const 1893 { 1894 CompositingReasons subtreeReasons = CompositingReasonNone; 1895 1896 // FIXME: this seems to be a potentially different layer than the layer for which this was called. May not be an error, but is very confusing. 1897 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); 1898 1899 // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented 1900 // via compositing so that they also apply to those composited descdendants. 1901 if (hasCompositedDescendants) { 1902 if (layer->transform()) 1903 subtreeReasons |= CompositingReasonTransformWithCompositedDescendants; 1904 1905 // If the implementation of createsGroup changes, we need to be aware of that in this part of code. 1906 ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->hasFilter() || renderer->hasBlendMode()) == renderer->createsGroup()); 1907 if (renderer->isTransparent()) 1908 subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants; 1909 if (renderer->hasMask()) 1910 subtreeReasons |= CompositingReasonMaskWithCompositedDescendants; 1911 if (renderer->hasFilter()) 1912 subtreeReasons |= CompositingReasonFilterWithCompositedDescendants; 1913 if (renderer->hasBlendMode()) 1914 subtreeReasons |= CompositingReasonBlendingWithCompositedDescendants; 1915 1916 if (renderer->hasReflection()) 1917 subtreeReasons |= CompositingReasonReflectionWithCompositedDescendants; 1918 1919 if (renderer->hasClipOrOverflowClip()) 1920 subtreeReasons |= CompositingReasonClipsCompositingDescendants; 1921 } 1922 1923 1924 // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that 1925 // will be affected by the preserve-3d or perspective. 1926 if (has3DTransformedDescendants) { 1927 if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D) 1928 subtreeReasons |= CompositingReasonPreserve3D; 1929 1930 if (renderer->style()->hasPerspective()) 1931 subtreeReasons |= CompositingReasonPerspective; 1932 } 1933 1934 return subtreeReasons; 1935 } 1936 1937 bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const 1938 { 1939 if (!(m_compositingTriggers & ChromeClient::FilterTrigger)) 1940 return false; 1941 1942 return renderer->hasFilter(); 1943 } 1944 1945 bool RenderLayerCompositor::requiresCompositingForBlending(RenderObject* renderer) const 1946 { 1947 return renderer->hasBlendMode(); 1948 } 1949 1950 bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const 1951 { 1952 // position:fixed elements that create their own stacking context (e.g. have an explicit z-index, 1953 // opacity, transform) can get their own composited layer. A stacking context is required otherwise 1954 // z-index and clipping will be broken. 1955 if (!renderer->isPositioned()) 1956 return false; 1957 1958 EPosition position = renderer->style()->position(); 1959 bool isFixed = renderer->isOutOfFlowPositioned() && position == FixedPosition; 1960 if (isFixed && !layer->isStackingContainer()) 1961 return false; 1962 1963 bool isSticky = renderer->isInFlowPositioned() && position == StickyPosition; 1964 if (!isFixed && !isSticky) 1965 return false; 1966 1967 // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled(). 1968 if (Settings* settings = m_renderView->document()->settings()) { 1969 if (!settings->acceleratedCompositingForFixedPositionEnabled()) 1970 return false; 1971 } 1972 1973 if (isSticky) 1974 return true; 1975 1976 RenderObject* container = renderer->container(); 1977 // If the renderer is not hooked up yet then we have to wait until it is. 1978 if (!container) { 1979 m_reevaluateCompositingAfterLayout = true; 1980 return false; 1981 } 1982 1983 // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements. 1984 // They will stay fixed wrt the container rather than the enclosing frame. 1985 if (container != m_renderView) { 1986 if (viewportConstrainedNotCompositedReason) 1987 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer; 1988 return false; 1989 } 1990 1991 // If the fixed-position element does not have any scrollable ancestor between it and 1992 // its container, then we do not need to spend compositor resources for it. Start by 1993 // assuming we can opt-out (i.e. no scrollable ancestor), and refine the answer below. 1994 bool hasScrollableAncestor = false; 1995 1996 // The FrameView has the scrollbars associated with the top level viewport, so we have to 1997 // check the FrameView in addition to the hierarchy of ancestors. 1998 FrameView* frameView = m_renderView->frameView(); 1999 if (frameView && frameView->isScrollable()) 2000 hasScrollableAncestor = true; 2001 2002 RenderLayer* ancestor = layer->parent(); 2003 while (ancestor && !hasScrollableAncestor) { 2004 if (frameView->containsScrollableArea(ancestor)) 2005 hasScrollableAncestor = true; 2006 if (ancestor->renderer() == m_renderView) 2007 break; 2008 ancestor = ancestor->parent(); 2009 } 2010 2011 if (!hasScrollableAncestor) { 2012 if (viewportConstrainedNotCompositedReason) 2013 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForUnscrollableAncestors; 2014 return false; 2015 } 2016 2017 // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done. 2018 if (!m_inPostLayoutUpdate) { 2019 m_reevaluateCompositingAfterLayout = true; 2020 return layer->isComposited(); 2021 } 2022 2023 bool paintsContent = layer->isVisuallyNonEmpty() || layer->hasVisibleDescendant(); 2024 if (!paintsContent) { 2025 if (viewportConstrainedNotCompositedReason) 2026 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent; 2027 return false; 2028 } 2029 2030 // Fixed position elements that are invisible in the current view don't get their own layer. 2031 if (FrameView* frameView = m_renderView->frameView()) { 2032 LayoutRect viewBounds = frameView->viewportConstrainedVisibleContentRect(); 2033 LayoutRect layerBounds = layer->calculateLayerBounds(rootRenderLayer(), 0, RenderLayer::DefaultCalculateLayerBoundsFlags 2034 | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask | RenderLayer::IncludeCompositedDescendants); 2035 if (!viewBounds.intersects(enclosingIntRect(layerBounds))) { 2036 if (viewportConstrainedNotCompositedReason) 2037 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView; 2038 return false; 2039 } 2040 } 2041 2042 return true; 2043 } 2044 2045 bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer* layer) const 2046 { 2047 return layer->needsCompositedScrolling(); 2048 } 2049 2050 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const 2051 { 2052 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger)) 2053 return false; 2054 2055 if (AnimationController* animController = renderer->animation()) 2056 return animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform); 2057 2058 return false; 2059 } 2060 2061 // If an element has negative z-index children, those children render in front of the 2062 // layer background, so we need an extra 'contents' layer for the foreground of the layer 2063 // object. 2064 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const 2065 { 2066 return layer->hasNegativeZOrderList(); 2067 } 2068 2069 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip) 2070 { 2071 if (!scrollbar) 2072 return; 2073 2074 context.save(); 2075 const IntRect& scrollbarRect = scrollbar->frameRect(); 2076 context.translate(-scrollbarRect.x(), -scrollbarRect.y()); 2077 IntRect transformedClip = clip; 2078 transformedClip.moveBy(scrollbarRect.location()); 2079 scrollbar->paint(&context, transformedClip); 2080 context.restore(); 2081 } 2082 2083 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip) 2084 { 2085 if (graphicsLayer == layerForHorizontalScrollbar()) 2086 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip); 2087 else if (graphicsLayer == layerForVerticalScrollbar()) 2088 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip); 2089 else if (graphicsLayer == layerForScrollCorner()) { 2090 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect(); 2091 context.save(); 2092 context.translate(-scrollCorner.x(), -scrollCorner.y()); 2093 IntRect transformedClip = clip; 2094 transformedClip.moveBy(scrollCorner.location()); 2095 m_renderView->frameView()->paintScrollCorner(&context, transformedClip); 2096 context.restore(); 2097 #if ENABLE(RUBBER_BANDING) 2098 } else if (graphicsLayer == layerForOverhangAreas()) { 2099 ScrollView* view = m_renderView->frameView(); 2100 view->calculateAndPaintOverhangAreas(&context, clip); 2101 #endif 2102 } 2103 } 2104 2105 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const 2106 { 2107 if (Settings* settings = m_renderView->document()->settings()) { 2108 if (settings->acceleratedCompositingForFixedRootBackgroundEnabled()) 2109 return true; 2110 } 2111 return false; 2112 } 2113 2114 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const 2115 { 2116 if (layer != m_renderView->layer()) 2117 return false; 2118 2119 return supportsFixedRootBackgroundCompositing() && m_renderView->rootBackgroundIsEntirelyFixed(); 2120 } 2121 2122 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const 2123 { 2124 // Get the fixed root background from the RenderView layer's backing. 2125 RenderLayer* viewLayer = m_renderView->layer(); 2126 if (!viewLayer) 2127 return 0; 2128 2129 if (viewLayer->isComposited() && viewLayer->backing()->backgroundLayerPaintsFixedRootBackground()) 2130 return viewLayer->backing()->backgroundLayer(); 2131 2132 return 0; 2133 } 2134 2135 static void resetTrackedRepaintRectsRecursive(GraphicsLayer* graphicsLayer) 2136 { 2137 if (!graphicsLayer) 2138 return; 2139 2140 graphicsLayer->resetTrackedRepaints(); 2141 2142 for (size_t i = 0; i < graphicsLayer->children().size(); ++i) 2143 resetTrackedRepaintRectsRecursive(graphicsLayer->children()[i]); 2144 2145 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer()) 2146 resetTrackedRepaintRectsRecursive(replicaLayer); 2147 2148 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer()) 2149 resetTrackedRepaintRectsRecursive(maskLayer); 2150 } 2151 2152 void RenderLayerCompositor::resetTrackedRepaintRects() 2153 { 2154 if (GraphicsLayer* rootLayer = rootGraphicsLayer()) 2155 resetTrackedRepaintRectsRecursive(rootLayer); 2156 } 2157 2158 void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints) 2159 { 2160 m_isTrackingRepaints = tracksRepaints; 2161 } 2162 2163 bool RenderLayerCompositor::isTrackingRepaints() const 2164 { 2165 return m_isTrackingRepaints; 2166 } 2167 2168 void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const 2169 { 2170 // Nothing to do here yet. 2171 } 2172 2173 static bool shouldCompositeOverflowControls(FrameView* view) 2174 { 2175 if (Page* page = view->frame()->page()) { 2176 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) 2177 if (scrollingCoordinator->coordinatesScrollingForFrameView(view)) 2178 return true; 2179 } 2180 2181 return true; 2182 } 2183 2184 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const 2185 { 2186 FrameView* view = m_renderView->frameView(); 2187 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar(); 2188 } 2189 2190 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const 2191 { 2192 FrameView* view = m_renderView->frameView(); 2193 return shouldCompositeOverflowControls(view) && view->verticalScrollbar(); 2194 } 2195 2196 bool RenderLayerCompositor::requiresScrollCornerLayer() const 2197 { 2198 FrameView* view = m_renderView->frameView(); 2199 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible(); 2200 } 2201 2202 #if ENABLE(RUBBER_BANDING) 2203 bool RenderLayerCompositor::requiresOverhangAreasLayer() const 2204 { 2205 // We don't want a layer if this is a subframe. 2206 if (!isMainFrame()) 2207 return false; 2208 2209 // We do want a layer if we have a scrolling coordinator and can scroll. 2210 if (scrollingCoordinator() && m_renderView->frameView()->hasOpaqueBackground()) 2211 return true; 2212 2213 // Chromium always wants a layer. 2214 return true; 2215 } 2216 #endif 2217 2218 void RenderLayerCompositor::updateOverflowControlsLayers() 2219 { 2220 #if ENABLE(RUBBER_BANDING) 2221 if (requiresOverhangAreasLayer()) { 2222 if (!m_layerForOverhangAreas) { 2223 m_layerForOverhangAreas = GraphicsLayer::create(graphicsLayerFactory(), this); 2224 #ifndef NDEBUG 2225 m_layerForOverhangAreas->setName("overhang areas"); 2226 #endif 2227 m_layerForOverhangAreas->setDrawsContent(false); 2228 m_layerForOverhangAreas->setSize(m_renderView->frameView()->frameRect().size()); 2229 2230 // We want the overhang areas layer to be positioned below the frame contents, 2231 // so insert it below the clip layer. 2232 m_overflowControlsHostLayer->addChildBelow(m_layerForOverhangAreas.get(), m_containerLayer.get()); 2233 } 2234 } else if (m_layerForOverhangAreas) { 2235 m_layerForOverhangAreas->removeFromParent(); 2236 m_layerForOverhangAreas = nullptr; 2237 } 2238 #endif 2239 2240 if (requiresHorizontalScrollbarLayer()) { 2241 if (!m_layerForHorizontalScrollbar) { 2242 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this); 2243 #ifndef NDEBUG 2244 m_layerForHorizontalScrollbar->setName("horizontal scrollbar"); 2245 #endif 2246 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get()); 2247 2248 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2249 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar); 2250 } 2251 } else if (m_layerForHorizontalScrollbar) { 2252 m_layerForHorizontalScrollbar->removeFromParent(); 2253 m_layerForHorizontalScrollbar = nullptr; 2254 2255 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2256 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar); 2257 } 2258 2259 if (requiresVerticalScrollbarLayer()) { 2260 if (!m_layerForVerticalScrollbar) { 2261 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this); 2262 #ifndef NDEBUG 2263 m_layerForVerticalScrollbar->setName("vertical scrollbar"); 2264 #endif 2265 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get()); 2266 2267 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2268 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar); 2269 } 2270 } else if (m_layerForVerticalScrollbar) { 2271 m_layerForVerticalScrollbar->removeFromParent(); 2272 m_layerForVerticalScrollbar = nullptr; 2273 2274 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2275 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar); 2276 } 2277 2278 if (requiresScrollCornerLayer()) { 2279 if (!m_layerForScrollCorner) { 2280 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this); 2281 #ifndef NDEBUG 2282 m_layerForScrollCorner->setName("scroll corner"); 2283 #endif 2284 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get()); 2285 } 2286 } else if (m_layerForScrollCorner) { 2287 m_layerForScrollCorner->removeFromParent(); 2288 m_layerForScrollCorner = nullptr; 2289 } 2290 2291 m_renderView->frameView()->positionScrollbarLayers(); 2292 } 2293 2294 void RenderLayerCompositor::ensureRootLayer() 2295 { 2296 RootLayerAttachment expectedAttachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; 2297 if (expectedAttachment == m_rootLayerAttachment) 2298 return; 2299 2300 if (!m_rootContentLayer) { 2301 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 2302 #ifndef NDEBUG 2303 m_rootContentLayer->setName("content root"); 2304 #endif 2305 IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect(); 2306 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY())); 2307 m_rootContentLayer->setPosition(FloatPoint()); 2308 2309 // Need to clip to prevent transformed content showing outside this frame 2310 m_rootContentLayer->setMasksToBounds(true); 2311 } 2312 2313 if (!m_overflowControlsHostLayer) { 2314 ASSERT(!m_scrollLayer); 2315 ASSERT(!m_containerLayer); 2316 2317 // Create a layer to host the clipping layer and the overflow controls layers. 2318 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 2319 #ifndef NDEBUG 2320 m_overflowControlsHostLayer->setName("overflow controls host"); 2321 #endif 2322 2323 // Create a clipping layer if this is an iframe 2324 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 2325 #ifndef NDEBUG 2326 m_containerLayer->setName("frame clipping"); 2327 #endif 2328 if (!isMainFrame()) 2329 m_containerLayer->setMasksToBounds(true); 2330 2331 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 2332 #ifndef NDEBUG 2333 m_scrollLayer->setName("frame scrolling"); 2334 #endif 2335 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2336 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true); 2337 2338 // Hook them up 2339 m_overflowControlsHostLayer->addChild(m_containerLayer.get()); 2340 m_containerLayer->addChild(m_scrollLayer.get()); 2341 m_scrollLayer->addChild(m_rootContentLayer.get()); 2342 2343 frameViewDidChangeSize(); 2344 frameViewDidScroll(); 2345 } 2346 2347 // Check to see if we have to change the attachment 2348 if (m_rootLayerAttachment != RootLayerUnattached) 2349 detachRootLayer(); 2350 2351 attachRootLayer(expectedAttachment); 2352 } 2353 2354 void RenderLayerCompositor::destroyRootLayer() 2355 { 2356 if (!m_rootContentLayer) 2357 return; 2358 2359 detachRootLayer(); 2360 2361 #if ENABLE(RUBBER_BANDING) 2362 if (m_layerForOverhangAreas) { 2363 m_layerForOverhangAreas->removeFromParent(); 2364 m_layerForOverhangAreas = nullptr; 2365 } 2366 #endif 2367 2368 if (m_layerForHorizontalScrollbar) { 2369 m_layerForHorizontalScrollbar->removeFromParent(); 2370 m_layerForHorizontalScrollbar = nullptr; 2371 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2372 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar); 2373 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar()) 2374 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size())); 2375 } 2376 2377 if (m_layerForVerticalScrollbar) { 2378 m_layerForVerticalScrollbar->removeFromParent(); 2379 m_layerForVerticalScrollbar = nullptr; 2380 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2381 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar); 2382 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar()) 2383 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size())); 2384 } 2385 2386 if (m_layerForScrollCorner) { 2387 m_layerForScrollCorner = nullptr; 2388 m_renderView->frameView()->invalidateScrollCorner(m_renderView->frameView()->scrollCornerRect()); 2389 } 2390 2391 if (m_overflowControlsHostLayer) { 2392 m_overflowControlsHostLayer = nullptr; 2393 m_containerLayer = nullptr; 2394 m_scrollLayer = nullptr; 2395 } 2396 ASSERT(!m_scrollLayer); 2397 m_rootContentLayer = nullptr; 2398 } 2399 2400 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment) 2401 { 2402 if (!m_rootContentLayer) 2403 return; 2404 2405 switch (attachment) { 2406 case RootLayerUnattached: 2407 ASSERT_NOT_REACHED(); 2408 break; 2409 case RootLayerAttachedViaChromeClient: { 2410 Frame* frame = m_renderView->frameView()->frame(); 2411 Page* page = frame ? frame->page() : 0; 2412 if (!page) 2413 return; 2414 2415 page->chrome().client()->attachRootGraphicsLayer(frame, rootGraphicsLayer()); 2416 break; 2417 } 2418 case RootLayerAttachedViaEnclosingFrame: { 2419 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration() 2420 // for the frame's renderer in the parent document. 2421 m_renderView->document()->ownerElement()->scheduleLayerUpdate(); 2422 break; 2423 } 2424 } 2425 2426 m_rootLayerAttachment = attachment; 2427 } 2428 2429 void RenderLayerCompositor::detachRootLayer() 2430 { 2431 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached) 2432 return; 2433 2434 switch (m_rootLayerAttachment) { 2435 case RootLayerAttachedViaEnclosingFrame: { 2436 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration() 2437 // for the frame's renderer in the parent document. 2438 if (m_overflowControlsHostLayer) 2439 m_overflowControlsHostLayer->removeFromParent(); 2440 else 2441 m_rootContentLayer->removeFromParent(); 2442 2443 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 2444 ownerElement->scheduleLayerUpdate(); 2445 break; 2446 } 2447 case RootLayerAttachedViaChromeClient: { 2448 Frame* frame = m_renderView->frameView()->frame(); 2449 Page* page = frame ? frame->page() : 0; 2450 if (!page) 2451 return; 2452 2453 page->chrome().client()->attachRootGraphicsLayer(frame, 0); 2454 } 2455 break; 2456 case RootLayerUnattached: 2457 break; 2458 } 2459 2460 m_rootLayerAttachment = RootLayerUnattached; 2461 } 2462 2463 void RenderLayerCompositor::updateRootLayerAttachment() 2464 { 2465 ensureRootLayer(); 2466 } 2467 2468 bool RenderLayerCompositor::isMainFrame() const 2469 { 2470 return !m_renderView->document()->ownerElement(); 2471 } 2472 2473 // IFrames are special, because we hook compositing layers together across iframe boundaries 2474 // when both parent and iframe content are composited. So when this frame becomes composited, we have 2475 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite. 2476 void RenderLayerCompositor::notifyIFramesOfCompositingChange() 2477 { 2478 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0; 2479 if (!frame) 2480 return; 2481 2482 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) { 2483 if (child->document() && child->document()->ownerElement()) 2484 child->document()->ownerElement()->scheduleLayerUpdate(); 2485 } 2486 2487 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so 2488 // we need to schedule a style recalc in our parent document. 2489 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 2490 ownerElement->scheduleLayerUpdate(); 2491 } 2492 2493 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const 2494 { 2495 const RenderStyle* style = layer->renderer()->style(); 2496 2497 if (style && 2498 (style->transformStyle3D() == TransformStyle3DPreserve3D || 2499 style->hasPerspective() || 2500 style->transform().has3DOperation())) 2501 return true; 2502 2503 const_cast<RenderLayer*>(layer)->updateLayerListsIfNeeded(); 2504 2505 #if !ASSERT_DISABLED 2506 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(layer)); 2507 #endif 2508 2509 if (layer->isStackingContainer()) { 2510 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 2511 size_t listSize = negZOrderList->size(); 2512 for (size_t i = 0; i < listSize; ++i) { 2513 RenderLayer* curLayer = negZOrderList->at(i); 2514 if (layerHas3DContent(curLayer)) 2515 return true; 2516 } 2517 } 2518 2519 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 2520 size_t listSize = posZOrderList->size(); 2521 for (size_t i = 0; i < listSize; ++i) { 2522 RenderLayer* curLayer = posZOrderList->at(i); 2523 if (layerHas3DContent(curLayer)) 2524 return true; 2525 } 2526 } 2527 } 2528 2529 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 2530 size_t listSize = normalFlowList->size(); 2531 for (size_t i = 0; i < listSize; ++i) { 2532 RenderLayer* curLayer = normalFlowList->at(i); 2533 if (layerHas3DContent(curLayer)) 2534 return true; 2535 } 2536 } 2537 return false; 2538 } 2539 2540 static bool isRootmostFixedOrStickyLayer(RenderLayer* layer) 2541 { 2542 if (layer->renderer()->isStickyPositioned()) 2543 return true; 2544 2545 if (layer->renderer()->style()->position() != FixedPosition) 2546 return false; 2547 2548 for (RenderLayer* stackingContainer = layer->ancestorStackingContainer(); stackingContainer; stackingContainer = stackingContainer->ancestorStackingContainer()) { 2549 if (stackingContainer->isComposited() && stackingContainer->renderer()->style()->position() == FixedPosition) 2550 return false; 2551 } 2552 2553 return true; 2554 } 2555 2556 void RenderLayerCompositor::updateViewportConstraintStatus(RenderLayer* layer) 2557 { 2558 if (isRootmostFixedOrStickyLayer(layer)) 2559 addViewportConstrainedLayer(layer); 2560 else 2561 removeViewportConstrainedLayer(layer); 2562 } 2563 2564 void RenderLayerCompositor::addViewportConstrainedLayer(RenderLayer* layer) 2565 { 2566 m_viewportConstrainedLayers.add(layer); 2567 } 2568 2569 void RenderLayerCompositor::removeViewportConstrainedLayer(RenderLayer* layer) 2570 { 2571 if (!m_viewportConstrainedLayers.contains(layer)) 2572 return; 2573 2574 m_viewportConstrainedLayers.remove(layer); 2575 } 2576 2577 FixedPositionViewportConstraints RenderLayerCompositor::computeFixedViewportConstraints(RenderLayer* layer) const 2578 { 2579 ASSERT(layer->isComposited()); 2580 2581 FrameView* frameView = m_renderView->frameView(); 2582 LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect(); 2583 2584 FixedPositionViewportConstraints constraints; 2585 2586 GraphicsLayer* graphicsLayer = layer->backing()->graphicsLayer(); 2587 2588 constraints.setLayerPositionAtLastLayout(graphicsLayer->position()); 2589 constraints.setViewportRectAtLastLayout(viewportRect); 2590 2591 RenderStyle* style = layer->renderer()->style(); 2592 if (!style->left().isAuto()) 2593 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft); 2594 2595 if (!style->right().isAuto()) 2596 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight); 2597 2598 if (!style->top().isAuto()) 2599 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop); 2600 2601 if (!style->bottom().isAuto()) 2602 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom); 2603 2604 // If left and right are auto, use left. 2605 if (style->left().isAuto() && style->right().isAuto()) 2606 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft); 2607 2608 // If top and bottom are auto, use top. 2609 if (style->top().isAuto() && style->bottom().isAuto()) 2610 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop); 2611 2612 return constraints; 2613 } 2614 2615 StickyPositionViewportConstraints RenderLayerCompositor::computeStickyViewportConstraints(RenderLayer* layer) const 2616 { 2617 ASSERT(layer->isComposited()); 2618 2619 FrameView* frameView = m_renderView->frameView(); 2620 LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect(); 2621 2622 StickyPositionViewportConstraints constraints; 2623 2624 RenderBoxModelObject* renderer = toRenderBoxModelObject(layer->renderer()); 2625 2626 renderer->computeStickyPositionConstraints(constraints, viewportRect); 2627 2628 GraphicsLayer* graphicsLayer = layer->backing()->graphicsLayer(); 2629 2630 constraints.setLayerPositionAtLastLayout(graphicsLayer->position()); 2631 constraints.setStickyOffsetAtLastLayout(renderer->stickyPositionOffset()); 2632 2633 return constraints; 2634 } 2635 2636 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const 2637 { 2638 if (Page* page = this->page()) 2639 return page->scrollingCoordinator(); 2640 2641 return 0; 2642 } 2643 2644 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const 2645 { 2646 if (Page* page = this->page()) 2647 return page->chrome().client()->graphicsLayerFactory(); 2648 2649 return 0; 2650 } 2651 2652 Page* RenderLayerCompositor::page() const 2653 { 2654 if (Frame* frame = m_renderView->frameView()->frame()) 2655 return frame->page(); 2656 2657 return 0; 2658 } 2659 2660 } // namespace WebCore 2661