1 /* 2 * Copyright (C) 2009 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 "Chrome.h" 33 #include "ChromeClient.h" 34 #include "CSSPropertyNames.h" 35 #include "Frame.h" 36 #include "FrameView.h" 37 #include "GraphicsLayer.h" 38 #include "HitTestResult.h" 39 #include "HTMLCanvasElement.h" 40 #include "Page.h" 41 #include "RenderEmbeddedObject.h" 42 #include "RenderLayerBacking.h" 43 #include "RenderReplica.h" 44 #include "RenderVideo.h" 45 #include "RenderView.h" 46 #include "Settings.h" 47 48 #if PROFILE_LAYER_REBUILD 49 #include <wtf/CurrentTime.h> 50 #endif 51 52 #ifndef NDEBUG 53 #include "CString.h" 54 #include "RenderTreeAsText.h" 55 #endif 56 57 #if ENABLE(3D_RENDERING) 58 // This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm'). 59 bool WebCoreHas3DRendering = true; 60 #endif 61 62 namespace WebCore { 63 64 using namespace HTMLNames; 65 66 struct CompositingState { 67 CompositingState(RenderLayer* compAncestor) 68 : m_compositingAncestor(compAncestor) 69 , m_subtreeIsCompositing(false) 70 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 71 , m_fixedSibling(false) 72 #endif 73 #ifndef NDEBUG 74 , m_depth(0) 75 #endif 76 { 77 } 78 79 RenderLayer* m_compositingAncestor; 80 bool m_subtreeIsCompositing; 81 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 82 bool m_fixedSibling; 83 #endif 84 #ifndef NDEBUG 85 int m_depth; 86 #endif 87 }; 88 89 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView) 90 : m_renderView(renderView) 91 , m_rootPlatformLayer(0) 92 , m_hasAcceleratedCompositing(true) 93 , m_showDebugBorders(false) 94 , m_showRepaintCounter(false) 95 , m_compositingConsultsOverlap(true) 96 , m_compositing(false) 97 , m_rootLayerAttached(false) 98 , m_compositingLayersNeedRebuild(false) 99 #if PROFILE_LAYER_REBUILD 100 , m_rootLayerUpdateCount(0) 101 #endif // PROFILE_LAYER_REBUILD 102 { 103 } 104 105 RenderLayerCompositor::~RenderLayerCompositor() 106 { 107 ASSERT(!m_rootLayerAttached); 108 } 109 110 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */) 111 { 112 if (enable != m_compositing) { 113 m_compositing = enable; 114 115 // We never go out of compositing mode for a given page, 116 // but if all the layers disappear, we'll just be left with 117 // the empty root layer, which has minimal overhead. 118 if (m_compositing) 119 ensureRootPlatformLayer(); 120 else 121 destroyRootPlatformLayer(); 122 } 123 } 124 125 void RenderLayerCompositor::cacheAcceleratedCompositingFlags() 126 { 127 bool hasAcceleratedCompositing = false; 128 bool showDebugBorders = false; 129 bool showRepaintCounter = false; 130 131 if (Settings* settings = m_renderView->document()->settings()) { 132 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled(); 133 showDebugBorders = settings->showDebugBorders(); 134 showRepaintCounter = settings->showRepaintCounter(); 135 } 136 137 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter) 138 setCompositingLayersNeedRebuild(); 139 140 m_hasAcceleratedCompositing = hasAcceleratedCompositing; 141 m_showDebugBorders = showDebugBorders; 142 m_showRepaintCounter = showRepaintCounter; 143 } 144 145 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild) 146 { 147 if (inCompositingMode()) 148 m_compositingLayersNeedRebuild = needRebuild; 149 } 150 151 void RenderLayerCompositor::scheduleSync() 152 { 153 Frame* frame = m_renderView->frameView()->frame(); 154 Page* page = frame ? frame->page() : 0; 155 if (!page) 156 return; 157 158 page->chrome()->client()->scheduleCompositingLayerSync(); 159 } 160 161 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot) 162 { 163 bool checkForHierarchyUpdate = false; 164 bool needGeometryUpdate = false; 165 166 switch (updateType) { 167 case CompositingUpdateAfterLayoutOrStyleChange: 168 case CompositingUpdateOnPaitingOrHitTest: 169 checkForHierarchyUpdate = true; 170 break; 171 case CompositingUpdateOnScroll: 172 if (m_compositingConsultsOverlap) 173 checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates. 174 175 needGeometryUpdate = true; 176 break; 177 } 178 179 if (!checkForHierarchyUpdate && !needGeometryUpdate) 180 return; 181 182 ASSERT(inCompositingMode()); 183 184 bool needHierarchyUpdate = m_compositingLayersNeedRebuild; 185 if (!updateRoot) { 186 // Only clear the flag if we're updating the entire hierarchy. 187 m_compositingLayersNeedRebuild = false; 188 updateRoot = rootRenderLayer(); 189 } 190 191 #if PROFILE_LAYER_REBUILD 192 ++m_rootLayerUpdateCount; 193 194 double startTime = WTF::currentTime(); 195 #endif 196 197 if (checkForHierarchyUpdate) { 198 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers. 199 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex. 200 CompositingState compState(updateRoot); 201 bool layersChanged = false; 202 if (m_compositingConsultsOverlap) { 203 OverlapMap overlapTestRequestMap; 204 computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged); 205 } else 206 computeCompositingRequirements(updateRoot, 0, compState, layersChanged); 207 208 needHierarchyUpdate |= layersChanged; 209 } 210 211 if (needHierarchyUpdate) { 212 // Update the hierarchy of the compositing layers. 213 CompositingState compState(updateRoot); 214 Vector<GraphicsLayer*> childList; 215 rebuildCompositingLayerTree(updateRoot, compState, childList); 216 217 // Host the document layer in the RenderView's root layer. 218 if (updateRoot == rootRenderLayer() && !childList.isEmpty()) 219 m_rootPlatformLayer->setChildren(childList); 220 } else if (needGeometryUpdate) { 221 // We just need to do a geometry update. This is only used for position:fixed scrolling; 222 // most of the time, geometry is updated via RenderLayer::styleChanged(). 223 updateLayerTreeGeometry(updateRoot); 224 } 225 226 #if PROFILE_LAYER_REBUILD 227 double endTime = WTF::currentTime(); 228 if (updateRoot == rootRenderLayer()) 229 fprintf(stderr, "Update %d: computeCompositingRequirements for the world took %fms\n", 230 m_rootLayerUpdateCount, 1000.0 * (endTime - startTime)); 231 #endif 232 ASSERT(updateRoot || !m_compositingLayersNeedRebuild); 233 234 if (!hasAcceleratedCompositing()) 235 enableCompositingMode(false); 236 } 237 238 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) 239 { 240 bool layerChanged = false; 241 242 if (needsToBeComposited(layer)) { 243 enableCompositingMode(); 244 245 // 3D transforms turn off the testing of overlap. 246 if (requiresCompositingForTransform(layer->renderer())) 247 setCompositingConsultsOverlap(false); 248 249 if (!layer->backing()) { 250 251 // If we need to repaint, do so before making backing 252 if (shouldRepaint == CompositingChangeRepaintNow) 253 repaintOnCompositingChange(layer); 254 255 layer->ensureBacking(); 256 layerChanged = true; 257 } 258 } else { 259 if (layer->backing()) { 260 // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to 261 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection 262 // are both either composited, or not composited. 263 if (layer->isReflection()) { 264 RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer(); 265 if (RenderLayerBacking* backing = sourceLayer->backing()) { 266 ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer()); 267 backing->graphicsLayer()->setReplicatedByLayer(0); 268 } 269 } 270 271 layer->clearBacking(); 272 layerChanged = true; 273 274 // The layer's cached repaints rects are relative to the repaint container, so change when 275 // compositing changes; we need to update them here. 276 layer->computeRepaintRects(); 277 278 // If we need to repaint, do so now that we've removed the backing 279 if (shouldRepaint == CompositingChangeRepaintNow) 280 repaintOnCompositingChange(layer); 281 } 282 } 283 284 #if ENABLE(VIDEO) 285 if (layerChanged && layer->renderer()->isVideo()) { 286 // If it's a video, give the media player a chance to hook up to the layer. 287 RenderVideo* video = toRenderVideo(layer->renderer()); 288 video->acceleratedRenderingStateChanged(); 289 } 290 #endif 291 return layerChanged; 292 } 293 294 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) 295 { 296 bool layerChanged = updateBacking(layer, shouldRepaint); 297 298 // See if we need content or clipping layers. Methods called here should assume 299 // that the compositing state of descendant layers has not been updated yet. 300 if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration()) 301 layerChanged = true; 302 303 return layerChanged; 304 } 305 306 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer) 307 { 308 // If the renderer is not attached yet, no need to repaint. 309 if (!layer->renderer()->parent()) 310 return; 311 312 RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint(); 313 if (!repaintContainer) 314 repaintContainer = m_renderView; 315 316 layer->repaintIncludingNonCompositingDescendants(repaintContainer); 317 if (repaintContainer == m_renderView) { 318 // The contents of this layer may be moving between the window 319 // and a GraphicsLayer, so we need to make sure the window system 320 // synchronizes those changes on the screen. 321 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization(); 322 } 323 } 324 325 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant 326 // RenderLayers that are rendered by the composited RenderLayer. 327 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) 328 { 329 if (!layer->isSelfPaintingLayer()) 330 return IntRect(); 331 332 IntRect boundingBoxRect, unionBounds; 333 boundingBoxRect = unionBounds = layer->localBoundingBox(); 334 335 if (layer->renderer()->hasOverflowClip() || layer->renderer()->hasMask()) { 336 int ancestorRelX = 0, ancestorRelY = 0; 337 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY); 338 boundingBoxRect.move(ancestorRelX, ancestorRelY); 339 return boundingBoxRect; 340 } 341 342 if (RenderLayer* reflection = layer->reflectionLayer()) { 343 if (!reflection->isComposited()) { 344 IntRect childUnionBounds = calculateCompositedBounds(reflection, layer); 345 unionBounds.unite(childUnionBounds); 346 } 347 } 348 349 ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0)); 350 351 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 352 size_t listSize = negZOrderList->size(); 353 for (size_t i = 0; i < listSize; ++i) { 354 RenderLayer* curLayer = negZOrderList->at(i); 355 if (!curLayer->isComposited()) { 356 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer); 357 unionBounds.unite(childUnionBounds); 358 } 359 } 360 } 361 362 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 363 size_t listSize = posZOrderList->size(); 364 for (size_t i = 0; i < listSize; ++i) { 365 RenderLayer* curLayer = posZOrderList->at(i); 366 if (!curLayer->isComposited()) { 367 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer); 368 unionBounds.unite(childUnionBounds); 369 } 370 } 371 } 372 373 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 374 size_t listSize = normalFlowList->size(); 375 for (size_t i = 0; i < listSize; ++i) { 376 RenderLayer* curLayer = normalFlowList->at(i); 377 if (!curLayer->isComposited()) { 378 IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer); 379 unionBounds.unite(curAbsBounds); 380 } 381 } 382 } 383 384 if (layer->paintsWithTransform(PaintBehaviorNormal)) { 385 TransformationMatrix* affineTrans = layer->transform(); 386 boundingBoxRect = affineTrans->mapRect(boundingBoxRect); 387 unionBounds = affineTrans->mapRect(unionBounds); 388 } 389 390 int ancestorRelX = 0, ancestorRelY = 0; 391 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY); 392 unionBounds.move(ancestorRelX, ancestorRelY); 393 394 return unionBounds; 395 } 396 397 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/) 398 { 399 setCompositingLayersNeedRebuild(); 400 } 401 402 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child) 403 { 404 if (!child->isComposited() || parent->renderer()->documentBeingDestroyed()) 405 return; 406 407 setCompositingParent(child, 0); 408 409 RenderLayer* compLayer = parent->enclosingCompositingLayer(); 410 if (compLayer) { 411 ASSERT(compLayer->backing()); 412 IntRect compBounds = child->backing()->compositedBounds(); 413 414 int offsetX = 0, offsetY = 0; 415 child->convertToLayerCoords(compLayer, offsetX, offsetY); 416 compBounds.move(offsetX, offsetY); 417 418 compLayer->setBackingNeedsRepaintInRect(compBounds); 419 420 // The contents of this layer may be moving from a GraphicsLayer to the window, 421 // so we need to make sure the window system synchronizes those changes on the screen. 422 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization(); 423 } 424 425 setCompositingLayersNeedRebuild(); 426 } 427 428 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const 429 { 430 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) { 431 if (curr->isStackingContext()) 432 return 0; 433 434 if (curr->renderer()->hasOverflowClip()) 435 return curr; 436 } 437 return 0; 438 } 439 440 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed) 441 { 442 if (layer->isRootLayer()) 443 return; 444 445 if (!boundsComputed) { 446 layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox(); 447 boundsComputed = true; 448 } 449 450 overlapMap.add(layer, layerBounds); 451 } 452 453 bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds) 454 { 455 RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end(); 456 for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) { 457 const IntRect& bounds = it->second; 458 if (layerBounds.intersects(bounds)) 459 return true; 460 } 461 462 return false; 463 } 464 465 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order) 466 // For the z-order children of a compositing layer: 467 // If a child layers has a compositing layer, then all subsequent layers must 468 // be compositing in order to render above that layer. 469 // 470 // If a child in the negative z-order list is compositing, then the layer itself 471 // must be compositing so that its contents render over that child. 472 // This implies that its positive z-index children must also be compositing. 473 // 474 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, OverlapMap* overlapMap, struct CompositingState& compositingState, bool& layersChanged) 475 { 476 layer->updateLayerPosition(); 477 layer->updateZOrderLists(); 478 layer->updateNormalFlowList(); 479 480 // Clear the flag 481 layer->setHasCompositingDescendant(false); 482 483 bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing; 484 485 bool haveComputedBounds = false; 486 IntRect absBounds; 487 if (overlapMap && !overlapMap->isEmpty()) { 488 // If we're testing for overlap, we only need to composite if we overlap something that is already composited. 489 absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox(); 490 haveComputedBounds = true; 491 mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds); 492 } 493 494 layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers); 495 496 // The children of this layer don't need to composite, unless there is 497 // a compositing layer among them, so start by inheriting the compositing 498 // ancestor with m_subtreeIsCompositing set to false. 499 CompositingState childState(compositingState.m_compositingAncestor); 500 #ifndef NDEBUG 501 ++childState.m_depth; 502 #endif 503 504 const bool willBeComposited = needsToBeComposited(layer); 505 506 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 507 // If we are a fixed layer, signal it to our siblings 508 if (layer->isFixed()) 509 compositingState.m_fixedSibling = true; 510 511 if (!willBeComposited && compositingState.m_fixedSibling) 512 layer->setMustOverlapCompositedLayers(true); 513 514 if (willBeComposited || compositingState.m_fixedSibling) { 515 #else 516 if (willBeComposited) { 517 #endif 518 // Tell the parent it has compositing descendants. 519 compositingState.m_subtreeIsCompositing = true; 520 // This layer now acts as the ancestor for kids. 521 childState.m_compositingAncestor = layer; 522 if (overlapMap) 523 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 524 } 525 526 #if ENABLE(VIDEO) 527 // Video is special. It's a replaced element with a content layer, but has shadow content 528 // for the controller that must render in front. Without this, the controls fail to show 529 // when the video element is a stacking context (e.g. due to opacity or transform). 530 if (willBeComposited && layer->renderer()->isVideo()) 531 childState.m_subtreeIsCompositing = true; 532 #endif 533 534 if (layer->isStackingContext()) { 535 ASSERT(!layer->m_zOrderListsDirty); 536 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 537 size_t listSize = negZOrderList->size(); 538 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 539 childState.m_fixedSibling = false; 540 541 // For the negative z-order, if we have a fixed layer 542 // we need to make all the siblings composited layers. 543 // Otherwise a negative layer (below the fixed layer) could 544 // still be drawn onto a higher z-order layer (e.g. the body) 545 // if not immediately intersecting with our fixed layer. 546 // So it's not enough here to only set m_fixedSibling for 547 // subsequent siblings as we do for the normal flow 548 // and positive z-order. 549 for (size_t j = 0; j < listSize; ++j) { 550 if ((negZOrderList->at(j))->isFixed()) { 551 childState.m_fixedSibling = true; 552 break; 553 } 554 } 555 #endif 556 557 for (size_t i = 0; i < listSize; ++i) { 558 RenderLayer* curLayer = negZOrderList->at(i); 559 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged); 560 561 // If we have to make a layer for this child, make one now so we can have a contents layer 562 // (since we need to ensure that the -ve z-order child renders underneath our contents). 563 if (!willBeComposited && childState.m_subtreeIsCompositing) { 564 // make layer compositing 565 layer->setMustOverlapCompositedLayers(true); 566 childState.m_compositingAncestor = layer; 567 if (overlapMap) 568 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 569 } 570 } 571 } 572 } 573 574 ASSERT(!layer->m_normalFlowListDirty); 575 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 576 size_t listSize = normalFlowList->size(); 577 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 578 childState.m_fixedSibling = false; 579 #endif 580 for (size_t i = 0; i < listSize; ++i) { 581 RenderLayer* curLayer = normalFlowList->at(i); 582 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged); 583 } 584 } 585 586 if (layer->isStackingContext()) { 587 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 588 size_t listSize = posZOrderList->size(); 589 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 590 childState.m_fixedSibling = false; 591 #endif 592 for (size_t i = 0; i < listSize; ++i) { 593 RenderLayer* curLayer = posZOrderList->at(i); 594 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged); 595 } 596 } 597 } 598 599 // If we have a software transform, and we have layers under us, we need to also 600 // be composited. Also, if we have opacity < 1, then we need to be a layer so that 601 // the child layers are opaque, then rendered with opacity on this layer. 602 if (!willBeComposited && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) { 603 layer->setMustOverlapCompositedLayers(true); 604 if (overlapMap) 605 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 606 } 607 608 if (layer->reflectionLayer()) 609 layer->reflectionLayer()->setMustOverlapCompositedLayers(needsToBeComposited(layer)); 610 611 // Subsequent layers in the parent stacking context also need to composite. 612 if (childState.m_subtreeIsCompositing) 613 compositingState.m_subtreeIsCompositing = true; 614 615 // If the layer is going into compositing mode, repaint its old location. 616 if (!layer->isComposited() && needsToBeComposited(layer)) 617 repaintOnCompositingChange(layer); 618 619 // Set the flag to say that this SC has compositing children. 620 // this can affect the answer to needsToBeComposited() when clipping, 621 // but that's ok here. 622 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing); 623 624 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree(). 625 if (updateBacking(layer, CompositingChangeRepaintNow)) 626 layersChanged = true; 627 628 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow)) 629 layersChanged = true; 630 } 631 632 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer) 633 { 634 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer); 635 ASSERT(childLayer->isComposited()); 636 637 // It's possible to be called with a parent that isn't yet composited when we're doing 638 // partial updates as required by painting or hit testing. Just bail in that case; 639 // we'll do a full layer update soon. 640 if (!parentLayer || !parentLayer->isComposited()) 641 return; 642 643 if (parentLayer) { 644 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers(); 645 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers(); 646 647 hostingLayer->addChild(hostedLayer); 648 } else 649 childLayer->backing()->childForSuperlayers()->removeFromParent(); 650 } 651 652 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer) 653 { 654 ASSERT(layer->isComposited()); 655 656 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers(); 657 hostingLayer->removeAllChildren(); 658 } 659 660 void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer) 661 { 662 ASSERT(layer->isComposited()); 663 664 GraphicsLayer* layerAnchor = layer->backing()->childForSuperlayers(); 665 666 if (layerAnchor->parent() != m_rootPlatformLayer) { 667 layerAnchor->removeFromParent(); 668 if (m_rootPlatformLayer) 669 m_rootPlatformLayer->addChild(layerAnchor); 670 } 671 } 672 673 #if ENABLE(VIDEO) 674 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const 675 { 676 if (!m_hasAcceleratedCompositing) 677 return false; 678 679 return o->supportsAcceleratedRendering(); 680 } 681 #endif 682 683 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer) 684 { 685 // Make the layer compositing if necessary, and set up clipping and content layers. 686 // Note that we can only do work here that is independent of whether the descendant layers 687 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary. 688 689 RenderLayerBacking* layerBacking = layer->backing(); 690 if (layerBacking) { 691 // The compositing state of all our children has been updated already, so now 692 // we can compute and cache the composited bounds for this layer. 693 layerBacking->updateCompositedBounds(); 694 695 if (RenderLayer* reflection = layer->reflectionLayer()) { 696 if (reflection->backing()) 697 reflection->backing()->updateCompositedBounds(); 698 } 699 700 layerBacking->updateGraphicsLayerConfiguration(); 701 layerBacking->updateGraphicsLayerGeometry(); 702 703 if (!layer->parent()) 704 updateRootLayerPosition(); 705 } 706 707 // If this layer has backing, then we are collecting its children, otherwise appending 708 // to the compositing child list of an enclosing layer. 709 Vector<GraphicsLayer*> layerChildren; 710 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer; 711 712 CompositingState childState = compositingState; 713 if (layer->isComposited()) 714 childState.m_compositingAncestor = layer; 715 716 #ifndef NDEBUG 717 ++childState.m_depth; 718 #endif 719 720 // The children of this stacking context don't need to composite, unless there is 721 // a compositing layer among them, so start by assuming false. 722 childState.m_subtreeIsCompositing = false; 723 724 if (layer->isStackingContext()) { 725 ASSERT(!layer->m_zOrderListsDirty); 726 727 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 728 size_t listSize = negZOrderList->size(); 729 for (size_t i = 0; i < listSize; ++i) { 730 RenderLayer* curLayer = negZOrderList->at(i); 731 rebuildCompositingLayerTree(curLayer, childState, childList); 732 } 733 } 734 735 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented. 736 if (layerBacking && layerBacking->foregroundLayer()) 737 childList.append(layerBacking->foregroundLayer()); 738 } 739 740 ASSERT(!layer->m_normalFlowListDirty); 741 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 742 size_t listSize = normalFlowList->size(); 743 for (size_t i = 0; i < listSize; ++i) { 744 RenderLayer* curLayer = normalFlowList->at(i); 745 rebuildCompositingLayerTree(curLayer, childState, childList); 746 } 747 } 748 749 if (layer->isStackingContext()) { 750 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 751 size_t listSize = posZOrderList->size(); 752 for (size_t i = 0; i < listSize; ++i) { 753 RenderLayer* curLayer = posZOrderList->at(i); 754 rebuildCompositingLayerTree(curLayer, childState, childList); 755 } 756 } 757 } 758 759 if (layerBacking) { 760 layerBacking->parentForSublayers()->setChildren(layerChildren); 761 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers()); 762 } 763 } 764 765 // This just updates layer geometry without changing the hierarchy. 766 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer) 767 { 768 if (RenderLayerBacking* layerBacking = layer->backing()) { 769 // The compositing state of all our children has been updated already, so now 770 // we can compute and cache the composited bounds for this layer. 771 layerBacking->updateCompositedBounds(); 772 773 if (RenderLayer* reflection = layer->reflectionLayer()) { 774 if (reflection->backing()) 775 reflection->backing()->updateCompositedBounds(); 776 } 777 778 layerBacking->updateGraphicsLayerConfiguration(); 779 layerBacking->updateGraphicsLayerGeometry(); 780 781 if (!layer->parent()) 782 updateRootLayerPosition(); 783 } 784 785 if (layer->isStackingContext()) { 786 ASSERT(!layer->m_zOrderListsDirty); 787 788 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 789 size_t listSize = negZOrderList->size(); 790 for (size_t i = 0; i < listSize; ++i) 791 updateLayerTreeGeometry(negZOrderList->at(i)); 792 } 793 } 794 795 ASSERT(!layer->m_normalFlowListDirty); 796 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 797 size_t listSize = normalFlowList->size(); 798 for (size_t i = 0; i < listSize; ++i) 799 updateLayerTreeGeometry(normalFlowList->at(i)); 800 } 801 802 if (layer->isStackingContext()) { 803 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 804 size_t listSize = posZOrderList->size(); 805 for (size_t i = 0; i < listSize; ++i) 806 updateLayerTreeGeometry(posZOrderList->at(i)); 807 } 808 } 809 } 810 811 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry. 812 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth) 813 { 814 if (layer != compositingAncestor) { 815 if (RenderLayerBacking* layerBacking = layer->backing()) { 816 layerBacking->updateCompositedBounds(); 817 818 if (RenderLayer* reflection = layer->reflectionLayer()) { 819 if (reflection->backing()) 820 reflection->backing()->updateCompositedBounds(); 821 } 822 823 layerBacking->updateGraphicsLayerGeometry(); 824 if (updateDepth == RenderLayerBacking::CompositingChildren) 825 return; 826 } 827 } 828 829 if (layer->reflectionLayer()) 830 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth); 831 832 if (!layer->hasCompositingDescendant()) 833 return; 834 835 if (layer->isStackingContext()) { 836 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 837 size_t listSize = negZOrderList->size(); 838 for (size_t i = 0; i < listSize; ++i) 839 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth); 840 } 841 } 842 843 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 844 size_t listSize = normalFlowList->size(); 845 for (size_t i = 0; i < listSize; ++i) 846 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth); 847 } 848 849 if (layer->isStackingContext()) { 850 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 851 size_t listSize = posZOrderList->size(); 852 for (size_t i = 0; i < listSize; ++i) 853 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth); 854 } 855 } 856 } 857 858 859 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect) 860 { 861 recursiveRepaintLayerRect(rootRenderLayer(), absRect); 862 } 863 864 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect) 865 { 866 // FIXME: This method does not work correctly with transforms. 867 if (layer->isComposited()) 868 layer->setBackingNeedsRepaintInRect(rect); 869 870 if (layer->hasCompositingDescendant()) { 871 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 872 size_t listSize = negZOrderList->size(); 873 for (size_t i = 0; i < listSize; ++i) { 874 RenderLayer* curLayer = negZOrderList->at(i); 875 int x = 0; 876 int y = 0; 877 curLayer->convertToLayerCoords(layer, x, y); 878 IntRect childRect(rect); 879 childRect.move(-x, -y); 880 recursiveRepaintLayerRect(curLayer, childRect); 881 } 882 } 883 884 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 885 size_t listSize = posZOrderList->size(); 886 for (size_t i = 0; i < listSize; ++i) { 887 RenderLayer* curLayer = posZOrderList->at(i); 888 int x = 0; 889 int y = 0; 890 curLayer->convertToLayerCoords(layer, x, y); 891 IntRect childRect(rect); 892 childRect.move(-x, -y); 893 recursiveRepaintLayerRect(curLayer, childRect); 894 } 895 } 896 } 897 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 898 size_t listSize = normalFlowList->size(); 899 for (size_t i = 0; i < listSize; ++i) { 900 RenderLayer* curLayer = normalFlowList->at(i); 901 int x = 0; 902 int y = 0; 903 curLayer->convertToLayerCoords(layer, x, y); 904 IntRect childRect(rect); 905 childRect.move(-x, -y); 906 recursiveRepaintLayerRect(curLayer, childRect); 907 } 908 } 909 } 910 911 RenderLayer* RenderLayerCompositor::rootRenderLayer() const 912 { 913 return m_renderView->layer(); 914 } 915 916 GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const 917 { 918 return m_rootPlatformLayer.get(); 919 } 920 921 void RenderLayerCompositor::didMoveOnscreen() 922 { 923 if (!m_rootPlatformLayer) 924 return; 925 926 Frame* frame = m_renderView->frameView()->frame(); 927 Page* page = frame ? frame->page() : 0; 928 if (!page) 929 return; 930 931 page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer.get()); 932 m_rootLayerAttached = true; 933 } 934 935 void RenderLayerCompositor::willMoveOffscreen() 936 { 937 if (!m_rootPlatformLayer || !m_rootLayerAttached) 938 return; 939 940 Frame* frame = m_renderView->frameView()->frame(); 941 Page* page = frame ? frame->page() : 0; 942 if (!page) 943 return; 944 945 page->chrome()->client()->attachRootGraphicsLayer(frame, 0); 946 m_rootLayerAttached = false; 947 } 948 949 void RenderLayerCompositor::updateRootLayerPosition() 950 { 951 if (m_rootPlatformLayer) 952 m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow())); 953 } 954 955 void RenderLayerCompositor::didStartAcceleratedAnimation() 956 { 957 // If an accelerated animation or transition runs, we have to turn off overlap checking because 958 // we don't do layout for every frame, but we have to ensure that the layering is 959 // correct between the animating object and other objects on the page. 960 setCompositingConsultsOverlap(false); 961 } 962 963 bool RenderLayerCompositor::has3DContent() const 964 { 965 return layerHas3DContent(rootRenderLayer()); 966 } 967 968 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const 969 { 970 if (!m_hasAcceleratedCompositing || !layer->isSelfPaintingLayer()) 971 return false; 972 973 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 974 // if an ancestor is fixed positioned, we need to be composited... 975 const RenderLayer* currLayer = layer; 976 while ((currLayer = currLayer->parent())) { 977 if (currLayer->isComposited() && currLayer->isFixed()) 978 return true; 979 } 980 #endif 981 982 return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers(); 983 } 984 985 #if PLATFORM(ANDROID) 986 bool RenderLayerCompositor::requiresCompositingForMobileSites(const RenderLayer* layer) const 987 { 988 // First, check if we are in an iframe, and if so bail out 989 if (m_renderView->document()->frame()->tree()->parent()) 990 return false; 991 992 RenderObject* renderer = layer->renderer(); 993 // Check for transforms 994 if (requiresCompositingForTransform(renderer)) 995 return true; 996 997 // Check for animations 998 if (requiresCompositingForAnimation(renderer)) 999 return true; 1000 1001 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) 1002 // For the moment, we want to only enable fixed composited layers on mobile websites. 1003 // We can consider a website as being a 'mobile' site if all the 1004 // following checks are true: 1005 // 1) - the viewport width is either undefined (-1) or equal to device-width (0), and 1006 // 2) - no scaling is allowed 1007 if (!layer->isFixed()) 1008 return false; 1009 1010 Settings* settings = m_renderView->document()->settings(); 1011 if (!settings) 1012 return false; 1013 1014 if ((settings->viewportWidth() == -1 || settings->viewportWidth() == 0) && 1015 !settings->viewportUserScalable()) 1016 return true; 1017 #endif 1018 1019 return false; 1020 } 1021 #endif 1022 1023 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons. 1024 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. 1025 // static 1026 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const 1027 { 1028 RenderObject* renderer = layer->renderer(); 1029 // The compositing state of a reflection should match that of its reflected layer. 1030 if (layer->isReflection()) { 1031 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected. 1032 layer = toRenderBoxModelObject(renderer)->layer(); 1033 } 1034 // The root layer always has a compositing layer, but it may not have backing. 1035 return (inCompositingMode() && layer->isRootLayer()) || 1036 #if PLATFORM(ANDROID) 1037 requiresCompositingForMobileSites(layer) || 1038 #else 1039 requiresCompositingForTransform(renderer) || 1040 requiresCompositingForVideo(renderer) || 1041 requiresCompositingForCanvas(renderer) || 1042 requiresCompositingForPlugin(renderer) || 1043 requiresCompositingForAnimation(renderer) || 1044 #endif 1045 renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden || 1046 clipsCompositingDescendants(layer); 1047 } 1048 1049 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips, 1050 // up to the enclosing compositing ancestor. This is required because compositing layers are parented 1051 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy. 1052 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy, 1053 // but a sibling in the z-order hierarchy. 1054 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const 1055 { 1056 if (!layer->isComposited() || !layer->parent()) 1057 return false; 1058 1059 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer(); 1060 if (!compositingAncestor) 1061 return false; 1062 1063 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(), 1064 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot), 1065 // and layer. 1066 RenderLayer* computeClipRoot = 0; 1067 RenderLayer* curr = layer; 1068 while (curr) { 1069 RenderLayer* next = curr->parent(); 1070 if (next == compositingAncestor) { 1071 computeClipRoot = curr; 1072 break; 1073 } 1074 curr = next; 1075 } 1076 1077 if (!computeClipRoot || computeClipRoot == layer) 1078 return false; 1079 1080 IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true); 1081 return backgroundRect != ClipRects::infiniteRect(); 1082 } 1083 1084 // Return true if the given layer is a stacking context and has compositing child 1085 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer 1086 // into the hierarchy between this layer and its children in the z-order hierarchy. 1087 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const 1088 { 1089 // FIXME: need to look at hasClip() too eventually 1090 return layer->hasCompositingDescendant() && 1091 layer->renderer()->hasOverflowClip(); 1092 } 1093 1094 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const 1095 { 1096 RenderStyle* style = renderer->style(); 1097 // Note that we ask the renderer if it has a transform, because the style may have transforms, 1098 // but the renderer may be an inline that doesn't suppport them. 1099 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective()); 1100 } 1101 1102 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const 1103 { 1104 #if ENABLE(VIDEO) 1105 if (renderer->isVideo()) { 1106 RenderVideo* video = toRenderVideo(renderer); 1107 return canAccelerateVideoRendering(video); 1108 } 1109 #else 1110 UNUSED_PARAM(renderer); 1111 #endif 1112 return false; 1113 } 1114 1115 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const 1116 { 1117 #if ENABLE(3D_CANVAS) 1118 if (renderer->isCanvas()) { 1119 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node()); 1120 return canvas->is3D(); 1121 } 1122 #else 1123 UNUSED_PARAM(renderer); 1124 #endif 1125 return false; 1126 } 1127 1128 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const 1129 { 1130 return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing(); 1131 } 1132 1133 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const 1134 { 1135 if (AnimationController* animController = renderer->animation()) { 1136 return (animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode()) 1137 || animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyWebkitTransform); 1138 } 1139 return false; 1140 } 1141 1142 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const 1143 { 1144 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection(); 1145 } 1146 1147 // If an element has negative z-index children, those children render in front of the 1148 // layer background, so we need an extra 'contents' layer for the foreground of the layer 1149 // object. 1150 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const 1151 { 1152 return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0); 1153 } 1154 1155 void RenderLayerCompositor::ensureRootPlatformLayer() 1156 { 1157 if (m_rootPlatformLayer) 1158 return; 1159 1160 m_rootPlatformLayer = GraphicsLayer::create(0); 1161 m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow())); 1162 m_rootPlatformLayer->setPosition(FloatPoint(0, 0)); 1163 // The root layer does flipping if we need it on this platform. 1164 m_rootPlatformLayer->setGeometryOrientation(GraphicsLayer::compositingCoordinatesOrientation()); 1165 1166 // Need to clip to prevent transformed content showing outside this frame 1167 m_rootPlatformLayer->setMasksToBounds(true); 1168 1169 didMoveOnscreen(); 1170 } 1171 1172 void RenderLayerCompositor::destroyRootPlatformLayer() 1173 { 1174 if (!m_rootPlatformLayer) 1175 return; 1176 1177 willMoveOffscreen(); 1178 m_rootPlatformLayer = 0; 1179 } 1180 1181 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const 1182 { 1183 const RenderStyle* style = layer->renderer()->style(); 1184 1185 if (style && 1186 (style->transformStyle3D() == TransformStyle3DPreserve3D || 1187 style->hasPerspective() || 1188 style->transform().has3DOperation())) 1189 return true; 1190 1191 if (layer->isStackingContext()) { 1192 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 1193 size_t listSize = negZOrderList->size(); 1194 for (size_t i = 0; i < listSize; ++i) { 1195 RenderLayer* curLayer = negZOrderList->at(i); 1196 if (layerHas3DContent(curLayer)) 1197 return true; 1198 } 1199 } 1200 1201 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 1202 size_t listSize = posZOrderList->size(); 1203 for (size_t i = 0; i < listSize; ++i) { 1204 RenderLayer* curLayer = posZOrderList->at(i); 1205 if (layerHas3DContent(curLayer)) 1206 return true; 1207 } 1208 } 1209 } 1210 1211 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 1212 size_t listSize = normalFlowList->size(); 1213 for (size_t i = 0; i < listSize; ++i) { 1214 RenderLayer* curLayer = normalFlowList->at(i); 1215 if (layerHas3DContent(curLayer)) 1216 return true; 1217 } 1218 } 1219 return false; 1220 } 1221 1222 } // namespace WebCore 1223 1224 #endif // USE(ACCELERATED_COMPOSITING) 1225