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)) { 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 728 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 729 // we don't want to signal that the subtree is compositing if the reason 730 // is because the layer is an overflow layer -- doing so would trigger 731 // all the above layers to be composited unnecessarily 732 if (willBeComposited && !layer->hasOverflowScroll() && !layer->isFixed()) { 733 #else 734 if (willBeComposited) { 735 #endif 736 // Tell the parent it has compositing descendants. 737 compositingState.m_subtreeIsCompositing = true; 738 // This layer now acts as the ancestor for kids. 739 childState.m_compositingAncestor = layer; 740 if (overlapMap) 741 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 742 } 743 744 #if ENABLE(VIDEO) 745 // Video is special. It's a replaced element with a content layer, but has shadow content 746 // for the controller that must render in front. Without this, the controls fail to show 747 // when the video element is a stacking context (e.g. due to opacity or transform). 748 if (willBeComposited && layer->renderer()->isVideo()) 749 childState.m_subtreeIsCompositing = true; 750 #endif 751 752 if (layer->isStackingContext()) { 753 ASSERT(!layer->m_zOrderListsDirty); 754 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 755 size_t listSize = negZOrderList->size(); 756 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 757 childState.m_fixedSibling = compositingState.m_fixedSibling; 758 if (checkForFixedLayers(negZOrderList, false)) 759 childState.m_fixedSibling = true; 760 #endif 761 for (size_t i = 0; i < listSize; ++i) { 762 RenderLayer* curLayer = negZOrderList->at(i); 763 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged); 764 765 // If we have to make a layer for this child, make one now so we can have a contents layer 766 // (since we need to ensure that the -ve z-order child renders underneath our contents). 767 if (!willBeComposited && childState.m_subtreeIsCompositing) { 768 // make layer compositing 769 layer->setMustOverlapCompositedLayers(true); 770 childState.m_compositingAncestor = layer; 771 if (overlapMap) 772 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 773 willBeComposited = true; 774 } 775 } 776 } 777 } 778 779 ASSERT(!layer->m_normalFlowListDirty); 780 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 781 size_t listSize = normalFlowList->size(); 782 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 783 childState.m_fixedSibling = compositingState.m_fixedSibling; 784 if (checkForFixedLayers(normalFlowList, true)) 785 childState.m_fixedSibling = true; 786 #endif 787 for (size_t i = 0; i < listSize; ++i) { 788 RenderLayer* curLayer = normalFlowList->at(i); 789 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged); 790 } 791 } 792 793 if (layer->isStackingContext()) { 794 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 795 size_t listSize = posZOrderList->size(); 796 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 797 childState.m_fixedSibling = compositingState.m_fixedSibling; 798 if (checkForFixedLayers(posZOrderList, true)) 799 childState.m_fixedSibling = true; 800 #endif 801 for (size_t i = 0; i < listSize; ++i) { 802 RenderLayer* curLayer = posZOrderList->at(i); 803 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged); 804 } 805 } 806 } 807 808 // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled). 809 if (layer->isRootLayer()) { 810 if (inCompositingMode() && m_hasAcceleratedCompositing) 811 willBeComposited = true; 812 } 813 814 ASSERT(willBeComposited == needsToBeComposited(layer)); 815 816 // If we have a software transform, and we have layers under us, we need to also 817 // be composited. Also, if we have opacity < 1, then we need to be a layer so that 818 // the child layers are opaque, then rendered with opacity on this layer. 819 if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) { 820 layer->setMustOverlapCompositedLayers(true); 821 if (overlapMap) 822 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 823 willBeComposited = true; 824 } 825 826 ASSERT(willBeComposited == needsToBeComposited(layer)); 827 if (layer->reflectionLayer()) 828 layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited); 829 830 // Subsequent layers in the parent stacking context also need to composite. 831 if (childState.m_subtreeIsCompositing) 832 compositingState.m_subtreeIsCompositing = true; 833 834 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 835 if (childState.m_hasFixedElement) 836 compositingState.m_hasFixedElement = true; 837 #endif 838 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 839 if (childState.m_hasScrollableElement) 840 compositingState.m_hasScrollableElement = true; 841 #endif 842 843 // Set the flag to say that this SC has compositing children. 844 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing); 845 846 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, 847 // so test that again. 848 if (!willBeComposited && canBeComposited(layer) && clipsCompositingDescendants(layer)) { 849 if (overlapMap) 850 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 851 willBeComposited = true; 852 } 853 854 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need 855 // to be composited, then we can drop out of compositing mode altogether. 856 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 857 // We also need to check that we don't have a scrollable layer, as this 858 // would not have set the m_subtreeIsCompositing flag 859 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !childState.m_hasScrollableElement && !childState.m_hasFixedElement && !requiresCompositingLayer(layer) && !m_forceCompositingMode) { 860 #else 861 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) { 862 #endif 863 enableCompositingMode(false); 864 willBeComposited = false; 865 } 866 867 // If the layer is going into compositing mode, repaint its old location. 868 ASSERT(willBeComposited == needsToBeComposited(layer)); 869 if (!layer->isComposited() && willBeComposited) 870 repaintOnCompositingChange(layer); 871 872 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree(). 873 if (updateBacking(layer, CompositingChangeRepaintNow)) 874 layersChanged = true; 875 876 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow)) 877 layersChanged = true; 878 } 879 880 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer) 881 { 882 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer); 883 ASSERT(childLayer->isComposited()); 884 885 // It's possible to be called with a parent that isn't yet composited when we're doing 886 // partial updates as required by painting or hit testing. Just bail in that case; 887 // we'll do a full layer update soon. 888 if (!parentLayer || !parentLayer->isComposited()) 889 return; 890 891 if (parentLayer) { 892 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers(); 893 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers(); 894 895 hostingLayer->addChild(hostedLayer); 896 } else 897 childLayer->backing()->childForSuperlayers()->removeFromParent(); 898 } 899 900 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer) 901 { 902 ASSERT(layer->isComposited()); 903 904 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers(); 905 hostingLayer->removeAllChildren(); 906 } 907 908 #if ENABLE(VIDEO) 909 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const 910 { 911 if (!m_hasAcceleratedCompositing) 912 return false; 913 914 return o->supportsAcceleratedRendering(); 915 } 916 #endif 917 918 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer) 919 { 920 // Make the layer compositing if necessary, and set up clipping and content layers. 921 // Note that we can only do work here that is independent of whether the descendant layers 922 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary. 923 924 RenderLayerBacking* layerBacking = layer->backing(); 925 if (layerBacking) { 926 // The compositing state of all our children has been updated already, so now 927 // we can compute and cache the composited bounds for this layer. 928 layerBacking->updateCompositedBounds(); 929 930 if (RenderLayer* reflection = layer->reflectionLayer()) { 931 if (reflection->backing()) 932 reflection->backing()->updateCompositedBounds(); 933 } 934 935 layerBacking->updateGraphicsLayerConfiguration(); 936 layerBacking->updateGraphicsLayerGeometry(); 937 938 if (!layer->parent()) 939 updateRootLayerPosition(); 940 } 941 942 // If this layer has backing, then we are collecting its children, otherwise appending 943 // to the compositing child list of an enclosing layer. 944 Vector<GraphicsLayer*> layerChildren; 945 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer; 946 947 CompositingState childState = compositingState; 948 if (layer->isComposited()) 949 childState.m_compositingAncestor = layer; 950 951 #ifndef NDEBUG 952 ++childState.m_depth; 953 #endif 954 955 // The children of this stacking context don't need to composite, unless there is 956 // a compositing layer among them, so start by assuming false. 957 childState.m_subtreeIsCompositing = false; 958 959 if (layer->isStackingContext()) { 960 ASSERT(!layer->m_zOrderListsDirty); 961 962 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 963 size_t listSize = negZOrderList->size(); 964 for (size_t i = 0; i < listSize; ++i) { 965 RenderLayer* curLayer = negZOrderList->at(i); 966 rebuildCompositingLayerTree(curLayer, childState, childList); 967 } 968 } 969 970 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented. 971 if (layerBacking && layerBacking->foregroundLayer()) 972 childList.append(layerBacking->foregroundLayer()); 973 } 974 975 ASSERT(!layer->m_normalFlowListDirty); 976 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 977 size_t listSize = normalFlowList->size(); 978 for (size_t i = 0; i < listSize; ++i) { 979 RenderLayer* curLayer = normalFlowList->at(i); 980 rebuildCompositingLayerTree(curLayer, childState, childList); 981 } 982 } 983 984 if (layer->isStackingContext()) { 985 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 986 size_t listSize = posZOrderList->size(); 987 for (size_t i = 0; i < listSize; ++i) { 988 RenderLayer* curLayer = posZOrderList->at(i); 989 rebuildCompositingLayerTree(curLayer, childState, childList); 990 } 991 } 992 } 993 994 if (layerBacking) { 995 bool parented = false; 996 if (layer->renderer()->isRenderPart()) 997 parented = parentFrameContentLayers(toRenderPart(layer->renderer())); 998 999 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer. 1000 // Otherwise, the overflow control layers are normal children. 1001 if (!layerBacking->hasClippingLayer()) { 1002 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) { 1003 overflowControlLayer->removeFromParent(); 1004 layerChildren.append(overflowControlLayer); 1005 } 1006 1007 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) { 1008 overflowControlLayer->removeFromParent(); 1009 layerChildren.append(overflowControlLayer); 1010 } 1011 1012 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) { 1013 overflowControlLayer->removeFromParent(); 1014 layerChildren.append(overflowControlLayer); 1015 } 1016 } 1017 1018 if (!parented) 1019 layerBacking->parentForSublayers()->setChildren(layerChildren); 1020 1021 #if ENABLE(FULLSCREEN_API) 1022 // For the sake of clients of the full screen renderer, don't reparent 1023 // the full screen layer out from under them if they're in the middle of 1024 // animating. 1025 if (layer->renderer()->isRenderFullScreen() && toRenderFullScreen(layer->renderer())->isAnimating()) 1026 return; 1027 #endif 1028 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers()); 1029 } 1030 } 1031 1032 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset) 1033 { 1034 if (m_overflowControlsHostLayer) 1035 m_overflowControlsHostLayer->setPosition(contentsOffset); 1036 } 1037 1038 void RenderLayerCompositor::frameViewDidChangeSize() 1039 { 1040 if (m_clipLayer) { 1041 FrameView* frameView = m_renderView->frameView(); 1042 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size()); 1043 1044 IntPoint scrollPosition = frameView->scrollPosition(); 1045 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y())); 1046 updateOverflowControlsLayers(); 1047 } 1048 } 1049 1050 void RenderLayerCompositor::frameViewDidScroll(const IntPoint& scrollPosition) 1051 { 1052 if (m_scrollLayer) 1053 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y())); 1054 } 1055 1056 String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo) 1057 { 1058 if (compositingLayerUpdatePending()) 1059 updateCompositingLayers(); 1060 1061 if (!m_rootPlatformLayer) 1062 return String(); 1063 1064 // We skip dumping the scroll and clip layers to keep layerTreeAsText output 1065 // similar between platforms. 1066 return m_rootPlatformLayer->layerTreeAsText(showDebugInfo ? LayerTreeAsTextDebug : LayerTreeAsTextBehaviorNormal); 1067 } 1068 1069 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer) 1070 { 1071 if (!renderer->node()->isFrameOwnerElement()) 1072 return 0; 1073 1074 HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(renderer->node()); 1075 if (Document* contentDocument = element->contentDocument()) { 1076 if (RenderView* view = contentDocument->renderView()) 1077 return view->compositor(); 1078 } 1079 return 0; 1080 } 1081 1082 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer) 1083 { 1084 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer); 1085 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame) 1086 return false; 1087 1088 RenderLayer* layer = renderer->layer(); 1089 if (!layer->isComposited()) 1090 return false; 1091 1092 RenderLayerBacking* backing = layer->backing(); 1093 GraphicsLayer* hostingLayer = backing->parentForSublayers(); 1094 GraphicsLayer* rootLayer = innerCompositor->rootPlatformLayer(); 1095 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) { 1096 hostingLayer->removeAllChildren(); 1097 hostingLayer->addChild(rootLayer); 1098 } 1099 return true; 1100 } 1101 1102 // This just updates layer geometry without changing the hierarchy. 1103 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer) 1104 { 1105 if (RenderLayerBacking* layerBacking = layer->backing()) { 1106 // The compositing state of all our children has been updated already, so now 1107 // we can compute and cache the composited bounds for this layer. 1108 layerBacking->updateCompositedBounds(); 1109 1110 if (RenderLayer* reflection = layer->reflectionLayer()) { 1111 if (reflection->backing()) 1112 reflection->backing()->updateCompositedBounds(); 1113 } 1114 1115 layerBacking->updateGraphicsLayerConfiguration(); 1116 layerBacking->updateGraphicsLayerGeometry(); 1117 1118 if (!layer->parent()) 1119 updateRootLayerPosition(); 1120 } 1121 1122 if (layer->isStackingContext()) { 1123 ASSERT(!layer->m_zOrderListsDirty); 1124 1125 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1126 size_t listSize = negZOrderList->size(); 1127 for (size_t i = 0; i < listSize; ++i) 1128 updateLayerTreeGeometry(negZOrderList->at(i)); 1129 } 1130 } 1131 1132 ASSERT(!layer->m_normalFlowListDirty); 1133 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1134 size_t listSize = normalFlowList->size(); 1135 for (size_t i = 0; i < listSize; ++i) 1136 updateLayerTreeGeometry(normalFlowList->at(i)); 1137 } 1138 1139 if (layer->isStackingContext()) { 1140 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1141 size_t listSize = posZOrderList->size(); 1142 for (size_t i = 0; i < listSize; ++i) 1143 updateLayerTreeGeometry(posZOrderList->at(i)); 1144 } 1145 } 1146 } 1147 1148 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry. 1149 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth) 1150 { 1151 if (layer != compositingAncestor) { 1152 if (RenderLayerBacking* layerBacking = layer->backing()) { 1153 layerBacking->updateCompositedBounds(); 1154 1155 if (RenderLayer* reflection = layer->reflectionLayer()) { 1156 if (reflection->backing()) 1157 reflection->backing()->updateCompositedBounds(); 1158 } 1159 1160 layerBacking->updateGraphicsLayerGeometry(); 1161 if (updateDepth == RenderLayerBacking::CompositingChildren) 1162 return; 1163 } 1164 } 1165 1166 if (layer->reflectionLayer()) 1167 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth); 1168 1169 if (!layer->hasCompositingDescendant()) 1170 return; 1171 1172 if (layer->isStackingContext()) { 1173 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1174 size_t listSize = negZOrderList->size(); 1175 for (size_t i = 0; i < listSize; ++i) 1176 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth); 1177 } 1178 } 1179 1180 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1181 size_t listSize = normalFlowList->size(); 1182 for (size_t i = 0; i < listSize; ++i) 1183 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth); 1184 } 1185 1186 if (layer->isStackingContext()) { 1187 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1188 size_t listSize = posZOrderList->size(); 1189 for (size_t i = 0; i < listSize; ++i) 1190 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth); 1191 } 1192 } 1193 } 1194 1195 1196 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect) 1197 { 1198 recursiveRepaintLayerRect(rootRenderLayer(), absRect); 1199 } 1200 1201 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect) 1202 { 1203 // FIXME: This method does not work correctly with transforms. 1204 if (layer->isComposited()) 1205 layer->setBackingNeedsRepaintInRect(rect); 1206 1207 if (layer->hasCompositingDescendant()) { 1208 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1209 size_t listSize = negZOrderList->size(); 1210 for (size_t i = 0; i < listSize; ++i) { 1211 RenderLayer* curLayer = negZOrderList->at(i); 1212 int x = 0; 1213 int y = 0; 1214 curLayer->convertToLayerCoords(layer, x, y); 1215 IntRect childRect(rect); 1216 childRect.move(-x, -y); 1217 recursiveRepaintLayerRect(curLayer, childRect); 1218 } 1219 } 1220 1221 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1222 size_t listSize = posZOrderList->size(); 1223 for (size_t i = 0; i < listSize; ++i) { 1224 RenderLayer* curLayer = posZOrderList->at(i); 1225 int x = 0; 1226 int y = 0; 1227 curLayer->convertToLayerCoords(layer, x, y); 1228 IntRect childRect(rect); 1229 childRect.move(-x, -y); 1230 recursiveRepaintLayerRect(curLayer, childRect); 1231 } 1232 } 1233 } 1234 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1235 size_t listSize = normalFlowList->size(); 1236 for (size_t i = 0; i < listSize; ++i) { 1237 RenderLayer* curLayer = normalFlowList->at(i); 1238 int x = 0; 1239 int y = 0; 1240 curLayer->convertToLayerCoords(layer, x, y); 1241 IntRect childRect(rect); 1242 childRect.move(-x, -y); 1243 recursiveRepaintLayerRect(curLayer, childRect); 1244 } 1245 } 1246 } 1247 1248 RenderLayer* RenderLayerCompositor::rootRenderLayer() const 1249 { 1250 return m_renderView->layer(); 1251 } 1252 1253 GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const 1254 { 1255 if (m_overflowControlsHostLayer) 1256 return m_overflowControlsHostLayer.get(); 1257 return m_rootPlatformLayer.get(); 1258 } 1259 1260 void RenderLayerCompositor::didMoveOnscreen() 1261 { 1262 if (!inCompositingMode() || m_rootLayerAttachment != RootLayerUnattached) 1263 return; 1264 1265 RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient; 1266 attachRootPlatformLayer(attachment); 1267 } 1268 1269 void RenderLayerCompositor::willMoveOffscreen() 1270 { 1271 if (!inCompositingMode() || m_rootLayerAttachment == RootLayerUnattached) 1272 return; 1273 1274 detachRootPlatformLayer(); 1275 } 1276 1277 void RenderLayerCompositor::updateRootLayerPosition() 1278 { 1279 if (m_rootPlatformLayer) { 1280 m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight())); 1281 m_rootPlatformLayer->setPosition(FloatPoint(m_renderView->docLeft(), m_renderView->docTop())); 1282 } 1283 if (m_clipLayer) { 1284 FrameView* frameView = m_renderView->frameView(); 1285 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size()); 1286 } 1287 } 1288 1289 void RenderLayerCompositor::didStartAcceleratedAnimation(CSSPropertyID property) 1290 { 1291 // If an accelerated animation or transition runs, we have to turn off overlap checking because 1292 // we don't do layout for every frame, but we have to ensure that the layering is 1293 // correct between the animating object and other objects on the page. 1294 if (property == CSSPropertyWebkitTransform) 1295 setCompositingConsultsOverlap(false); 1296 } 1297 1298 bool RenderLayerCompositor::has3DContent() const 1299 { 1300 return layerHas3DContent(rootRenderLayer()); 1301 } 1302 1303 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view) 1304 { 1305 #if PLATFORM(MAC) 1306 // frames are only independently composited in Mac pre-WebKit2. 1307 return view->platformWidget(); 1308 #endif 1309 return false; 1310 } 1311 1312 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const 1313 { 1314 #if PLATFORM(ANDROID) 1315 if (enclosingFrameElement() && !allowsIndependentlyCompositedFrames(m_renderView->frameView())) 1316 return true; 1317 #endif 1318 // Parent document content needs to be able to render on top of a composited frame, so correct behavior 1319 // is to have the parent document become composited too. However, this can cause problems on platforms that 1320 // use native views for frames (like Mac), so disable that behavior on those platforms for now. 1321 HTMLFrameOwnerElement* ownerElement = enclosingFrameElement(); 1322 RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0; 1323 1324 // If we are the top-level frame, don't propagate. 1325 if (!ownerElement) 1326 return false; 1327 1328 if (!allowsIndependentlyCompositedFrames(m_renderView->frameView())) 1329 return true; 1330 1331 if (!renderer || !renderer->isRenderPart()) 1332 return false; 1333 1334 // On Mac, only propagate compositing if the frame is overlapped in the parent 1335 // document, or the parent is already compositing, or the main frame is scaled. 1336 Frame* frame = m_renderView->frameView()->frame(); 1337 Page* page = frame ? frame->page() : 0; 1338 if (page->mainFrame()->pageScaleFactor() != 1) 1339 return true; 1340 1341 RenderPart* frameRenderer = toRenderPart(renderer); 1342 if (frameRenderer->widget()) { 1343 ASSERT(frameRenderer->widget()->isFrameView()); 1344 FrameView* view = static_cast<FrameView*>(frameRenderer->widget()); 1345 if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor()) 1346 return true; 1347 } 1348 1349 return false; 1350 } 1351 1352 HTMLFrameOwnerElement* RenderLayerCompositor::enclosingFrameElement() const 1353 { 1354 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 1355 return (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(objectTag)) ? ownerElement : 0; 1356 1357 return 0; 1358 } 1359 1360 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const 1361 { 1362 if (!canBeComposited(layer)) 1363 return false; 1364 1365 // The root layer always has a compositing layer, but it may not have backing. 1366 return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer()); 1367 } 1368 1369 #if PLATFORM(ANDROID) 1370 bool RenderLayerCompositor::requiresCompositingForAndroidLayers(const RenderLayer* layer) const 1371 { 1372 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 1373 if (layer->hasOverflowScroll()) 1374 return true; 1375 if (layer->isRootLayer() && m_renderView->frameView()->hasOverflowScroll()) 1376 return true; 1377 #endif 1378 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 1379 1380 // Enable composited layers (for fixed elements) 1381 if (layer->isFixed()) 1382 return true; 1383 #endif 1384 return false; 1385 } 1386 #endif 1387 1388 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons. 1389 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. 1390 // static 1391 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const 1392 { 1393 RenderObject* renderer = layer->renderer(); 1394 // The compositing state of a reflection should match that of its reflected layer. 1395 if (layer->isReflection()) { 1396 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected. 1397 layer = toRenderBoxModelObject(renderer)->layer(); 1398 } 1399 return requiresCompositingForTransform(renderer) 1400 #if PLATFORM(ANDROID) 1401 || requiresCompositingForAndroidLayers(layer) 1402 #endif 1403 || requiresCompositingForVideo(renderer) 1404 || requiresCompositingForCanvas(renderer) 1405 || requiresCompositingForPlugin(renderer) 1406 || requiresCompositingForFrame(renderer) 1407 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden) 1408 || clipsCompositingDescendants(layer) 1409 || requiresCompositingForAnimation(renderer) 1410 || requiresCompositingForFullScreen(renderer); 1411 } 1412 1413 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const 1414 { 1415 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer(); 1416 } 1417 1418 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips, 1419 // up to the enclosing compositing ancestor. This is required because compositing layers are parented 1420 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy. 1421 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy, 1422 // but a sibling in the z-order hierarchy. 1423 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const 1424 { 1425 if (!layer->isComposited() || !layer->parent()) 1426 return false; 1427 1428 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer(); 1429 if (!compositingAncestor) 1430 return false; 1431 1432 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(), 1433 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot), 1434 // and layer. 1435 RenderLayer* computeClipRoot = 0; 1436 RenderLayer* curr = layer; 1437 while (curr) { 1438 RenderLayer* next = curr->parent(); 1439 if (next == compositingAncestor) { 1440 computeClipRoot = curr; 1441 break; 1442 } 1443 curr = next; 1444 } 1445 1446 if (!computeClipRoot || computeClipRoot == layer) 1447 return false; 1448 1449 IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true); 1450 return backgroundRect != PaintInfo::infiniteRect(); 1451 } 1452 1453 // Return true if the given layer is a stacking context and has compositing child 1454 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer 1455 // into the hierarchy between this layer and its children in the z-order hierarchy. 1456 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const 1457 { 1458 #if ENABLE(ANDROID_OVERFLOW_SCROLL) 1459 if (layer->hasOverflowScroll()) 1460 return false; 1461 #endif 1462 return layer->hasCompositingDescendant() && 1463 (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip()); 1464 } 1465 1466 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const 1467 { 1468 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger)) 1469 return false; 1470 1471 RenderStyle* style = renderer->style(); 1472 // Note that we ask the renderer if it has a transform, because the style may have transforms, 1473 // but the renderer may be an inline that doesn't suppport them. 1474 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective()); 1475 } 1476 1477 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const 1478 { 1479 if (!(m_compositingTriggers & ChromeClient::VideoTrigger)) 1480 return false; 1481 #if ENABLE(VIDEO) 1482 if (renderer->isVideo()) { 1483 RenderVideo* video = toRenderVideo(renderer); 1484 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video); 1485 } 1486 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 1487 else if (renderer->isRenderPart()) { 1488 if (!m_hasAcceleratedCompositing) 1489 return false; 1490 1491 Node* node = renderer->node(); 1492 if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag))) 1493 return false; 1494 1495 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node); 1496 return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false; 1497 } 1498 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO) 1499 #else 1500 UNUSED_PARAM(renderer); 1501 #endif 1502 return false; 1503 } 1504 1505 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const 1506 { 1507 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger)) 1508 return false; 1509 1510 if (renderer->isCanvas()) { 1511 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node()); 1512 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated(); 1513 } 1514 return false; 1515 } 1516 1517 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const 1518 { 1519 if (!(m_compositingTriggers & ChromeClient::PluginTrigger)) 1520 return false; 1521 1522 bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) 1523 || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing()); 1524 if (!composite) 1525 return false; 1526 1527 m_compositingDependsOnGeometry = true; 1528 1529 RenderWidget* pluginRenderer = toRenderWidget(renderer); 1530 // If we can't reliably know the size of the plugin yet, don't change compositing state. 1531 if (pluginRenderer->needsLayout()) 1532 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited(); 1533 1534 // Don't go into compositing mode if height or width are zero, or size is 1x1. 1535 IntRect contentBox = pluginRenderer->contentBoxRect(); 1536 #if PLATFORM(ANDROID) 1537 // allow all plugins including 1x1 to be composited, so that they are drawn, 1538 // and acquire an ANativeWindow on the UI thread 1539 return contentBox.height() * contentBox.width() > 0; 1540 #else 1541 return contentBox.height() * contentBox.width() > 1; 1542 #endif 1543 } 1544 1545 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const 1546 { 1547 if (!renderer->isRenderPart()) 1548 return false; 1549 1550 RenderPart* frameRenderer = toRenderPart(renderer); 1551 1552 if (!frameRenderer->requiresAcceleratedCompositing()) 1553 return false; 1554 1555 m_compositingDependsOnGeometry = true; 1556 1557 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer); 1558 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame()) 1559 return false; 1560 1561 // If we can't reliably know the size of the iframe yet, don't change compositing state. 1562 if (renderer->needsLayout()) 1563 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited(); 1564 1565 // Don't go into compositing mode if height or width are zero. 1566 IntRect contentBox = frameRenderer->contentBoxRect(); 1567 return contentBox.height() * contentBox.width() > 0; 1568 } 1569 1570 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const 1571 { 1572 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger)) 1573 return false; 1574 1575 if (AnimationController* animController = renderer->animation()) { 1576 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode()) 1577 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform); 1578 } 1579 return false; 1580 } 1581 1582 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const 1583 { 1584 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection(); 1585 } 1586 1587 bool RenderLayerCompositor::requiresCompositingForFullScreen(RenderObject* renderer) const 1588 { 1589 #if ENABLE(FULLSCREEN_API) 1590 return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating(); 1591 #else 1592 UNUSED_PARAM(renderer); 1593 return false; 1594 #endif 1595 } 1596 1597 // If an element has negative z-index children, those children render in front of the 1598 // layer background, so we need an extra 'contents' layer for the foreground of the layer 1599 // object. 1600 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const 1601 { 1602 return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0); 1603 } 1604 1605 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const 1606 { 1607 // We need to handle our own scrolling if we're: 1608 return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2) 1609 || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac 1610 } 1611 1612 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip) 1613 { 1614 if (!scrollbar) 1615 return; 1616 1617 context.save(); 1618 const IntRect& scrollbarRect = scrollbar->frameRect(); 1619 context.translate(-scrollbarRect.x(), -scrollbarRect.y()); 1620 IntRect transformedClip = clip; 1621 transformedClip.move(scrollbarRect.x(), scrollbarRect.y()); 1622 scrollbar->paint(&context, transformedClip); 1623 context.restore(); 1624 } 1625 1626 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip) 1627 { 1628 if (graphicsLayer == layerForHorizontalScrollbar()) 1629 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip); 1630 else if (graphicsLayer == layerForVerticalScrollbar()) 1631 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip); 1632 else if (graphicsLayer == layerForScrollCorner()) { 1633 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect(); 1634 context.save(); 1635 context.translate(-scrollCorner.x(), -scrollCorner.y()); 1636 IntRect transformedClip = clip; 1637 transformedClip.move(scrollCorner.x(), scrollCorner.y()); 1638 m_renderView->frameView()->paintScrollCorner(&context, transformedClip); 1639 context.restore(); 1640 } 1641 } 1642 1643 static bool shouldCompositeOverflowControls(ScrollView* view) 1644 { 1645 if (view->platformWidget()) 1646 return false; 1647 #if !PLATFORM(CHROMIUM) 1648 if (!view->hasOverlayScrollbars()) 1649 return false; 1650 #endif 1651 return true; 1652 } 1653 1654 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const 1655 { 1656 ScrollView* view = m_renderView->frameView(); 1657 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar(); 1658 } 1659 1660 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const 1661 { 1662 ScrollView* view = m_renderView->frameView(); 1663 return shouldCompositeOverflowControls(view) && view->verticalScrollbar(); 1664 } 1665 1666 bool RenderLayerCompositor::requiresScrollCornerLayer() const 1667 { 1668 ScrollView* view = m_renderView->frameView(); 1669 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible(); 1670 } 1671 1672 void RenderLayerCompositor::updateOverflowControlsLayers() 1673 { 1674 bool layersChanged = false; 1675 1676 if (requiresHorizontalScrollbarLayer()) { 1677 m_layerForHorizontalScrollbar = GraphicsLayer::create(this); 1678 #ifndef NDEBUG 1679 m_layerForHorizontalScrollbar->setName("horizontal scrollbar"); 1680 #endif 1681 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get()); 1682 layersChanged = true; 1683 } else if (m_layerForHorizontalScrollbar) { 1684 m_layerForHorizontalScrollbar->removeFromParent(); 1685 m_layerForHorizontalScrollbar = 0; 1686 layersChanged = true; 1687 } 1688 1689 if (requiresVerticalScrollbarLayer()) { 1690 m_layerForVerticalScrollbar = GraphicsLayer::create(this); 1691 #ifndef NDEBUG 1692 m_layerForVerticalScrollbar->setName("vertical scrollbar"); 1693 #endif 1694 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get()); 1695 layersChanged = true; 1696 } else if (m_layerForVerticalScrollbar) { 1697 m_layerForVerticalScrollbar->removeFromParent(); 1698 m_layerForVerticalScrollbar = 0; 1699 layersChanged = true; 1700 } 1701 1702 if (requiresScrollCornerLayer()) { 1703 m_layerForScrollCorner = GraphicsLayer::create(this); 1704 #ifndef NDEBUG 1705 m_layerForScrollCorner->setName("scroll corner"); 1706 #endif 1707 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get()); 1708 layersChanged = true; 1709 } else if (m_layerForScrollCorner) { 1710 m_layerForScrollCorner->removeFromParent(); 1711 m_layerForScrollCorner = 0; 1712 layersChanged = true; 1713 } 1714 1715 if (layersChanged) 1716 m_renderView->frameView()->positionScrollbarLayers(); 1717 } 1718 1719 void RenderLayerCompositor::ensureRootPlatformLayer() 1720 { 1721 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient; 1722 if (expectedAttachment == m_rootLayerAttachment) 1723 return; 1724 1725 if (!m_rootPlatformLayer) { 1726 m_rootPlatformLayer = GraphicsLayer::create(0); 1727 #ifndef NDEBUG 1728 m_rootPlatformLayer->setName("Root platform"); 1729 #endif 1730 m_rootPlatformLayer->setSize(FloatSize(m_renderView->maxXLayoutOverflow(), m_renderView->maxYLayoutOverflow())); 1731 m_rootPlatformLayer->setPosition(FloatPoint()); 1732 1733 // Need to clip to prevent transformed content showing outside this frame 1734 m_rootPlatformLayer->setMasksToBounds(true); 1735 } 1736 1737 if (requiresScrollLayer(expectedAttachment)) { 1738 if (!m_overflowControlsHostLayer) { 1739 ASSERT(!m_scrollLayer); 1740 ASSERT(!m_clipLayer); 1741 1742 // Create a layer to host the clipping layer and the overflow controls layers. 1743 m_overflowControlsHostLayer = GraphicsLayer::create(0); 1744 #ifndef NDEBUG 1745 m_overflowControlsHostLayer->setName("overflow controls host"); 1746 #endif 1747 1748 // Create a clipping layer if this is an iframe 1749 m_clipLayer = GraphicsLayer::create(this); 1750 #ifndef NDEBUG 1751 m_clipLayer->setName("iframe Clipping"); 1752 #endif 1753 m_clipLayer->setMasksToBounds(true); 1754 1755 m_scrollLayer = GraphicsLayer::create(this); 1756 #ifndef NDEBUG 1757 m_scrollLayer->setName("iframe scrolling"); 1758 #endif 1759 1760 // Hook them up 1761 m_overflowControlsHostLayer->addChild(m_clipLayer.get()); 1762 m_clipLayer->addChild(m_scrollLayer.get()); 1763 m_scrollLayer->addChild(m_rootPlatformLayer.get()); 1764 1765 frameViewDidChangeSize(); 1766 frameViewDidScroll(m_renderView->frameView()->scrollPosition()); 1767 } 1768 } else { 1769 if (m_overflowControlsHostLayer) { 1770 m_overflowControlsHostLayer = 0; 1771 m_clipLayer = 0; 1772 m_scrollLayer = 0; 1773 } 1774 } 1775 1776 // Check to see if we have to change the attachment 1777 if (m_rootLayerAttachment != RootLayerUnattached) 1778 detachRootPlatformLayer(); 1779 1780 attachRootPlatformLayer(expectedAttachment); 1781 } 1782 1783 void RenderLayerCompositor::destroyRootPlatformLayer() 1784 { 1785 if (!m_rootPlatformLayer) 1786 return; 1787 1788 detachRootPlatformLayer(); 1789 1790 if (m_layerForHorizontalScrollbar) { 1791 m_layerForHorizontalScrollbar->removeFromParent(); 1792 m_layerForHorizontalScrollbar = 0; 1793 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar()) 1794 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size())); 1795 } 1796 1797 if (m_layerForVerticalScrollbar) { 1798 m_layerForVerticalScrollbar->removeFromParent(); 1799 m_layerForVerticalScrollbar = 0; 1800 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar()) 1801 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size())); 1802 } 1803 1804 if (m_layerForScrollCorner) { 1805 m_layerForScrollCorner = 0; 1806 m_renderView->frameView()->invalidateScrollCorner(); 1807 } 1808 1809 if (m_overflowControlsHostLayer) { 1810 m_overflowControlsHostLayer = 0; 1811 m_clipLayer = 0; 1812 m_scrollLayer = 0; 1813 } 1814 ASSERT(!m_scrollLayer); 1815 m_rootPlatformLayer = 0; 1816 } 1817 1818 void RenderLayerCompositor::attachRootPlatformLayer(RootLayerAttachment attachment) 1819 { 1820 if (!m_rootPlatformLayer) 1821 return; 1822 1823 switch (attachment) { 1824 case RootLayerUnattached: 1825 ASSERT_NOT_REACHED(); 1826 break; 1827 case RootLayerAttachedViaChromeClient: { 1828 Frame* frame = m_renderView->frameView()->frame(); 1829 Page* page = frame ? frame->page() : 0; 1830 if (!page) 1831 return; 1832 1833 page->chrome()->client()->attachRootGraphicsLayer(frame, rootPlatformLayer()); 1834 break; 1835 } 1836 case RootLayerAttachedViaEnclosingFrame: { 1837 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration() 1838 // for the frame's renderer in the parent document. 1839 scheduleNeedsStyleRecalc(m_renderView->document()->ownerElement()); 1840 break; 1841 } 1842 } 1843 1844 m_rootLayerAttachment = attachment; 1845 rootLayerAttachmentChanged(); 1846 } 1847 1848 void RenderLayerCompositor::detachRootPlatformLayer() 1849 { 1850 if (!m_rootPlatformLayer || m_rootLayerAttachment == RootLayerUnattached) 1851 return; 1852 1853 switch (m_rootLayerAttachment) { 1854 case RootLayerAttachedViaEnclosingFrame: { 1855 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration() 1856 // for the frame's renderer in the parent document. 1857 if (m_overflowControlsHostLayer) 1858 m_overflowControlsHostLayer->removeFromParent(); 1859 else 1860 m_rootPlatformLayer->removeFromParent(); 1861 1862 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 1863 scheduleNeedsStyleRecalc(ownerElement); 1864 break; 1865 } 1866 case RootLayerAttachedViaChromeClient: { 1867 Frame* frame = m_renderView->frameView()->frame(); 1868 Page* page = frame ? frame->page() : 0; 1869 if (!page) 1870 return; 1871 1872 page->chrome()->client()->attachRootGraphicsLayer(frame, 0); 1873 } 1874 break; 1875 case RootLayerUnattached: 1876 break; 1877 } 1878 1879 m_rootLayerAttachment = RootLayerUnattached; 1880 rootLayerAttachmentChanged(); 1881 } 1882 1883 void RenderLayerCompositor::updateRootLayerAttachment() 1884 { 1885 ensureRootPlatformLayer(); 1886 } 1887 1888 void RenderLayerCompositor::rootLayerAttachmentChanged() 1889 { 1890 // The attachment can affect whether the RenderView layer's paintingGoesToWindow() behavior, 1891 // so call updateGraphicsLayerGeometry() to udpate that. 1892 RenderLayer* layer = m_renderView->layer(); 1893 if (RenderLayerBacking* backing = layer ? layer->backing() : 0) 1894 backing->updateDrawsContent(); 1895 } 1896 1897 static void needsStyleRecalcCallback(Node* node) 1898 { 1899 node->setNeedsStyleRecalc(SyntheticStyleChange); 1900 } 1901 1902 void RenderLayerCompositor::scheduleNeedsStyleRecalc(Element* element) 1903 { 1904 if (ContainerNode::postAttachCallbacksAreSuspended()) 1905 ContainerNode::queuePostAttachCallback(needsStyleRecalcCallback, element); 1906 else 1907 element->setNeedsStyleRecalc(SyntheticStyleChange); 1908 } 1909 1910 // IFrames are special, because we hook compositing layers together across iframe boundaries 1911 // when both parent and iframe content are composited. So when this frame becomes composited, we have 1912 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite. 1913 void RenderLayerCompositor::notifyIFramesOfCompositingChange() 1914 { 1915 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0; 1916 if (!frame) 1917 return; 1918 1919 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) { 1920 if (child->document() && child->document()->ownerElement()) 1921 scheduleNeedsStyleRecalc(child->document()->ownerElement()); 1922 } 1923 1924 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so 1925 // we need to schedule a style recalc in our parent document. 1926 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement()) 1927 scheduleNeedsStyleRecalc(ownerElement); 1928 } 1929 1930 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const 1931 { 1932 const RenderStyle* style = layer->renderer()->style(); 1933 1934 if (style && 1935 (style->transformStyle3D() == TransformStyle3DPreserve3D || 1936 style->hasPerspective() || 1937 style->transform().has3DOperation())) 1938 return true; 1939 1940 if (layer->isStackingContext()) { 1941 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1942 size_t listSize = negZOrderList->size(); 1943 for (size_t i = 0; i < listSize; ++i) { 1944 RenderLayer* curLayer = negZOrderList->at(i); 1945 if (layerHas3DContent(curLayer)) 1946 return true; 1947 } 1948 } 1949 1950 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1951 size_t listSize = posZOrderList->size(); 1952 for (size_t i = 0; i < listSize; ++i) { 1953 RenderLayer* curLayer = posZOrderList->at(i); 1954 if (layerHas3DContent(curLayer)) 1955 return true; 1956 } 1957 } 1958 } 1959 1960 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1961 size_t listSize = normalFlowList->size(); 1962 for (size_t i = 0; i < listSize; ++i) { 1963 RenderLayer* curLayer = normalFlowList->at(i); 1964 if (layerHas3DContent(curLayer)) 1965 return true; 1966 } 1967 } 1968 return false; 1969 } 1970 1971 void RenderLayerCompositor::updateContentsScale(float scale, RenderLayer* layer) 1972 { 1973 if (!layer) 1974 layer = rootRenderLayer(); 1975 1976 layer->updateContentsScale(scale); 1977 1978 if (layer->isStackingContext()) { 1979 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1980 size_t listSize = negZOrderList->size(); 1981 for (size_t i = 0; i < listSize; ++i) 1982 updateContentsScale(scale, negZOrderList->at(i)); 1983 } 1984 1985 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1986 size_t listSize = posZOrderList->size(); 1987 for (size_t i = 0; i < listSize; ++i) 1988 updateContentsScale(scale, posZOrderList->at(i)); 1989 } 1990 } 1991 1992 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1993 size_t listSize = normalFlowList->size(); 1994 for (size_t i = 0; i < listSize; ++i) 1995 updateContentsScale(scale, normalFlowList->at(i)); 1996 } 1997 } 1998 1999 } // namespace WebCore 2000 2001 #endif // USE(ACCELERATED_COMPOSITING) 2002