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 return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer()); 1370 } 1371 1372 #if PLATFORM(ANDROID) 1373 bool RenderLayerCompositor::requiresCompositingForAndroidLayers(const RenderLayer* layer) const 1374 { 1375 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 1376 if (layer->hasOverflowScroll()) 1377 return true; 1378 if (layer->isRootLayer() && m_renderView->frameView()->hasOverflowScroll()) 1379 return true; 1380 #endif 1381 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 1382 1383 // Enable composited layers (for fixed elements) 1384 if (layer->isFixed()) 1385 return true; 1386 #endif 1387 return false; 1388 } 1389 #endif 1390 1391 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons. 1392 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. 1393 // static 1394 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const 1395 { 1396 RenderObject* renderer = layer->renderer(); 1397 // The compositing state of a reflection should match that of its reflected layer. 1398 if (layer->isReflection()) { 1399 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected. 1400 layer = toRenderBoxModelObject(renderer)->layer(); 1401 } 1402 return requiresCompositingForTransform(renderer) 1403 #if PLATFORM(ANDROID) 1404 || requiresCompositingForAndroidLayers(layer) 1405 #endif 1406 || requiresCompositingForVideo(renderer) 1407 || requiresCompositingForCanvas(renderer) 1408 || requiresCompositingForPlugin(renderer) 1409 || requiresCompositingForFrame(renderer) 1410 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden) 1411 || clipsCompositingDescendants(layer) 1412 || requiresCompositingForAnimation(renderer) 1413 || requiresCompositingForFullScreen(renderer); 1414 } 1415 1416 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const 1417 { 1418 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer(); 1419 } 1420 1421 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips, 1422 // up to the enclosing compositing ancestor. This is required because compositing layers are parented 1423 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy. 1424 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy, 1425 // but a sibling in the z-order hierarchy. 1426 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const 1427 { 1428 if (!layer->isComposited() || !layer->parent()) 1429 return false; 1430 1431 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer(); 1432 if (!compositingAncestor) 1433 return false; 1434 1435 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(), 1436 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot), 1437 // and layer. 1438 RenderLayer* computeClipRoot = 0; 1439 RenderLayer* curr = layer; 1440 while (curr) { 1441 RenderLayer* next = curr->parent(); 1442 if (next == compositingAncestor) { 1443 computeClipRoot = curr; 1444 break; 1445 } 1446 curr = next; 1447 } 1448 1449 if (!computeClipRoot || computeClipRoot == layer) 1450 return false; 1451 1452 IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true); 1453 return backgroundRect != PaintInfo::infiniteRect(); 1454 } 1455 1456 // Return true if the given layer is a stacking context and has compositing child 1457 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer 1458 // into the hierarchy between this layer and its children in the z-order hierarchy. 1459 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const 1460 { 1461 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 1462 if (layer->hasOverflowScroll()) 1463 return false; 1464 #endif 1465 return layer->hasCompositingDescendant() && 1466 (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip()); 1467 } 1468 1469 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const 1470 { 1471 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger)) 1472 return false; 1473 1474 RenderStyle* style = renderer->style(); 1475 // Note that we ask the renderer if it has a transform, because the style may have transforms, 1476 // but the renderer may be an inline that doesn't suppport them. 1477 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective()); 1478 } 1479 1480 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const 1481 { 1482 if (!(m_compositingTriggers & ChromeClient::VideoTrigger)) 1483 return false; 1484 #if ENABLE(VIDEO) 1485 if (renderer->isVideo()) { 1486 RenderVideo* video = toRenderVideo(renderer); 1487 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video); 1488 } 1489 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 1490 else if (renderer->isRenderPart()) { 1491 if (!m_hasAcceleratedCompositing) 1492 return false; 1493 1494 Node* node = renderer->node(); 1495 if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag))) 1496 return false; 1497 1498 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node); 1499 return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false; 1500 } 1501 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO) 1502 #else 1503 UNUSED_PARAM(renderer); 1504 #endif 1505 return false; 1506 } 1507 1508 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const 1509 { 1510 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger)) 1511 return false; 1512 1513 if (renderer->isCanvas()) { 1514 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node()); 1515 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated(); 1516 } 1517 return false; 1518 } 1519 1520 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const 1521 { 1522 if (!(m_compositingTriggers & ChromeClient::PluginTrigger)) 1523 return false; 1524 1525 bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) 1526 || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing()); 1527 if (!composite) 1528 return false; 1529 1530 m_compositingDependsOnGeometry = true; 1531 1532 RenderWidget* pluginRenderer = toRenderWidget(renderer); 1533 // If we can't reliably know the size of the plugin yet, don't change compositing state. 1534 if (pluginRenderer->needsLayout()) 1535 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited(); 1536 1537 // Don't go into compositing mode if height or width are zero, or size is 1x1. 1538 IntRect contentBox = pluginRenderer->contentBoxRect(); 1539 #if PLATFORM(ANDROID) 1540 // allow all plugins including 1x1 to be composited, so that they are drawn, 1541 // and acquire an ANativeWindow on the UI thread 1542 return contentBox.height() * contentBox.width() > 0; 1543 #else 1544 return contentBox.height() * contentBox.width() > 1; 1545 #endif 1546 } 1547 1548 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const 1549 { 1550 if (!renderer->isRenderPart()) 1551 return false; 1552 1553 RenderPart* frameRenderer = toRenderPart(renderer); 1554 1555 if (!frameRenderer->requiresAcceleratedCompositing()) 1556 return false; 1557 1558 m_compositingDependsOnGeometry = true; 1559 1560 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer); 1561 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame()) 1562 return false; 1563 1564 // If we can't reliably know the size of the iframe yet, don't change compositing state. 1565 if (renderer->needsLayout()) 1566 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited(); 1567 1568 // Don't go into compositing mode if height or width are zero. 1569 IntRect contentBox = frameRenderer->contentBoxRect(); 1570 return contentBox.height() * contentBox.width() > 0; 1571 } 1572 1573 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const 1574 { 1575 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger)) 1576 return false; 1577 1578 if (AnimationController* animController = renderer->animation()) { 1579 #if PLATFORM(ANDROID) 1580 // android renders an opacity animation much faster if it's composited 1581 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity)) 1582 #else 1583 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode()) 1584 #endif 1585 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform); 1586 } 1587 return false; 1588 } 1589 1590 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const 1591 { 1592 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection(); 1593 } 1594 1595 bool RenderLayerCompositor::requiresCompositingForFullScreen(RenderObject* renderer) const 1596 { 1597 #if ENABLE(FULLSCREEN_API) 1598 return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating(); 1599 #else 1600 UNUSED_PARAM(renderer); 1601 return false; 1602 #endif 1603 } 1604 1605 // If an element has negative z-index children, those children render in front of the 1606 // layer background, so we need an extra 'contents' layer for the foreground of the layer 1607 // object. 1608 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const 1609 { 1610 return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0); 1611 } 1612 1613 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const 1614 { 1615 // We need to handle our own scrolling if we're: 1616 return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2) 1617 || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac 1618 } 1619 1620 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip) 1621 { 1622 if (!scrollbar) 1623 return; 1624 1625 context.save(); 1626 const IntRect& scrollbarRect = scrollbar->frameRect(); 1627 context.translate(-scrollbarRect.x(), -scrollbarRect.y()); 1628 IntRect transformedClip = clip; 1629 transformedClip.move(scrollbarRect.x(), scrollbarRect.y()); 1630 scrollbar->paint(&context, transformedClip); 1631 context.restore(); 1632 } 1633 1634 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip) 1635 { 1636 if (graphicsLayer == layerForHorizontalScrollbar()) 1637 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip); 1638 else if (graphicsLayer == layerForVerticalScrollbar()) 1639 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip); 1640 else if (graphicsLayer == layerForScrollCorner()) { 1641 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect(); 1642 context.save(); 1643 context.translate(-scrollCorner.x(), -scrollCorner.y()); 1644 IntRect transformedClip = clip; 1645 transformedClip.move(scrollCorner.x(), scrollCorner.y()); 1646 m_renderView->frameView()->paintScrollCorner(&context, transformedClip); 1647 context.restore(); 1648 } 1649 } 1650 1651 static bool shouldCompositeOverflowControls(ScrollView* view) 1652 { 1653 if (view->platformWidget()) 1654 return false; 1655 #if !PLATFORM(CHROMIUM) 1656 if (!view->hasOverlayScrollbars()) 1657 return false; 1658 #endif 1659 return true; 1660 } 1661 1662 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const 1663 { 1664 ScrollView* view = m_renderView->frameView(); 1665 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar(); 1666 } 1667 1668 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const 1669 { 1670 ScrollView* view = m_renderView->frameView(); 1671 return shouldCompositeOverflowControls(view) && view->verticalScrollbar(); 1672 } 1673 1674 bool RenderLayerCompositor::requiresScrollCornerLayer() const 1675 { 1676 ScrollView* view = m_renderView->frameView(); 1677 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible(); 1678 } 1679 1680 void RenderLayerCompositor::updateOverflowControlsLayers() 1681 { 1682 bool layersChanged = false; 1683 1684 if (requiresHorizontalScrollbarLayer()) { 1685 m_layerForHorizontalScrollbar = GraphicsLayer::create(this); 1686 #ifndef NDEBUG 1687 m_layerForHorizontalScrollbar->setName("horizontal scrollbar"); 1688 #endif 1689 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get()); 1690 layersChanged = true; 1691 } else if (m_layerForHorizontalScrollbar) { 1692 m_layerForHorizontalScrollbar->removeFromParent(); 1693 m_layerForHorizontalScrollbar = 0; 1694 layersChanged = true; 1695 } 1696 1697 if (requiresVerticalScrollbarLayer()) { 1698 m_layerForVerticalScrollbar = GraphicsLayer::create(this); 1699 #ifndef NDEBUG 1700 m_layerForVerticalScrollbar->setName("vertical scrollbar"); 1701 #endif 1702 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get()); 1703 layersChanged = true; 1704 } else if (m_layerForVerticalScrollbar) { 1705 m_layerForVerticalScrollbar->removeFromParent(); 1706 m_layerForVerticalScrollbar = 0; 1707 layersChanged = true; 1708 } 1709 1710 if (requiresScrollCornerLayer()) { 1711 m_layerForScrollCorner = GraphicsLayer::create(this); 1712 #ifndef NDEBUG 1713 m_layerForScrollCorner->setName("scroll corner"); 1714 #endif 1715 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get()); 1716 layersChanged = true; 1717 } else if (m_layerForScrollCorner) { 1718 m_layerForScrollCorner->removeFromParent(); 1719 m_layerForScrollCorner = 0; 1720 layersChanged = true; 1721 } 1722 1723 if (layersChanged) 1724 m_renderView->frameView()->positionScrollbarLayers(); 1725 } 1726 1727 void RenderLayerCompositor::ensureRootPlatformLayer() 1728 { 1729 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient; 1730 if (expectedAttachment == m_rootLayerAttachment) 1731 return; 1732 1733 if (!m_rootPlatformLayer) { 1734 m_rootPlatformLayer = GraphicsLayer::create(0); 1735 #ifndef NDEBUG 1736 m_rootPlatformLayer->setName("Root platform"); 1737 #endif 1738 m_rootPlatformLayer->setSize(FloatSize(m_renderView->maxXLayoutOverflow(), m_renderView->maxYLayoutOverflow())); 1739 m_rootPlatformLayer->setPosition(FloatPoint()); 1740 1741 // Need to clip to prevent transformed content showing outside this frame 1742 m_rootPlatformLayer->setMasksToBounds(true); 1743 } 1744 1745 if (requiresScrollLayer(expectedAttachment)) { 1746 if (!m_overflowControlsHostLayer) { 1747 ASSERT(!m_scrollLayer); 1748 ASSERT(!m_clipLayer); 1749 1750 // Create a layer to host the clipping layer and the overflow controls layers. 1751 m_overflowControlsHostLayer = GraphicsLayer::create(0); 1752 #ifndef NDEBUG 1753 m_overflowControlsHostLayer->setName("overflow controls host"); 1754 #endif 1755 1756 // Create a clipping layer if this is an iframe 1757 m_clipLayer = GraphicsLayer::create(this); 1758 #ifndef NDEBUG 1759 m_clipLayer->setName("iframe Clipping"); 1760 #endif 1761 m_clipLayer->setMasksToBounds(true); 1762 1763 m_scrollLayer = GraphicsLayer::create(this); 1764 #ifndef NDEBUG 1765 m_scrollLayer->setName("iframe scrolling"); 1766 #endif 1767 1768 // Hook them up 1769 m_overflowControlsHostLayer->addChild(m_clipLayer.get()); 1770 m_clipLayer->addChild(m_scrollLayer.get()); 1771 m_scrollLayer->addChild(m_rootPlatformLayer.get()); 1772 1773 frameViewDidChangeSize(); 1774 frameViewDidScroll(m_renderView->frameView()->scrollPosition()); 1775 } 1776 } else { 1777 if (m_overflowControlsHostLayer) { 1778 m_overflowControlsHostLayer = 0; 1779 m_clipLayer = 0; 1780 m_scrollLayer = 0; 1781 } 1782 } 1783 1784 // Check to see if we have to change the attachment 1785 if (m_rootLayerAttachment != RootLayerUnattached) 1786 detachRootPlatformLayer(); 1787 1788 attachRootPlatformLayer(expectedAttachment); 1789 } 1790 1791 void RenderLayerCompositor::destroyRootPlatformLayer() 1792 { 1793 if (!m_rootPlatformLayer) 1794 return; 1795 1796 detachRootPlatformLayer(); 1797 1798 if (m_layerForHorizontalScrollbar) { 1799 m_layerForHorizontalScrollbar->removeFromParent(); 1800 m_layerForHorizontalScrollbar = 0; 1801 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar()) 1802 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size())); 1803 } 1804 1805 if (m_layerForVerticalScrollbar) { 1806 m_layerForVerticalScrollbar->removeFromParent(); 1807 m_layerForVerticalScrollbar = 0; 1808 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar()) 1809 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size())); 1810 } 1811 1812 if (m_layerForScrollCorner) { 1813 m_layerForScrollCorner = 0; 1814 m_renderView->frameView()->invalidateScrollCorner(); 1815 } 1816 1817 if (m_overflowControlsHostLayer) { 1818 m_overflowControlsHostLayer = 0; 1819 m_clipLayer = 0; 1820 m_scrollLayer = 0; 1821 } 1822 ASSERT(!m_scrollLayer); 1823 m_rootPlatformLayer = 0; 1824 } 1825 1826 void RenderLayerCompositor::attachRootPlatformLayer(RootLayerAttachment attachment) 1827 { 1828 if (!m_rootPlatformLayer) 1829 return; 1830 1831 switch (attachment) { 1832 case RootLayerUnattached: 1833 ASSERT_NOT_REACHED(); 1834 break; 1835 case RootLayerAttachedViaChromeClient: { 1836 Frame* frame = m_renderView->frameView()->frame(); 1837 Page* page = frame ? frame->page() : 0; 1838 if (!page) 1839 return; 1840 1841 page->chrome()->client()->attachRootGraphicsLayer(frame, rootPlatformLayer()); 1842 break; 1843 } 1844 case RootLayerAttachedViaEnclosingFrame: { 1845 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration() 1846 // for the frame's renderer in the parent document. 1847 scheduleNeedsStyleRecalc(m_renderView->document()->ownerElement()); 1848 break; 1849 } 1850 } 1851 1852 m_rootLayerAttachment = attachment; 1853 rootLayerAttachmentChanged(); 1854 } 1855 1856 void RenderLayerCompositor::detachRootPlatformLayer() 1857 { 1858 if (!m_rootPlatformLayer || m_rootLayerAttachment == RootLayerUnattached) 1859 return; 1860 1861 switch (m_rootLayerAttachment) { 1862 case RootLayerAttachedViaEnclosingFrame: { 1863 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration() 1864 // for the frame's renderer in the parent document. 1865 if (m_overflowControlsHostLayer) 1866 m_overflowControlsHostLayer->removeFromParent(); 1867 else 1868 m_rootPlatformLayer->removeFromParent(); 1869 1870 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 1871 scheduleNeedsStyleRecalc(ownerElement); 1872 break; 1873 } 1874 case RootLayerAttachedViaChromeClient: { 1875 Frame* frame = m_renderView->frameView()->frame(); 1876 Page* page = frame ? frame->page() : 0; 1877 if (!page) 1878 return; 1879 1880 page->chrome()->client()->attachRootGraphicsLayer(frame, 0); 1881 } 1882 break; 1883 case RootLayerUnattached: 1884 break; 1885 } 1886 1887 m_rootLayerAttachment = RootLayerUnattached; 1888 rootLayerAttachmentChanged(); 1889 } 1890 1891 void RenderLayerCompositor::updateRootLayerAttachment() 1892 { 1893 ensureRootPlatformLayer(); 1894 } 1895 1896 void RenderLayerCompositor::rootLayerAttachmentChanged() 1897 { 1898 // The attachment can affect whether the RenderView layer's paintingGoesToWindow() behavior, 1899 // so call updateGraphicsLayerGeometry() to udpate that. 1900 RenderLayer* layer = m_renderView->layer(); 1901 if (RenderLayerBacking* backing = layer ? layer->backing() : 0) 1902 backing->updateDrawsContent(); 1903 } 1904 1905 static void needsStyleRecalcCallback(Node* node) 1906 { 1907 node->setNeedsStyleRecalc(SyntheticStyleChange); 1908 } 1909 1910 void RenderLayerCompositor::scheduleNeedsStyleRecalc(Element* element) 1911 { 1912 if (ContainerNode::postAttachCallbacksAreSuspended()) 1913 ContainerNode::queuePostAttachCallback(needsStyleRecalcCallback, element); 1914 else 1915 element->setNeedsStyleRecalc(SyntheticStyleChange); 1916 } 1917 1918 // IFrames are special, because we hook compositing layers together across iframe boundaries 1919 // when both parent and iframe content are composited. So when this frame becomes composited, we have 1920 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite. 1921 void RenderLayerCompositor::notifyIFramesOfCompositingChange() 1922 { 1923 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0; 1924 if (!frame) 1925 return; 1926 1927 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) { 1928 if (child->document() && child->document()->ownerElement()) 1929 scheduleNeedsStyleRecalc(child->document()->ownerElement()); 1930 } 1931 1932 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so 1933 // we need to schedule a style recalc in our parent document. 1934 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 1935 scheduleNeedsStyleRecalc(ownerElement); 1936 } 1937 1938 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const 1939 { 1940 const RenderStyle* style = layer->renderer()->style(); 1941 1942 if (style && 1943 (style->transformStyle3D() == TransformStyle3DPreserve3D || 1944 style->hasPerspective() || 1945 style->transform().has3DOperation())) 1946 return true; 1947 1948 if (layer->isStackingContext()) { 1949 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1950 size_t listSize = negZOrderList->size(); 1951 for (size_t i = 0; i < listSize; ++i) { 1952 RenderLayer* curLayer = negZOrderList->at(i); 1953 if (layerHas3DContent(curLayer)) 1954 return true; 1955 } 1956 } 1957 1958 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1959 size_t listSize = posZOrderList->size(); 1960 for (size_t i = 0; i < listSize; ++i) { 1961 RenderLayer* curLayer = posZOrderList->at(i); 1962 if (layerHas3DContent(curLayer)) 1963 return true; 1964 } 1965 } 1966 } 1967 1968 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1969 size_t listSize = normalFlowList->size(); 1970 for (size_t i = 0; i < listSize; ++i) { 1971 RenderLayer* curLayer = normalFlowList->at(i); 1972 if (layerHas3DContent(curLayer)) 1973 return true; 1974 } 1975 } 1976 return false; 1977 } 1978 1979 void RenderLayerCompositor::updateContentsScale(float scale, RenderLayer* layer) 1980 { 1981 if (!layer) 1982 layer = rootRenderLayer(); 1983 1984 layer->updateContentsScale(scale); 1985 1986 if (layer->isStackingContext()) { 1987 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1988 size_t listSize = negZOrderList->size(); 1989 for (size_t i = 0; i < listSize; ++i) 1990 updateContentsScale(scale, negZOrderList->at(i)); 1991 } 1992 1993 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1994 size_t listSize = posZOrderList->size(); 1995 for (size_t i = 0; i < listSize; ++i) 1996 updateContentsScale(scale, posZOrderList->at(i)); 1997 } 1998 } 1999 2000 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 2001 size_t listSize = normalFlowList->size(); 2002 for (size_t i = 0; i < listSize; ++i) 2003 updateContentsScale(scale, normalFlowList->at(i)); 2004 } 2005 } 2006 2007 } // namespace WebCore 2008 2009 #endif // USE(ACCELERATED_COMPOSITING) 2010