• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/CompositedLayerMapping.h"
29 
30 #include "CSSPropertyNames.h"
31 #include "HTMLNames.h"
32 #include "RuntimeEnabledFeatures.h"
33 #include "core/animation/ActiveAnimations.h"
34 #include "core/fetch/ImageResource.h"
35 #include "core/html/HTMLIFrameElement.h"
36 #include "core/html/HTMLMediaElement.h"
37 #include "core/html/canvas/CanvasRenderingContext.h"
38 #include "core/inspector/InspectorInstrumentation.h"
39 #include "core/page/Chrome.h"
40 #include "core/frame/FrameView.h"
41 #include "core/frame/Settings.h"
42 #include "core/frame/animation/AnimationController.h"
43 #include "core/page/scrolling/ScrollingCoordinator.h"
44 #include "core/plugins/PluginView.h"
45 #include "core/rendering/FilterEffectRenderer.h"
46 #include "core/rendering/RenderApplet.h"
47 #include "core/rendering/RenderEmbeddedObject.h"
48 #include "core/rendering/RenderIFrame.h"
49 #include "core/rendering/RenderImage.h"
50 #include "core/rendering/RenderLayerCompositor.h"
51 #include "core/rendering/RenderLayerStackingNodeIterator.h"
52 #include "core/rendering/RenderVideo.h"
53 #include "core/rendering/RenderView.h"
54 #include "core/rendering/animation/WebAnimationProvider.h"
55 #include "core/rendering/style/KeyframeList.h"
56 #include "platform/LengthFunctions.h"
57 #include "platform/fonts/FontCache.h"
58 #include "platform/graphics/GraphicsContext.h"
59 #include "platform/graphics/GraphicsContext3D.h"
60 #include "platform/graphics/filters/custom/CustomFilterOperation.h"
61 #include "wtf/CurrentTime.h"
62 #include "wtf/text/StringBuilder.h"
63 
64 using namespace std;
65 
66 namespace WebCore {
67 
68 using namespace HTMLNames;
69 
70 static IntRect clipBox(RenderBox* renderer);
71 
contentsRect(const RenderObject * renderer)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 
backgroundRect(const RenderObject * renderer)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 
isAcceleratedCanvas(const RenderObject * renderer)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 
hasBoxDecorations(const RenderStyle * style)117 static bool hasBoxDecorations(const RenderStyle* style)
118 {
119     return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
120 }
121 
hasBoxDecorationsOrBackgroundImage(const RenderStyle * style)122 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
123 {
124     return hasBoxDecorations(style) || style->hasBackgroundImage();
125 }
126 
contentLayerSupportsDirectBackgroundComposition(const RenderObject * renderer)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 
isAcceleratedContents(RenderObject * renderer)142 static inline bool isAcceleratedContents(RenderObject* renderer)
143 {
144     return isAcceleratedCanvas(renderer)
145         || (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
146         || renderer->isVideo();
147 }
148 
149 // Get the scrolling coordinator in a way that works inside CompositedLayerMapping's destructor.
scrollingCoordinatorFromLayer(RenderLayer * layer)150 static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer* layer)
151 {
152     Page* page = layer->renderer()->frame()->page();
153     if (!page)
154         return 0;
155 
156     return page->scrollingCoordinator();
157 }
158 
CompositedLayerMapping(RenderLayer * layer)159 CompositedLayerMapping::CompositedLayerMapping(RenderLayer* layer)
160     : m_owningLayer(layer)
161     , m_animationProvider(adoptPtr(new WebAnimationProvider))
162     , m_artificiallyInflatedBounds(false)
163     , m_boundsConstrainedByClipping(false)
164     , m_isMainFrameRenderViewLayer(false)
165     , m_requiresOwnBackingStoreForIntrinsicReasons(true)
166     , m_requiresOwnBackingStoreForAncestorReasons(true)
167     , m_canCompositeFilters(false)
168     , m_backgroundLayerPaintsFixedRootBackground(false)
169 {
170     if (layer->isRootLayer() && renderer()->frame()->isMainFrame())
171         m_isMainFrameRenderViewLayer = true;
172 
173     createPrimaryGraphicsLayer();
174 }
175 
~CompositedLayerMapping()176 CompositedLayerMapping::~CompositedLayerMapping()
177 {
178     // Do not leave the destroyed pointer dangling on any RenderLayers that painted to this mapping's squashing layer.
179     for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
180         if (m_squashedLayers[i].renderLayer->groupedMapping() == this)
181             m_squashedLayers[i].renderLayer->setGroupedMapping(0);
182     }
183 
184     updateClippingLayers(false, false);
185     updateOverflowControlsLayers(false, false, false);
186     updateForegroundLayer(false);
187     updateBackgroundLayer(false);
188     updateMaskLayer(false);
189     updateClippingMaskLayers(false);
190     updateScrollingLayers(false);
191     updateSquashingLayers(false);
192     destroyGraphicsLayers();
193 }
194 
createGraphicsLayer(CompositingReasons reasons)195 PassOwnPtr<GraphicsLayer> CompositedLayerMapping::createGraphicsLayer(CompositingReasons reasons)
196 {
197     GraphicsLayerFactory* graphicsLayerFactory = 0;
198     if (Page* page = renderer()->frame()->page())
199         graphicsLayerFactory = page->chrome().client().graphicsLayerFactory();
200 
201     OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this);
202 
203     graphicsLayer->setCompositingReasons(reasons);
204 
205     return graphicsLayer.release();
206 }
207 
createPrimaryGraphicsLayer()208 void CompositedLayerMapping::createPrimaryGraphicsLayer()
209 {
210     m_graphicsLayer = createGraphicsLayer(m_owningLayer->compositingReasons());
211 
212 #if !OS(ANDROID)
213     if (m_isMainFrameRenderViewLayer)
214         m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
215 #endif
216 
217     updateOpacity(renderer()->style());
218     updateTransform(renderer()->style());
219     updateFilters(renderer()->style());
220 
221     if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
222         updateLayerBlendMode(renderer()->style());
223         updateIsRootForIsolatedGroup();
224     }
225 }
226 
destroyGraphicsLayers()227 void CompositedLayerMapping::destroyGraphicsLayers()
228 {
229     if (m_graphicsLayer)
230         m_graphicsLayer->removeFromParent();
231 
232     m_ancestorClippingLayer = nullptr;
233     m_graphicsLayer = nullptr;
234     m_foregroundLayer = nullptr;
235     m_backgroundLayer = nullptr;
236     m_childContainmentLayer = nullptr;
237     m_maskLayer = nullptr;
238     m_childClippingMaskLayer = nullptr;
239 
240     m_scrollingLayer = nullptr;
241     m_scrollingContentsLayer = nullptr;
242 }
243 
updateOpacity(const RenderStyle * style)244 void CompositedLayerMapping::updateOpacity(const RenderStyle* style)
245 {
246     m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
247 }
248 
updateTransform(const RenderStyle * style)249 void CompositedLayerMapping::updateTransform(const RenderStyle* style)
250 {
251     // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin
252     // baked into it, and we don't want that.
253     TransformationMatrix t;
254     if (m_owningLayer->hasTransform()) {
255         style->applyTransform(t, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
256         makeMatrixRenderable(t, compositor()->canRender3DTransforms());
257     }
258 
259     m_graphicsLayer->setTransform(t);
260 }
261 
updateFilters(const RenderStyle * style)262 void CompositedLayerMapping::updateFilters(const RenderStyle* style)
263 {
264     bool didCompositeFilters = m_canCompositeFilters;
265     m_canCompositeFilters = m_graphicsLayer->setFilters(owningLayer()->computeFilterOperations(style));
266     if (didCompositeFilters != m_canCompositeFilters) {
267         //
268         // If filters used to be painted in software and are now painted in the compositor, we need to:
269         // (1) Remove the FilterEffectRenderer, which was used for painting filters in software.
270         // (2) Repaint the layer contents to remove the software-applied filter because the compositor will apply it.
271         //
272         // Similarly, if filters used to be painted in the compositor and are now painted in software, we need to:
273         // (1) Create a FilterEffectRenderer.
274         // (2) Repaint the layer contents to apply a software filter because the compositor won't apply it.
275         //
276         m_owningLayer->updateOrRemoveFilterEffectRenderer();
277         setContentsNeedDisplay();
278     }
279 }
280 
updateLayerBlendMode(const RenderStyle * style)281 void CompositedLayerMapping::updateLayerBlendMode(const RenderStyle* style)
282 {
283     setBlendMode(style->blendMode());
284 }
285 
updateIsRootForIsolatedGroup()286 void CompositedLayerMapping::updateIsRootForIsolatedGroup()
287 {
288     bool isolate = m_owningLayer->shouldIsolateCompositedDescendants();
289 
290     // non stacking context layers should never isolate
291     ASSERT(m_owningLayer->stackingNode()->isStackingContext() || !isolate);
292 
293     m_graphicsLayer->setIsRootForIsolatedGroup(isolate);
294 }
295 
updateContentsOpaque()296 void CompositedLayerMapping::updateContentsOpaque()
297 {
298     // For non-root layers, background is always painted by the primary graphics layer.
299     ASSERT(m_isMainFrameRenderViewLayer || !m_backgroundLayer);
300     if (m_backgroundLayer) {
301         m_graphicsLayer->setContentsOpaque(false);
302         m_backgroundLayer->setContentsOpaque(m_owningLayer->backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
303     } else {
304         m_graphicsLayer->setContentsOpaque(m_owningLayer->backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
305     }
306 }
307 
hasNonZeroTransformOrigin(const RenderObject * renderer)308 static bool hasNonZeroTransformOrigin(const RenderObject* renderer)
309 {
310     RenderStyle* style = renderer->style();
311     return (style->transformOriginX().type() == Fixed && style->transformOriginX().value())
312         || (style->transformOriginY().type() == Fixed && style->transformOriginY().value());
313 }
314 
layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer * layer)315 static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer* layer)
316 {
317     for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
318         if (curr->hasTransform() || curr->needsCompositedScrolling())
319             return true;
320     }
321 
322     return false;
323 }
324 
shouldClipCompositedBounds() const325 bool CompositedLayerMapping::shouldClipCompositedBounds() const
326 {
327     // Scrollbar layers use this layer for relative positioning, so don't clip.
328     if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
329         return false;
330 
331     if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
332         return false;
333 
334     // Scrolled composited layers are clipped by their ancestor clipping layer,
335     // so don't clip these, either.
336     bool hasAncestorClippingLayer = compositor()->clippedByAncestor(m_owningLayer);
337     bool clippingAncestorIsScrollParent = m_owningLayer->renderer()->containingBlock()->enclosingLayer() == m_owningLayer->ancestorScrollingLayer();
338     if (hasAncestorClippingLayer && clippingAncestorIsScrollParent)
339         return false;
340 
341     return true;
342 }
343 
updateCompositedBounds()344 void CompositedLayerMapping::updateCompositedBounds()
345 {
346     // We need to know if we draw content in order to update our bounds (this has an effect
347     // on whether or not descendands will paint into our backing). Update this value now.
348     updateDrawsContent(isSimpleContainerCompositingLayer());
349 
350     IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
351 
352     // Clip to the size of the document or enclosing overflow-scroll layer.
353     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
354     // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
355     if (shouldClipCompositedBounds()) {
356         RenderView* view = m_owningLayer->renderer()->view();
357         RenderLayer* rootLayer = view->layer();
358 
359         LayoutRect clippingBounds;
360         if (renderer()->style()->position() == FixedPosition && renderer()->container() == view)
361             clippingBounds = view->frameView()->viewportConstrainedVisibleContentRect();
362         else
363             clippingBounds = view->unscaledDocumentRect();
364 
365         if (m_owningLayer != rootLayer)
366             clippingBounds.intersect(m_owningLayer->backgroundClipRect(ClipRectsContext(rootLayer, 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
367 
368         LayoutPoint delta;
369         m_owningLayer->convertToLayerCoords(rootLayer, delta);
370         clippingBounds.move(-delta.x(), -delta.y());
371 
372         layerBounds.intersect(pixelSnappedIntRect(clippingBounds));
373         m_boundsConstrainedByClipping = true;
374     } else {
375         m_boundsConstrainedByClipping = false;
376     }
377 
378     // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
379     // then we need to ensure that the compositing layer has non-zero size so that we can apply
380     // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
381     if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) {
382         layerBounds.setWidth(1);
383         layerBounds.setHeight(1);
384         m_artificiallyInflatedBounds = true;
385     } else {
386         m_artificiallyInflatedBounds = false;
387     }
388 
389     setCompositedBounds(layerBounds);
390 }
391 
updateAfterWidgetResize()392 void CompositedLayerMapping::updateAfterWidgetResize()
393 {
394     if (renderer()->isRenderPart()) {
395         if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
396             innerCompositor->frameViewDidChangeSize();
397             innerCompositor->frameViewDidChangeLocation(contentsBox().location());
398         }
399     }
400 }
401 
updateCompositingReasons()402 void CompositedLayerMapping::updateCompositingReasons()
403 {
404     // All other layers owned by this mapping will have the same compositing reason
405     // for their lifetime, so they are initialized only when created.
406     m_graphicsLayer->setCompositingReasons(m_owningLayer->compositingReasons());
407 }
408 
updateAfterLayout(UpdateAfterLayoutFlags flags)409 void CompositedLayerMapping::updateAfterLayout(UpdateAfterLayoutFlags flags)
410 {
411     RenderLayerCompositor* layerCompositor = compositor();
412     if (!layerCompositor->compositingLayersNeedRebuild()) {
413         // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the
414         // position of this layer's GraphicsLayer depends on the position of our compositing
415         // ancestor's GraphicsLayer. That cannot be determined until all the descendant
416         // RenderLayers of that ancestor have been processed via updateLayerPositions().
417         //
418         // The solution is to update compositing children of this layer here,
419         // via updateCompositingChildrenGeometry().
420         updateCompositedBounds();
421         layerCompositor->updateCompositingDescendantGeometry(m_owningLayer->stackingNode(), m_owningLayer, flags & CompositingChildrenOnly);
422 
423         if (flags & IsUpdateRoot) {
424             updateGraphicsLayerGeometry();
425             layerCompositor->updateRootLayerPosition();
426             RenderLayerStackingNode* stackingContainer = m_owningLayer->stackingNode()->enclosingStackingContainerNode();
427             if (!layerCompositor->compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != m_owningLayer->stackingNode()))
428                 layerCompositor->updateCompositingDescendantGeometry(stackingContainer, stackingContainer->layer(), flags & CompositingChildrenOnly);
429         }
430     }
431 
432     if (flags & NeedsFullRepaint && !paintsIntoCompositedAncestor())
433         setContentsNeedDisplay();
434 }
435 
updateGraphicsLayerConfiguration()436 bool CompositedLayerMapping::updateGraphicsLayerConfiguration()
437 {
438     RenderLayerCompositor* compositor = this->compositor();
439     RenderObject* renderer = this->renderer();
440 
441     m_owningLayer->updateDescendantDependentFlags();
442     m_owningLayer->stackingNode()->updateZOrderLists();
443 
444     bool layerConfigChanged = false;
445     setBackgroundLayerPaintsFixedRootBackground(compositor->needsFixedRootBackgroundLayer(m_owningLayer));
446 
447     // The background layer is currently only used for fixed root backgrounds.
448     if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
449         layerConfigChanged = true;
450 
451     if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
452         layerConfigChanged = true;
453 
454     bool needsDescendentsClippingLayer = compositor->clipsCompositingDescendants(m_owningLayer);
455 
456     // Our scrolling layer will clip.
457     if (m_owningLayer->needsCompositedScrolling())
458         needsDescendentsClippingLayer = false;
459 
460     RenderLayer* scrollParent = m_owningLayer->scrollParent();
461     bool needsAncestorClip = compositor->clippedByAncestor(m_owningLayer);
462     if (scrollParent) {
463         // If our containing block is our ancestor scrolling layer, then we'll already be clipped
464         // to it via our scroll parent and we don't need an ancestor clipping layer.
465         if (m_owningLayer->renderer()->containingBlock()->enclosingLayer() == m_owningLayer->ancestorCompositedScrollingLayer())
466             needsAncestorClip = false;
467     }
468     if (updateClippingLayers(needsAncestorClip, needsDescendentsClippingLayer))
469         layerConfigChanged = true;
470 
471     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
472         layerConfigChanged = true;
473 
474     if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling()))
475         layerConfigChanged = true;
476 
477     updateScrollParent(scrollParent);
478     updateClipParent(m_owningLayer->clipParent());
479 
480     if (updateSquashingLayers(!m_squashedLayers.isEmpty()))
481         layerConfigChanged = true;
482 
483     if (layerConfigChanged)
484         updateInternalHierarchy();
485 
486     if (updateMaskLayer(renderer->hasMask()))
487         m_graphicsLayer->setMaskLayer(m_maskLayer.get());
488 
489     bool hasChildClippingLayer = compositor->clipsCompositingDescendants(m_owningLayer) && (hasClippingLayer() || hasScrollingLayer());
490     bool needsChildClippingMask = (renderer->style()->clipPath() || renderer->style()->hasBorderRadius()) && (hasChildClippingLayer || isAcceleratedContents(renderer));
491     if (updateClippingMaskLayers(needsChildClippingMask)) {
492         if (hasClippingLayer())
493             clippingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
494         else if (hasScrollingLayer())
495             scrollingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
496         else if (isAcceleratedContents(renderer))
497             m_graphicsLayer->setContentsClippingMaskLayer(m_childClippingMaskLayer.get());
498     }
499 
500     if (m_owningLayer->reflectionInfo()) {
501         if (m_owningLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
502             GraphicsLayer* reflectionLayer = m_owningLayer->reflectionInfo()->reflectionLayer()->compositedLayerMapping()->mainGraphicsLayer();
503             m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
504         }
505     } else {
506         m_graphicsLayer->setReplicatedByLayer(0);
507     }
508 
509     updateBackgroundColor(isSimpleContainerCompositingLayer());
510 
511     if (isDirectlyCompositedImage())
512         updateImageContents();
513 
514     if (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) {
515         PluginView* pluginView = toPluginView(toRenderWidget(renderer)->widget());
516         m_graphicsLayer->setContentsToPlatformLayer(pluginView->platformLayer());
517     } else if (renderer->node() && renderer->node()->isFrameOwnerElement() && toHTMLFrameOwnerElement(renderer->node())->contentFrame()) {
518         blink::WebLayer* layer = toHTMLFrameOwnerElement(renderer->node())->contentFrame()->remotePlatformLayer();
519         if (layer)
520             m_graphicsLayer->setContentsToPlatformLayer(layer);
521     } else if (renderer->isVideo()) {
522         HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer->node());
523         m_graphicsLayer->setContentsToPlatformLayer(mediaElement->platformLayer());
524     } else if (isAcceleratedCanvas(renderer)) {
525         HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
526         if (CanvasRenderingContext* context = canvas->renderingContext())
527             m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer());
528         layerConfigChanged = true;
529     }
530     if (renderer->isRenderPart())
531         layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer));
532 
533     return layerConfigChanged;
534 }
535 
clipBox(RenderBox * renderer)536 static IntRect clipBox(RenderBox* renderer)
537 {
538     LayoutRect result = PaintInfo::infiniteRect();
539     if (renderer->hasOverflowClip())
540         result = renderer->overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions.
541 
542     if (renderer->hasClip())
543         result.intersect(renderer->clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
544 
545     return pixelSnappedIntRect(result);
546 }
547 
updateGraphicsLayerGeometry()548 void CompositedLayerMapping::updateGraphicsLayerGeometry()
549 {
550     // If we haven't built z-order lists yet, wait until later.
551     if (m_owningLayer->stackingNode()->isStackingContainer() && m_owningLayer->stackingNode()->zOrderListsDirty())
552         return;
553 
554     // Set transform property, if it is not animating. We have to do this here because the transform
555     // is affected by the layer dimensions.
556     if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()
557         ? !hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyWebkitTransform)
558         : !renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitTransform))
559         updateTransform(renderer()->style());
560 
561     // Set opacity, if it is not animating.
562     if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()
563         ? !hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyOpacity)
564         : !renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity))
565         updateOpacity(renderer()->style());
566 
567     bool isSimpleContainer = isSimpleContainerCompositingLayer();
568 
569     m_owningLayer->updateDescendantDependentFlags();
570 
571     // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
572     // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
573     // non-compositing visible layers.
574     bool contentsVisible = m_owningLayer->hasVisibleContent() || hasVisibleNonCompositingDescendantLayers();
575     if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer()->isVideo()) {
576         HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer()->node());
577         if (mediaElement->isFullscreen())
578             contentsVisible = false;
579     }
580     m_graphicsLayer->setContentsVisible(contentsVisible);
581 
582     RenderStyle* style = renderer()->style();
583     // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
584     bool preserves3D = style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection();
585     m_graphicsLayer->setPreserves3D(preserves3D);
586     m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
587 
588     RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
589 
590     // We compute everything relative to the enclosing compositing layer.
591     IntRect ancestorCompositingBounds;
592     if (compAncestor) {
593         ASSERT(compAncestor->hasCompositedLayerMapping());
594         ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->compositedLayerMapping()->compositedBounds());
595     }
596 
597     IntRect localCompositingBounds = pixelSnappedIntRect(compositedBounds());
598 
599     IntRect relativeCompositingBounds(localCompositingBounds);
600     IntPoint delta;
601     m_owningLayer->convertToPixelSnappedLayerCoords(compAncestor, delta);
602     relativeCompositingBounds.moveBy(delta);
603 
604     IntPoint graphicsLayerParentLocation;
605     if (compAncestor && compAncestor->compositedLayerMapping()->hasClippingLayer()) {
606         // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
607         // position relative to it.
608         IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
609         graphicsLayerParentLocation = clippingBox.location();
610     } else if (compAncestor) {
611         graphicsLayerParentLocation = ancestorCompositingBounds.location();
612     } else {
613         graphicsLayerParentLocation = renderer()->view()->documentRect().location();
614     }
615 
616     if (compAncestor && compAncestor->needsCompositedScrolling()) {
617         RenderBox* renderBox = toRenderBox(compAncestor->renderer());
618         IntSize scrollOffset = renderBox->scrolledContentOffset();
619         IntPoint scrollOrigin(renderBox->borderLeft(), renderBox->borderTop());
620         graphicsLayerParentLocation = scrollOrigin - scrollOffset;
621     }
622 
623     if (compAncestor && m_ancestorClippingLayer) {
624         // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
625         // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
626         // for a compositing layer, rootLayer is the layer itself.
627         ClipRectsContext clipRectsContext(compAncestor, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
628         IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(clipRectsContext).rect()); // FIXME: Incorrect for CSS regions.
629         ASSERT(parentClipRect != PaintInfo::infiniteRect());
630         m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
631         m_ancestorClippingLayer->setSize(parentClipRect.size());
632 
633         // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
634         m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);
635 
636         // The primary layer is then parented in, and positioned relative to this clipping layer.
637         graphicsLayerParentLocation = parentClipRect.location();
638     }
639 
640     FloatSize contentsSize = relativeCompositingBounds.size();
641 
642     m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
643     m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
644 
645     FloatSize oldSize = m_graphicsLayer->size();
646     if (oldSize != contentsSize) {
647         m_graphicsLayer->setSize(contentsSize);
648         // Usually invalidation will happen via layout etc, but if we've affected the layer
649         // size by constraining relative to a clipping ancestor or the viewport, we
650         // have to invalidate to avoid showing stretched content.
651         if (m_boundsConstrainedByClipping)
652             m_graphicsLayer->setNeedsDisplay();
653     }
654 
655     // If we have a layer that clips children, position it.
656     IntRect clippingBox;
657     if (GraphicsLayer* clipLayer = clippingLayer()) {
658         clippingBox = clipBox(toRenderBox(renderer()));
659         clipLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location()));
660         clipLayer->setSize(clippingBox.size());
661         clipLayer->setOffsetFromRenderer(toIntSize(clippingBox.location()));
662         if (m_childClippingMaskLayer && !m_scrollingLayer) {
663             m_childClippingMaskLayer->setPosition(clipLayer->position());
664             m_childClippingMaskLayer->setSize(clipLayer->size());
665             m_childClippingMaskLayer->setOffsetFromRenderer(clipLayer->offsetFromRenderer());
666         }
667     }
668 
669     if (m_maskLayer) {
670         if (m_maskLayer->size() != m_graphicsLayer->size()) {
671             m_maskLayer->setSize(m_graphicsLayer->size());
672             m_maskLayer->setNeedsDisplay();
673         }
674         m_maskLayer->setPosition(FloatPoint());
675         m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
676     }
677 
678     if (m_owningLayer->hasTransform()) {
679         const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
680 
681         // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
682         IntRect layerBounds = IntRect(delta, borderBox.size());
683 
684         // Update properties that depend on layer dimensions
685         FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
686         // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
687         FloatPoint3D anchor(relativeCompositingBounds.width() != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width()  : 0.5f,
688             relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
689             transformOrigin.z());
690         m_graphicsLayer->setAnchorPoint(anchor);
691 
692         RenderStyle* style = renderer()->style();
693         GraphicsLayer* clipLayer = clippingLayer();
694         if (style->hasPerspective()) {
695             TransformationMatrix t = owningLayer()->perspectiveTransform();
696 
697             if (clipLayer) {
698                 clipLayer->setChildrenTransform(t);
699                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
700             } else {
701                 m_graphicsLayer->setChildrenTransform(t);
702             }
703         } else {
704             if (clipLayer)
705                 clipLayer->setChildrenTransform(TransformationMatrix());
706             else
707                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
708         }
709     } else {
710         m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
711     }
712 
713     if (m_foregroundLayer) {
714         FloatPoint foregroundPosition;
715         FloatSize foregroundSize = contentsSize;
716         IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
717         if (hasClippingLayer()) {
718             // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
719             // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
720             foregroundSize = FloatSize(clippingBox.size());
721             foregroundOffset = toIntSize(clippingBox.location());
722         }
723 
724         m_foregroundLayer->setPosition(foregroundPosition);
725         if (foregroundSize != m_foregroundLayer->size()) {
726             m_foregroundLayer->setSize(foregroundSize);
727             m_foregroundLayer->setNeedsDisplay();
728         }
729         m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
730     }
731 
732     if (m_backgroundLayer) {
733         FloatPoint backgroundPosition;
734         FloatSize backgroundSize = contentsSize;
735         if (backgroundLayerPaintsFixedRootBackground()) {
736             FrameView* frameView = toRenderView(renderer())->frameView();
737             backgroundSize = frameView->visibleContentRect().size();
738         }
739         m_backgroundLayer->setPosition(backgroundPosition);
740         if (backgroundSize != m_backgroundLayer->size()) {
741             m_backgroundLayer->setSize(backgroundSize);
742             m_backgroundLayer->setNeedsDisplay();
743         }
744         m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
745     }
746 
747     if (m_owningLayer->reflectionInfo() && m_owningLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
748         CompositedLayerMappingPtr reflectionCompositedLayerMapping = m_owningLayer->reflectionInfo()->reflectionLayer()->compositedLayerMapping();
749         reflectionCompositedLayerMapping->updateGraphicsLayerGeometry();
750 
751         // The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
752         // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
753         FloatRect layerBounds = compositedBounds();
754         FloatRect reflectionLayerBounds = reflectionCompositedLayerMapping->compositedBounds();
755         reflectionCompositedLayerMapping->mainGraphicsLayer()->setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location()));
756     }
757 
758     if (m_scrollingLayer) {
759         ASSERT(m_scrollingContentsLayer);
760         RenderBox* renderBox = toRenderBox(renderer());
761         IntRect clientBox = enclosingIntRect(renderBox->clientBoxRect());
762         // FIXME: We should make RenderBox::clientBoxRect consider scrollbar placement.
763         if (style->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
764             clientBox.move(renderBox->verticalScrollbarWidth(), 0);
765 
766         IntSize adjustedScrollOffset = m_owningLayer->scrollableArea()->adjustedScrollOffset();
767         m_scrollingLayer->setPosition(FloatPoint(clientBox.location() - localCompositingBounds.location()));
768         m_scrollingLayer->setSize(clientBox.size());
769 
770         IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
771         m_scrollingLayer->setOffsetFromRenderer(-toIntSize(clientBox.location()));
772 
773         if (m_childClippingMaskLayer) {
774             m_childClippingMaskLayer->setPosition(m_scrollingLayer->position());
775             m_childClippingMaskLayer->setSize(m_scrollingLayer->size());
776             m_childClippingMaskLayer->setOffsetFromRenderer(toIntSize(clientBox.location()));
777         }
778 
779         bool clientBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
780 
781         IntSize scrollSize(renderBox->scrollWidth(), renderBox->scrollHeight());
782         if (scrollSize != m_scrollingContentsLayer->size() || clientBoxOffsetChanged)
783             m_scrollingContentsLayer->setNeedsDisplay();
784 
785         IntSize scrollingContentsOffset = toIntSize(clientBox.location() - adjustedScrollOffset);
786         if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size()) {
787             bool scrollingCoordinatorHandlesOffset = compositor()->scrollingLayerDidChange(m_owningLayer);
788 
789             if (scrollingCoordinatorHandlesOffset)
790                 m_scrollingContentsLayer->setPosition(-m_owningLayer->scrollableArea()->scrollOrigin());
791             else
792                 m_scrollingContentsLayer->setPosition(FloatPoint(-adjustedScrollOffset));
793         }
794 
795         m_scrollingContentsLayer->setSize(scrollSize);
796         // FIXME: The paint offset and the scroll offset should really be separate concepts.
797         m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
798 
799         if (m_foregroundLayer) {
800             if (m_foregroundLayer->size() != m_scrollingContentsLayer->size())
801                 m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
802             m_foregroundLayer->setNeedsDisplay();
803             m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer());
804         }
805     }
806 
807     if (m_squashingLayer) {
808         ASSERT(compositor()->layerSquashingEnabled());
809 
810         IntRect totalSquashBounds;
811         for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
812             IntRect squashedBounds = compositor()->calculateCompositedBounds(m_squashedLayers[i].renderLayer, m_squashedLayers[i].renderLayer);
813 
814             // Store the composited bounds before applying the offset.
815             // FIXME: consider whether it is more efficient or clarifies the math to store the compositedBounds after applying the offset.
816             m_squashedLayers[i].compositedBounds = squashedBounds;
817 
818             squashedBounds.move(m_squashedLayers[i].offsetFromBackingRoot);
819             totalSquashBounds.unite(squashedBounds);
820         }
821 
822         IntPoint squashLayerPosition;
823         // FIXME: this logic needs to update depending on what "containment" layers are added to CompositedLayerMapping due to other changes
824         if (m_ancestorClippingLayer) {
825             squashLayerPosition = IntPoint(m_ancestorClippingLayer->position().x() + totalSquashBounds.location().x(),
826                 m_ancestorClippingLayer->position().y() + totalSquashBounds.location().y());
827         } else {
828             squashLayerPosition = IntPoint(m_graphicsLayer->position().x() + totalSquashBounds.location().x(),
829                 m_graphicsLayer->position().y() + totalSquashBounds.location().y());
830         }
831 
832         m_squashingLayer->setPosition(squashLayerPosition);
833         m_squashingLayer->setSize(totalSquashBounds.size());
834 
835         // Now that the position of the squashing layer is known, update the offsets for each squashed RenderLayer.
836         for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
837             m_squashedLayers[i].offsetFromRenderer = IntSize(-m_squashedLayers[i].offsetFromBackingRoot.width() - m_graphicsLayer->position().x() + m_squashingLayer->position().x(),
838                 -m_squashedLayers[i].offsetFromBackingRoot.height() - m_graphicsLayer->position().y() + m_squashingLayer->position().y());
839 
840             // FIXME: find a better design to avoid this redundant value - most likely it will make
841             // sense to move the paint task info into RenderLayer's m_compositingProperties.
842             m_squashedLayers[i].renderLayer->setOffsetFromSquashingLayerOrigin(m_squashedLayers[i].offsetFromRenderer);
843         }
844     }
845 
846     if (m_owningLayer->scrollableArea())
847         m_owningLayer->scrollableArea()->positionOverflowControls();
848 
849     // We can't make this call in RenderLayerCompositor::allocateOrClearCompositedLayerMapping
850     // since it depends on whether compAncestor draws content, which gets updated later.
851     updateRequiresOwnBackingStoreForAncestorReasons(compAncestor);
852 
853     if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
854         updateLayerBlendMode(style);
855         updateIsRootForIsolatedGroup();
856     }
857 
858     updateContentsRect(isSimpleContainer);
859     updateBackgroundColor(isSimpleContainer);
860     updateDrawsContent(isSimpleContainer);
861     updateContentsOpaque();
862     updateAfterWidgetResize();
863     registerScrollingLayers();
864 
865     updateCompositingReasons();
866 }
867 
registerScrollingLayers()868 void CompositedLayerMapping::registerScrollingLayers()
869 {
870     // Register fixed position layers and their containers with the scrolling coordinator.
871     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
872     if (!scrollingCoordinator)
873         return;
874 
875     compositor()->updateViewportConstraintStatus(m_owningLayer);
876 
877     scrollingCoordinator->updateLayerPositionConstraint(m_owningLayer);
878 
879     // Page scale is applied as a transform on the root render view layer. Because the scroll
880     // layer is further up in the hierarchy, we need to avoid marking the root render view
881     // layer as a container.
882     bool isContainer = m_owningLayer->hasTransform() && !m_owningLayer->isRootLayer();
883     // FIXME: we should make certain that childForSuperLayers will never be the m_squashingContainmentLayer here
884     scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer);
885 }
886 
updateInternalHierarchy()887 void CompositedLayerMapping::updateInternalHierarchy()
888 {
889     // m_foregroundLayer has to be inserted in the correct order with child layers,
890     // so it's not inserted here.
891     if (m_ancestorClippingLayer)
892         m_ancestorClippingLayer->removeAllChildren();
893 
894     m_graphicsLayer->removeFromParent();
895 
896     if (m_ancestorClippingLayer)
897         m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
898 
899     if (m_childContainmentLayer) {
900         m_childContainmentLayer->removeFromParent();
901         m_graphicsLayer->addChild(m_childContainmentLayer.get());
902     }
903 
904     if (m_scrollingLayer) {
905         GraphicsLayer* superlayer = m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
906         m_scrollingLayer->removeFromParent();
907         superlayer->addChild(m_scrollingLayer.get());
908     }
909 
910     // The clip for child layers does not include space for overflow controls, so they exist as
911     // siblings of the clipping layer if we have one. Normal children of this layer are set as
912     // children of the clipping layer.
913     if (m_layerForHorizontalScrollbar) {
914         m_layerForHorizontalScrollbar->removeFromParent();
915         m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
916     }
917     if (m_layerForVerticalScrollbar) {
918         m_layerForVerticalScrollbar->removeFromParent();
919         m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
920     }
921     if (m_layerForScrollCorner) {
922         m_layerForScrollCorner->removeFromParent();
923         m_graphicsLayer->addChild(m_layerForScrollCorner.get());
924     }
925 
926     // The squashing containment layer, if it exists, becomes a no-op parent.
927     if (m_squashingLayer) {
928         ASSERT(compositor()->layerSquashingEnabled());
929         ASSERT(m_squashingContainmentLayer);
930 
931         m_squashingContainmentLayer->removeAllChildren();
932 
933         if (m_ancestorClippingLayer)
934             m_squashingContainmentLayer->addChild(m_ancestorClippingLayer.get());
935         else
936             m_squashingContainmentLayer->addChild(m_graphicsLayer.get());
937 
938         m_squashingContainmentLayer->addChild(m_squashingLayer.get());
939     }
940 }
941 
updateContentsRect(bool isSimpleContainer)942 void CompositedLayerMapping::updateContentsRect(bool isSimpleContainer)
943 {
944     IntRect contentsRect;
945     if (isSimpleContainer && renderer()->hasBackground())
946         contentsRect = backgroundBox();
947     else
948         contentsRect = contentsBox();
949 
950     m_graphicsLayer->setContentsRect(contentsRect);
951 }
952 
updateDrawsContent(bool isSimpleContainer)953 void CompositedLayerMapping::updateDrawsContent(bool isSimpleContainer)
954 {
955     if (m_scrollingLayer) {
956         // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
957         // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
958         // m_scrollingLayer never has backing store.
959         // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
960         bool hasNonScrollingPaintedContent = m_owningLayer->hasVisibleContent() && m_owningLayer->hasBoxDecorationsOrBackground();
961         m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
962 
963         bool hasScrollingPaintedContent = m_owningLayer->hasVisibleContent() && (renderer()->hasBackground() || paintsChildren());
964         m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
965         return;
966     }
967 
968     bool hasPaintedContent = containsPaintedContent(isSimpleContainer);
969     if (hasPaintedContent && isAcceleratedCanvas(renderer())) {
970         CanvasRenderingContext* context = toHTMLCanvasElement(renderer()->node())->renderingContext();
971         // Content layer may be null if context is lost.
972         if (blink::WebLayer* contentLayer = context->platformLayer()) {
973             Color bgColor;
974             if (contentLayerSupportsDirectBackgroundComposition(renderer())) {
975                 bgColor = rendererBackgroundColor();
976                 hasPaintedContent = false;
977             }
978             contentLayer->setBackgroundColor(bgColor.rgb());
979         }
980     }
981 
982     // FIXME: we could refine this to only allocate backings for one of these layers if possible.
983     m_graphicsLayer->setDrawsContent(hasPaintedContent);
984     if (m_foregroundLayer)
985         m_foregroundLayer->setDrawsContent(hasPaintedContent);
986 
987     if (m_backgroundLayer)
988         m_backgroundLayer->setDrawsContent(hasPaintedContent);
989 }
990 
991 // Return true if the layers changed.
updateClippingLayers(bool needsAncestorClip,bool needsDescendantClip)992 bool CompositedLayerMapping::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
993 {
994     bool layersChanged = false;
995 
996     if (needsAncestorClip) {
997         if (!m_ancestorClippingLayer) {
998             m_ancestorClippingLayer = createGraphicsLayer(CompositingReasonLayerForClip);
999             m_ancestorClippingLayer->setMasksToBounds(true);
1000             layersChanged = true;
1001         }
1002     } else if (m_ancestorClippingLayer) {
1003         m_ancestorClippingLayer->removeFromParent();
1004         m_ancestorClippingLayer = nullptr;
1005         layersChanged = true;
1006     }
1007 
1008     if (needsDescendantClip) {
1009         // We don't need a child containment layer if we're the main frame render view
1010         // layer. It's redundant as the frame clip above us will handle this clipping.
1011         if (!m_childContainmentLayer && !m_isMainFrameRenderViewLayer) {
1012             m_childContainmentLayer = createGraphicsLayer(CompositingReasonLayerForClip);
1013             m_childContainmentLayer->setMasksToBounds(true);
1014             layersChanged = true;
1015         }
1016     } else if (hasClippingLayer()) {
1017         m_childContainmentLayer->removeFromParent();
1018         m_childContainmentLayer = nullptr;
1019         layersChanged = true;
1020     }
1021 
1022     return layersChanged;
1023 }
1024 
setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)1025 void CompositedLayerMapping::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
1026 {
1027     m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
1028 }
1029 
updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer,bool needsVerticalScrollbarLayer,bool needsScrollCornerLayer)1030 bool CompositedLayerMapping::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
1031 {
1032     bool horizontalScrollbarLayerChanged = false;
1033     if (needsHorizontalScrollbarLayer) {
1034         if (!m_layerForHorizontalScrollbar) {
1035             m_layerForHorizontalScrollbar = createGraphicsLayer(CompositingReasonLayerForScrollbar);
1036             horizontalScrollbarLayerChanged = true;
1037         }
1038     } else if (m_layerForHorizontalScrollbar) {
1039         m_layerForHorizontalScrollbar = nullptr;
1040         horizontalScrollbarLayerChanged = true;
1041     }
1042 
1043     bool verticalScrollbarLayerChanged = false;
1044     if (needsVerticalScrollbarLayer) {
1045         if (!m_layerForVerticalScrollbar) {
1046             m_layerForVerticalScrollbar = createGraphicsLayer(CompositingReasonLayerForScrollbar);
1047             verticalScrollbarLayerChanged = true;
1048         }
1049     } else if (m_layerForVerticalScrollbar) {
1050         m_layerForVerticalScrollbar = nullptr;
1051         verticalScrollbarLayerChanged = true;
1052     }
1053 
1054     bool scrollCornerLayerChanged = false;
1055     if (needsScrollCornerLayer) {
1056         if (!m_layerForScrollCorner) {
1057             m_layerForScrollCorner = createGraphicsLayer(CompositingReasonLayerForScrollbar);
1058             scrollCornerLayerChanged = true;
1059         }
1060     } else if (m_layerForScrollCorner) {
1061         m_layerForScrollCorner = nullptr;
1062         scrollCornerLayerChanged = true;
1063     }
1064 
1065     if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
1066         if (horizontalScrollbarLayerChanged)
1067             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer->scrollableArea(), HorizontalScrollbar);
1068         if (verticalScrollbarLayerChanged)
1069             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer->scrollableArea(), VerticalScrollbar);
1070     }
1071 
1072     return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
1073 }
1074 
positionOverflowControlsLayers(const IntSize & offsetFromRoot)1075 void CompositedLayerMapping::positionOverflowControlsLayers(const IntSize& offsetFromRoot)
1076 {
1077     IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
1078     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
1079         Scrollbar* hBar = m_owningLayer->scrollableArea()->horizontalScrollbar();
1080         if (hBar) {
1081             layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
1082             layer->setSize(hBar->frameRect().size());
1083             if (layer->hasContentsLayer())
1084                 layer->setContentsRect(IntRect(IntPoint(), hBar->frameRect().size()));
1085         }
1086         layer->setDrawsContent(hBar && !layer->hasContentsLayer());
1087     }
1088 
1089     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
1090         Scrollbar* vBar = m_owningLayer->scrollableArea()->verticalScrollbar();
1091         if (vBar) {
1092             layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
1093             layer->setSize(vBar->frameRect().size());
1094             if (layer->hasContentsLayer())
1095                 layer->setContentsRect(IntRect(IntPoint(), vBar->frameRect().size()));
1096         }
1097         layer->setDrawsContent(vBar && !layer->hasContentsLayer());
1098     }
1099 
1100     if (GraphicsLayer* layer = layerForScrollCorner()) {
1101         const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollableArea()->scrollCornerAndResizerRect();
1102         layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
1103         layer->setSize(scrollCornerAndResizer.size());
1104         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
1105     }
1106 }
1107 
hasUnpositionedOverflowControlsLayers() const1108 bool CompositedLayerMapping::hasUnpositionedOverflowControlsLayers() const
1109 {
1110     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
1111         if (!layer->drawsContent())
1112             return true;
1113     }
1114 
1115     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
1116         if (!layer->drawsContent())
1117             return true;
1118     }
1119 
1120     if (GraphicsLayer* layer = layerForScrollCorner()) {
1121         if (!layer->drawsContent())
1122             return true;
1123     }
1124 
1125     return false;
1126 }
1127 
updateForegroundLayer(bool needsForegroundLayer)1128 bool CompositedLayerMapping::updateForegroundLayer(bool needsForegroundLayer)
1129 {
1130     bool layerChanged = false;
1131     if (needsForegroundLayer) {
1132         if (!m_foregroundLayer) {
1133             m_foregroundLayer = createGraphicsLayer(CompositingReasonLayerForForeground);
1134             m_foregroundLayer->setDrawsContent(true);
1135             m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
1136             layerChanged = true;
1137         }
1138     } else if (m_foregroundLayer) {
1139         m_foregroundLayer->removeFromParent();
1140         m_foregroundLayer = nullptr;
1141         layerChanged = true;
1142     }
1143 
1144     if (layerChanged)
1145         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1146 
1147     return layerChanged;
1148 }
1149 
updateBackgroundLayer(bool needsBackgroundLayer)1150 bool CompositedLayerMapping::updateBackgroundLayer(bool needsBackgroundLayer)
1151 {
1152     bool layerChanged = false;
1153     if (needsBackgroundLayer) {
1154         if (!m_backgroundLayer) {
1155             m_backgroundLayer = createGraphicsLayer(CompositingReasonLayerForBackground);
1156             m_backgroundLayer->setDrawsContent(true);
1157             m_backgroundLayer->setAnchorPoint(FloatPoint3D());
1158             m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
1159 #if !OS(ANDROID)
1160             m_backgroundLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
1161             m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(false);
1162 #endif
1163             layerChanged = true;
1164         }
1165     } else {
1166         if (m_backgroundLayer) {
1167             m_backgroundLayer->removeFromParent();
1168             m_backgroundLayer = nullptr;
1169 #if !OS(ANDROID)
1170             m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
1171 #endif
1172             layerChanged = true;
1173         }
1174     }
1175 
1176     if (layerChanged && !m_owningLayer->renderer()->documentBeingDestroyed())
1177         compositor()->rootFixedBackgroundsChanged();
1178 
1179     return layerChanged;
1180 }
1181 
updateMaskLayer(bool needsMaskLayer)1182 bool CompositedLayerMapping::updateMaskLayer(bool needsMaskLayer)
1183 {
1184     bool layerChanged = false;
1185     if (needsMaskLayer) {
1186         if (!m_maskLayer) {
1187             m_maskLayer = createGraphicsLayer(CompositingReasonLayerForMask);
1188             m_maskLayer->setDrawsContent(true);
1189             m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
1190             layerChanged = true;
1191         }
1192     } else if (m_maskLayer) {
1193         m_maskLayer = nullptr;
1194         layerChanged = true;
1195     }
1196 
1197     if (layerChanged)
1198         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1199 
1200     return layerChanged;
1201 }
1202 
updateClippingMaskLayers(bool needsChildClippingMaskLayer)1203 bool CompositedLayerMapping::updateClippingMaskLayers(bool needsChildClippingMaskLayer)
1204 {
1205     bool layerChanged = false;
1206     if (needsChildClippingMaskLayer) {
1207         if (!m_childClippingMaskLayer) {
1208             m_childClippingMaskLayer = createGraphicsLayer(CompositingReasonLayerForMask);
1209             m_childClippingMaskLayer->setDrawsContent(true);
1210             m_childClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintChildClippingMask);
1211             layerChanged = true;
1212         }
1213     } else if (m_childClippingMaskLayer) {
1214         m_childClippingMaskLayer = nullptr;
1215         layerChanged = true;
1216     }
1217     return layerChanged;
1218 }
1219 
updateScrollingLayers(bool needsScrollingLayers)1220 bool CompositedLayerMapping::updateScrollingLayers(bool needsScrollingLayers)
1221 {
1222     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
1223 
1224     bool layerChanged = false;
1225     if (needsScrollingLayers) {
1226         if (!m_scrollingLayer) {
1227             // Outer layer which corresponds with the scroll view.
1228             m_scrollingLayer = createGraphicsLayer(CompositingReasonLayerForClip);
1229             m_scrollingLayer->setDrawsContent(false);
1230             m_scrollingLayer->setMasksToBounds(true);
1231 
1232             // Inner layer which renders the content that scrolls.
1233             m_scrollingContentsLayer = createGraphicsLayer(CompositingReasonLayerForScrollingContainer);
1234             m_scrollingContentsLayer->setDrawsContent(true);
1235             GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
1236             if (!m_foregroundLayer)
1237                 paintPhase |= GraphicsLayerPaintForeground;
1238             m_scrollingContentsLayer->setPaintingPhase(paintPhase);
1239             m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
1240 
1241             layerChanged = true;
1242             if (scrollingCoordinator)
1243                 scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer->scrollableArea());
1244         }
1245     } else if (m_scrollingLayer) {
1246         m_scrollingLayer = nullptr;
1247         m_scrollingContentsLayer = nullptr;
1248         layerChanged = true;
1249         if (scrollingCoordinator)
1250             scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer->scrollableArea());
1251     }
1252 
1253     if (layerChanged) {
1254         updateInternalHierarchy();
1255         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1256         m_graphicsLayer->setNeedsDisplay();
1257         if (renderer()->view())
1258             compositor()->scrollingLayerDidChange(m_owningLayer);
1259     }
1260 
1261     return layerChanged;
1262 }
1263 
updateScrollParentForGraphicsLayer(GraphicsLayer * layer,GraphicsLayer * topmostLayer,RenderLayer * scrollParent,ScrollingCoordinator * scrollingCoordinator)1264 static void updateScrollParentForGraphicsLayer(GraphicsLayer* layer, GraphicsLayer* topmostLayer, RenderLayer* scrollParent, ScrollingCoordinator* scrollingCoordinator)
1265 {
1266     if (!layer)
1267         return;
1268 
1269     // Only the topmost layer has a scroll parent. All other layers have a null scroll parent.
1270     if (layer != topmostLayer)
1271         scrollParent = 0;
1272 
1273     scrollingCoordinator->updateScrollParentForGraphicsLayer(layer, scrollParent);
1274 }
1275 
updateScrollParent(RenderLayer * scrollParent)1276 void CompositedLayerMapping::updateScrollParent(RenderLayer* scrollParent)
1277 {
1278 
1279     if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
1280         GraphicsLayer* topmostLayer = childForSuperlayers();
1281         updateScrollParentForGraphicsLayer(m_squashingContainmentLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
1282         updateScrollParentForGraphicsLayer(m_ancestorClippingLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
1283         updateScrollParentForGraphicsLayer(m_graphicsLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
1284     }
1285 }
1286 
updateClipParent(RenderLayer * clipParent)1287 void CompositedLayerMapping::updateClipParent(RenderLayer* clipParent)
1288 {
1289     if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer))
1290         scrollingCoordinator->updateClipParentForGraphicsLayer(m_graphicsLayer.get(), clipParent);
1291 }
1292 
updateSquashingLayers(bool needsSquashingLayers)1293 bool CompositedLayerMapping::updateSquashingLayers(bool needsSquashingLayers)
1294 {
1295     bool layersChanged = false;
1296 
1297     if (needsSquashingLayers) {
1298         ASSERT(compositor()->layerSquashingEnabled());
1299 
1300         if (!m_squashingLayer) {
1301             ASSERT(!m_squashingContainmentLayer);
1302 
1303             m_squashingLayer = createGraphicsLayer(CompositingReasonOverlap);
1304             m_squashingLayer->setDrawsContent(true);
1305             m_squashingLayer->setNeedsDisplay();
1306             layersChanged = true;
1307 
1308             // FIXME: containment layer needs a new CompositingReason, CompositingReasonOverlap is not appropriate.
1309             m_squashingContainmentLayer = createGraphicsLayer(CompositingReasonOverlap);
1310             // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
1311             bool preserves3D = renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection();
1312             m_squashingContainmentLayer->setPreserves3D(preserves3D);
1313             layersChanged = true;
1314         }
1315 
1316         ASSERT(m_squashingLayer && m_squashingContainmentLayer);
1317     } else {
1318         if (m_squashingLayer) {
1319             m_squashingLayer->removeFromParent();
1320             m_squashingLayer = nullptr;
1321             layersChanged = true;
1322             // FIXME: do we need to invalidate something here?
1323 
1324             ASSERT(m_squashingContainmentLayer);
1325             m_squashingContainmentLayer->removeFromParent();
1326             m_squashingContainmentLayer = nullptr;
1327             layersChanged = true;
1328         }
1329 
1330         ASSERT(!m_squashingLayer && !m_squashingContainmentLayer);
1331     }
1332 
1333     return layersChanged;
1334 }
1335 
paintingPhaseForPrimaryLayer() const1336 GraphicsLayerPaintingPhase CompositedLayerMapping::paintingPhaseForPrimaryLayer() const
1337 {
1338     unsigned phase = 0;
1339     if (!m_backgroundLayer)
1340         phase |= GraphicsLayerPaintBackground;
1341     if (!m_foregroundLayer)
1342         phase |= GraphicsLayerPaintForeground;
1343     if (!m_maskLayer)
1344         phase |= GraphicsLayerPaintMask;
1345 
1346     if (m_scrollingContentsLayer) {
1347         phase &= ~GraphicsLayerPaintForeground;
1348         phase |= GraphicsLayerPaintCompositedScroll;
1349     }
1350 
1351     if (m_owningLayer->compositingReasons() & CompositingReasonOverflowScrollingParent)
1352         phase |= GraphicsLayerPaintCompositedScroll;
1353 
1354     return static_cast<GraphicsLayerPaintingPhase>(phase);
1355 }
1356 
compositingOpacity(float rendererOpacity) const1357 float CompositedLayerMapping::compositingOpacity(float rendererOpacity) const
1358 {
1359     float finalOpacity = rendererOpacity;
1360 
1361     for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) {
1362         // We only care about parents that are stacking contexts.
1363         // Recall that opacity creates stacking context.
1364         if (!curr->stackingNode()->isStackingContainer())
1365             continue;
1366 
1367         // If we found a composited layer, regardless of whether it actually
1368         // paints into it, we want to compute opacity relative to it. So we can
1369         // break here.
1370         //
1371         // FIXME: with grouped backings, a composited descendant will have to
1372         // continue past the grouped (squashed) layers that its parents may
1373         // contribute to. This whole confusion can be avoided by specifying
1374         // explicitly the composited ancestor where we would stop accumulating
1375         // opacity.
1376         if (curr->compositingState() == PaintsIntoOwnBacking || curr->compositingState() == HasOwnBackingButPaintsIntoAncestor)
1377             break;
1378 
1379         finalOpacity *= curr->renderer()->opacity();
1380     }
1381 
1382     return finalOpacity;
1383 }
1384 
rendererBackgroundColor() const1385 Color CompositedLayerMapping::rendererBackgroundColor() const
1386 {
1387     RenderObject* backgroundRenderer = renderer();
1388     if (backgroundRenderer->isRoot())
1389         backgroundRenderer = backgroundRenderer->rendererForRootBackground();
1390 
1391     return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor);
1392 }
1393 
updateBackgroundColor(bool isSimpleContainer)1394 void CompositedLayerMapping::updateBackgroundColor(bool isSimpleContainer)
1395 {
1396     Color backgroundColor = rendererBackgroundColor();
1397     if (isSimpleContainer) {
1398         m_graphicsLayer->setContentsToSolidColor(backgroundColor);
1399         m_graphicsLayer->setBackgroundColor(Color());
1400     } else {
1401         // An unset (invalid) color will remove the solid color.
1402         m_graphicsLayer->setContentsToSolidColor(Color());
1403         m_graphicsLayer->setBackgroundColor(backgroundColor);
1404     }
1405 }
1406 
supportsDirectBoxDecorationsComposition(const RenderObject * renderer)1407 static bool supportsDirectBoxDecorationsComposition(const RenderObject* renderer)
1408 {
1409     if (renderer->hasClip())
1410         return false;
1411 
1412     if (hasBoxDecorationsOrBackgroundImage(renderer->style()))
1413         return false;
1414 
1415     // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
1416     if (renderer->style()->backgroundComposite() != CompositeSourceOver)
1417         return false;
1418 
1419     if (renderer->style()->backgroundClip() == TextFillBox)
1420         return false;
1421 
1422     return true;
1423 }
1424 
paintsBoxDecorations() const1425 bool CompositedLayerMapping::paintsBoxDecorations() const
1426 {
1427     if (!m_owningLayer->hasVisibleBoxDecorations())
1428         return false;
1429 
1430     if (!supportsDirectBoxDecorationsComposition(renderer()))
1431         return true;
1432 
1433     return false;
1434 }
1435 
paintsChildren() const1436 bool CompositedLayerMapping::paintsChildren() const
1437 {
1438     if (m_owningLayer->hasVisibleContent() && m_owningLayer->hasNonEmptyChildRenderers())
1439         return true;
1440 
1441     if (hasVisibleNonCompositingDescendantLayers())
1442         return true;
1443 
1444     return false;
1445 }
1446 
isCompositedPlugin(RenderObject * renderer)1447 static bool isCompositedPlugin(RenderObject* renderer)
1448 {
1449     return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
1450 }
1451 
1452 // A "simple container layer" is a RenderLayer which has no visible content to render.
1453 // It may have no children, or all its children may be themselves composited.
1454 // This is a useful optimization, because it allows us to avoid allocating backing store.
isSimpleContainerCompositingLayer() const1455 bool CompositedLayerMapping::isSimpleContainerCompositingLayer() const
1456 {
1457     RenderObject* renderObject = renderer();
1458     if (renderObject->hasMask()) // masks require special treatment
1459         return false;
1460 
1461     if (renderObject->isReplaced() && !isCompositedPlugin(renderObject))
1462         return false;
1463 
1464     if (paintsBoxDecorations() || paintsChildren())
1465         return false;
1466 
1467     if (renderObject->isRenderRegion())
1468         return false;
1469 
1470     if (renderObject->node() && renderObject->node()->isDocumentNode()) {
1471         // Look to see if the root object has a non-simple background
1472         RenderObject* rootObject = renderObject->document().documentElement() ? renderObject->document().documentElement()->renderer() : 0;
1473         if (!rootObject)
1474             return false;
1475 
1476         RenderStyle* style = rootObject->style();
1477 
1478         // Reject anything that has a border, a border-radius or outline,
1479         // or is not a simple background (no background, or solid color).
1480         if (hasBoxDecorationsOrBackgroundImage(style))
1481             return false;
1482 
1483         // Now look at the body's renderer.
1484         HTMLElement* body = renderObject->document().body();
1485         RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
1486         if (!bodyObject)
1487             return false;
1488 
1489         style = bodyObject->style();
1490 
1491         if (hasBoxDecorationsOrBackgroundImage(style))
1492             return false;
1493     }
1494 
1495     return true;
1496 }
1497 
hasVisibleNonCompositingDescendant(RenderLayer * parent)1498 static bool hasVisibleNonCompositingDescendant(RenderLayer* parent)
1499 {
1500     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
1501     parent->stackingNode()->updateLayerListsIfNeeded();
1502 
1503 #if !ASSERT_DISABLED
1504     LayerListMutationDetector mutationChecker(parent->stackingNode());
1505 #endif
1506 
1507     RenderLayerStackingNodeIterator normalFlowIterator(*parent->stackingNode(), NormalFlowChildren);
1508     while (RenderLayerStackingNode* curNode = normalFlowIterator.next()) {
1509         RenderLayer* curLayer = curNode->layer();
1510         if (!curLayer->hasCompositedLayerMapping()
1511             && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
1512             return true;
1513     }
1514 
1515     if (!parent->hasVisibleDescendant())
1516         return false;
1517 
1518     RenderLayerStackingNodeIterator zOrderIterator(*parent->stackingNode(), NegativeZOrderChildren | PositiveZOrderChildren);
1519     while (RenderLayerStackingNode* curNode = zOrderIterator.next()) {
1520         RenderLayer* curLayer = curNode->layer();
1521         if (!curLayer->hasCompositedLayerMapping()
1522             && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
1523             return true;
1524     }
1525 
1526     return false;
1527 }
1528 
1529 // FIXME: By name the implementation is correct. But the code that uses this function means something
1530 // very slightly different - the implementation needs to also include composited descendants that
1531 // don't paint into their own backing, and instead paint into this backing.
hasVisibleNonCompositingDescendantLayers() const1532 bool CompositedLayerMapping::hasVisibleNonCompositingDescendantLayers() const
1533 {
1534     return hasVisibleNonCompositingDescendant(m_owningLayer);
1535 }
1536 
containsPaintedContent(bool isSimpleContainer) const1537 bool CompositedLayerMapping::containsPaintedContent(bool isSimpleContainer) const
1538 {
1539     if (isSimpleContainer || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer->isReflection())
1540         return false;
1541 
1542     if (isDirectlyCompositedImage())
1543         return false;
1544 
1545     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
1546     // and set background color on the layer in that case, instead of allocating backing store and painting.
1547     if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
1548         return m_owningLayer->hasBoxDecorationsOrBackground();
1549 
1550     return true;
1551 }
1552 
1553 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
1554 // that require painting. Direct compositing saves backing store.
isDirectlyCompositedImage() const1555 bool CompositedLayerMapping::isDirectlyCompositedImage() const
1556 {
1557     RenderObject* renderObject = renderer();
1558 
1559     if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground() || renderObject->hasClip())
1560         return false;
1561 
1562     RenderImage* imageRenderer = toRenderImage(renderObject);
1563     if (ImageResource* cachedImage = imageRenderer->cachedImage()) {
1564         if (!cachedImage->hasImage())
1565             return false;
1566 
1567         Image* image = cachedImage->imageForRenderer(imageRenderer);
1568         return image->isBitmapImage();
1569     }
1570 
1571     return false;
1572 }
1573 
contentChanged(ContentChangeType changeType)1574 void CompositedLayerMapping::contentChanged(ContentChangeType changeType)
1575 {
1576     if ((changeType == ImageChanged) && isDirectlyCompositedImage()) {
1577         updateImageContents();
1578         return;
1579     }
1580 
1581     if ((changeType == MaskImageChanged) && m_maskLayer) {
1582         // The composited layer bounds relies on box->maskClipRect(), which changes
1583         // when the mask image becomes available.
1584         updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot);
1585     }
1586 
1587     if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && isAcceleratedCanvas(renderer())) {
1588         m_graphicsLayer->setContentsNeedsDisplay();
1589         return;
1590     }
1591 }
1592 
updateImageContents()1593 void CompositedLayerMapping::updateImageContents()
1594 {
1595     ASSERT(renderer()->isImage());
1596     RenderImage* imageRenderer = toRenderImage(renderer());
1597 
1598     ImageResource* cachedImage = imageRenderer->cachedImage();
1599     if (!cachedImage)
1600         return;
1601 
1602     Image* image = cachedImage->imageForRenderer(imageRenderer);
1603     if (!image)
1604         return;
1605 
1606     // We have to wait until the image is fully loaded before setting it on the layer.
1607     if (!cachedImage->isLoaded())
1608         return;
1609 
1610     // This is a no-op if the layer doesn't have an inner layer for the image.
1611     m_graphicsLayer->setContentsToImage(image);
1612     bool isSimpleContainer = false;
1613     updateDrawsContent(isSimpleContainer);
1614 
1615     // Image animation is "lazy", in that it automatically stops unless someone is drawing
1616     // the image. So we have to kick the animation each time; this has the downside that the
1617     // image will keep animating, even if its layer is not visible.
1618     image->startAnimation();
1619 }
1620 
computeTransformOrigin(const IntRect & borderBox) const1621 FloatPoint3D CompositedLayerMapping::computeTransformOrigin(const IntRect& borderBox) const
1622 {
1623     RenderStyle* style = renderer()->style();
1624 
1625     FloatPoint3D origin;
1626     origin.setX(floatValueForLength(style->transformOriginX(), borderBox.width()));
1627     origin.setY(floatValueForLength(style->transformOriginY(), borderBox.height()));
1628     origin.setZ(style->transformOriginZ());
1629 
1630     return origin;
1631 }
1632 
computePerspectiveOrigin(const IntRect & borderBox) const1633 FloatPoint CompositedLayerMapping::computePerspectiveOrigin(const IntRect& borderBox) const
1634 {
1635     RenderStyle* style = renderer()->style();
1636 
1637     float boxWidth = borderBox.width();
1638     float boxHeight = borderBox.height();
1639 
1640     FloatPoint origin;
1641     origin.setX(floatValueForLength(style->perspectiveOriginX(), boxWidth));
1642     origin.setY(floatValueForLength(style->perspectiveOriginY(), boxHeight));
1643 
1644     return origin;
1645 }
1646 
1647 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
contentOffsetInCompostingLayer() const1648 IntSize CompositedLayerMapping::contentOffsetInCompostingLayer() const
1649 {
1650     return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y());
1651 }
1652 
contentsBox() const1653 IntRect CompositedLayerMapping::contentsBox() const
1654 {
1655     IntRect contentsBox = contentsRect(renderer());
1656     contentsBox.move(contentOffsetInCompostingLayer());
1657     return contentsBox;
1658 }
1659 
backgroundBox() const1660 IntRect CompositedLayerMapping::backgroundBox() const
1661 {
1662     IntRect backgroundBox = backgroundRect(renderer());
1663     backgroundBox.move(contentOffsetInCompostingLayer());
1664     return backgroundBox;
1665 }
1666 
parentForSublayers() const1667 GraphicsLayer* CompositedLayerMapping::parentForSublayers() const
1668 {
1669     if (m_scrollingContentsLayer)
1670         return m_scrollingContentsLayer.get();
1671 
1672     return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
1673 }
1674 
childForSuperlayers() const1675 GraphicsLayer* CompositedLayerMapping::childForSuperlayers() const
1676 {
1677     if (m_squashingContainmentLayer)
1678         return m_squashingContainmentLayer.get();
1679 
1680     if (m_ancestorClippingLayer)
1681         return m_ancestorClippingLayer.get();
1682 
1683     return m_graphicsLayer.get();
1684 }
1685 
updateRequiresOwnBackingStoreForAncestorReasons(const RenderLayer * compositingAncestorLayer)1686 bool CompositedLayerMapping::updateRequiresOwnBackingStoreForAncestorReasons(const RenderLayer* compositingAncestorLayer)
1687 {
1688     bool previousRequiresOwnBackingStoreForAncestorReasons = m_requiresOwnBackingStoreForAncestorReasons;
1689     bool previousPaintsIntoCompositedAncestor = paintsIntoCompositedAncestor();
1690     bool canPaintIntoAncestor = compositingAncestorLayer
1691         && (compositingAncestorLayer->compositedLayerMapping()->mainGraphicsLayer()->drawsContent()
1692             || compositingAncestorLayer->compositedLayerMapping()->paintsIntoCompositedAncestor());
1693     m_requiresOwnBackingStoreForAncestorReasons = !canPaintIntoAncestor;
1694 
1695     if (paintsIntoCompositedAncestor() != previousPaintsIntoCompositedAncestor)
1696         paintsIntoCompositedAncestorChanged();
1697     return m_requiresOwnBackingStoreForAncestorReasons != previousRequiresOwnBackingStoreForAncestorReasons;
1698 }
1699 
updateRequiresOwnBackingStoreForIntrinsicReasons()1700 bool CompositedLayerMapping::updateRequiresOwnBackingStoreForIntrinsicReasons()
1701 {
1702     bool previousRequiresOwnBackingStoreForIntrinsicReasons = m_requiresOwnBackingStoreForIntrinsicReasons;
1703     bool previousPaintsIntoCompositedAncestor = paintsIntoCompositedAncestor();
1704     RenderObject* renderer = m_owningLayer->renderer();
1705     m_requiresOwnBackingStoreForIntrinsicReasons = m_owningLayer->isRootLayer()
1706         || (m_owningLayer->compositingReasons() & CompositingReasonComboReasonsThatRequireOwnBacking)
1707         || m_owningLayer->transform()
1708         || m_owningLayer->clipsCompositingDescendantsWithBorderRadius() // FIXME: Revisit this if the paintsIntoCompositedAncestor state is removed.
1709         || renderer->isTransparent()
1710         || renderer->hasMask()
1711         || renderer->hasReflection()
1712         || renderer->hasFilter();
1713 
1714     if (paintsIntoCompositedAncestor() != previousPaintsIntoCompositedAncestor)
1715         paintsIntoCompositedAncestorChanged();
1716     return m_requiresOwnBackingStoreForIntrinsicReasons != previousRequiresOwnBackingStoreForIntrinsicReasons;
1717 }
1718 
paintsIntoCompositedAncestorChanged()1719 void CompositedLayerMapping::paintsIntoCompositedAncestorChanged()
1720 {
1721     // The answer to paintsIntoCompositedAncestor() affects cached clip rects, so when
1722     // it changes we have to clear clip rects on descendants.
1723     m_owningLayer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
1724     m_owningLayer->repainter().computeRepaintRectsIncludingDescendants();
1725 
1726     compositor()->repaintInCompositedAncestor(m_owningLayer, compositedBounds());
1727 }
1728 
setBlendMode(blink::WebBlendMode blendMode)1729 void CompositedLayerMapping::setBlendMode(blink::WebBlendMode blendMode)
1730 {
1731     if (m_ancestorClippingLayer) {
1732         m_ancestorClippingLayer->setBlendMode(blendMode);
1733         m_graphicsLayer->setBlendMode(blink::WebBlendModeNormal);
1734     } else {
1735         m_graphicsLayer->setBlendMode(blendMode);
1736     }
1737 }
1738 
setContentsNeedDisplay()1739 void CompositedLayerMapping::setContentsNeedDisplay()
1740 {
1741     ASSERT(!paintsIntoCompositedAncestor());
1742 
1743     if (m_graphicsLayer && m_graphicsLayer->drawsContent())
1744         m_graphicsLayer->setNeedsDisplay();
1745 
1746     if (m_foregroundLayer && m_foregroundLayer->drawsContent())
1747         m_foregroundLayer->setNeedsDisplay();
1748 
1749     if (m_backgroundLayer && m_backgroundLayer->drawsContent())
1750         m_backgroundLayer->setNeedsDisplay();
1751 
1752     if (m_maskLayer && m_maskLayer->drawsContent())
1753         m_maskLayer->setNeedsDisplay();
1754 
1755     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent())
1756         m_childClippingMaskLayer->setNeedsDisplay();
1757 
1758     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
1759         m_scrollingContentsLayer->setNeedsDisplay();
1760 }
1761 
1762 // r is in the coordinate space of the layer's render object
setContentsNeedDisplayInRect(const IntRect & r)1763 void CompositedLayerMapping::setContentsNeedDisplayInRect(const IntRect& r)
1764 {
1765     ASSERT(!paintsIntoCompositedAncestor());
1766 
1767     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
1768         IntRect layerDirtyRect = r;
1769         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer());
1770         m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect);
1771     }
1772 
1773     if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
1774         IntRect layerDirtyRect = r;
1775         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer());
1776         m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect);
1777     }
1778 
1779     // FIXME: need to split out repaints for the background.
1780     if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
1781         IntRect layerDirtyRect = r;
1782         layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer());
1783         m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect);
1784     }
1785 
1786     if (m_maskLayer && m_maskLayer->drawsContent()) {
1787         IntRect layerDirtyRect = r;
1788         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer());
1789         m_maskLayer->setNeedsDisplayInRect(layerDirtyRect);
1790     }
1791 
1792     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent()) {
1793         IntRect layerDirtyRect = r;
1794         layerDirtyRect.move(-m_childClippingMaskLayer->offsetFromRenderer());
1795         m_childClippingMaskLayer->setNeedsDisplayInRect(layerDirtyRect);
1796     }
1797 
1798     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
1799         IntRect layerDirtyRect = r;
1800         layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer());
1801         m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect);
1802     }
1803 }
1804 
doPaintTask(GraphicsLayerPaintInfo & paintInfo,GraphicsContext * context,const IntRect & clip)1805 void CompositedLayerMapping::doPaintTask(GraphicsLayerPaintInfo& paintInfo, GraphicsContext* context,
1806     const IntRect& clip) // In the coords of rootLayer.
1807 {
1808     if (paintsIntoCompositedAncestor()) {
1809         ASSERT_NOT_REACHED();
1810         return;
1811     }
1812 
1813     FontCachePurgePreventer fontCachePurgePreventer;
1814 
1815     PaintLayerFlags paintFlags = 0;
1816     if (paintInfo.paintingPhase & GraphicsLayerPaintBackground)
1817         paintFlags |= PaintLayerPaintingCompositingBackgroundPhase;
1818     if (paintInfo.paintingPhase & GraphicsLayerPaintForeground)
1819         paintFlags |= PaintLayerPaintingCompositingForegroundPhase;
1820     if (paintInfo.paintingPhase & GraphicsLayerPaintMask)
1821         paintFlags |= PaintLayerPaintingCompositingMaskPhase;
1822     if (paintInfo.paintingPhase & GraphicsLayerPaintChildClippingMask)
1823         paintFlags |= PaintLayerPaintingChildClippingMaskPhase;
1824     if (paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents)
1825         paintFlags |= PaintLayerPaintingOverflowContents;
1826     if (paintInfo.paintingPhase & GraphicsLayerPaintCompositedScroll)
1827         paintFlags |= PaintLayerPaintingCompositingScrollingPhase;
1828 
1829     if (paintInfo.isBackgroundLayer)
1830         paintFlags |= (PaintLayerPaintingRootBackgroundOnly | PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
1831     else if (compositor()->fixedRootBackgroundLayer())
1832         paintFlags |= PaintLayerPaintingSkipRootBackground;
1833 
1834     // Note carefully: in theory it is appropriate to invoke context->save() here
1835     // and restore the context after painting. For efficiency, we are assuming that
1836     // it is equivalent to manually undo this offset translation, which means we are
1837     // assuming that the context's space was not affected by the RenderLayer
1838     // painting code.
1839 
1840     LayoutSize offset = paintInfo.offsetFromRenderer;
1841     context->translate(-offset);
1842     LayoutRect relativeClip(clip);
1843     relativeClip.move(offset);
1844 
1845     // The dirtyRect is in the coords of the painting root.
1846     IntRect dirtyRect = pixelSnappedIntRect(relativeClip);
1847     if (!(paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents))
1848         dirtyRect.intersect(paintInfo.compositedBounds);
1849 
1850 #ifndef NDEBUG
1851     paintInfo.renderLayer->renderer()->assertSubtreeIsLaidOut();
1852 #endif
1853 
1854     if (paintInfo.renderLayer->compositingState() != PaintsIntoGroupedBacking) {
1855         // FIXME: GraphicsLayers need a way to split for RenderRegions.
1856         LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, LayoutSize());
1857         paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags);
1858 
1859         ASSERT(!paintInfo.isBackgroundLayer || paintFlags & PaintLayerPaintingRootBackgroundOnly);
1860 
1861         if (paintInfo.renderLayer->containsDirtyOverlayScrollbars())
1862             paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags | PaintLayerPaintingOverlayScrollbars);
1863     } else {
1864         ASSERT(compositor()->layerSquashingEnabled());
1865         LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, LayoutSize());
1866         paintInfo.renderLayer->paintLayer(context, paintingInfo, paintFlags);
1867     }
1868 
1869     ASSERT(!paintInfo.renderLayer->m_usedTransparency);
1870 
1871     // Manually restore the context to its original state by applying the opposite translation.
1872     context->translate(offset);
1873 }
1874 
paintScrollbar(Scrollbar * scrollbar,GraphicsContext & context,const IntRect & clip)1875 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1876 {
1877     if (!scrollbar)
1878         return;
1879 
1880     context.save();
1881     const IntRect& scrollbarRect = scrollbar->frameRect();
1882     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1883     IntRect transformedClip = clip;
1884     transformedClip.moveBy(scrollbarRect.location());
1885     scrollbar->paint(&context, transformedClip);
1886     context.restore();
1887 }
1888 
1889 // Up-call from compositing layer drawing callback.
paintContents(const GraphicsLayer * graphicsLayer,GraphicsContext & context,GraphicsLayerPaintingPhase paintingPhase,const IntRect & clip)1890 void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
1891 {
1892 #ifndef NDEBUG
1893     if (Page* page = renderer()->frame()->page())
1894         page->setIsPainting(true);
1895 #endif
1896     InspectorInstrumentation::willPaint(m_owningLayer->renderer(), graphicsLayer);
1897 
1898     if (graphicsLayer == m_graphicsLayer.get()
1899         || graphicsLayer == m_foregroundLayer.get()
1900         || graphicsLayer == m_backgroundLayer.get()
1901         || graphicsLayer == m_maskLayer.get()
1902         || graphicsLayer == m_childClippingMaskLayer.get()
1903         || graphicsLayer == m_scrollingContentsLayer.get()) {
1904 
1905         GraphicsLayerPaintInfo paintInfo;
1906         paintInfo.renderLayer = m_owningLayer;
1907         paintInfo.compositedBounds = compositedBounds();
1908         paintInfo.offsetFromRenderer = graphicsLayer->offsetFromRenderer();
1909         paintInfo.paintingPhase = paintingPhase;
1910         paintInfo.isBackgroundLayer = (graphicsLayer == m_backgroundLayer);
1911 
1912         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
1913         doPaintTask(paintInfo, &context, clip);
1914     } else if (graphicsLayer == m_squashingLayer.get()) {
1915         ASSERT(compositor()->layerSquashingEnabled());
1916         for (size_t i = 0; i < m_squashedLayers.size(); ++i)
1917             doPaintTask(m_squashedLayers[i], &context, clip);
1918     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
1919         paintScrollbar(m_owningLayer->scrollableArea()->horizontalScrollbar(), context, clip);
1920     } else if (graphicsLayer == layerForVerticalScrollbar()) {
1921         paintScrollbar(m_owningLayer->scrollableArea()->verticalScrollbar(), context, clip);
1922     } else if (graphicsLayer == layerForScrollCorner()) {
1923         const IntRect& scrollCornerAndResizer = m_owningLayer->scrollableArea()->scrollCornerAndResizerRect();
1924         context.save();
1925         context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
1926         IntRect transformedClip = clip;
1927         transformedClip.moveBy(scrollCornerAndResizer.location());
1928         m_owningLayer->scrollableArea()->paintScrollCorner(&context, IntPoint(), transformedClip);
1929         m_owningLayer->scrollableArea()->paintResizer(&context, IntPoint(), transformedClip);
1930         context.restore();
1931     }
1932     InspectorInstrumentation::didPaint(m_owningLayer->renderer(), graphicsLayer, &context, clip);
1933 #ifndef NDEBUG
1934     if (Page* page = renderer()->frame()->page())
1935         page->setIsPainting(false);
1936 #endif
1937 }
1938 
didCommitChangesForLayer(const GraphicsLayer * layer) const1939 void CompositedLayerMapping::didCommitChangesForLayer(const GraphicsLayer* layer) const
1940 {
1941 }
1942 
getCurrentTransform(const GraphicsLayer * graphicsLayer,TransformationMatrix & transform) const1943 bool CompositedLayerMapping::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
1944 {
1945     if (graphicsLayer != m_graphicsLayer.get())
1946         return false;
1947 
1948     if (m_owningLayer->hasTransform()) {
1949         transform = m_owningLayer->currentTransform(RenderStyle::ExcludeTransformOrigin);
1950         return true;
1951     }
1952     return false;
1953 }
1954 
isTrackingRepaints() const1955 bool CompositedLayerMapping::isTrackingRepaints() const
1956 {
1957     GraphicsLayerClient* client = compositor();
1958     return client ? client->isTrackingRepaints() : false;
1959 }
1960 
collectTrackedRepaintRectsForGraphicsLayer(GraphicsLayer * graphicsLayer,Vector<FloatRect> & rects)1961 static void collectTrackedRepaintRectsForGraphicsLayer(GraphicsLayer* graphicsLayer, Vector<FloatRect>& rects)
1962 {
1963     if (graphicsLayer)
1964         graphicsLayer->collectTrackedRepaintRects(rects);
1965 }
1966 
collectTrackedRepaintRects() const1967 PassOwnPtr<Vector<FloatRect> > CompositedLayerMapping::collectTrackedRepaintRects() const
1968 {
1969     OwnPtr<Vector<FloatRect> > rects = adoptPtr(new Vector<FloatRect>);
1970     collectTrackedRepaintRectsForGraphicsLayer(m_ancestorClippingLayer.get(), *rects);
1971     collectTrackedRepaintRectsForGraphicsLayer(m_graphicsLayer.get(), *rects);
1972     collectTrackedRepaintRectsForGraphicsLayer(m_childContainmentLayer.get(), *rects);
1973     collectTrackedRepaintRectsForGraphicsLayer(m_scrollingLayer.get(), *rects);
1974     collectTrackedRepaintRectsForGraphicsLayer(m_scrollingContentsLayer.get(), *rects);
1975     collectTrackedRepaintRectsForGraphicsLayer(m_maskLayer.get(), *rects);
1976     collectTrackedRepaintRectsForGraphicsLayer(m_childClippingMaskLayer.get(), *rects);
1977     collectTrackedRepaintRectsForGraphicsLayer(m_foregroundLayer.get(), *rects);
1978     collectTrackedRepaintRectsForGraphicsLayer(m_backgroundLayer.get(), *rects);
1979     collectTrackedRepaintRectsForGraphicsLayer(m_layerForHorizontalScrollbar.get(), *rects);
1980     collectTrackedRepaintRectsForGraphicsLayer(m_layerForVerticalScrollbar.get(), *rects);
1981     collectTrackedRepaintRectsForGraphicsLayer(m_layerForScrollCorner.get(), *rects);
1982     return rects.release();
1983 }
1984 
1985 #ifndef NDEBUG
verifyNotPainting()1986 void CompositedLayerMapping::verifyNotPainting()
1987 {
1988     ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPainting());
1989 }
1990 #endif
1991 
startAnimation(double timeOffset,const CSSAnimationData * anim,const KeyframeList & keyframes)1992 bool CompositedLayerMapping::startAnimation(double timeOffset, const CSSAnimationData* anim, const KeyframeList& keyframes)
1993 {
1994     bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
1995     IntSize boxSize;
1996     if (hasTransform)
1997         boxSize = toRenderBox(renderer())->pixelSnappedBorderBoxRect().size();
1998     WebAnimations animations(m_animationProvider->startAnimation(timeOffset, anim, keyframes, hasTransform, boxSize));
1999     if (animations.isEmpty())
2000         return false;
2001 
2002     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
2003     bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
2004     int animationId = m_animationProvider->getWebAnimationId(keyframes.animationName());
2005 
2006     // Animating only some properties of the animation is not supported. So if the
2007     // GraphicsLayer rejects any property of the animation, we have to remove the
2008     // animation and return false to indicate un-accelerated animation is required.
2009     if (hasTransform) {
2010         if (!animations.m_transformAnimation || !m_graphicsLayer->addAnimation(animations.m_transformAnimation.release()))
2011             return false;
2012     }
2013     if (hasOpacity) {
2014         if (!animations.m_opacityAnimation || !m_graphicsLayer->addAnimation(animations.m_opacityAnimation.release())) {
2015             if (hasTransform)
2016                 m_graphicsLayer->removeAnimation(animationId);
2017             return false;
2018         }
2019     }
2020     if (hasFilter) {
2021         if (!animations.m_filterAnimation || !m_graphicsLayer->addAnimation(animations.m_filterAnimation.release())) {
2022             if (hasTransform || hasOpacity)
2023                 m_graphicsLayer->removeAnimation(animationId);
2024             return false;
2025         }
2026     }
2027     return true;
2028 }
2029 
animationPaused(double timeOffset,const String & animationName)2030 void CompositedLayerMapping::animationPaused(double timeOffset, const String& animationName)
2031 {
2032     int animationId = m_animationProvider->getWebAnimationId(animationName);
2033     ASSERT(animationId);
2034     m_graphicsLayer->pauseAnimation(animationId, timeOffset);
2035 }
2036 
animationFinished(const String & animationName)2037 void CompositedLayerMapping::animationFinished(const String& animationName)
2038 {
2039     int animationId = m_animationProvider->getWebAnimationId(animationName);
2040     ASSERT(animationId);
2041     m_graphicsLayer->removeAnimation(animationId);
2042 }
2043 
startTransition(double timeOffset,CSSPropertyID property,const RenderStyle * fromStyle,const RenderStyle * toStyle)2044 bool CompositedLayerMapping::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
2045 {
2046     ASSERT(property != CSSPropertyInvalid);
2047     IntSize boxSize;
2048     if (property == CSSPropertyWebkitTransform && m_owningLayer->hasTransform()) {
2049         ASSERT(renderer()->isBox());
2050         boxSize = toRenderBox(renderer())->pixelSnappedBorderBoxRect().size();
2051     }
2052     float fromOpacity = 0;
2053     float toOpacity = 0;
2054     if (property == CSSPropertyOpacity) {
2055         fromOpacity = compositingOpacity(fromStyle->opacity());
2056         toOpacity = compositingOpacity(toStyle->opacity());
2057     }
2058 
2059     // Although KeyframeAnimation can have multiple properties of the animation, ImplicitAnimation (= Transition) has only one animation property.
2060     WebAnimations animations(m_animationProvider->startTransition(timeOffset, property, fromStyle,
2061         toStyle, m_owningLayer->hasTransform(), m_owningLayer->hasFilter(), boxSize, fromOpacity, toOpacity));
2062     if (animations.m_transformAnimation && m_graphicsLayer->addAnimation(animations.m_transformAnimation.release())) {
2063         // To ensure that the correct transform is visible when the animation ends, also set the final transform.
2064         updateTransform(toStyle);
2065         return true;
2066     }
2067     if (animations.m_opacityAnimation && m_graphicsLayer->addAnimation(animations.m_opacityAnimation.release())) {
2068         // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
2069         updateOpacity(toStyle);
2070         return true;
2071     }
2072     if (animations.m_filterAnimation && m_graphicsLayer->addAnimation(animations.m_filterAnimation.release())) {
2073         // To ensure that the correct filter is visible when the animation ends, also set the final filter.
2074         updateFilters(toStyle);
2075         return true;
2076     }
2077 
2078     return false;
2079 }
2080 
transitionPaused(double timeOffset,CSSPropertyID property)2081 void CompositedLayerMapping::transitionPaused(double timeOffset, CSSPropertyID property)
2082 {
2083     int animationId = m_animationProvider->getWebAnimationId(property);
2084     ASSERT(animationId);
2085     m_graphicsLayer->pauseAnimation(animationId, timeOffset);
2086 }
2087 
transitionFinished(CSSPropertyID property)2088 void CompositedLayerMapping::transitionFinished(CSSPropertyID property)
2089 {
2090     int animationId = m_animationProvider->getWebAnimationId(property);
2091     ASSERT(animationId);
2092     m_graphicsLayer->removeAnimation(animationId);
2093 }
2094 
notifyAnimationStarted(const GraphicsLayer *,double wallClockTime,double monotonicTime)2095 void CompositedLayerMapping::notifyAnimationStarted(const GraphicsLayer*, double wallClockTime, double monotonicTime)
2096 {
2097     if (RuntimeEnabledFeatures::webAnimationsCSSEnabled())
2098         renderer()->node()->document().cssPendingAnimations().notifyCompositorAnimationStarted(monotonicTime);
2099     else
2100         renderer()->animation().notifyAnimationStarted(renderer(), wallClockTime);
2101 }
2102 
compositedBounds() const2103 IntRect CompositedLayerMapping::compositedBounds() const
2104 {
2105     return m_compositedBounds;
2106 }
2107 
setCompositedBounds(const IntRect & bounds)2108 void CompositedLayerMapping::setCompositedBounds(const IntRect& bounds)
2109 {
2110     m_compositedBounds = bounds;
2111 }
2112 
addRenderLayerToSquashingGraphicsLayer(RenderLayer * layer,IntSize offsetFromTargetBacking,size_t nextSquashedLayerIndex)2113 void CompositedLayerMapping::addRenderLayerToSquashingGraphicsLayer(RenderLayer* layer, IntSize offsetFromTargetBacking, size_t nextSquashedLayerIndex)
2114 {
2115     ASSERT(compositor()->layerSquashingEnabled());
2116 
2117     GraphicsLayerPaintInfo paintInfo;
2118     paintInfo.renderLayer = layer;
2119     // NOTE: composited bounds are updated elsewhere
2120     // NOTE: offsetFromRenderer is updated elsewhere
2121     paintInfo.offsetFromBackingRoot = offsetFromTargetBacking;
2122     paintInfo.paintingPhase = GraphicsLayerPaintAllWithOverflowClip;
2123     paintInfo.isBackgroundLayer = false;
2124 
2125     // Change tracking on squashing layers: at the first sign of something changed, just invalidate the layer.
2126     // FIXME: Perhaps we can find a tighter more clever mechanism later.
2127     if (nextSquashedLayerIndex < m_squashedLayers.size()) {
2128         if (m_squashedLayers[nextSquashedLayerIndex].renderLayer != layer) {
2129             m_squashedLayers[nextSquashedLayerIndex] = paintInfo;
2130             if (m_squashingLayer)
2131                 m_squashingLayer->setNeedsDisplay();
2132         }
2133     } else {
2134         m_squashedLayers.append(paintInfo);
2135         if (m_squashingLayer)
2136             m_squashingLayer->setNeedsDisplay();
2137     }
2138     layer->setGroupedMapping(this);
2139 }
2140 
finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex)2141 void CompositedLayerMapping::finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex)
2142 {
2143     ASSERT(compositor()->layerSquashingEnabled());
2144 
2145     // Any additional squashed RenderLayers in the array no longer exist, and removing invalidates the squashingLayer contents.
2146     if (nextSquashedLayerIndex < m_squashedLayers.size()) {
2147         m_squashedLayers.remove(nextSquashedLayerIndex, m_squashedLayers.size() - nextSquashedLayerIndex);
2148         if (m_squashingLayer)
2149             m_squashingLayer->setNeedsDisplay();
2150     }
2151 }
2152 
compositingLayerType() const2153 CompositingLayerType CompositedLayerMapping::compositingLayerType() const
2154 {
2155     if (m_graphicsLayer->hasContentsLayer())
2156         return MediaCompositingLayer;
2157 
2158     if (m_graphicsLayer->drawsContent())
2159         return NormalCompositingLayer;
2160 
2161     return ContainerCompositingLayer;
2162 }
2163 
backingStoreMemoryEstimate() const2164 double CompositedLayerMapping::backingStoreMemoryEstimate() const
2165 {
2166     double backingMemory;
2167 
2168     // m_ancestorClippingLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
2169     backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
2170     if (m_foregroundLayer)
2171         backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
2172     if (m_backgroundLayer)
2173         backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
2174     if (m_maskLayer)
2175         backingMemory += m_maskLayer->backingStoreMemoryEstimate();
2176     if (m_childClippingMaskLayer)
2177         backingMemory += m_childClippingMaskLayer->backingStoreMemoryEstimate();
2178 
2179     if (m_scrollingContentsLayer)
2180         backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
2181 
2182     if (m_layerForHorizontalScrollbar)
2183         backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
2184 
2185     if (m_layerForVerticalScrollbar)
2186         backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
2187 
2188     if (m_layerForScrollCorner)
2189         backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
2190 
2191     return backingMemory;
2192 }
2193 
debugName(const GraphicsLayer * graphicsLayer)2194 String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer)
2195 {
2196     String name;
2197     if (graphicsLayer == m_graphicsLayer.get()) {
2198         name = m_owningLayer->debugName();
2199     } else if (graphicsLayer == m_ancestorClippingLayer.get()) {
2200         name = "Ancestor Clipping Layer";
2201     } else if (graphicsLayer == m_foregroundLayer.get()) {
2202         name = m_owningLayer->debugName() + " (foreground) Layer";
2203     } else if (graphicsLayer == m_backgroundLayer.get()) {
2204         name = m_owningLayer->debugName() + " (background) Layer";
2205     } else if (graphicsLayer == m_childContainmentLayer.get()) {
2206         name = "Child Containment Layer";
2207     } else if (graphicsLayer == m_maskLayer.get()) {
2208         name = "Mask Layer";
2209     } else if (graphicsLayer == m_childClippingMaskLayer.get()) {
2210         name = "Child Clipping Mask Layer";
2211     } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
2212         name = "Horizontal Scrollbar Layer";
2213     } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
2214         name = "Vertical Scrollbar Layer";
2215     } else if (graphicsLayer == m_layerForScrollCorner.get()) {
2216         name = "Scroll Corner Layer";
2217     } else if (graphicsLayer == m_scrollingLayer.get()) {
2218         name = "Scrolling Layer";
2219     } else if (graphicsLayer == m_scrollingContentsLayer.get()) {
2220         name = "Scrolling Contents Layer";
2221     } else {
2222         ASSERT_NOT_REACHED();
2223     }
2224 
2225     return name;
2226 }
2227 
2228 } // namespace WebCore
2229