1 /* 2 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 28 #include "core/rendering/RenderLayerBacking.h" 29 30 #include "CSSPropertyNames.h" 31 #include "HTMLNames.h" 32 #include "RuntimeEnabledFeatures.h" 33 #include "core/html/HTMLIFrameElement.h" 34 #include "core/html/HTMLMediaElement.h" 35 #include "core/html/canvas/CanvasRenderingContext.h" 36 #include "core/inspector/InspectorInstrumentation.h" 37 #include "core/loader/cache/ImageResource.h" 38 #include "core/page/Chrome.h" 39 #include "core/page/FrameView.h" 40 #include "core/page/Settings.h" 41 #include "core/page/animation/AnimationController.h" 42 #include "core/page/scrolling/ScrollingCoordinator.h" 43 #include "core/platform/graphics/FontCache.h" 44 #include "core/platform/graphics/GraphicsContext.h" 45 #include "core/platform/graphics/GraphicsLayer.h" 46 #include "core/plugins/PluginView.h" 47 #include "core/rendering/RenderApplet.h" 48 #include "core/rendering/RenderEmbeddedObject.h" 49 #include "core/rendering/RenderIFrame.h" 50 #include "core/rendering/RenderImage.h" 51 #include "core/rendering/RenderLayer.h" 52 #include "core/rendering/RenderLayerCompositor.h" 53 #include "core/rendering/RenderVideo.h" 54 #include "core/rendering/RenderView.h" 55 #include "core/rendering/style/KeyframeList.h" 56 #include "wtf/CurrentTime.h" 57 #include "wtf/text/StringBuilder.h" 58 59 #include "core/platform/graphics/filters/custom/CustomFilterOperation.h" 60 #include "core/rendering/FilterEffectRenderer.h" 61 62 #include "core/platform/graphics/GraphicsContext3D.h" 63 64 using namespace std; 65 66 namespace WebCore { 67 68 using namespace HTMLNames; 69 70 static IntRect clipBox(RenderBox* renderer); 71 72 static IntRect contentsRect(const RenderObject* renderer) 73 { 74 if (!renderer->isBox()) 75 return IntRect(); 76 77 return renderer->isVideo() ? 78 toRenderVideo(renderer)->videoBox() : 79 pixelSnappedIntRect(toRenderBox(renderer)->contentBoxRect()); 80 } 81 82 static IntRect backgroundRect(const RenderObject* renderer) 83 { 84 if (!renderer->isBox()) 85 return IntRect(); 86 87 LayoutRect rect; 88 const RenderBox* box = toRenderBox(renderer); 89 EFillBox clip = box->style()->backgroundClip(); 90 switch (clip) { 91 case BorderFillBox: 92 rect = box->borderBoxRect(); 93 break; 94 case PaddingFillBox: 95 rect = box->paddingBoxRect(); 96 break; 97 case ContentFillBox: 98 rect = box->contentBoxRect(); 99 break; 100 case TextFillBox: 101 break; 102 } 103 104 return pixelSnappedIntRect(rect); 105 } 106 107 static inline bool isAcceleratedCanvas(const RenderObject* renderer) 108 { 109 if (renderer->isCanvas()) { 110 HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node()); 111 if (CanvasRenderingContext* context = canvas->renderingContext()) 112 return context->isAccelerated(); 113 } 114 return false; 115 } 116 117 static bool hasBoxDecorations(const RenderStyle* style) 118 { 119 return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter(); 120 } 121 122 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style) 123 { 124 return hasBoxDecorations(style) || style->hasBackgroundImage(); 125 } 126 127 static bool contentLayerSupportsDirectBackgroundComposition(const RenderObject* renderer) 128 { 129 // No support for decorations - border, border-radius or outline. 130 // Only simple background - solid color or transparent. 131 if (hasBoxDecorationsOrBackgroundImage(renderer->style())) 132 return false; 133 134 // If there is no background, there is nothing to support. 135 if (!renderer->style()->hasBackground()) 136 return true; 137 138 // Simple background that is contained within the contents rect. 139 return contentsRect(renderer).contains(backgroundRect(renderer)); 140 } 141 142 // Get the scrolling coordinator in a way that works inside RenderLayerBacking's destructor. 143 static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer* layer) 144 { 145 Page* page = layer->renderer()->frame()->page(); 146 if (!page) 147 return 0; 148 149 return page->scrollingCoordinator(); 150 } 151 152 RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) 153 : m_owningLayer(layer) 154 , m_artificiallyInflatedBounds(false) 155 , m_boundsConstrainedByClipping(false) 156 , m_isMainFrameRenderViewLayer(false) 157 , m_requiresOwnBackingStore(true) 158 , m_canCompositeFilters(false) 159 , m_backgroundLayerPaintsFixedRootBackground(false) 160 { 161 if (layer->isRootLayer()) { 162 Frame* frame = toRenderView(renderer())->frameView()->frame(); 163 Page* page = frame ? frame->page() : 0; 164 if (page && frame && page->mainFrame() == frame) { 165 m_isMainFrameRenderViewLayer = true; 166 } 167 } 168 169 createPrimaryGraphicsLayer(); 170 } 171 172 RenderLayerBacking::~RenderLayerBacking() 173 { 174 updateClippingLayers(false, false); 175 updateOverflowControlsLayers(false, false, false); 176 updateForegroundLayer(false); 177 updateBackgroundLayer(false); 178 updateMaskLayer(false); 179 updateScrollingLayers(false); 180 destroyGraphicsLayers(); 181 } 182 183 PassOwnPtr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name, CompositingReasons reasons) 184 { 185 GraphicsLayerFactory* graphicsLayerFactory = 0; 186 if (Page* page = renderer()->frame()->page()) 187 graphicsLayerFactory = page->chrome().client()->graphicsLayerFactory(); 188 189 OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this); 190 191 #ifndef NDEBUG 192 graphicsLayer->setName(name); 193 #else 194 UNUSED_PARAM(name); 195 #endif 196 197 graphicsLayer->setCompositingReasons(reasons); 198 199 return graphicsLayer.release(); 200 } 201 202 void RenderLayerBacking::createPrimaryGraphicsLayer() 203 { 204 String layerName; 205 #ifndef NDEBUG 206 layerName = m_owningLayer->debugName(); 207 #endif 208 209 m_graphicsLayer = createGraphicsLayer(layerName, m_owningLayer->compositingReasons()); 210 211 #if !OS(ANDROID) 212 if (m_isMainFrameRenderViewLayer) 213 m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true); 214 #endif 215 216 updateOpacity(renderer()->style()); 217 updateTransform(renderer()->style()); 218 updateFilters(renderer()->style()); 219 220 if (RuntimeEnabledFeatures::cssCompositingEnabled()) 221 updateLayerBlendMode(renderer()->style()); 222 } 223 224 void RenderLayerBacking::destroyGraphicsLayers() 225 { 226 if (m_graphicsLayer) 227 m_graphicsLayer->removeFromParent(); 228 229 m_ancestorClippingLayer = nullptr; 230 m_graphicsLayer = nullptr; 231 m_foregroundLayer = nullptr; 232 m_backgroundLayer = nullptr; 233 m_childContainmentLayer = nullptr; 234 m_maskLayer = nullptr; 235 236 m_scrollingLayer = nullptr; 237 m_scrollingContentsLayer = nullptr; 238 } 239 240 void RenderLayerBacking::updateOpacity(const RenderStyle* style) 241 { 242 m_graphicsLayer->setOpacity(compositingOpacity(style->opacity())); 243 } 244 245 void RenderLayerBacking::updateTransform(const RenderStyle* style) 246 { 247 // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin 248 // baked into it, and we don't want that. 249 TransformationMatrix t; 250 if (m_owningLayer->hasTransform()) { 251 style->applyTransform(t, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin); 252 makeMatrixRenderable(t, compositor()->canRender3DTransforms()); 253 } 254 255 m_graphicsLayer->setTransform(t); 256 } 257 258 void RenderLayerBacking::updateFilters(const RenderStyle* style) 259 { 260 bool didCompositeFilters = m_canCompositeFilters; 261 m_canCompositeFilters = m_graphicsLayer->setFilters(owningLayer()->computeFilterOperations(style)); 262 if (didCompositeFilters != m_canCompositeFilters) { 263 // 264 // If filters used to be painted in software and are now painted in the compositor, we need to: 265 // (1) Remove the FilterEffectRenderer, which was used for painting filters in software. 266 // (2) Repaint the layer contents to remove the software-applied filter because the compositor will apply it. 267 // 268 // Similarly, if filters used to be painted in the compositor and are now painted in software, we need to: 269 // (1) Create a FilterEffectRenderer. 270 // (2) Repaint the layer contents to apply a software filter because the compositor won't apply it. 271 // 272 m_owningLayer->updateOrRemoveFilterEffectRenderer(); 273 setContentsNeedDisplay(); 274 } 275 } 276 277 void RenderLayerBacking::updateLayerBlendMode(const RenderStyle*) 278 { 279 } 280 281 void RenderLayerBacking::updateContentsOpaque() 282 { 283 // For non-root layers, background is always painted by the primary graphics layer. 284 ASSERT(m_isMainFrameRenderViewLayer || !m_backgroundLayer); 285 if (m_backgroundLayer) { 286 m_graphicsLayer->setContentsOpaque(false); 287 m_backgroundLayer->setContentsOpaque(m_owningLayer->backgroundIsKnownToBeOpaqueInRect(compositedBounds())); 288 } else { 289 m_graphicsLayer->setContentsOpaque(m_owningLayer->backgroundIsKnownToBeOpaqueInRect(compositedBounds())); 290 } 291 } 292 293 static bool hasNonZeroTransformOrigin(const RenderObject* renderer) 294 { 295 RenderStyle* style = renderer->style(); 296 return (style->transformOriginX().type() == Fixed && style->transformOriginX().value()) 297 || (style->transformOriginY().type() == Fixed && style->transformOriginY().value()); 298 } 299 300 static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer* layer) 301 { 302 for (RenderLayer* curr = layer; curr; curr = curr->parent()) { 303 if (curr->hasTransform() || curr->needsCompositedScrolling()) 304 return true; 305 } 306 307 return false; 308 } 309 310 bool RenderLayerBacking::shouldClipCompositedBounds() const 311 { 312 // Scrollbar layers use this layer for relative positioning, so don't clip. 313 if (layerForHorizontalScrollbar() || layerForVerticalScrollbar()) 314 return false; 315 316 if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer)) 317 return false; 318 319 return true; 320 } 321 322 void RenderLayerBacking::updateCompositedBounds() 323 { 324 IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); 325 326 // Clip to the size of the document or enclosing overflow-scroll layer. 327 // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with. 328 // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist. 329 if (shouldClipCompositedBounds()) { 330 RenderView* view = m_owningLayer->renderer()->view(); 331 RenderLayer* rootLayer = view->layer(); 332 333 LayoutRect clippingBounds; 334 if (renderer()->style()->position() == FixedPosition && renderer()->container() == view) 335 clippingBounds = view->frameView()->viewportConstrainedVisibleContentRect(); 336 else 337 clippingBounds = view->unscaledDocumentRect(); 338 339 if (m_owningLayer != rootLayer) 340 clippingBounds.intersect(m_owningLayer->backgroundClipRect(RenderLayer::ClipRectsContext(rootLayer, 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions. 341 342 LayoutPoint delta; 343 m_owningLayer->convertToLayerCoords(rootLayer, delta); 344 clippingBounds.move(-delta.x(), -delta.y()); 345 346 layerBounds.intersect(pixelSnappedIntRect(clippingBounds)); 347 m_boundsConstrainedByClipping = true; 348 } else 349 m_boundsConstrainedByClipping = false; 350 351 // If the element has a transform-origin that has fixed lengths, and the renderer has zero size, 352 // then we need to ensure that the compositing layer has non-zero size so that we can apply 353 // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value). 354 if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) { 355 layerBounds.setWidth(1); 356 layerBounds.setHeight(1); 357 m_artificiallyInflatedBounds = true; 358 } else 359 m_artificiallyInflatedBounds = false; 360 361 setCompositedBounds(layerBounds); 362 } 363 364 void RenderLayerBacking::updateAfterWidgetResize() 365 { 366 if (renderer()->isRenderPart()) { 367 if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) { 368 innerCompositor->frameViewDidChangeSize(); 369 innerCompositor->frameViewDidChangeLocation(contentsBox().location()); 370 } 371 } 372 } 373 374 void RenderLayerBacking::updateCompositingReasons() 375 { 376 // All other layers owned by this backing will have the same compositing reason 377 // for their lifetime, so they are initialized only when created. 378 m_graphicsLayer->setCompositingReasons(m_owningLayer->compositingReasons()); 379 } 380 381 void RenderLayerBacking::updateAfterLayout(UpdateAfterLayoutFlags flags) 382 { 383 RenderLayerCompositor* layerCompositor = compositor(); 384 if (!layerCompositor->compositingLayersNeedRebuild()) { 385 // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the 386 // position of this layer's GraphicsLayer depends on the position of our compositing 387 // ancestor's GraphicsLayer. That cannot be determined until all the descendant 388 // RenderLayers of that ancestor have been processed via updateLayerPositions(). 389 // 390 // The solution is to update compositing children of this layer here, 391 // via updateCompositingChildrenGeometry(). 392 updateCompositedBounds(); 393 layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, flags & CompositingChildrenOnly); 394 395 if (flags & IsUpdateRoot) { 396 updateGraphicsLayerGeometry(); 397 layerCompositor->updateRootLayerPosition(); 398 RenderLayer* stackingContainer = m_owningLayer->enclosingStackingContainer(); 399 if (!layerCompositor->compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != m_owningLayer)) 400 layerCompositor->updateCompositingDescendantGeometry(stackingContainer, stackingContainer, flags & CompositingChildrenOnly); 401 } 402 } 403 404 if (flags & NeedsFullRepaint && !paintsIntoCompositedAncestor()) 405 setContentsNeedDisplay(); 406 } 407 408 bool RenderLayerBacking::updateGraphicsLayerConfiguration() 409 { 410 RenderLayerCompositor* compositor = this->compositor(); 411 RenderObject* renderer = this->renderer(); 412 413 m_owningLayer->updateDescendantDependentFlags(); 414 m_owningLayer->updateZOrderLists(); 415 416 bool layerConfigChanged = false; 417 setBackgroundLayerPaintsFixedRootBackground(compositor->needsFixedRootBackgroundLayer(m_owningLayer)); 418 419 // The background layer is currently only used for fixed root backgrounds. 420 if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground)) 421 layerConfigChanged = true; 422 423 if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer))) 424 layerConfigChanged = true; 425 426 bool needsDescendentsClippingLayer = compositor->clipsCompositingDescendants(m_owningLayer); 427 428 // Our scrolling layer will clip. 429 if (m_owningLayer->needsCompositedScrolling()) 430 needsDescendentsClippingLayer = false; 431 432 if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), needsDescendentsClippingLayer)) 433 layerConfigChanged = true; 434 435 if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer())) 436 layerConfigChanged = true; 437 438 if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling())) 439 layerConfigChanged = true; 440 441 if (layerConfigChanged) 442 updateInternalHierarchy(); 443 444 if (updateMaskLayer(renderer->hasMask())) 445 m_graphicsLayer->setMaskLayer(m_maskLayer.get()); 446 447 if (m_owningLayer->hasReflection()) { 448 if (m_owningLayer->reflectionLayer()->backing()) { 449 GraphicsLayer* reflectionLayer = m_owningLayer->reflectionLayer()->backing()->graphicsLayer(); 450 m_graphicsLayer->setReplicatedByLayer(reflectionLayer); 451 } 452 } else 453 m_graphicsLayer->setReplicatedByLayer(0); 454 455 updateBackgroundColor(isSimpleContainerCompositingLayer()); 456 457 if (isDirectlyCompositedImage()) 458 updateImageContents(); 459 460 if (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) { 461 PluginView* pluginView = toPluginView(toRenderWidget(renderer)->widget()); 462 m_graphicsLayer->setContentsToMedia(pluginView->platformLayer()); 463 } else if (renderer->isVideo()) { 464 HTMLMediaElement* mediaElement = toMediaElement(renderer->node()); 465 m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer()); 466 } else if (isAcceleratedCanvas(renderer)) { 467 HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node()); 468 if (CanvasRenderingContext* context = canvas->renderingContext()) 469 m_graphicsLayer->setContentsToCanvas(context->platformLayer()); 470 layerConfigChanged = true; 471 } 472 if (renderer->isRenderPart()) 473 layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer)); 474 475 return layerConfigChanged; 476 } 477 478 static IntRect clipBox(RenderBox* renderer) 479 { 480 LayoutRect result = PaintInfo::infiniteRect(); 481 if (renderer->hasOverflowClip()) 482 result = renderer->overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions. 483 484 if (renderer->hasClip()) 485 result.intersect(renderer->clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions. 486 487 return pixelSnappedIntRect(result); 488 } 489 490 void RenderLayerBacking::updateGraphicsLayerGeometry() 491 { 492 // If we haven't built z-order lists yet, wait until later. 493 if (m_owningLayer->isStackingContainer() && m_owningLayer->m_zOrderListsDirty) 494 return; 495 496 // Set transform property, if it is not animating. We have to do this here because the transform 497 // is affected by the layer dimensions. 498 if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitTransform)) 499 updateTransform(renderer()->style()); 500 501 // Set opacity, if it is not animating. 502 if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity)) 503 updateOpacity(renderer()->style()); 504 505 if (RuntimeEnabledFeatures::cssCompositingEnabled()) 506 updateLayerBlendMode(renderer()->style()); 507 508 bool isSimpleContainer = isSimpleContainerCompositingLayer(); 509 510 m_owningLayer->updateDescendantDependentFlags(); 511 512 // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing 513 // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any 514 // non-compositing visible layers. 515 m_graphicsLayer->setContentsVisible(m_owningLayer->hasVisibleContent() || hasVisibleNonCompositingDescendantLayers()); 516 517 RenderStyle* style = renderer()->style(); 518 // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959 519 bool preserves3D = style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection(); 520 m_graphicsLayer->setPreserves3D(preserves3D); 521 m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible); 522 523 RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer(); 524 525 // We compute everything relative to the enclosing compositing layer. 526 IntRect ancestorCompositingBounds; 527 if (compAncestor) { 528 ASSERT(compAncestor->backing()); 529 ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->backing()->compositedBounds()); 530 } 531 532 IntRect localCompositingBounds = pixelSnappedIntRect(compositedBounds()); 533 534 IntRect relativeCompositingBounds(localCompositingBounds); 535 IntPoint delta; 536 m_owningLayer->convertToPixelSnappedLayerCoords(compAncestor, delta); 537 relativeCompositingBounds.moveBy(delta); 538 539 IntPoint graphicsLayerParentLocation; 540 if (compAncestor && compAncestor->backing()->hasClippingLayer()) { 541 // If the compositing ancestor has a layer to clip children, we parent in that, and therefore 542 // position relative to it. 543 IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer())); 544 graphicsLayerParentLocation = clippingBox.location(); 545 } else if (compAncestor) 546 graphicsLayerParentLocation = ancestorCompositingBounds.location(); 547 else 548 graphicsLayerParentLocation = renderer()->view()->documentRect().location(); 549 550 if (compAncestor && compAncestor->needsCompositedScrolling()) { 551 RenderBox* renderBox = toRenderBox(compAncestor->renderer()); 552 IntSize scrollOffset = compAncestor->scrolledContentOffset(); 553 IntPoint scrollOrigin(renderBox->borderLeft(), renderBox->borderTop()); 554 graphicsLayerParentLocation = scrollOrigin - scrollOffset; 555 } 556 557 if (compAncestor && m_ancestorClippingLayer) { 558 // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this 559 // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects 560 // for a compositing layer, rootLayer is the layer itself. 561 RenderLayer::ClipRectsContext clipRectsContext(compAncestor, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip); 562 IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(clipRectsContext).rect()); // FIXME: Incorrect for CSS regions. 563 ASSERT(parentClipRect != PaintInfo::infiniteRect()); 564 m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation)); 565 m_ancestorClippingLayer->setSize(parentClipRect.size()); 566 567 // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords. 568 m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta); 569 570 // The primary layer is then parented in, and positioned relative to this clipping layer. 571 graphicsLayerParentLocation = parentClipRect.location(); 572 } 573 574 FloatSize contentsSize = relativeCompositingBounds.size(); 575 576 m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation)); 577 m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location())); 578 579 FloatSize oldSize = m_graphicsLayer->size(); 580 if (oldSize != contentsSize) { 581 m_graphicsLayer->setSize(contentsSize); 582 // Usually invalidation will happen via layout etc, but if we've affected the layer 583 // size by constraining relative to a clipping ancestor or the viewport, we 584 // have to invalidate to avoid showing stretched content. 585 if (m_boundsConstrainedByClipping) 586 m_graphicsLayer->setNeedsDisplay(); 587 } 588 589 // If we have a layer that clips children, position it. 590 IntRect clippingBox; 591 if (GraphicsLayer* clipLayer = clippingLayer()) { 592 clippingBox = clipBox(toRenderBox(renderer())); 593 clipLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location())); 594 clipLayer->setSize(clippingBox.size()); 595 clipLayer->setOffsetFromRenderer(toIntSize(clippingBox.location())); 596 } 597 598 if (m_maskLayer) { 599 if (m_maskLayer->size() != m_graphicsLayer->size()) { 600 m_maskLayer->setSize(m_graphicsLayer->size()); 601 m_maskLayer->setNeedsDisplay(); 602 } 603 m_maskLayer->setPosition(FloatPoint()); 604 m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer()); 605 } 606 607 if (m_owningLayer->hasTransform()) { 608 const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect(); 609 610 // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds. 611 IntRect layerBounds = IntRect(delta, borderBox.size()); 612 613 // Update properties that depend on layer dimensions 614 FloatPoint3D transformOrigin = computeTransformOrigin(borderBox); 615 // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set. 616 FloatPoint3D anchor(relativeCompositingBounds.width() != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width() : 0.5f, 617 relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f, 618 transformOrigin.z()); 619 m_graphicsLayer->setAnchorPoint(anchor); 620 621 RenderStyle* style = renderer()->style(); 622 GraphicsLayer* clipLayer = clippingLayer(); 623 if (style->hasPerspective()) { 624 TransformationMatrix t = owningLayer()->perspectiveTransform(); 625 626 if (clipLayer) { 627 clipLayer->setChildrenTransform(t); 628 m_graphicsLayer->setChildrenTransform(TransformationMatrix()); 629 } 630 else 631 m_graphicsLayer->setChildrenTransform(t); 632 } else { 633 if (clipLayer) 634 clipLayer->setChildrenTransform(TransformationMatrix()); 635 else 636 m_graphicsLayer->setChildrenTransform(TransformationMatrix()); 637 } 638 } else { 639 m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0)); 640 } 641 642 if (m_foregroundLayer) { 643 FloatPoint foregroundPosition; 644 FloatSize foregroundSize = contentsSize; 645 IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer(); 646 if (hasClippingLayer()) { 647 // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it, 648 // so that it gets correctly sorted with children. In that case, position relative to the clipping layer. 649 foregroundSize = FloatSize(clippingBox.size()); 650 foregroundOffset = toIntSize(clippingBox.location()); 651 } 652 653 m_foregroundLayer->setPosition(foregroundPosition); 654 if (foregroundSize != m_foregroundLayer->size()) { 655 m_foregroundLayer->setSize(foregroundSize); 656 m_foregroundLayer->setNeedsDisplay(); 657 } 658 m_foregroundLayer->setOffsetFromRenderer(foregroundOffset); 659 } 660 661 if (m_backgroundLayer) { 662 FloatPoint backgroundPosition; 663 FloatSize backgroundSize = contentsSize; 664 if (backgroundLayerPaintsFixedRootBackground()) { 665 FrameView* frameView = toRenderView(renderer())->frameView(); 666 backgroundSize = frameView->visibleContentRect().size(); 667 } 668 m_backgroundLayer->setPosition(backgroundPosition); 669 if (backgroundSize != m_backgroundLayer->size()) { 670 m_backgroundLayer->setSize(backgroundSize); 671 m_backgroundLayer->setNeedsDisplay(); 672 } 673 m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer()); 674 } 675 676 if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) { 677 RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing(); 678 reflectionBacking->updateGraphicsLayerGeometry(); 679 680 // The reflection layer has the bounds of m_owningLayer->reflectionLayer(), 681 // but the reflected layer is the bounds of this layer, so we need to position it appropriately. 682 FloatRect layerBounds = compositedBounds(); 683 FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds(); 684 reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location())); 685 } 686 687 if (m_scrollingLayer) { 688 ASSERT(m_scrollingContentsLayer); 689 RenderBox* renderBox = toRenderBox(renderer()); 690 IntRect clientBox = enclosingIntRect(renderBox->clientBoxRect()); 691 // FIXME: We should make RenderBox::clientBoxRect consider scrollbar placement. 692 if (style->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) 693 clientBox.move(renderBox->verticalScrollbarWidth(), 0); 694 695 IntSize adjustedScrollOffset = m_owningLayer->adjustedScrollOffset(); 696 m_scrollingLayer->setPosition(FloatPoint(clientBox.location() - localCompositingBounds.location())); 697 m_scrollingLayer->setSize(clientBox.size()); 698 699 IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer(); 700 m_scrollingLayer->setOffsetFromRenderer(-toIntSize(clientBox.location())); 701 702 bool clientBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer(); 703 704 IntSize scrollSize(m_owningLayer->scrollWidth(), m_owningLayer->scrollHeight()); 705 if (scrollSize != m_scrollingContentsLayer->size() || clientBoxOffsetChanged) 706 m_scrollingContentsLayer->setNeedsDisplay(); 707 708 IntSize scrollingContentsOffset = toIntSize(clientBox.location() - adjustedScrollOffset); 709 if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size()) { 710 bool scrollingCoordinatorHandlesOffset = compositor()->scrollingLayerDidChange(m_owningLayer); 711 712 if (scrollingCoordinatorHandlesOffset) 713 m_scrollingContentsLayer->setPosition(-m_owningLayer->scrollOrigin()); 714 else 715 m_scrollingContentsLayer->setPosition(FloatPoint(-adjustedScrollOffset)); 716 } 717 718 m_scrollingContentsLayer->setSize(scrollSize); 719 // FIXME: The paint offset and the scroll offset should really be separate concepts. 720 m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay); 721 722 if (m_foregroundLayer) { 723 if (m_foregroundLayer->size() != m_scrollingContentsLayer->size()) 724 m_foregroundLayer->setSize(m_scrollingContentsLayer->size()); 725 m_foregroundLayer->setNeedsDisplay(); 726 m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer()); 727 } 728 } 729 730 // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store. 731 setRequiresOwnBackingStore(compositor()->requiresOwnBackingStore(m_owningLayer, compAncestor)); 732 733 updateContentsRect(isSimpleContainer); 734 updateBackgroundColor(isSimpleContainer); 735 updateDrawsContent(isSimpleContainer); 736 updateContentsOpaque(); 737 updateAfterWidgetResize(); 738 registerScrollingLayers(); 739 740 updateCompositingReasons(); 741 } 742 743 void RenderLayerBacking::registerScrollingLayers() 744 { 745 // Register fixed position layers and their containers with the scrolling coordinator. 746 ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer); 747 if (!scrollingCoordinator) 748 return; 749 750 compositor()->updateViewportConstraintStatus(m_owningLayer); 751 752 scrollingCoordinator->updateLayerPositionConstraint(m_owningLayer); 753 754 // Page scale is applied as a transform on the root render view layer. Because the scroll 755 // layer is further up in the hierarchy, we need to avoid marking the root render view 756 // layer as a container. 757 bool isContainer = m_owningLayer->hasTransform() && !m_owningLayer->isRootLayer(); 758 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer); 759 } 760 761 void RenderLayerBacking::updateInternalHierarchy() 762 { 763 // m_foregroundLayer has to be inserted in the correct order with child layers, 764 // so it's not inserted here. 765 if (m_ancestorClippingLayer) 766 m_ancestorClippingLayer->removeAllChildren(); 767 768 m_graphicsLayer->removeFromParent(); 769 770 if (m_ancestorClippingLayer) 771 m_ancestorClippingLayer->addChild(m_graphicsLayer.get()); 772 773 if (m_childContainmentLayer) { 774 m_childContainmentLayer->removeFromParent(); 775 m_graphicsLayer->addChild(m_childContainmentLayer.get()); 776 } 777 778 if (m_scrollingLayer) { 779 GraphicsLayer* superlayer = m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get(); 780 m_scrollingLayer->removeFromParent(); 781 superlayer->addChild(m_scrollingLayer.get()); 782 } 783 784 // The clip for child layers does not include space for overflow controls, so they exist as 785 // siblings of the clipping layer if we have one. Normal children of this layer are set as 786 // children of the clipping layer. 787 if (m_layerForHorizontalScrollbar) { 788 m_layerForHorizontalScrollbar->removeFromParent(); 789 m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get()); 790 } 791 if (m_layerForVerticalScrollbar) { 792 m_layerForVerticalScrollbar->removeFromParent(); 793 m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get()); 794 } 795 if (m_layerForScrollCorner) { 796 m_layerForScrollCorner->removeFromParent(); 797 m_graphicsLayer->addChild(m_layerForScrollCorner.get()); 798 } 799 } 800 801 void RenderLayerBacking::updateContentsRect(bool isSimpleContainer) 802 { 803 IntRect contentsRect; 804 if (isSimpleContainer && renderer()->hasBackground()) 805 contentsRect = backgroundBox(); 806 else 807 contentsRect = contentsBox(); 808 809 m_graphicsLayer->setContentsRect(contentsRect); 810 } 811 812 void RenderLayerBacking::updateDrawsContent(bool isSimpleContainer) 813 { 814 if (m_scrollingLayer) { 815 // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere. 816 // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint. 817 // m_scrollingLayer never has backing store. 818 // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint. 819 bool hasNonScrollingPaintedContent = m_owningLayer->hasVisibleContent() && m_owningLayer->hasBoxDecorationsOrBackground(); 820 m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent); 821 822 bool hasScrollingPaintedContent = m_owningLayer->hasVisibleContent() && (renderer()->hasBackground() || paintsChildren()); 823 m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent); 824 return; 825 } 826 827 bool hasPaintedContent = containsPaintedContent(isSimpleContainer); 828 if (hasPaintedContent && isAcceleratedCanvas(renderer())) { 829 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node()); 830 CanvasRenderingContext* context = canvas->renderingContext(); 831 // Content layer may be null if context is lost. 832 if (WebKit::WebLayer* contentLayer = context->platformLayer()) { 833 Color bgColor; 834 if (contentLayerSupportsDirectBackgroundComposition(renderer())) { 835 bgColor = rendererBackgroundColor(); 836 hasPaintedContent = false; 837 } 838 contentLayer->setBackgroundColor(bgColor.rgb()); 839 } 840 } 841 842 // FIXME: we could refine this to only allocate backing for one of these layers if possible. 843 m_graphicsLayer->setDrawsContent(hasPaintedContent); 844 if (m_foregroundLayer) 845 m_foregroundLayer->setDrawsContent(hasPaintedContent); 846 847 if (m_backgroundLayer) 848 m_backgroundLayer->setDrawsContent(hasPaintedContent); 849 } 850 851 // Return true if the layers changed. 852 bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip) 853 { 854 bool layersChanged = false; 855 856 if (needsAncestorClip) { 857 if (!m_ancestorClippingLayer) { 858 m_ancestorClippingLayer = createGraphicsLayer("Ancestor clipping Layer", CompositingReasonLayerForClip); 859 m_ancestorClippingLayer->setMasksToBounds(true); 860 layersChanged = true; 861 } 862 } else if (m_ancestorClippingLayer) { 863 m_ancestorClippingLayer->removeFromParent(); 864 m_ancestorClippingLayer = nullptr; 865 layersChanged = true; 866 } 867 868 if (needsDescendantClip) { 869 // We don't need a child containment layer if we're the main frame render view 870 // layer. It's redundant as the frame clip above us will handle this clipping. 871 if (!m_childContainmentLayer && !m_isMainFrameRenderViewLayer) { 872 m_childContainmentLayer = createGraphicsLayer("Child clipping Layer", CompositingReasonLayerForClip); 873 m_childContainmentLayer->setMasksToBounds(true); 874 layersChanged = true; 875 } 876 } else if (hasClippingLayer()) { 877 m_childContainmentLayer->removeFromParent(); 878 m_childContainmentLayer = nullptr; 879 layersChanged = true; 880 } 881 882 return layersChanged; 883 } 884 885 void RenderLayerBacking::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground) 886 { 887 m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground; 888 } 889 890 bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer) 891 { 892 bool horizontalScrollbarLayerChanged = false; 893 if (needsHorizontalScrollbarLayer) { 894 if (!m_layerForHorizontalScrollbar) { 895 m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar", CompositingReasonLayerForScrollbar); 896 horizontalScrollbarLayerChanged = true; 897 } 898 } else if (m_layerForHorizontalScrollbar) { 899 m_layerForHorizontalScrollbar = nullptr; 900 horizontalScrollbarLayerChanged = true; 901 } 902 903 bool verticalScrollbarLayerChanged = false; 904 if (needsVerticalScrollbarLayer) { 905 if (!m_layerForVerticalScrollbar) { 906 m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar", CompositingReasonLayerForScrollbar); 907 verticalScrollbarLayerChanged = true; 908 } 909 } else if (m_layerForVerticalScrollbar) { 910 m_layerForVerticalScrollbar = nullptr; 911 verticalScrollbarLayerChanged = true; 912 } 913 914 bool scrollCornerLayerChanged = false; 915 if (needsScrollCornerLayer) { 916 if (!m_layerForScrollCorner) { 917 m_layerForScrollCorner = createGraphicsLayer("scroll corner", CompositingReasonLayerForScrollbar); 918 scrollCornerLayerChanged = true; 919 } 920 } else if (m_layerForScrollCorner) { 921 m_layerForScrollCorner = nullptr; 922 scrollCornerLayerChanged = true; 923 } 924 925 if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) { 926 if (horizontalScrollbarLayerChanged) 927 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, HorizontalScrollbar); 928 if (verticalScrollbarLayerChanged) 929 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, VerticalScrollbar); 930 } 931 932 return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged; 933 } 934 935 void RenderLayerBacking::positionOverflowControlsLayers(const IntSize& offsetFromRoot) 936 { 937 IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer(); 938 if (GraphicsLayer* layer = layerForHorizontalScrollbar()) { 939 Scrollbar* hBar = m_owningLayer->horizontalScrollbar(); 940 if (hBar) { 941 layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer); 942 layer->setSize(hBar->frameRect().size()); 943 if (layer->hasContentsLayer()) 944 layer->setContentsRect(IntRect(IntPoint(), hBar->frameRect().size())); 945 } 946 layer->setDrawsContent(hBar && !layer->hasContentsLayer()); 947 } 948 949 if (GraphicsLayer* layer = layerForVerticalScrollbar()) { 950 Scrollbar* vBar = m_owningLayer->verticalScrollbar(); 951 if (vBar) { 952 layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer); 953 layer->setSize(vBar->frameRect().size()); 954 if (layer->hasContentsLayer()) 955 layer->setContentsRect(IntRect(IntPoint(), vBar->frameRect().size())); 956 } 957 layer->setDrawsContent(vBar && !layer->hasContentsLayer()); 958 } 959 960 if (GraphicsLayer* layer = layerForScrollCorner()) { 961 const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect(); 962 layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer); 963 layer->setSize(scrollCornerAndResizer.size()); 964 layer->setDrawsContent(!scrollCornerAndResizer.isEmpty()); 965 } 966 } 967 968 bool RenderLayerBacking::hasUnpositionedOverflowControlsLayers() const 969 { 970 if (GraphicsLayer* layer = layerForHorizontalScrollbar()) 971 if (!layer->drawsContent()) 972 return true; 973 974 if (GraphicsLayer* layer = layerForVerticalScrollbar()) 975 if (!layer->drawsContent()) 976 return true; 977 978 if (GraphicsLayer* layer = layerForScrollCorner()) 979 if (!layer->drawsContent()) 980 return true; 981 982 return false; 983 } 984 985 bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer) 986 { 987 bool layerChanged = false; 988 if (needsForegroundLayer) { 989 if (!m_foregroundLayer) { 990 String layerName; 991 #ifndef NDEBUG 992 layerName = m_owningLayer->debugName() + " (foreground)"; 993 #endif 994 m_foregroundLayer = createGraphicsLayer(layerName, CompositingReasonLayerForForeground); 995 m_foregroundLayer->setDrawsContent(true); 996 m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground); 997 layerChanged = true; 998 } 999 } else if (m_foregroundLayer) { 1000 m_foregroundLayer->removeFromParent(); 1001 m_foregroundLayer = nullptr; 1002 layerChanged = true; 1003 } 1004 1005 if (layerChanged) 1006 m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer()); 1007 1008 return layerChanged; 1009 } 1010 1011 bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer) 1012 { 1013 bool layerChanged = false; 1014 if (needsBackgroundLayer) { 1015 if (!m_backgroundLayer) { 1016 String layerName; 1017 #ifndef NDEBUG 1018 layerName = m_owningLayer->debugName() + " (background)"; 1019 #endif 1020 m_backgroundLayer = createGraphicsLayer(layerName, CompositingReasonLayerForBackground); 1021 m_backgroundLayer->setDrawsContent(true); 1022 m_backgroundLayer->setAnchorPoint(FloatPoint3D()); 1023 m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground); 1024 #if !OS(ANDROID) 1025 m_backgroundLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true); 1026 m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(false); 1027 #endif 1028 layerChanged = true; 1029 } 1030 } else { 1031 if (m_backgroundLayer) { 1032 m_backgroundLayer->removeFromParent(); 1033 m_backgroundLayer = nullptr; 1034 #if !OS(ANDROID) 1035 m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true); 1036 #endif 1037 layerChanged = true; 1038 } 1039 } 1040 1041 if (layerChanged && !m_owningLayer->renderer()->documentBeingDestroyed()) 1042 compositor()->rootFixedBackgroundsChanged(); 1043 1044 return layerChanged; 1045 } 1046 1047 bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer) 1048 { 1049 bool layerChanged = false; 1050 if (needsMaskLayer) { 1051 if (!m_maskLayer) { 1052 m_maskLayer = createGraphicsLayer("Mask", CompositingReasonLayerForMask); 1053 m_maskLayer->setDrawsContent(true); 1054 m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask); 1055 layerChanged = true; 1056 } 1057 } else if (m_maskLayer) { 1058 m_maskLayer = nullptr; 1059 layerChanged = true; 1060 } 1061 1062 if (layerChanged) 1063 m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer()); 1064 1065 return layerChanged; 1066 } 1067 1068 bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers) 1069 { 1070 ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer); 1071 1072 bool layerChanged = false; 1073 if (needsScrollingLayers) { 1074 if (!m_scrollingLayer) { 1075 // Outer layer which corresponds with the scroll view. 1076 m_scrollingLayer = createGraphicsLayer("Scrolling container", CompositingReasonLayerForClip); 1077 m_scrollingLayer->setDrawsContent(false); 1078 m_scrollingLayer->setMasksToBounds(true); 1079 1080 // Inner layer which renders the content that scrolls. 1081 m_scrollingContentsLayer = createGraphicsLayer("Scrolled Contents", CompositingReasonLayerForScrollingContainer); 1082 m_scrollingContentsLayer->setDrawsContent(true); 1083 GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll; 1084 if (!m_foregroundLayer) 1085 paintPhase |= GraphicsLayerPaintForeground; 1086 m_scrollingContentsLayer->setPaintingPhase(paintPhase); 1087 m_scrollingLayer->addChild(m_scrollingContentsLayer.get()); 1088 1089 layerChanged = true; 1090 if (scrollingCoordinator) 1091 scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer); 1092 } 1093 } else if (m_scrollingLayer) { 1094 m_scrollingLayer = nullptr; 1095 m_scrollingContentsLayer = nullptr; 1096 layerChanged = true; 1097 if (scrollingCoordinator) 1098 scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer); 1099 } 1100 1101 if (layerChanged) { 1102 updateInternalHierarchy(); 1103 m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer()); 1104 m_graphicsLayer->setNeedsDisplay(); 1105 if (renderer()->view()) 1106 compositor()->scrollingLayerDidChange(m_owningLayer); 1107 } 1108 1109 return layerChanged; 1110 } 1111 1112 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const 1113 { 1114 unsigned phase = 0; 1115 if (!m_backgroundLayer) 1116 phase |= GraphicsLayerPaintBackground; 1117 if (!m_foregroundLayer) 1118 phase |= GraphicsLayerPaintForeground; 1119 if (!m_maskLayer) 1120 phase |= GraphicsLayerPaintMask; 1121 1122 if (m_scrollingContentsLayer) { 1123 phase &= ~GraphicsLayerPaintForeground; 1124 phase |= GraphicsLayerPaintCompositedScroll; 1125 } 1126 1127 return static_cast<GraphicsLayerPaintingPhase>(phase); 1128 } 1129 1130 float RenderLayerBacking::compositingOpacity(float rendererOpacity) const 1131 { 1132 float finalOpacity = rendererOpacity; 1133 1134 for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) { 1135 // We only care about parents that are stacking contexts. 1136 // Recall that opacity creates stacking context. 1137 if (!curr->isStackingContainer()) 1138 continue; 1139 1140 // If we found a compositing layer, we want to compute opacity 1141 // relative to it. So we can break here. 1142 if (curr->isComposited()) 1143 break; 1144 1145 finalOpacity *= curr->renderer()->opacity(); 1146 } 1147 1148 return finalOpacity; 1149 } 1150 1151 Color RenderLayerBacking::rendererBackgroundColor() const 1152 { 1153 RenderObject* backgroundRenderer = renderer(); 1154 if (backgroundRenderer->isRoot()) 1155 backgroundRenderer = backgroundRenderer->rendererForRootBackground(); 1156 1157 return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor); 1158 } 1159 1160 void RenderLayerBacking::updateBackgroundColor(bool isSimpleContainer) 1161 { 1162 Color backgroundColor = rendererBackgroundColor(); 1163 if (isSimpleContainer) { 1164 m_graphicsLayer->setContentsToSolidColor(backgroundColor); 1165 m_graphicsLayer->setBackgroundColor(Color()); 1166 } else { 1167 // An unset (invalid) color will remove the solid color. 1168 m_graphicsLayer->setContentsToSolidColor(Color()); 1169 m_graphicsLayer->setBackgroundColor(backgroundColor); 1170 } 1171 } 1172 1173 static bool supportsDirectBoxDecorationsComposition(const RenderObject* renderer) 1174 { 1175 if (!GraphicsLayer::supportsBackgroundColorContent()) 1176 return false; 1177 1178 if (renderer->hasClip()) 1179 return false; 1180 1181 if (hasBoxDecorationsOrBackgroundImage(renderer->style())) 1182 return false; 1183 1184 // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now. 1185 if (renderer->style()->backgroundComposite() != CompositeSourceOver) 1186 return false; 1187 1188 if (renderer->style()->backgroundClip() == TextFillBox) 1189 return false; 1190 1191 return true; 1192 } 1193 1194 bool RenderLayerBacking::paintsBoxDecorations() const 1195 { 1196 if (!m_owningLayer->hasVisibleBoxDecorations()) 1197 return false; 1198 1199 if (!supportsDirectBoxDecorationsComposition(renderer())) 1200 return true; 1201 1202 return false; 1203 } 1204 1205 bool RenderLayerBacking::paintsChildren() const 1206 { 1207 if (m_owningLayer->hasVisibleContent() && m_owningLayer->hasNonEmptyChildRenderers()) 1208 return true; 1209 1210 if (hasVisibleNonCompositingDescendantLayers()) 1211 return true; 1212 1213 return false; 1214 } 1215 1216 static bool isCompositedPlugin(RenderObject* renderer) 1217 { 1218 return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing(); 1219 } 1220 1221 // A "simple container layer" is a RenderLayer which has no visible content to render. 1222 // It may have no children, or all its children may be themselves composited. 1223 // This is a useful optimization, because it allows us to avoid allocating backing store. 1224 bool RenderLayerBacking::isSimpleContainerCompositingLayer() const 1225 { 1226 RenderObject* renderObject = renderer(); 1227 if (renderObject->hasMask()) // masks require special treatment 1228 return false; 1229 1230 if (renderObject->isReplaced() && !isCompositedPlugin(renderObject)) 1231 return false; 1232 1233 if (paintsBoxDecorations() || paintsChildren()) 1234 return false; 1235 1236 if (renderObject->isRenderRegion()) 1237 return false; 1238 1239 if (renderObject->node() && renderObject->node()->isDocumentNode()) { 1240 // Look to see if the root object has a non-simple background 1241 RenderObject* rootObject = renderObject->document()->documentElement() ? renderObject->document()->documentElement()->renderer() : 0; 1242 if (!rootObject) 1243 return false; 1244 1245 RenderStyle* style = rootObject->style(); 1246 1247 // Reject anything that has a border, a border-radius or outline, 1248 // or is not a simple background (no background, or solid color). 1249 if (hasBoxDecorationsOrBackgroundImage(style)) 1250 return false; 1251 1252 // Now look at the body's renderer. 1253 HTMLElement* body = renderObject->document()->body(); 1254 RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0; 1255 if (!bodyObject) 1256 return false; 1257 1258 style = bodyObject->style(); 1259 1260 if (hasBoxDecorationsOrBackgroundImage(style)) 1261 return false; 1262 } 1263 1264 return true; 1265 } 1266 1267 static bool hasVisibleNonCompositingDescendant(RenderLayer* parent) 1268 { 1269 // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512. 1270 parent->updateLayerListsIfNeeded(); 1271 1272 #if !ASSERT_DISABLED 1273 LayerListMutationDetector mutationChecker(parent); 1274 #endif 1275 1276 if (Vector<RenderLayer*>* normalFlowList = parent->normalFlowList()) { 1277 size_t listSize = normalFlowList->size(); 1278 for (size_t i = 0; i < listSize; ++i) { 1279 RenderLayer* curLayer = normalFlowList->at(i); 1280 if (!curLayer->isComposited() 1281 && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer))) 1282 return true; 1283 } 1284 } 1285 1286 if (parent->isStackingContainer()) { 1287 if (!parent->hasVisibleDescendant()) 1288 return false; 1289 1290 // Use the m_hasCompositingDescendant bit to optimize? 1291 if (Vector<RenderLayer*>* negZOrderList = parent->negZOrderList()) { 1292 size_t listSize = negZOrderList->size(); 1293 for (size_t i = 0; i < listSize; ++i) { 1294 RenderLayer* curLayer = negZOrderList->at(i); 1295 if (!curLayer->isComposited() 1296 && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer))) 1297 return true; 1298 } 1299 } 1300 1301 if (Vector<RenderLayer*>* posZOrderList = parent->posZOrderList()) { 1302 size_t listSize = posZOrderList->size(); 1303 for (size_t i = 0; i < listSize; ++i) { 1304 RenderLayer* curLayer = posZOrderList->at(i); 1305 if (!curLayer->isComposited() 1306 && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer))) 1307 return true; 1308 } 1309 } 1310 } 1311 1312 return false; 1313 } 1314 1315 // Conservative test for having no rendered children. 1316 bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const 1317 { 1318 return hasVisibleNonCompositingDescendant(m_owningLayer); 1319 } 1320 1321 bool RenderLayerBacking::containsPaintedContent(bool isSimpleContainer) const 1322 { 1323 if (isSimpleContainer || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer->isReflection()) 1324 return false; 1325 1326 if (isDirectlyCompositedImage()) 1327 return false; 1328 1329 // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely, 1330 // and set background color on the layer in that case, instead of allocating backing store and painting. 1331 if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo()) 1332 return m_owningLayer->hasBoxDecorationsOrBackground(); 1333 1334 return true; 1335 } 1336 1337 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations 1338 // that require painting. Direct compositing saves backing store. 1339 bool RenderLayerBacking::isDirectlyCompositedImage() const 1340 { 1341 RenderObject* renderObject = renderer(); 1342 1343 if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground() || renderObject->hasClip()) 1344 return false; 1345 1346 RenderImage* imageRenderer = toRenderImage(renderObject); 1347 if (ImageResource* cachedImage = imageRenderer->cachedImage()) { 1348 if (!cachedImage->hasImage()) 1349 return false; 1350 1351 Image* image = cachedImage->imageForRenderer(imageRenderer); 1352 if (!image->isBitmapImage()) 1353 return false; 1354 1355 return m_graphicsLayer->shouldDirectlyCompositeImage(image); 1356 } 1357 1358 return false; 1359 } 1360 1361 void RenderLayerBacking::contentChanged(ContentChangeType changeType) 1362 { 1363 if ((changeType == ImageChanged) && isDirectlyCompositedImage()) { 1364 updateImageContents(); 1365 return; 1366 } 1367 1368 if ((changeType == MaskImageChanged) && m_maskLayer) { 1369 // The composited layer bounds relies on box->maskClipRect(), which changes 1370 // when the mask image becomes available. 1371 updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot); 1372 } 1373 1374 if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && isAcceleratedCanvas(renderer())) { 1375 m_graphicsLayer->setContentsNeedsDisplay(); 1376 return; 1377 } 1378 } 1379 1380 void RenderLayerBacking::updateImageContents() 1381 { 1382 ASSERT(renderer()->isImage()); 1383 RenderImage* imageRenderer = toRenderImage(renderer()); 1384 1385 ImageResource* cachedImage = imageRenderer->cachedImage(); 1386 if (!cachedImage) 1387 return; 1388 1389 Image* image = cachedImage->imageForRenderer(imageRenderer); 1390 if (!image) 1391 return; 1392 1393 // We have to wait until the image is fully loaded before setting it on the layer. 1394 if (!cachedImage->isLoaded()) 1395 return; 1396 1397 // This is a no-op if the layer doesn't have an inner layer for the image. 1398 m_graphicsLayer->setContentsToImage(image); 1399 bool isSimpleContainer = false; 1400 updateDrawsContent(isSimpleContainer); 1401 1402 // Image animation is "lazy", in that it automatically stops unless someone is drawing 1403 // the image. So we have to kick the animation each time; this has the downside that the 1404 // image will keep animating, even if its layer is not visible. 1405 image->startAnimation(); 1406 } 1407 1408 FloatPoint3D RenderLayerBacking::computeTransformOrigin(const IntRect& borderBox) const 1409 { 1410 RenderStyle* style = renderer()->style(); 1411 1412 FloatPoint3D origin; 1413 origin.setX(floatValueForLength(style->transformOriginX(), borderBox.width())); 1414 origin.setY(floatValueForLength(style->transformOriginY(), borderBox.height())); 1415 origin.setZ(style->transformOriginZ()); 1416 1417 return origin; 1418 } 1419 1420 FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox) const 1421 { 1422 RenderStyle* style = renderer()->style(); 1423 1424 float boxWidth = borderBox.width(); 1425 float boxHeight = borderBox.height(); 1426 1427 FloatPoint origin; 1428 origin.setX(floatValueForLength(style->perspectiveOriginX(), boxWidth)); 1429 origin.setY(floatValueForLength(style->perspectiveOriginY(), boxHeight)); 1430 1431 return origin; 1432 } 1433 1434 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted. 1435 IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const 1436 { 1437 return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y()); 1438 } 1439 1440 IntRect RenderLayerBacking::contentsBox() const 1441 { 1442 IntRect contentsBox = contentsRect(renderer()); 1443 contentsBox.move(contentOffsetInCompostingLayer()); 1444 return contentsBox; 1445 } 1446 1447 IntRect RenderLayerBacking::backgroundBox() const 1448 { 1449 IntRect backgroundBox = backgroundRect(renderer()); 1450 backgroundBox.move(contentOffsetInCompostingLayer()); 1451 return backgroundBox; 1452 } 1453 1454 GraphicsLayer* RenderLayerBacking::parentForSublayers() const 1455 { 1456 if (m_scrollingContentsLayer) 1457 return m_scrollingContentsLayer.get(); 1458 1459 return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get(); 1460 } 1461 1462 GraphicsLayer* RenderLayerBacking::childForSuperlayers() const 1463 { 1464 if (m_ancestorClippingLayer) 1465 return m_ancestorClippingLayer.get(); 1466 1467 return m_graphicsLayer.get(); 1468 } 1469 1470 void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking) 1471 { 1472 if (requiresOwnBacking == m_requiresOwnBackingStore) 1473 return; 1474 1475 m_requiresOwnBackingStore = requiresOwnBacking; 1476 1477 // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects 1478 // cached clip rects, so when it changes we have to clear clip rects on descendants. 1479 m_owningLayer->clearClipRectsIncludingDescendants(PaintingClipRects); 1480 m_owningLayer->computeRepaintRectsIncludingDescendants(); 1481 1482 compositor()->repaintInCompositedAncestor(m_owningLayer, compositedBounds()); 1483 } 1484 1485 void RenderLayerBacking::setBlendMode(BlendMode) 1486 { 1487 } 1488 1489 void RenderLayerBacking::setContentsNeedDisplay() 1490 { 1491 ASSERT(!paintsIntoCompositedAncestor()); 1492 1493 if (m_graphicsLayer && m_graphicsLayer->drawsContent()) 1494 m_graphicsLayer->setNeedsDisplay(); 1495 1496 if (m_foregroundLayer && m_foregroundLayer->drawsContent()) 1497 m_foregroundLayer->setNeedsDisplay(); 1498 1499 if (m_backgroundLayer && m_backgroundLayer->drawsContent()) 1500 m_backgroundLayer->setNeedsDisplay(); 1501 1502 if (m_maskLayer && m_maskLayer->drawsContent()) 1503 m_maskLayer->setNeedsDisplay(); 1504 1505 if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) 1506 m_scrollingContentsLayer->setNeedsDisplay(); 1507 } 1508 1509 // r is in the coordinate space of the layer's render object 1510 void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r) 1511 { 1512 ASSERT(!paintsIntoCompositedAncestor()); 1513 1514 if (m_graphicsLayer && m_graphicsLayer->drawsContent()) { 1515 IntRect layerDirtyRect = r; 1516 layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer()); 1517 m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect); 1518 } 1519 1520 if (m_foregroundLayer && m_foregroundLayer->drawsContent()) { 1521 IntRect layerDirtyRect = r; 1522 layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer()); 1523 m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect); 1524 } 1525 1526 // FIXME: need to split out repaints for the background. 1527 if (m_backgroundLayer && m_backgroundLayer->drawsContent()) { 1528 IntRect layerDirtyRect = r; 1529 layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer()); 1530 m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect); 1531 } 1532 1533 if (m_maskLayer && m_maskLayer->drawsContent()) { 1534 IntRect layerDirtyRect = r; 1535 layerDirtyRect.move(-m_maskLayer->offsetFromRenderer()); 1536 m_maskLayer->setNeedsDisplayInRect(layerDirtyRect); 1537 } 1538 1539 if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) { 1540 IntRect layerDirtyRect = r; 1541 layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer()); 1542 m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect); 1543 } 1544 } 1545 1546 void RenderLayerBacking::doPaintTask(GraphicsLayerPaintInfo& paintInfo, GraphicsContext* context, 1547 const IntRect& clip) // In the coords of rootLayer. 1548 { 1549 if (paintsIntoCompositedAncestor()) { 1550 ASSERT_NOT_REACHED(); 1551 return; 1552 } 1553 1554 FontCachePurgePreventer fontCachePurgePreventer; 1555 1556 RenderLayer::PaintLayerFlags paintFlags = 0; 1557 if (paintInfo.paintingPhase & GraphicsLayerPaintBackground) 1558 paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase; 1559 if (paintInfo.paintingPhase & GraphicsLayerPaintForeground) 1560 paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase; 1561 if (paintInfo.paintingPhase & GraphicsLayerPaintMask) 1562 paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase; 1563 if (paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents) 1564 paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents; 1565 if (paintInfo.paintingPhase & GraphicsLayerPaintCompositedScroll) 1566 paintFlags |= RenderLayer::PaintLayerPaintingCompositingScrollingPhase; 1567 1568 if (paintInfo.isBackgroundLayer) 1569 paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers. 1570 else if (compositor()->fixedRootBackgroundLayer()) 1571 paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground; 1572 1573 InspectorInstrumentation::willPaint(paintInfo.renderLayer->renderer()); 1574 1575 // Note carefully: in theory it is appropriate to invoke context->save() here 1576 // and restore the context after painting. For efficiency, we are assuming that 1577 // it is equivalent to manually undo this offset translation, which means we are 1578 // assuming that the context's space was not affected by the RenderLayer 1579 // painting code. 1580 1581 LayoutSize offset = paintInfo.offsetFromRenderer; 1582 context->translate(-offset); 1583 LayoutRect relativeClip(clip); 1584 relativeClip.move(offset); 1585 1586 // The dirtyRect is in the coords of the painting root. 1587 IntRect dirtyRect = pixelSnappedIntRect(relativeClip); 1588 if (!(paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents)) 1589 dirtyRect.intersect(paintInfo.compositedBounds); 1590 1591 // FIXME: GraphicsLayers need a way to split for RenderRegions. 1592 RenderLayer::LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, LayoutSize()); 1593 paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags); 1594 1595 ASSERT(!paintInfo.isBackgroundLayer || paintFlags & RenderLayer::PaintLayerPaintingRootBackgroundOnly); 1596 1597 if (paintInfo.renderLayer->containsDirtyOverlayScrollbars()) 1598 paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars); 1599 1600 ASSERT(!paintInfo.renderLayer->m_usedTransparency); 1601 1602 // Manually restore the context to its original state by applying the opposite translation. 1603 context->translate(offset); 1604 1605 InspectorInstrumentation::didPaint(paintInfo.renderLayer->renderer(), context, clip); 1606 } 1607 1608 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip) 1609 { 1610 if (!scrollbar) 1611 return; 1612 1613 context.save(); 1614 const IntRect& scrollbarRect = scrollbar->frameRect(); 1615 context.translate(-scrollbarRect.x(), -scrollbarRect.y()); 1616 IntRect transformedClip = clip; 1617 transformedClip.moveBy(scrollbarRect.location()); 1618 scrollbar->paint(&context, transformedClip); 1619 context.restore(); 1620 } 1621 1622 // Up-call from compositing layer drawing callback. 1623 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip) 1624 { 1625 #ifndef NDEBUG 1626 if (Page* page = renderer()->frame()->page()) 1627 page->setIsPainting(true); 1628 #endif 1629 1630 if (graphicsLayer == m_graphicsLayer.get() 1631 || graphicsLayer == m_foregroundLayer.get() 1632 || graphicsLayer == m_backgroundLayer.get() 1633 || graphicsLayer == m_maskLayer.get() 1634 || graphicsLayer == m_scrollingContentsLayer.get()) { 1635 1636 GraphicsLayerPaintInfo paintInfo; 1637 paintInfo.renderLayer = m_owningLayer; 1638 paintInfo.compositedBounds = compositedBounds(); 1639 paintInfo.offsetFromRenderer = graphicsLayer->offsetFromRenderer(); 1640 paintInfo.paintingPhase = paintingPhase; 1641 paintInfo.isBackgroundLayer = (graphicsLayer == m_backgroundLayer); 1642 1643 // We have to use the same root as for hit testing, because both methods can compute and cache clipRects. 1644 doPaintTask(paintInfo, &context, clip); 1645 } else if (graphicsLayer == layerForHorizontalScrollbar()) { 1646 paintScrollbar(m_owningLayer->horizontalScrollbar(), context, clip); 1647 } else if (graphicsLayer == layerForVerticalScrollbar()) { 1648 paintScrollbar(m_owningLayer->verticalScrollbar(), context, clip); 1649 } else if (graphicsLayer == layerForScrollCorner()) { 1650 const IntRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect(); 1651 context.save(); 1652 context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y()); 1653 IntRect transformedClip = clip; 1654 transformedClip.moveBy(scrollCornerAndResizer.location()); 1655 m_owningLayer->paintScrollCorner(&context, IntPoint(), transformedClip); 1656 m_owningLayer->paintResizer(&context, IntPoint(), transformedClip); 1657 context.restore(); 1658 } 1659 #ifndef NDEBUG 1660 if (Page* page = renderer()->frame()->page()) 1661 page->setIsPainting(false); 1662 #endif 1663 } 1664 1665 void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer* layer) const 1666 { 1667 } 1668 1669 bool RenderLayerBacking::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const 1670 { 1671 if (graphicsLayer != m_graphicsLayer.get()) 1672 return false; 1673 1674 if (m_owningLayer->hasTransform()) { 1675 transform = m_owningLayer->currentTransform(RenderStyle::ExcludeTransformOrigin); 1676 return true; 1677 } 1678 return false; 1679 } 1680 1681 bool RenderLayerBacking::isTrackingRepaints() const 1682 { 1683 GraphicsLayerClient* client = compositor(); 1684 return client ? client->isTrackingRepaints() : false; 1685 } 1686 1687 #ifndef NDEBUG 1688 void RenderLayerBacking::verifyNotPainting() 1689 { 1690 ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPainting()); 1691 } 1692 #endif 1693 1694 bool RenderLayerBacking::startAnimation(double timeOffset, const CSSAnimationData* anim, const KeyframeList& keyframes) 1695 { 1696 bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity); 1697 bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform); 1698 bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter); 1699 1700 if (!hasOpacity && !hasTransform && !hasFilter) 1701 return false; 1702 1703 KeyframeValueList transformVector(AnimatedPropertyWebkitTransform); 1704 KeyframeValueList opacityVector(AnimatedPropertyOpacity); 1705 KeyframeValueList filterVector(AnimatedPropertyWebkitFilter); 1706 1707 size_t numKeyframes = keyframes.size(); 1708 for (size_t i = 0; i < numKeyframes; ++i) { 1709 const KeyframeValue& currentKeyframe = keyframes[i]; 1710 const RenderStyle* keyframeStyle = currentKeyframe.style(); 1711 float key = currentKeyframe.key(); 1712 1713 if (!keyframeStyle) 1714 continue; 1715 1716 // Get timing function. 1717 RefPtr<TimingFunction> tf = keyframeStyle->hasAnimations() ? (*keyframeStyle->animations()).animation(0)->timingFunction() : 0; 1718 1719 bool isFirstOrLastKeyframe = key == 0 || key == 1; 1720 if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitTransform)) 1721 transformVector.insert(adoptPtr(new TransformAnimationValue(key, &(keyframeStyle->transform()), tf))); 1722 1723 if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity)) 1724 opacityVector.insert(adoptPtr(new FloatAnimationValue(key, keyframeStyle->opacity(), tf))); 1725 1726 if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter)) 1727 filterVector.insert(adoptPtr(new FilterAnimationValue(key, &(keyframeStyle->filter()), tf))); 1728 } 1729 1730 bool didAnimate = false; 1731 1732 if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), anim, keyframes.animationName(), timeOffset)) 1733 didAnimate = true; 1734 1735 if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset)) 1736 didAnimate = true; 1737 1738 if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset)) 1739 didAnimate = true; 1740 1741 return didAnimate; 1742 } 1743 1744 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName) 1745 { 1746 m_graphicsLayer->pauseAnimation(animationName, timeOffset); 1747 } 1748 1749 void RenderLayerBacking::animationFinished(const String& animationName) 1750 { 1751 m_graphicsLayer->removeAnimation(animationName); 1752 } 1753 1754 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle) 1755 { 1756 bool didAnimate = false; 1757 1758 ASSERT(property != CSSPropertyInvalid); 1759 1760 if (property == CSSPropertyOpacity) { 1761 const CSSAnimationData* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity); 1762 if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) { 1763 KeyframeValueList opacityVector(AnimatedPropertyOpacity); 1764 opacityVector.insert(adoptPtr(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity())))); 1765 opacityVector.insert(adoptPtr(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity())))); 1766 // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here. 1767 if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) { 1768 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity. 1769 updateOpacity(toStyle); 1770 didAnimate = true; 1771 } 1772 } 1773 } 1774 1775 if (property == CSSPropertyWebkitTransform && m_owningLayer->hasTransform()) { 1776 const CSSAnimationData* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform); 1777 if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) { 1778 KeyframeValueList transformVector(AnimatedPropertyWebkitTransform); 1779 transformVector.insert(adoptPtr(new TransformAnimationValue(0, &fromStyle->transform()))); 1780 transformVector.insert(adoptPtr(new TransformAnimationValue(1, &toStyle->transform()))); 1781 if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) { 1782 // To ensure that the correct transform is visible when the animation ends, also set the final transform. 1783 updateTransform(toStyle); 1784 didAnimate = true; 1785 } 1786 } 1787 } 1788 1789 if (property == CSSPropertyWebkitFilter && m_owningLayer->hasFilter()) { 1790 const CSSAnimationData* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter); 1791 if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) { 1792 KeyframeValueList filterVector(AnimatedPropertyWebkitFilter); 1793 filterVector.insert(adoptPtr(new FilterAnimationValue(0, &fromStyle->filter()))); 1794 filterVector.insert(adoptPtr(new FilterAnimationValue(1, &toStyle->filter()))); 1795 if (m_graphicsLayer->addAnimation(filterVector, IntSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset)) { 1796 // To ensure that the correct filter is visible when the animation ends, also set the final filter. 1797 updateFilters(toStyle); 1798 didAnimate = true; 1799 } 1800 } 1801 } 1802 1803 return didAnimate; 1804 } 1805 1806 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID property) 1807 { 1808 AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property); 1809 if (animatedProperty != AnimatedPropertyInvalid) 1810 m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset); 1811 } 1812 1813 void RenderLayerBacking::transitionFinished(CSSPropertyID property) 1814 { 1815 AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property); 1816 if (animatedProperty != AnimatedPropertyInvalid) 1817 m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty)); 1818 } 1819 1820 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time) 1821 { 1822 renderer()->animation()->notifyAnimationStarted(renderer(), time); 1823 } 1824 1825 // This is used for the 'freeze' API, for testing only. 1826 void RenderLayerBacking::suspendAnimations(double time) 1827 { 1828 m_graphicsLayer->suspendAnimations(time); 1829 } 1830 1831 void RenderLayerBacking::resumeAnimations() 1832 { 1833 m_graphicsLayer->resumeAnimations(); 1834 } 1835 1836 IntRect RenderLayerBacking::compositedBounds() const 1837 { 1838 return m_compositedBounds; 1839 } 1840 1841 void RenderLayerBacking::setCompositedBounds(const IntRect& bounds) 1842 { 1843 m_compositedBounds = bounds; 1844 } 1845 1846 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property) 1847 { 1848 CSSPropertyID cssProperty = CSSPropertyInvalid; 1849 switch (property) { 1850 case AnimatedPropertyWebkitTransform: 1851 cssProperty = CSSPropertyWebkitTransform; 1852 break; 1853 case AnimatedPropertyOpacity: 1854 cssProperty = CSSPropertyOpacity; 1855 break; 1856 case AnimatedPropertyBackgroundColor: 1857 cssProperty = CSSPropertyBackgroundColor; 1858 break; 1859 case AnimatedPropertyWebkitFilter: 1860 cssProperty = CSSPropertyWebkitFilter; 1861 break; 1862 case AnimatedPropertyInvalid: 1863 ASSERT_NOT_REACHED(); 1864 } 1865 return cssProperty; 1866 } 1867 1868 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty) 1869 { 1870 switch (cssProperty) { 1871 case CSSPropertyWebkitTransform: 1872 return AnimatedPropertyWebkitTransform; 1873 case CSSPropertyOpacity: 1874 return AnimatedPropertyOpacity; 1875 case CSSPropertyBackgroundColor: 1876 return AnimatedPropertyBackgroundColor; 1877 case CSSPropertyWebkitFilter: 1878 return AnimatedPropertyWebkitFilter; 1879 default: 1880 // It's fine if we see other css properties here; they are just not accelerated. 1881 break; 1882 } 1883 return AnimatedPropertyInvalid; 1884 } 1885 1886 CompositingLayerType RenderLayerBacking::compositingLayerType() const 1887 { 1888 if (m_graphicsLayer->hasContentsLayer()) 1889 return MediaCompositingLayer; 1890 1891 if (m_graphicsLayer->drawsContent()) 1892 return NormalCompositingLayer; 1893 1894 return ContainerCompositingLayer; 1895 } 1896 1897 double RenderLayerBacking::backingStoreMemoryEstimate() const 1898 { 1899 double backingMemory; 1900 1901 // m_ancestorClippingLayer and m_childContainmentLayer are just used for masking or containment, so have no backing. 1902 backingMemory = m_graphicsLayer->backingStoreMemoryEstimate(); 1903 if (m_foregroundLayer) 1904 backingMemory += m_foregroundLayer->backingStoreMemoryEstimate(); 1905 if (m_backgroundLayer) 1906 backingMemory += m_backgroundLayer->backingStoreMemoryEstimate(); 1907 if (m_maskLayer) 1908 backingMemory += m_maskLayer->backingStoreMemoryEstimate(); 1909 1910 if (m_scrollingContentsLayer) 1911 backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate(); 1912 1913 if (m_layerForHorizontalScrollbar) 1914 backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate(); 1915 1916 if (m_layerForVerticalScrollbar) 1917 backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate(); 1918 1919 if (m_layerForScrollCorner) 1920 backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate(); 1921 1922 return backingMemory; 1923 } 1924 1925 } // namespace WebCore 1926