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 #if USE(ACCELERATED_COMPOSITING) 29 #include "RenderLayerCompositor.h" 30 31 #include "AnimationController.h" 32 #include "CanvasRenderingContext.h" 33 #include "CSSPropertyNames.h" 34 #include "Chrome.h" 35 #include "ChromeClient.h" 36 #include "Frame.h" 37 #include "FrameView.h" 38 #include "GraphicsLayer.h" 39 #include "HTMLCanvasElement.h" 40 #include "HTMLIFrameElement.h" 41 #include "HTMLNames.h" 42 #include "HitTestResult.h" 43 #include "NodeList.h" 44 #include "Page.h" 45 #include "RenderApplet.h" 46 #include "RenderEmbeddedObject.h" 47 #include "RenderFullScreen.h" 48 #include "RenderIFrame.h" 49 #include "RenderLayerBacking.h" 50 #include "RenderReplica.h" 51 #include "RenderVideo.h" 52 #include "RenderView.h" 53 #include "Settings.h" 54 55 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 56 #include "HTMLMediaElement.h" 57 #endif 58 59 #if PROFILE_LAYER_REBUILD 60 #include <wtf/CurrentTime.h> 61 #endif 62 63 #ifndef NDEBUG 64 #include "RenderTreeAsText.h" 65 #endif 66 67 #if ENABLE(3D_RENDERING) 68 // This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm'). 69 bool WebCoreHas3DRendering = true; 70 #endif 71 72 namespace WebCore { 73 74 using namespace HTMLNames; 75 76 struct CompositingState { 77 CompositingState(RenderLayer* compAncestor) 78 : m_compositingAncestor(compAncestor) 79 , m_subtreeIsCompositing(false) 80 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 81 , m_fixedSibling(false) 82 , m_hasFixedElement(false) 83 #endif 84 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 85 , m_hasScrollableElement(false) 86 #endif 87 #ifndef NDEBUG 88 , m_depth(0) 89 #endif 90 { 91 } 92 93 RenderLayer* m_compositingAncestor; 94 bool m_subtreeIsCompositing; 95 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 96 bool m_fixedSibling; 97 bool m_hasFixedElement; 98 #endif 99 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 100 bool m_hasScrollableElement; 101 #endif 102 #ifndef NDEBUG 103 int m_depth; 104 #endif 105 }; 106 107 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView) 108 : m_renderView(renderView) 109 , m_rootPlatformLayer(0) 110 , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired) 111 , m_hasAcceleratedCompositing(true) 112 , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers)) 113 , m_showDebugBorders(false) 114 , m_showRepaintCounter(false) 115 , m_compositingConsultsOverlap(true) 116 , m_compositingDependsOnGeometry(false) 117 , m_compositing(false) 118 , m_compositingLayersNeedRebuild(false) 119 , m_flushingLayers(false) 120 , m_forceCompositingMode(false) 121 , m_rootLayerAttachment(RootLayerUnattached) 122 #if PROFILE_LAYER_REBUILD 123 , m_rootLayerUpdateCount(0) 124 #endif // PROFILE_LAYER_REBUILD 125 { 126 Settings* settings = m_renderView->document()->settings(); 127 128 // Even when forcing compositing mode, ignore child frames, or this will trigger 129 // layer creation from the enclosing RenderIFrame. 130 ASSERT(m_renderView->document()->frame()); 131 if (settings && settings->forceCompositingMode() && settings->acceleratedCompositingEnabled() 132 && !m_renderView->document()->frame()->tree()->parent()) { 133 m_forceCompositingMode = true; 134 enableCompositingMode(); 135 } 136 } 137 138 RenderLayerCompositor::~RenderLayerCompositor() 139 { 140 ASSERT(m_rootLayerAttachment == RootLayerUnattached); 141 } 142 143 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */) 144 { 145 if (enable != m_compositing) { 146 m_compositing = enable; 147 148 if (m_compositing) { 149 ensureRootPlatformLayer(); 150 notifyIFramesOfCompositingChange(); 151 } else 152 destroyRootPlatformLayer(); 153 } 154 } 155 156 void RenderLayerCompositor::cacheAcceleratedCompositingFlags() 157 { 158 bool hasAcceleratedCompositing = false; 159 bool showDebugBorders = false; 160 bool showRepaintCounter = false; 161 162 if (Settings* settings = m_renderView->document()->settings()) { 163 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled(); 164 showDebugBorders = settings->showDebugBorders(); 165 showRepaintCounter = settings->showRepaintCounter(); 166 } 167 168 // We allow the chrome to override the settings, in case the page is rendered 169 // on a chrome that doesn't allow accelerated compositing. 170 if (hasAcceleratedCompositing) { 171 Frame* frame = m_renderView->frameView()->frame(); 172 Page* page = frame ? frame->page() : 0; 173 if (page) { 174 ChromeClient* chromeClient = page->chrome()->client(); 175 m_compositingTriggers = chromeClient->allowedCompositingTriggers(); 176 hasAcceleratedCompositing = m_compositingTriggers; 177 } 178 } 179 180 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter) 181 setCompositingLayersNeedRebuild(); 182 183 m_hasAcceleratedCompositing = hasAcceleratedCompositing; 184 m_showDebugBorders = showDebugBorders; 185 m_showRepaintCounter = showRepaintCounter; 186 } 187 188 bool RenderLayerCompositor::canRender3DTransforms() const 189 { 190 return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger); 191 } 192 193 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild) 194 { 195 if (inCompositingMode()) 196 m_compositingLayersNeedRebuild = needRebuild; 197 } 198 199 void RenderLayerCompositor::scheduleLayerFlush() 200 { 201 Frame* frame = m_renderView->frameView()->frame(); 202 Page* page = frame ? frame->page() : 0; 203 if (!page) 204 return; 205 206 page->chrome()->client()->scheduleCompositingLayerSync(); 207 } 208 209 void RenderLayerCompositor::flushPendingLayerChanges() 210 { 211 ASSERT(!m_flushingLayers); 212 m_flushingLayers = true; 213 214 // FIXME: FrameView::syncCompositingStateRecursive() calls this for each 215 // frame, so when compositing layers are connected between frames, we'll 216 // end up syncing subframe's layers multiple times. 217 // https://bugs.webkit.org/show_bug.cgi?id=52489 218 if (GraphicsLayer* rootLayer = rootPlatformLayer()) 219 rootLayer->syncCompositingState(); 220 221 ASSERT(m_flushingLayers); 222 m_flushingLayers = false; 223 } 224 225 RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const 226 { 227 if (!m_renderView->frameView()) 228 return 0; 229 230 for (Frame* frame = m_renderView->frameView()->frame(); frame; frame = frame->tree()->parent()) { 231 RenderLayerCompositor* compositor = frame->contentRenderer() ? frame->contentRenderer()->compositor() : 0; 232 if (compositor->isFlushingLayers()) 233 return compositor; 234 } 235 236 return 0; 237 } 238 239 void RenderLayerCompositor::scheduleCompositingLayerUpdate() 240 { 241 if (!m_updateCompositingLayersTimer.isActive()) 242 m_updateCompositingLayersTimer.startOneShot(0); 243 } 244 245 bool RenderLayerCompositor::compositingLayerUpdatePending() const 246 { 247 return m_updateCompositingLayersTimer.isActive(); 248 } 249 250 void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*) 251 { 252 updateCompositingLayers(); 253 } 254 255 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot) 256 { 257 m_updateCompositingLayersTimer.stop(); 258 259 if (!m_compositingDependsOnGeometry && !m_compositing) 260 return; 261 262 bool checkForHierarchyUpdate = m_compositingDependsOnGeometry; 263 bool needGeometryUpdate = false; 264 265 switch (updateType) { 266 case CompositingUpdateAfterLayoutOrStyleChange: 267 case CompositingUpdateOnPaitingOrHitTest: 268 checkForHierarchyUpdate = true; 269 break; 270 case CompositingUpdateOnScroll: 271 if (m_compositingConsultsOverlap) 272 checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates. 273 274 needGeometryUpdate = true; 275 break; 276 } 277 278 if (!checkForHierarchyUpdate && !needGeometryUpdate) 279 return; 280 281 bool needHierarchyUpdate = m_compositingLayersNeedRebuild; 282 if (!updateRoot || m_compositingConsultsOverlap) { 283 // Only clear the flag if we're updating the entire hierarchy. 284 m_compositingLayersNeedRebuild = false; 285 updateRoot = rootRenderLayer(); 286 } 287 288 #if PROFILE_LAYER_REBUILD 289 ++m_rootLayerUpdateCount; 290 291 double startTime = WTF::currentTime(); 292 #endif 293 294 if (checkForHierarchyUpdate) { 295 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers. 296 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex. 297 CompositingState compState(updateRoot); 298 bool layersChanged = false; 299 300 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 301 compState.m_hasFixedElement = false; 302 #endif 303 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 304 compState.m_hasScrollableElement = false; 305 #endif 306 if (m_compositingConsultsOverlap) { 307 OverlapMap overlapTestRequestMap; 308 computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged); 309 } else 310 computeCompositingRequirements(updateRoot, 0, compState, layersChanged); 311 312 needHierarchyUpdate |= layersChanged; 313 } 314 315 if (needHierarchyUpdate) { 316 // Update the hierarchy of the compositing layers. 317 CompositingState compState(updateRoot); 318 Vector<GraphicsLayer*> childList; 319 rebuildCompositingLayerTree(updateRoot, compState, childList); 320 321 // Host the document layer in the RenderView's root layer. 322 if (updateRoot == rootRenderLayer()) { 323 if (childList.isEmpty()) 324 destroyRootPlatformLayer(); 325 else 326 m_rootPlatformLayer->setChildren(childList); 327 } 328 } else if (needGeometryUpdate) { 329 // We just need to do a geometry update. This is only used for position:fixed scrolling; 330 // most of the time, geometry is updated via RenderLayer::styleChanged(). 331 updateLayerTreeGeometry(updateRoot); 332 } 333 334 #if PROFILE_LAYER_REBUILD 335 double endTime = WTF::currentTime(); 336 if (updateRoot == rootRenderLayer()) 337 fprintf(stderr, "Update %d: computeCompositingRequirements for the world took %fms\n", 338 m_rootLayerUpdateCount, 1000.0 * (endTime - startTime)); 339 #endif 340 ASSERT(updateRoot || !m_compositingLayersNeedRebuild); 341 342 if (!hasAcceleratedCompositing()) 343 enableCompositingMode(false); 344 } 345 346 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) 347 { 348 bool layerChanged = false; 349 350 if (needsToBeComposited(layer)) { 351 enableCompositingMode(); 352 353 // 3D transforms turn off the testing of overlap. 354 if (requiresCompositingForTransform(layer->renderer())) 355 setCompositingConsultsOverlap(false); 356 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 357 // If we are a child of a scrollable layer, ignore the overlap from the 358 // scrollable layer as it can cause child layers to become composited 359 // siblings and will not scroll with the main content layer. 360 if (layer->hasOverflowParent()) 361 setCompositingConsultsOverlap(false); 362 #endif 363 364 if (!layer->backing()) { 365 366 // If we need to repaint, do so before making backing 367 if (shouldRepaint == CompositingChangeRepaintNow) 368 repaintOnCompositingChange(layer); 369 370 layer->ensureBacking(); 371 372 #if PLATFORM(MAC) && USE(CA) 373 if (m_renderView->document()->settings()->acceleratedDrawingEnabled()) 374 layer->backing()->graphicsLayer()->setAcceleratesDrawing(true); 375 else if (layer->renderer()->isCanvas()) { 376 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(layer->renderer()->node()); 377 if (canvas->renderingContext() && canvas->renderingContext()->isAccelerated()) 378 layer->backing()->graphicsLayer()->setAcceleratesDrawing(true); 379 } 380 #endif 381 layerChanged = true; 382 } 383 } else { 384 if (layer->backing()) { 385 // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to 386 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection 387 // are both either composited, or not composited. 388 if (layer->isReflection()) { 389 RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer(); 390 if (RenderLayerBacking* backing = sourceLayer->backing()) { 391 ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer()); 392 backing->graphicsLayer()->setReplicatedByLayer(0); 393 } 394 } 395 396 layer->clearBacking(); 397 layerChanged = true; 398 399 // The layer's cached repaints rects are relative to the repaint container, so change when 400 // compositing changes; we need to update them here. 401 layer->computeRepaintRects(); 402 403 // If we need to repaint, do so now that we've removed the backing 404 if (shouldRepaint == CompositingChangeRepaintNow) 405 repaintOnCompositingChange(layer); 406 } 407 } 408 409 #if ENABLE(VIDEO) 410 if (layerChanged && layer->renderer()->isVideo()) { 411 // If it's a video, give the media player a chance to hook up to the layer. 412 RenderVideo* video = toRenderVideo(layer->renderer()); 413 video->acceleratedRenderingStateChanged(); 414 } 415 #endif 416 417 if (layerChanged && layer->renderer()->isRenderPart()) { 418 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer())); 419 if (innerCompositor && innerCompositor->inCompositingMode()) 420 innerCompositor->updateRootLayerAttachment(); 421 } 422 423 return layerChanged; 424 } 425 426 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) 427 { 428 bool layerChanged = updateBacking(layer, shouldRepaint); 429 430 // See if we need content or clipping layers. Methods called here should assume 431 // that the compositing state of descendant layers has not been updated yet. 432 if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration()) 433 layerChanged = true; 434 435 return layerChanged; 436 } 437 438 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer) 439 { 440 // If the renderer is not attached yet, no need to repaint. 441 if (layer->renderer() != m_renderView && !layer->renderer()->parent()) 442 return; 443 444 RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint(); 445 if (!repaintContainer) 446 repaintContainer = m_renderView; 447 448 layer->repaintIncludingNonCompositingDescendants(repaintContainer); 449 if (repaintContainer == m_renderView) { 450 // The contents of this layer may be moving between the window 451 // and a GraphicsLayer, so we need to make sure the window system 452 // synchronizes those changes on the screen. 453 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization(); 454 } 455 } 456 457 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant 458 // RenderLayers that are rendered by the composited RenderLayer. 459 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) 460 { 461 if (!canBeComposited(layer)) 462 return IntRect(); 463 464 IntRect boundingBoxRect = layer->localBoundingBox(); 465 if (layer->renderer()->isRoot()) { 466 // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited), 467 // then it has to be big enough to cover the viewport in order to display the background. This is akin 468 // to the code in RenderBox::paintRootBoxFillLayers(). 469 if (m_renderView->frameView()) { 470 int rw = m_renderView->frameView()->contentsWidth(); 471 int rh = m_renderView->frameView()->contentsHeight(); 472 473 boundingBoxRect.setWidth(max(boundingBoxRect.width(), rw - boundingBoxRect.x())); 474 boundingBoxRect.setHeight(max(boundingBoxRect.height(), rh - boundingBoxRect.y())); 475 } 476 } 477 478 IntRect unionBounds = boundingBoxRect; 479 480 if (layer->renderer()->hasOverflowClip() || layer->renderer()->hasMask()) { 481 int ancestorRelX = 0, ancestorRelY = 0; 482 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY); 483 boundingBoxRect.move(ancestorRelX, ancestorRelY); 484 return boundingBoxRect; 485 } 486 487 if (RenderLayer* reflection = layer->reflectionLayer()) { 488 if (!reflection->isComposited()) { 489 IntRect childUnionBounds = calculateCompositedBounds(reflection, layer); 490 unionBounds.unite(childUnionBounds); 491 } 492 } 493 494 ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0)); 495 496 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 497 size_t listSize = negZOrderList->size(); 498 for (size_t i = 0; i < listSize; ++i) { 499 RenderLayer* curLayer = negZOrderList->at(i); 500 if (!curLayer->isComposited()) { 501 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer); 502 unionBounds.unite(childUnionBounds); 503 } 504 } 505 } 506 507 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 508 size_t listSize = posZOrderList->size(); 509 for (size_t i = 0; i < listSize; ++i) { 510 RenderLayer* curLayer = posZOrderList->at(i); 511 if (!curLayer->isComposited()) { 512 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer); 513 unionBounds.unite(childUnionBounds); 514 } 515 } 516 } 517 518 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 519 size_t listSize = normalFlowList->size(); 520 for (size_t i = 0; i < listSize; ++i) { 521 RenderLayer* curLayer = normalFlowList->at(i); 522 if (!curLayer->isComposited()) { 523 IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer); 524 unionBounds.unite(curAbsBounds); 525 } 526 } 527 } 528 529 if (layer->paintsWithTransform(PaintBehaviorNormal)) { 530 TransformationMatrix* affineTrans = layer->transform(); 531 boundingBoxRect = affineTrans->mapRect(boundingBoxRect); 532 unionBounds = affineTrans->mapRect(unionBounds); 533 } 534 535 int ancestorRelX = 0, ancestorRelY = 0; 536 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY); 537 unionBounds.move(ancestorRelX, ancestorRelY); 538 539 return unionBounds; 540 } 541 542 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/) 543 { 544 setCompositingLayersNeedRebuild(); 545 } 546 547 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child) 548 { 549 if (!child->isComposited() || parent->renderer()->documentBeingDestroyed()) 550 return; 551 552 setCompositingParent(child, 0); 553 554 RenderLayer* compLayer = parent->enclosingCompositingLayer(); 555 if (compLayer) { 556 ASSERT(compLayer->backing()); 557 IntRect compBounds = child->backing()->compositedBounds(); 558 559 int offsetX = 0, offsetY = 0; 560 child->convertToLayerCoords(compLayer, offsetX, offsetY); 561 compBounds.move(offsetX, offsetY); 562 563 compLayer->setBackingNeedsRepaintInRect(compBounds); 564 565 // The contents of this layer may be moving from a GraphicsLayer to the window, 566 // so we need to make sure the window system synchronizes those changes on the screen. 567 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization(); 568 } 569 570 setCompositingLayersNeedRebuild(); 571 } 572 573 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const 574 { 575 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) { 576 if (curr->isStackingContext()) 577 return 0; 578 579 if (curr->renderer()->hasOverflowClip() || curr->renderer()->hasClip()) 580 return curr; 581 } 582 return 0; 583 } 584 585 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed) 586 { 587 if (layer->isRootLayer()) 588 return; 589 590 if (!boundsComputed) { 591 layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox(); 592 // Empty rects never intersect, but we need them to for the purposes of overlap testing. 593 if (layerBounds.isEmpty()) 594 layerBounds.setSize(IntSize(1, 1)); 595 boundsComputed = true; 596 } 597 598 overlapMap.add(layer, layerBounds); 599 } 600 601 bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds) 602 { 603 RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end(); 604 for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) { 605 const IntRect& bounds = it->second; 606 if (layerBounds.intersects(bounds)) { 607 return true; 608 } 609 } 610 611 return false; 612 } 613 614 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 615 616 // to properly support z-index with composited fixed elements, we need to turn 617 // layers following a fixed layer into compositing mode; but if a layer is fully 618 // contained into a previous layer already composited (that is not the fixed 619 // layer), we don't need to composite it. This saves up quite a bit on the 620 // number of layers we have to composite. 621 // 622 bool RenderLayerCompositor::checkForFixedLayers(Vector<RenderLayer*>* list, bool stopAtFixedLayer) 623 { 624 int listSize = list->size(); 625 int haveFixedLayer = -1; 626 bool fixedSibling = false; 627 for (int j = 0; j < listSize; ++j) { 628 RenderLayer* currentLayer = list->at(j); 629 if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) { 630 haveFixedLayer = j; 631 fixedSibling = true; 632 } 633 IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad( 634 FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox(); 635 if ((currentLayerBounds.width() <= 1 636 || currentLayerBounds.height() <= 1) 637 && haveFixedLayer == j) { 638 haveFixedLayer = -1; 639 fixedSibling = false; 640 } 641 if (haveFixedLayer != -1 && haveFixedLayer != j) { 642 bool needComposite = true; 643 int stop = 0; 644 if (stopAtFixedLayer) 645 stop = haveFixedLayer + 1; 646 647 for (int k = j - 1; k >= stop; --k) { 648 RenderLayer* aLayer = list->at(k); 649 if (aLayer && aLayer->renderer()) { 650 IntRect bounds = aLayer->renderer()->localToAbsoluteQuad( 651 FloatRect(aLayer->localBoundingBox())).enclosingBoundingBox(); 652 if (bounds.contains(currentLayerBounds) 653 && needsToBeComposited(aLayer) && aLayer->isStackingContext()) { 654 needComposite = false; 655 break; 656 } 657 } 658 } 659 currentLayer->setShouldComposite(needComposite); 660 } 661 } 662 return fixedSibling; 663 } 664 665 #endif 666 667 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order) 668 // For the z-order children of a compositing layer: 669 // If a child layers has a compositing layer, then all subsequent layers must 670 // be compositing in order to render above that layer. 671 // 672 // If a child in the negative z-order list is compositing, then the layer itself 673 // must be compositing so that its contents render over that child. 674 // This implies that its positive z-index children must also be compositing. 675 // 676 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, OverlapMap* overlapMap, struct CompositingState& compositingState, bool& layersChanged) 677 { 678 layer->updateLayerPosition(); 679 layer->updateZOrderLists(); 680 layer->updateNormalFlowList(); 681 682 // Clear the flag 683 layer->setHasCompositingDescendant(false); 684 685 bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing; 686 687 bool haveComputedBounds = false; 688 IntRect absBounds; 689 if (overlapMap && !overlapMap->isEmpty()) { 690 // If we're testing for overlap, we only need to composite if we overlap something that is already composited. 691 absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox(); 692 // Empty rects never intersect, but we need them to for the purposes of overlap testing. 693 if (absBounds.isEmpty()) 694 absBounds.setSize(IntSize(1, 1)); 695 haveComputedBounds = true; 696 mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds); 697 } 698 699 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 700 if (compositingState.m_fixedSibling) 701 layer->setMustOverlapCompositedLayers(layer->shouldComposite()); 702 else 703 layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers); 704 #else 705 layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers); 706 #endif 707 708 // The children of this layer don't need to composite, unless there is 709 // a compositing layer among them, so start by inheriting the compositing 710 // ancestor with m_subtreeIsCompositing set to false. 711 CompositingState childState(compositingState.m_compositingAncestor); 712 #ifndef NDEBUG 713 ++childState.m_depth; 714 #endif 715 716 bool willBeComposited = needsToBeComposited(layer); 717 718 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 719 // tell the parent it has scrollable descendants. 720 if (layer->hasOverflowScroll()) 721 compositingState.m_hasScrollableElement = true; 722 #endif 723 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 724 if (layer->isFixed()) 725 compositingState.m_hasFixedElement = true; 726 #endif 727 if (willBeComposited) { 728 // Tell the parent it has compositing descendants. 729 compositingState.m_subtreeIsCompositing = true; 730 // This layer now acts as the ancestor for kids. 731 childState.m_compositingAncestor = layer; 732 if (overlapMap) 733 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 734 } 735 736 #if ENABLE(VIDEO) 737 // Video is special. It's a replaced element with a content layer, but has shadow content 738 // for the controller that must render in front. Without this, the controls fail to show 739 // when the video element is a stacking context (e.g. due to opacity or transform). 740 if (willBeComposited && layer->renderer()->isVideo()) 741 childState.m_subtreeIsCompositing = true; 742 #endif 743 744 if (layer->isStackingContext()) { 745 ASSERT(!layer->m_zOrderListsDirty); 746 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 747 size_t listSize = negZOrderList->size(); 748 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 749 childState.m_fixedSibling = compositingState.m_fixedSibling; 750 if (checkForFixedLayers(negZOrderList, false)) 751 childState.m_fixedSibling = true; 752 #endif 753 for (size_t i = 0; i < listSize; ++i) { 754 RenderLayer* curLayer = negZOrderList->at(i); 755 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged); 756 757 // If we have to make a layer for this child, make one now so we can have a contents layer 758 // (since we need to ensure that the -ve z-order child renders underneath our contents). 759 #ifdef ANDROID 760 // Normally we try to reduce the number of layers by not promoting all fixed 761 // or scrollable elements to their own compositing layer. But in the case that 762 // we have such an element in the negative z-order, we must make it a layer 763 // otherwise the content will be painted at a higher z-index. This breaks pages 764 // that set a large image with a z-index of -1 to implement a background image, 765 // for example. 766 bool childRequiresCompositing = childState.m_hasFixedElement || childState.m_hasScrollableElement; 767 if (!willBeComposited && (childState.m_subtreeIsCompositing || childRequiresCompositing)) { 768 #else 769 if (!willBeComposited && childState.m_subtreeIsCompositing) { 770 #endif 771 // make layer compositing 772 layer->setMustOverlapCompositedLayers(true); 773 childState.m_compositingAncestor = layer; 774 if (overlapMap) 775 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 776 willBeComposited = true; 777 } 778 } 779 } 780 } 781 782 ASSERT(!layer->m_normalFlowListDirty); 783 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 784 size_t listSize = normalFlowList->size(); 785 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 786 childState.m_fixedSibling = compositingState.m_fixedSibling; 787 if (checkForFixedLayers(normalFlowList, true)) 788 childState.m_fixedSibling = true; 789 #endif 790 for (size_t i = 0; i < listSize; ++i) { 791 RenderLayer* curLayer = normalFlowList->at(i); 792 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged); 793 } 794 } 795 796 if (layer->isStackingContext()) { 797 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 798 size_t listSize = posZOrderList->size(); 799 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 800 childState.m_fixedSibling = compositingState.m_fixedSibling; 801 if (checkForFixedLayers(posZOrderList, true)) 802 childState.m_fixedSibling = true; 803 #endif 804 for (size_t i = 0; i < listSize; ++i) { 805 RenderLayer* curLayer = posZOrderList->at(i); 806 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged); 807 } 808 } 809 } 810 811 // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled). 812 if (layer->isRootLayer()) { 813 if (inCompositingMode() && m_hasAcceleratedCompositing) 814 willBeComposited = true; 815 } 816 817 ASSERT(willBeComposited == needsToBeComposited(layer)); 818 819 // If we have a software transform, and we have layers under us, we need to also 820 // be composited. Also, if we have opacity < 1, then we need to be a layer so that 821 // the child layers are opaque, then rendered with opacity on this layer. 822 if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) { 823 layer->setMustOverlapCompositedLayers(true); 824 if (overlapMap) 825 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 826 willBeComposited = true; 827 } 828 829 ASSERT(willBeComposited == needsToBeComposited(layer)); 830 if (layer->reflectionLayer()) 831 layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited); 832 833 // Subsequent layers in the parent stacking context also need to composite. 834 if (childState.m_subtreeIsCompositing) 835 compositingState.m_subtreeIsCompositing = true; 836 837 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 838 if (childState.m_hasFixedElement) 839 compositingState.m_hasFixedElement = true; 840 #endif 841 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 842 if (childState.m_hasScrollableElement) 843 compositingState.m_hasScrollableElement = true; 844 #endif 845 846 // Set the flag to say that this SC has compositing children. 847 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing); 848 849 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, 850 // so test that again. 851 if (!willBeComposited && canBeComposited(layer) && clipsCompositingDescendants(layer)) { 852 if (overlapMap) 853 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 854 willBeComposited = true; 855 } 856 857 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need 858 // to be composited, then we can drop out of compositing mode altogether. 859 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 860 // We also need to check that we don't have a scrollable layer, as this 861 // would not have set the m_subtreeIsCompositing flag 862 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !childState.m_hasScrollableElement && !childState.m_hasFixedElement && !requiresCompositingLayer(layer) && !m_forceCompositingMode) { 863 #else 864 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) { 865 #endif 866 enableCompositingMode(false); 867 willBeComposited = false; 868 } 869 870 // If the layer is going into compositing mode, repaint its old location. 871 ASSERT(willBeComposited == needsToBeComposited(layer)); 872 if (!layer->isComposited() && willBeComposited) 873 repaintOnCompositingChange(layer); 874 875 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree(). 876 if (updateBacking(layer, CompositingChangeRepaintNow)) 877 layersChanged = true; 878 879 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow)) 880 layersChanged = true; 881 } 882 883 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer) 884 { 885 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer); 886 ASSERT(childLayer->isComposited()); 887 888 // It's possible to be called with a parent that isn't yet composited when we're doing 889 // partial updates as required by painting or hit testing. Just bail in that case; 890 // we'll do a full layer update soon. 891 if (!parentLayer || !parentLayer->isComposited()) 892 return; 893 894 if (parentLayer) { 895 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers(); 896 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers(); 897 898 hostingLayer->addChild(hostedLayer); 899 } else 900 childLayer->backing()->childForSuperlayers()->removeFromParent(); 901 } 902 903 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer) 904 { 905 ASSERT(layer->isComposited()); 906 907 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers(); 908 hostingLayer->removeAllChildren(); 909 } 910 911 #if ENABLE(VIDEO) 912 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const 913 { 914 if (!m_hasAcceleratedCompositing) 915 return false; 916 917 return o->supportsAcceleratedRendering(); 918 } 919 #endif 920 921 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer) 922 { 923 // Make the layer compositing if necessary, and set up clipping and content layers. 924 // Note that we can only do work here that is independent of whether the descendant layers 925 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary. 926 927 RenderLayerBacking* layerBacking = layer->backing(); 928 if (layerBacking) { 929 // The compositing state of all our children has been updated already, so now 930 // we can compute and cache the composited bounds for this layer. 931 layerBacking->updateCompositedBounds(); 932 933 if (RenderLayer* reflection = layer->reflectionLayer()) { 934 if (reflection->backing()) 935 reflection->backing()->updateCompositedBounds(); 936 } 937 938 layerBacking->updateGraphicsLayerConfiguration(); 939 layerBacking->updateGraphicsLayerGeometry(); 940 941 if (!layer->parent()) 942 updateRootLayerPosition(); 943 } 944 945 // If this layer has backing, then we are collecting its children, otherwise appending 946 // to the compositing child list of an enclosing layer. 947 Vector<GraphicsLayer*> layerChildren; 948 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer; 949 950 CompositingState childState = compositingState; 951 if (layer->isComposited()) 952 childState.m_compositingAncestor = layer; 953 954 #ifndef NDEBUG 955 ++childState.m_depth; 956 #endif 957 958 // The children of this stacking context don't need to composite, unless there is 959 // a compositing layer among them, so start by assuming false. 960 childState.m_subtreeIsCompositing = false; 961 962 if (layer->isStackingContext()) { 963 ASSERT(!layer->m_zOrderListsDirty); 964 965 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 966 size_t listSize = negZOrderList->size(); 967 for (size_t i = 0; i < listSize; ++i) { 968 RenderLayer* curLayer = negZOrderList->at(i); 969 rebuildCompositingLayerTree(curLayer, childState, childList); 970 } 971 } 972 973 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented. 974 if (layerBacking && layerBacking->foregroundLayer()) 975 childList.append(layerBacking->foregroundLayer()); 976 } 977 978 ASSERT(!layer->m_normalFlowListDirty); 979 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 980 size_t listSize = normalFlowList->size(); 981 for (size_t i = 0; i < listSize; ++i) { 982 RenderLayer* curLayer = normalFlowList->at(i); 983 rebuildCompositingLayerTree(curLayer, childState, childList); 984 } 985 } 986 987 if (layer->isStackingContext()) { 988 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 989 size_t listSize = posZOrderList->size(); 990 for (size_t i = 0; i < listSize; ++i) { 991 RenderLayer* curLayer = posZOrderList->at(i); 992 rebuildCompositingLayerTree(curLayer, childState, childList); 993 } 994 } 995 } 996 997 if (layerBacking) { 998 bool parented = false; 999 if (layer->renderer()->isRenderPart()) 1000 parented = parentFrameContentLayers(toRenderPart(layer->renderer())); 1001 1002 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer. 1003 // Otherwise, the overflow control layers are normal children. 1004 if (!layerBacking->hasClippingLayer()) { 1005 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) { 1006 overflowControlLayer->removeFromParent(); 1007 layerChildren.append(overflowControlLayer); 1008 } 1009 1010 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) { 1011 overflowControlLayer->removeFromParent(); 1012 layerChildren.append(overflowControlLayer); 1013 } 1014 1015 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) { 1016 overflowControlLayer->removeFromParent(); 1017 layerChildren.append(overflowControlLayer); 1018 } 1019 } 1020 1021 if (!parented) 1022 layerBacking->parentForSublayers()->setChildren(layerChildren); 1023 1024 #if ENABLE(FULLSCREEN_API) 1025 // For the sake of clients of the full screen renderer, don't reparent 1026 // the full screen layer out from under them if they're in the middle of 1027 // animating. 1028 if (layer->renderer()->isRenderFullScreen() && toRenderFullScreen(layer->renderer())->isAnimating()) 1029 return; 1030 #endif 1031 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers()); 1032 } 1033 } 1034 1035 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset) 1036 { 1037 if (m_overflowControlsHostLayer) 1038 m_overflowControlsHostLayer->setPosition(contentsOffset); 1039 } 1040 1041 void RenderLayerCompositor::frameViewDidChangeSize() 1042 { 1043 if (m_clipLayer) { 1044 FrameView* frameView = m_renderView->frameView(); 1045 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size()); 1046 1047 IntPoint scrollPosition = frameView->scrollPosition(); 1048 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y())); 1049 updateOverflowControlsLayers(); 1050 } 1051 } 1052 1053 void RenderLayerCompositor::frameViewDidScroll(const IntPoint& scrollPosition) 1054 { 1055 if (m_scrollLayer) 1056 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y())); 1057 } 1058 1059 String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo) 1060 { 1061 if (compositingLayerUpdatePending()) 1062 updateCompositingLayers(); 1063 1064 if (!m_rootPlatformLayer) 1065 return String(); 1066 1067 // We skip dumping the scroll and clip layers to keep layerTreeAsText output 1068 // similar between platforms. 1069 return m_rootPlatformLayer->layerTreeAsText(showDebugInfo ? LayerTreeAsTextDebug : LayerTreeAsTextBehaviorNormal); 1070 } 1071 1072 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer) 1073 { 1074 if (!renderer->node()->isFrameOwnerElement()) 1075 return 0; 1076 1077 HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(renderer->node()); 1078 if (Document* contentDocument = element->contentDocument()) { 1079 if (RenderView* view = contentDocument->renderView()) 1080 return view->compositor(); 1081 } 1082 return 0; 1083 } 1084 1085 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer) 1086 { 1087 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer); 1088 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame) 1089 return false; 1090 1091 RenderLayer* layer = renderer->layer(); 1092 if (!layer->isComposited()) 1093 return false; 1094 1095 RenderLayerBacking* backing = layer->backing(); 1096 GraphicsLayer* hostingLayer = backing->parentForSublayers(); 1097 GraphicsLayer* rootLayer = innerCompositor->rootPlatformLayer(); 1098 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) { 1099 hostingLayer->removeAllChildren(); 1100 hostingLayer->addChild(rootLayer); 1101 } 1102 return true; 1103 } 1104 1105 // This just updates layer geometry without changing the hierarchy. 1106 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer) 1107 { 1108 if (RenderLayerBacking* layerBacking = layer->backing()) { 1109 // The compositing state of all our children has been updated already, so now 1110 // we can compute and cache the composited bounds for this layer. 1111 layerBacking->updateCompositedBounds(); 1112 1113 if (RenderLayer* reflection = layer->reflectionLayer()) { 1114 if (reflection->backing()) 1115 reflection->backing()->updateCompositedBounds(); 1116 } 1117 1118 layerBacking->updateGraphicsLayerConfiguration(); 1119 layerBacking->updateGraphicsLayerGeometry(); 1120 1121 if (!layer->parent()) 1122 updateRootLayerPosition(); 1123 } 1124 1125 if (layer->isStackingContext()) { 1126 ASSERT(!layer->m_zOrderListsDirty); 1127 1128 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1129 size_t listSize = negZOrderList->size(); 1130 for (size_t i = 0; i < listSize; ++i) 1131 updateLayerTreeGeometry(negZOrderList->at(i)); 1132 } 1133 } 1134 1135 ASSERT(!layer->m_normalFlowListDirty); 1136 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1137 size_t listSize = normalFlowList->size(); 1138 for (size_t i = 0; i < listSize; ++i) 1139 updateLayerTreeGeometry(normalFlowList->at(i)); 1140 } 1141 1142 if (layer->isStackingContext()) { 1143 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1144 size_t listSize = posZOrderList->size(); 1145 for (size_t i = 0; i < listSize; ++i) 1146 updateLayerTreeGeometry(posZOrderList->at(i)); 1147 } 1148 } 1149 } 1150 1151 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry. 1152 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth) 1153 { 1154 if (layer != compositingAncestor) { 1155 if (RenderLayerBacking* layerBacking = layer->backing()) { 1156 layerBacking->updateCompositedBounds(); 1157 1158 if (RenderLayer* reflection = layer->reflectionLayer()) { 1159 if (reflection->backing()) 1160 reflection->backing()->updateCompositedBounds(); 1161 } 1162 1163 layerBacking->updateGraphicsLayerGeometry(); 1164 if (updateDepth == RenderLayerBacking::CompositingChildren) 1165 return; 1166 } 1167 } 1168 1169 if (layer->reflectionLayer()) 1170 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth); 1171 1172 if (!layer->hasCompositingDescendant()) 1173 return; 1174 1175 if (layer->isStackingContext()) { 1176 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1177 size_t listSize = negZOrderList->size(); 1178 for (size_t i = 0; i < listSize; ++i) 1179 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth); 1180 } 1181 } 1182 1183 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1184 size_t listSize = normalFlowList->size(); 1185 for (size_t i = 0; i < listSize; ++i) 1186 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth); 1187 } 1188 1189 if (layer->isStackingContext()) { 1190 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1191 size_t listSize = posZOrderList->size(); 1192 for (size_t i = 0; i < listSize; ++i) 1193 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth); 1194 } 1195 } 1196 } 1197 1198 1199 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect) 1200 { 1201 recursiveRepaintLayerRect(rootRenderLayer(), absRect); 1202 } 1203 1204 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect) 1205 { 1206 // FIXME: This method does not work correctly with transforms. 1207 if (layer->isComposited()) 1208 layer->setBackingNeedsRepaintInRect(rect); 1209 1210 if (layer->hasCompositingDescendant()) { 1211 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1212 size_t listSize = negZOrderList->size(); 1213 for (size_t i = 0; i < listSize; ++i) { 1214 RenderLayer* curLayer = negZOrderList->at(i); 1215 int x = 0; 1216 int y = 0; 1217 curLayer->convertToLayerCoords(layer, x, y); 1218 IntRect childRect(rect); 1219 childRect.move(-x, -y); 1220 recursiveRepaintLayerRect(curLayer, childRect); 1221 } 1222 } 1223 1224 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1225 size_t listSize = posZOrderList->size(); 1226 for (size_t i = 0; i < listSize; ++i) { 1227 RenderLayer* curLayer = posZOrderList->at(i); 1228 int x = 0; 1229 int y = 0; 1230 curLayer->convertToLayerCoords(layer, x, y); 1231 IntRect childRect(rect); 1232 childRect.move(-x, -y); 1233 recursiveRepaintLayerRect(curLayer, childRect); 1234 } 1235 } 1236 } 1237 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1238 size_t listSize = normalFlowList->size(); 1239 for (size_t i = 0; i < listSize; ++i) { 1240 RenderLayer* curLayer = normalFlowList->at(i); 1241 int x = 0; 1242 int y = 0; 1243 curLayer->convertToLayerCoords(layer, x, y); 1244 IntRect childRect(rect); 1245 childRect.move(-x, -y); 1246 recursiveRepaintLayerRect(curLayer, childRect); 1247 } 1248 } 1249 } 1250 1251 RenderLayer* RenderLayerCompositor::rootRenderLayer() const 1252 { 1253 return m_renderView->layer(); 1254 } 1255 1256 GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const 1257 { 1258 if (m_overflowControlsHostLayer) 1259 return m_overflowControlsHostLayer.get(); 1260 return m_rootPlatformLayer.get(); 1261 } 1262 1263 void RenderLayerCompositor::didMoveOnscreen() 1264 { 1265 if (!inCompositingMode() || m_rootLayerAttachment != RootLayerUnattached) 1266 return; 1267 1268 RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient; 1269 attachRootPlatformLayer(attachment); 1270 } 1271 1272 void RenderLayerCompositor::willMoveOffscreen() 1273 { 1274 if (!inCompositingMode() || m_rootLayerAttachment == RootLayerUnattached) 1275 return; 1276 1277 detachRootPlatformLayer(); 1278 } 1279 1280 void RenderLayerCompositor::updateRootLayerPosition() 1281 { 1282 if (m_rootPlatformLayer) { 1283 m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight())); 1284 m_rootPlatformLayer->setPosition(FloatPoint(m_renderView->docLeft(), m_renderView->docTop())); 1285 } 1286 if (m_clipLayer) { 1287 FrameView* frameView = m_renderView->frameView(); 1288 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size()); 1289 } 1290 } 1291 1292 void RenderLayerCompositor::didStartAcceleratedAnimation(CSSPropertyID property) 1293 { 1294 // If an accelerated animation or transition runs, we have to turn off overlap checking because 1295 // we don't do layout for every frame, but we have to ensure that the layering is 1296 // correct between the animating object and other objects on the page. 1297 if (property == CSSPropertyWebkitTransform) 1298 setCompositingConsultsOverlap(false); 1299 } 1300 1301 bool RenderLayerCompositor::has3DContent() const 1302 { 1303 return layerHas3DContent(rootRenderLayer()); 1304 } 1305 1306 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view) 1307 { 1308 #if PLATFORM(MAC) 1309 // frames are only independently composited in Mac pre-WebKit2. 1310 return view->platformWidget(); 1311 #endif 1312 return false; 1313 } 1314 1315 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const 1316 { 1317 #if PLATFORM(ANDROID) 1318 if (enclosingFrameElement() && !allowsIndependentlyCompositedFrames(m_renderView->frameView())) 1319 return true; 1320 #endif 1321 // Parent document content needs to be able to render on top of a composited frame, so correct behavior 1322 // is to have the parent document become composited too. However, this can cause problems on platforms that 1323 // use native views for frames (like Mac), so disable that behavior on those platforms for now. 1324 HTMLFrameOwnerElement* ownerElement = enclosingFrameElement(); 1325 RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0; 1326 1327 // If we are the top-level frame, don't propagate. 1328 if (!ownerElement) 1329 return false; 1330 1331 if (!allowsIndependentlyCompositedFrames(m_renderView->frameView())) 1332 return true; 1333 1334 if (!renderer || !renderer->isRenderPart()) 1335 return false; 1336 1337 // On Mac, only propagate compositing if the frame is overlapped in the parent 1338 // document, or the parent is already compositing, or the main frame is scaled. 1339 Frame* frame = m_renderView->frameView()->frame(); 1340 Page* page = frame ? frame->page() : 0; 1341 if (page->mainFrame()->pageScaleFactor() != 1) 1342 return true; 1343 1344 RenderPart* frameRenderer = toRenderPart(renderer); 1345 if (frameRenderer->widget()) { 1346 ASSERT(frameRenderer->widget()->isFrameView()); 1347 FrameView* view = static_cast<FrameView*>(frameRenderer->widget()); 1348 if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor()) 1349 return true; 1350 } 1351 1352 return false; 1353 } 1354 1355 HTMLFrameOwnerElement* RenderLayerCompositor::enclosingFrameElement() const 1356 { 1357 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 1358 return (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(objectTag)) ? ownerElement : 0; 1359 1360 return 0; 1361 } 1362 1363 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const 1364 { 1365 if (!canBeComposited(layer)) 1366 return false; 1367 1368 // The root layer always has a compositing layer, but it may not have backing. 1369 #if PLATFORM(ANDROID) 1370 // If we do not have a root platform layer, don't use the 1371 // mustOverlapCompositedLayers() as a cue that this layer needs to be 1372 // composited -- the layers tree has been detached. 1373 // Otherwise we can end up in a cycle where updateBacking() switches composited 1374 // mode on because a layer has mustOverlapCompositedLayers() (by calling 1375 // enableCompositingMode()), while computeCompositingRequirements() will 1376 // (correctly) say that we do not need to be in composited mode and turns it 1377 // off, rince and repeat... 1378 return requiresCompositingLayer(layer) 1379 || (m_rootPlatformLayer && layer->mustOverlapCompositedLayers()) 1380 || (inCompositingMode() && layer->isRootLayer()); 1381 #else 1382 return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer()); 1383 #endif 1384 } 1385 1386 #if PLATFORM(ANDROID) 1387 bool RenderLayerCompositor::requiresCompositingForAndroidLayers(const RenderLayer* layer) const 1388 { 1389 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 1390 if (layer->hasOverflowScroll()) 1391 return true; 1392 if (layer->isRootLayer() && m_renderView->frameView()->hasOverflowScroll()) 1393 return true; 1394 #endif 1395 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 1396 1397 // Enable composited layers (for fixed elements) 1398 if (layer->isFixed()) 1399 return true; 1400 #endif 1401 return false; 1402 } 1403 #endif 1404 1405 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons. 1406 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. 1407 // static 1408 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const 1409 { 1410 RenderObject* renderer = layer->renderer(); 1411 // The compositing state of a reflection should match that of its reflected layer. 1412 if (layer->isReflection()) { 1413 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected. 1414 layer = toRenderBoxModelObject(renderer)->layer(); 1415 } 1416 return requiresCompositingForTransform(renderer) 1417 #if PLATFORM(ANDROID) 1418 || requiresCompositingForAndroidLayers(layer) 1419 #endif 1420 || requiresCompositingForVideo(renderer) 1421 || requiresCompositingForCanvas(renderer) 1422 || requiresCompositingForPlugin(renderer) 1423 || requiresCompositingForFrame(renderer) 1424 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden) 1425 || clipsCompositingDescendants(layer) 1426 || requiresCompositingForAnimation(renderer) 1427 || requiresCompositingForFullScreen(renderer); 1428 } 1429 1430 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const 1431 { 1432 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer(); 1433 } 1434 1435 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips, 1436 // up to the enclosing compositing ancestor. This is required because compositing layers are parented 1437 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy. 1438 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy, 1439 // but a sibling in the z-order hierarchy. 1440 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const 1441 { 1442 if (!layer->isComposited() || !layer->parent()) 1443 return false; 1444 1445 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer(); 1446 if (!compositingAncestor) 1447 return false; 1448 1449 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(), 1450 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot), 1451 // and layer. 1452 RenderLayer* computeClipRoot = 0; 1453 RenderLayer* curr = layer; 1454 while (curr) { 1455 RenderLayer* next = curr->parent(); 1456 if (next == compositingAncestor) { 1457 computeClipRoot = curr; 1458 break; 1459 } 1460 curr = next; 1461 } 1462 1463 if (!computeClipRoot || computeClipRoot == layer) 1464 return false; 1465 1466 IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true); 1467 return backgroundRect != PaintInfo::infiniteRect(); 1468 } 1469 1470 // Return true if the given layer is a stacking context and has compositing child 1471 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer 1472 // into the hierarchy between this layer and its children in the z-order hierarchy. 1473 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const 1474 { 1475 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 1476 if (layer->hasOverflowScroll()) 1477 return false; 1478 #endif 1479 return layer->hasCompositingDescendant() && 1480 (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip()); 1481 } 1482 1483 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const 1484 { 1485 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger)) 1486 return false; 1487 1488 RenderStyle* style = renderer->style(); 1489 // Note that we ask the renderer if it has a transform, because the style may have transforms, 1490 // but the renderer may be an inline that doesn't suppport them. 1491 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective()); 1492 } 1493 1494 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const 1495 { 1496 if (!(m_compositingTriggers & ChromeClient::VideoTrigger)) 1497 return false; 1498 #if ENABLE(VIDEO) 1499 if (renderer->isVideo()) { 1500 RenderVideo* video = toRenderVideo(renderer); 1501 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video); 1502 } 1503 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 1504 else if (renderer->isRenderPart()) { 1505 if (!m_hasAcceleratedCompositing) 1506 return false; 1507 1508 Node* node = renderer->node(); 1509 if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag))) 1510 return false; 1511 1512 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node); 1513 return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false; 1514 } 1515 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO) 1516 #else 1517 UNUSED_PARAM(renderer); 1518 #endif 1519 return false; 1520 } 1521 1522 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const 1523 { 1524 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger)) 1525 return false; 1526 1527 if (renderer->isCanvas()) { 1528 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node()); 1529 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated(); 1530 } 1531 return false; 1532 } 1533 1534 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const 1535 { 1536 if (!(m_compositingTriggers & ChromeClient::PluginTrigger)) 1537 return false; 1538 1539 bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) 1540 || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing()); 1541 if (!composite) 1542 return false; 1543 1544 m_compositingDependsOnGeometry = true; 1545 1546 RenderWidget* pluginRenderer = toRenderWidget(renderer); 1547 // If we can't reliably know the size of the plugin yet, don't change compositing state. 1548 if (pluginRenderer->needsLayout()) 1549 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited(); 1550 1551 // Don't go into compositing mode if height or width are zero, or size is 1x1. 1552 IntRect contentBox = pluginRenderer->contentBoxRect(); 1553 #if PLATFORM(ANDROID) 1554 // allow all plugins including 1x1 to be composited, so that they are drawn, 1555 // and acquire an ANativeWindow on the UI thread 1556 return contentBox.height() * contentBox.width() > 0; 1557 #else 1558 return contentBox.height() * contentBox.width() > 1; 1559 #endif 1560 } 1561 1562 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const 1563 { 1564 if (!renderer->isRenderPart()) 1565 return false; 1566 1567 RenderPart* frameRenderer = toRenderPart(renderer); 1568 1569 if (!frameRenderer->requiresAcceleratedCompositing()) 1570 return false; 1571 1572 m_compositingDependsOnGeometry = true; 1573 1574 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer); 1575 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame()) 1576 return false; 1577 1578 // If we can't reliably know the size of the iframe yet, don't change compositing state. 1579 if (renderer->needsLayout()) 1580 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited(); 1581 1582 // Don't go into compositing mode if height or width are zero. 1583 IntRect contentBox = frameRenderer->contentBoxRect(); 1584 return contentBox.height() * contentBox.width() > 0; 1585 } 1586 1587 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const 1588 { 1589 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger)) 1590 return false; 1591 1592 if (AnimationController* animController = renderer->animation()) { 1593 #if PLATFORM(ANDROID) 1594 // android renders an opacity animation much faster if it's composited 1595 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity)) 1596 #else 1597 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode()) 1598 #endif 1599 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform); 1600 } 1601 return false; 1602 } 1603 1604 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const 1605 { 1606 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection(); 1607 } 1608 1609 bool RenderLayerCompositor::requiresCompositingForFullScreen(RenderObject* renderer) const 1610 { 1611 #if ENABLE(FULLSCREEN_API) 1612 return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating(); 1613 #else 1614 UNUSED_PARAM(renderer); 1615 return false; 1616 #endif 1617 } 1618 1619 // If an element has negative z-index children, those children render in front of the 1620 // layer background, so we need an extra 'contents' layer for the foreground of the layer 1621 // object. 1622 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const 1623 { 1624 return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0); 1625 } 1626 1627 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const 1628 { 1629 // We need to handle our own scrolling if we're: 1630 return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2) 1631 || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac 1632 } 1633 1634 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip) 1635 { 1636 if (!scrollbar) 1637 return; 1638 1639 context.save(); 1640 const IntRect& scrollbarRect = scrollbar->frameRect(); 1641 context.translate(-scrollbarRect.x(), -scrollbarRect.y()); 1642 IntRect transformedClip = clip; 1643 transformedClip.move(scrollbarRect.x(), scrollbarRect.y()); 1644 scrollbar->paint(&context, transformedClip); 1645 context.restore(); 1646 } 1647 1648 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip) 1649 { 1650 if (graphicsLayer == layerForHorizontalScrollbar()) 1651 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip); 1652 else if (graphicsLayer == layerForVerticalScrollbar()) 1653 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip); 1654 else if (graphicsLayer == layerForScrollCorner()) { 1655 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect(); 1656 context.save(); 1657 context.translate(-scrollCorner.x(), -scrollCorner.y()); 1658 IntRect transformedClip = clip; 1659 transformedClip.move(scrollCorner.x(), scrollCorner.y()); 1660 m_renderView->frameView()->paintScrollCorner(&context, transformedClip); 1661 context.restore(); 1662 } 1663 } 1664 1665 static bool shouldCompositeOverflowControls(ScrollView* view) 1666 { 1667 if (view->platformWidget()) 1668 return false; 1669 #if !PLATFORM(CHROMIUM) 1670 if (!view->hasOverlayScrollbars()) 1671 return false; 1672 #endif 1673 return true; 1674 } 1675 1676 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const 1677 { 1678 ScrollView* view = m_renderView->frameView(); 1679 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar(); 1680 } 1681 1682 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const 1683 { 1684 ScrollView* view = m_renderView->frameView(); 1685 return shouldCompositeOverflowControls(view) && view->verticalScrollbar(); 1686 } 1687 1688 bool RenderLayerCompositor::requiresScrollCornerLayer() const 1689 { 1690 ScrollView* view = m_renderView->frameView(); 1691 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible(); 1692 } 1693 1694 void RenderLayerCompositor::updateOverflowControlsLayers() 1695 { 1696 bool layersChanged = false; 1697 1698 if (requiresHorizontalScrollbarLayer()) { 1699 m_layerForHorizontalScrollbar = GraphicsLayer::create(this); 1700 #ifndef NDEBUG 1701 m_layerForHorizontalScrollbar->setName("horizontal scrollbar"); 1702 #endif 1703 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get()); 1704 layersChanged = true; 1705 } else if (m_layerForHorizontalScrollbar) { 1706 m_layerForHorizontalScrollbar->removeFromParent(); 1707 m_layerForHorizontalScrollbar = 0; 1708 layersChanged = true; 1709 } 1710 1711 if (requiresVerticalScrollbarLayer()) { 1712 m_layerForVerticalScrollbar = GraphicsLayer::create(this); 1713 #ifndef NDEBUG 1714 m_layerForVerticalScrollbar->setName("vertical scrollbar"); 1715 #endif 1716 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get()); 1717 layersChanged = true; 1718 } else if (m_layerForVerticalScrollbar) { 1719 m_layerForVerticalScrollbar->removeFromParent(); 1720 m_layerForVerticalScrollbar = 0; 1721 layersChanged = true; 1722 } 1723 1724 if (requiresScrollCornerLayer()) { 1725 m_layerForScrollCorner = GraphicsLayer::create(this); 1726 #ifndef NDEBUG 1727 m_layerForScrollCorner->setName("scroll corner"); 1728 #endif 1729 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get()); 1730 layersChanged = true; 1731 } else if (m_layerForScrollCorner) { 1732 m_layerForScrollCorner->removeFromParent(); 1733 m_layerForScrollCorner = 0; 1734 layersChanged = true; 1735 } 1736 1737 if (layersChanged) 1738 m_renderView->frameView()->positionScrollbarLayers(); 1739 } 1740 1741 void RenderLayerCompositor::ensureRootPlatformLayer() 1742 { 1743 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient; 1744 if (expectedAttachment == m_rootLayerAttachment) 1745 return; 1746 1747 if (!m_rootPlatformLayer) { 1748 m_rootPlatformLayer = GraphicsLayer::create(0); 1749 #ifndef NDEBUG 1750 m_rootPlatformLayer->setName("Root platform"); 1751 #endif 1752 m_rootPlatformLayer->setSize(FloatSize(m_renderView->maxXLayoutOverflow(), m_renderView->maxYLayoutOverflow())); 1753 m_rootPlatformLayer->setPosition(FloatPoint()); 1754 1755 // Need to clip to prevent transformed content showing outside this frame 1756 m_rootPlatformLayer->setMasksToBounds(true); 1757 } 1758 1759 if (requiresScrollLayer(expectedAttachment)) { 1760 if (!m_overflowControlsHostLayer) { 1761 ASSERT(!m_scrollLayer); 1762 ASSERT(!m_clipLayer); 1763 1764 // Create a layer to host the clipping layer and the overflow controls layers. 1765 m_overflowControlsHostLayer = GraphicsLayer::create(0); 1766 #ifndef NDEBUG 1767 m_overflowControlsHostLayer->setName("overflow controls host"); 1768 #endif 1769 1770 // Create a clipping layer if this is an iframe 1771 m_clipLayer = GraphicsLayer::create(this); 1772 #ifndef NDEBUG 1773 m_clipLayer->setName("iframe Clipping"); 1774 #endif 1775 m_clipLayer->setMasksToBounds(true); 1776 1777 m_scrollLayer = GraphicsLayer::create(this); 1778 #ifndef NDEBUG 1779 m_scrollLayer->setName("iframe scrolling"); 1780 #endif 1781 1782 // Hook them up 1783 m_overflowControlsHostLayer->addChild(m_clipLayer.get()); 1784 m_clipLayer->addChild(m_scrollLayer.get()); 1785 m_scrollLayer->addChild(m_rootPlatformLayer.get()); 1786 1787 frameViewDidChangeSize(); 1788 frameViewDidScroll(m_renderView->frameView()->scrollPosition()); 1789 } 1790 } else { 1791 if (m_overflowControlsHostLayer) { 1792 m_overflowControlsHostLayer = 0; 1793 m_clipLayer = 0; 1794 m_scrollLayer = 0; 1795 } 1796 } 1797 1798 // Check to see if we have to change the attachment 1799 if (m_rootLayerAttachment != RootLayerUnattached) 1800 detachRootPlatformLayer(); 1801 1802 attachRootPlatformLayer(expectedAttachment); 1803 } 1804 1805 void RenderLayerCompositor::destroyRootPlatformLayer() 1806 { 1807 if (!m_rootPlatformLayer) 1808 return; 1809 1810 detachRootPlatformLayer(); 1811 1812 if (m_layerForHorizontalScrollbar) { 1813 m_layerForHorizontalScrollbar->removeFromParent(); 1814 m_layerForHorizontalScrollbar = 0; 1815 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar()) 1816 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size())); 1817 } 1818 1819 if (m_layerForVerticalScrollbar) { 1820 m_layerForVerticalScrollbar->removeFromParent(); 1821 m_layerForVerticalScrollbar = 0; 1822 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar()) 1823 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size())); 1824 } 1825 1826 if (m_layerForScrollCorner) { 1827 m_layerForScrollCorner = 0; 1828 m_renderView->frameView()->invalidateScrollCorner(); 1829 } 1830 1831 if (m_overflowControlsHostLayer) { 1832 m_overflowControlsHostLayer = 0; 1833 m_clipLayer = 0; 1834 m_scrollLayer = 0; 1835 } 1836 ASSERT(!m_scrollLayer); 1837 m_rootPlatformLayer = 0; 1838 } 1839 1840 void RenderLayerCompositor::attachRootPlatformLayer(RootLayerAttachment attachment) 1841 { 1842 if (!m_rootPlatformLayer) 1843 return; 1844 1845 switch (attachment) { 1846 case RootLayerUnattached: 1847 ASSERT_NOT_REACHED(); 1848 break; 1849 case RootLayerAttachedViaChromeClient: { 1850 Frame* frame = m_renderView->frameView()->frame(); 1851 Page* page = frame ? frame->page() : 0; 1852 if (!page) 1853 return; 1854 1855 page->chrome()->client()->attachRootGraphicsLayer(frame, rootPlatformLayer()); 1856 break; 1857 } 1858 case RootLayerAttachedViaEnclosingFrame: { 1859 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration() 1860 // for the frame's renderer in the parent document. 1861 scheduleNeedsStyleRecalc(m_renderView->document()->ownerElement()); 1862 break; 1863 } 1864 } 1865 1866 m_rootLayerAttachment = attachment; 1867 rootLayerAttachmentChanged(); 1868 } 1869 1870 void RenderLayerCompositor::detachRootPlatformLayer() 1871 { 1872 if (!m_rootPlatformLayer || m_rootLayerAttachment == RootLayerUnattached) 1873 return; 1874 1875 switch (m_rootLayerAttachment) { 1876 case RootLayerAttachedViaEnclosingFrame: { 1877 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration() 1878 // for the frame's renderer in the parent document. 1879 if (m_overflowControlsHostLayer) 1880 m_overflowControlsHostLayer->removeFromParent(); 1881 else 1882 m_rootPlatformLayer->removeFromParent(); 1883 1884 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 1885 scheduleNeedsStyleRecalc(ownerElement); 1886 break; 1887 } 1888 case RootLayerAttachedViaChromeClient: { 1889 Frame* frame = m_renderView->frameView()->frame(); 1890 Page* page = frame ? frame->page() : 0; 1891 if (!page) 1892 return; 1893 1894 page->chrome()->client()->attachRootGraphicsLayer(frame, 0); 1895 } 1896 break; 1897 case RootLayerUnattached: 1898 break; 1899 } 1900 1901 m_rootLayerAttachment = RootLayerUnattached; 1902 rootLayerAttachmentChanged(); 1903 } 1904 1905 void RenderLayerCompositor::updateRootLayerAttachment() 1906 { 1907 ensureRootPlatformLayer(); 1908 } 1909 1910 void RenderLayerCompositor::rootLayerAttachmentChanged() 1911 { 1912 // The attachment can affect whether the RenderView layer's paintingGoesToWindow() behavior, 1913 // so call updateGraphicsLayerGeometry() to udpate that. 1914 RenderLayer* layer = m_renderView->layer(); 1915 if (RenderLayerBacking* backing = layer ? layer->backing() : 0) 1916 backing->updateDrawsContent(); 1917 } 1918 1919 static void needsStyleRecalcCallback(Node* node) 1920 { 1921 node->setNeedsStyleRecalc(SyntheticStyleChange); 1922 } 1923 1924 void RenderLayerCompositor::scheduleNeedsStyleRecalc(Element* element) 1925 { 1926 if (ContainerNode::postAttachCallbacksAreSuspended()) 1927 ContainerNode::queuePostAttachCallback(needsStyleRecalcCallback, element); 1928 else 1929 element->setNeedsStyleRecalc(SyntheticStyleChange); 1930 } 1931 1932 // IFrames are special, because we hook compositing layers together across iframe boundaries 1933 // when both parent and iframe content are composited. So when this frame becomes composited, we have 1934 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite. 1935 void RenderLayerCompositor::notifyIFramesOfCompositingChange() 1936 { 1937 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0; 1938 if (!frame) 1939 return; 1940 1941 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) { 1942 if (child->document() && child->document()->ownerElement()) 1943 scheduleNeedsStyleRecalc(child->document()->ownerElement()); 1944 } 1945 1946 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so 1947 // we need to schedule a style recalc in our parent document. 1948 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 1949 scheduleNeedsStyleRecalc(ownerElement); 1950 } 1951 1952 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const 1953 { 1954 const RenderStyle* style = layer->renderer()->style(); 1955 1956 if (style && 1957 (style->transformStyle3D() == TransformStyle3DPreserve3D || 1958 style->hasPerspective() || 1959 style->transform().has3DOperation())) 1960 return true; 1961 1962 if (layer->isStackingContext()) { 1963 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1964 size_t listSize = negZOrderList->size(); 1965 for (size_t i = 0; i < listSize; ++i) { 1966 RenderLayer* curLayer = negZOrderList->at(i); 1967 if (layerHas3DContent(curLayer)) 1968 return true; 1969 } 1970 } 1971 1972 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1973 size_t listSize = posZOrderList->size(); 1974 for (size_t i = 0; i < listSize; ++i) { 1975 RenderLayer* curLayer = posZOrderList->at(i); 1976 if (layerHas3DContent(curLayer)) 1977 return true; 1978 } 1979 } 1980 } 1981 1982 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1983 size_t listSize = normalFlowList->size(); 1984 for (size_t i = 0; i < listSize; ++i) { 1985 RenderLayer* curLayer = normalFlowList->at(i); 1986 if (layerHas3DContent(curLayer)) 1987 return true; 1988 } 1989 } 1990 return false; 1991 } 1992 1993 void RenderLayerCompositor::updateContentsScale(float scale, RenderLayer* layer) 1994 { 1995 if (!layer) 1996 layer = rootRenderLayer(); 1997 1998 layer->updateContentsScale(scale); 1999 2000 if (layer->isStackingContext()) { 2001 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 2002 size_t listSize = negZOrderList->size(); 2003 for (size_t i = 0; i < listSize; ++i) 2004 updateContentsScale(scale, negZOrderList->at(i)); 2005 } 2006 2007 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 2008 size_t listSize = posZOrderList->size(); 2009 for (size_t i = 0; i < listSize; ++i) 2010 updateContentsScale(scale, posZOrderList->at(i)); 2011 } 2012 } 2013 2014 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 2015 size_t listSize = normalFlowList->size(); 2016 for (size_t i = 0; i < listSize; ++i) 2017 updateContentsScale(scale, normalFlowList->at(i)); 2018 } 2019 } 2020 2021 } // namespace WebCore 2022 2023 #endif // USE(ACCELERATED_COMPOSITING) 2024