• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 
28 #include "core/rendering/RenderLayerCompositor.h"
29 
30 #include "CSSPropertyNames.h"
31 #include "HTMLNames.h"
32 #include "RuntimeEnabledFeatures.h"
33 #include "core/animation/ActiveAnimations.h"
34 #include "core/animation/DocumentAnimations.h"
35 #include "core/dom/FullscreenElementStack.h"
36 #include "core/dom/NodeList.h"
37 #include "core/html/HTMLCanvasElement.h"
38 #include "core/html/HTMLIFrameElement.h"
39 #include "core/html/HTMLVideoElement.h"
40 #include "core/html/canvas/CanvasRenderingContext.h"
41 #include "core/inspector/InspectorInstrumentation.h"
42 #include "core/page/Chrome.h"
43 #include "core/frame/Frame.h"
44 #include "core/frame/FrameView.h"
45 #include "core/page/Page.h"
46 #include "core/frame/Settings.h"
47 #include "core/frame/animation/AnimationController.h"
48 #include "core/page/scrolling/ScrollingConstraints.h"
49 #include "core/page/scrolling/ScrollingCoordinator.h"
50 #include "core/rendering/CompositedLayerMapping.h"
51 #include "core/rendering/HitTestResult.h"
52 #include "core/rendering/RenderApplet.h"
53 #include "core/rendering/RenderEmbeddedObject.h"
54 #include "core/rendering/RenderFullScreen.h"
55 #include "core/rendering/RenderGeometryMap.h"
56 #include "core/rendering/RenderIFrame.h"
57 #include "core/rendering/RenderLayerStackingNode.h"
58 #include "core/rendering/RenderLayerStackingNodeIterator.h"
59 #include "core/rendering/RenderReplica.h"
60 #include "core/rendering/RenderVideo.h"
61 #include "core/rendering/RenderView.h"
62 #include "platform/OverscrollTheme.h"
63 #include "platform/TraceEvent.h"
64 #include "platform/geometry/TransformState.h"
65 #include "platform/graphics/GraphicsLayer.h"
66 #include "platform/scroll/ScrollbarTheme.h"
67 #include "public/platform/Platform.h"
68 #include "wtf/TemporaryChange.h"
69 
70 #ifndef NDEBUG
71 #include "core/rendering/RenderTreeAsText.h"
72 #endif
73 
74 namespace WebCore {
75 
76 using namespace HTMLNames;
77 
78 class OverlapMapContainer {
79 public:
add(const IntRect & bounds)80     void add(const IntRect& bounds)
81     {
82         m_layerRects.append(bounds);
83         m_boundingBox.unite(bounds);
84     }
85 
overlapsLayers(const IntRect & bounds) const86     bool overlapsLayers(const IntRect& bounds) const
87     {
88         // Checking with the bounding box will quickly reject cases when
89         // layers are created for lists of items going in one direction and
90         // never overlap with each other.
91         if (!bounds.intersects(m_boundingBox))
92             return false;
93         for (unsigned i = 0; i < m_layerRects.size(); i++) {
94             if (m_layerRects[i].intersects(bounds))
95                 return true;
96         }
97         return false;
98     }
99 
unite(const OverlapMapContainer & otherContainer)100     void unite(const OverlapMapContainer& otherContainer)
101     {
102         m_layerRects.append(otherContainer.m_layerRects);
103         m_boundingBox.unite(otherContainer.m_boundingBox);
104     }
105 private:
106     Vector<IntRect> m_layerRects;
107     IntRect m_boundingBox;
108 };
109 
110 class RenderLayerCompositor::OverlapMap {
111     WTF_MAKE_NONCOPYABLE(OverlapMap);
112 public:
OverlapMap()113     OverlapMap()
114         : m_geometryMap(UseTransforms)
115     {
116         // Begin by assuming the root layer will be composited so that there
117         // is something on the stack. The root layer should also never get a
118         // finishCurrentOverlapTestingContext() call.
119         beginNewOverlapTestingContext();
120     }
121 
add(const RenderLayer * layer,const IntRect & bounds)122     void add(const RenderLayer* layer, const IntRect& bounds)
123     {
124         // Layers do not contribute to overlap immediately--instead, they will
125         // contribute to overlap as soon as they have been recursively processed
126         // and popped off the stack.
127         ASSERT(m_overlapStack.size() >= 2);
128         m_overlapStack[m_overlapStack.size() - 2].add(bounds);
129         m_layers.add(layer);
130     }
131 
contains(const RenderLayer * layer)132     bool contains(const RenderLayer* layer)
133     {
134         return m_layers.contains(layer);
135     }
136 
overlapsLayers(const IntRect & bounds) const137     bool overlapsLayers(const IntRect& bounds) const
138     {
139         return m_overlapStack.last().overlapsLayers(bounds);
140     }
141 
isEmpty()142     bool isEmpty()
143     {
144         return m_layers.isEmpty();
145     }
146 
beginNewOverlapTestingContext()147     void beginNewOverlapTestingContext()
148     {
149         // This effectively creates a new "clean slate" for overlap state.
150         // This is used when we know that a subtree or remaining set of
151         // siblings does not need to check overlap with things behind it.
152         m_overlapStack.append(OverlapMapContainer());
153     }
154 
finishCurrentOverlapTestingContext()155     void finishCurrentOverlapTestingContext()
156     {
157         // The overlap information on the top of the stack is still necessary
158         // for checking overlap of any layers outside this context that may
159         // overlap things from inside this context. Therefore, we must merge
160         // the information from the top of the stack before popping the stack.
161         //
162         // FIXME: we may be able to avoid this deep copy by rearranging how
163         //        overlapMap state is managed.
164         m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
165         m_overlapStack.removeLast();
166     }
167 
geometryMap()168     RenderGeometryMap& geometryMap() { return m_geometryMap; }
169 
170 private:
171     Vector<OverlapMapContainer> m_overlapStack;
172     HashSet<const RenderLayer*> m_layers;
173     RenderGeometryMap m_geometryMap;
174 };
175 
176 struct CompositingRecursionData {
CompositingRecursionDataWebCore::CompositingRecursionData177     CompositingRecursionData(RenderLayer* compAncestor, bool testOverlap)
178         : m_compositingAncestor(compAncestor)
179         , m_subtreeIsCompositing(false)
180         , m_hasUnisolatedCompositedBlendingDescendant(false)
181         , m_testingOverlap(testOverlap)
182 #ifndef NDEBUG
183         , m_depth(0)
184 #endif
185     {
186     }
187 
CompositingRecursionDataWebCore::CompositingRecursionData188     CompositingRecursionData(const CompositingRecursionData& other)
189         : m_compositingAncestor(other.m_compositingAncestor)
190         , m_subtreeIsCompositing(other.m_subtreeIsCompositing)
191         , m_hasUnisolatedCompositedBlendingDescendant(other.m_hasUnisolatedCompositedBlendingDescendant)
192         , m_testingOverlap(other.m_testingOverlap)
193 #ifndef NDEBUG
194         , m_depth(other.m_depth + 1)
195 #endif
196     {
197     }
198 
199     RenderLayer* m_compositingAncestor;
200     bool m_subtreeIsCompositing;
201     bool m_hasUnisolatedCompositedBlendingDescendant;
202     bool m_testingOverlap;
203 #ifndef NDEBUG
204     int m_depth;
205 #endif
206 };
207 
208 
RenderLayerCompositor(RenderView * renderView)209 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
210     : m_renderView(renderView)
211     , m_hasAcceleratedCompositing(true)
212     , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
213     , m_showRepaintCounter(false)
214     , m_needsToRecomputeCompositingRequirements(false)
215     , m_needsToUpdateLayerTreeGeometry(false)
216     , m_compositing(false)
217     , m_compositingLayersNeedRebuild(false)
218     , m_forceCompositingMode(false)
219     , m_inPostLayoutUpdate(false)
220     , m_needsUpdateCompositingRequirementsState(false)
221     , m_isTrackingRepaints(false)
222     , m_rootLayerAttachment(RootLayerUnattached)
223 {
224 }
225 
~RenderLayerCompositor()226 RenderLayerCompositor::~RenderLayerCompositor()
227 {
228     ASSERT(m_rootLayerAttachment == RootLayerUnattached);
229 }
230 
enableCompositingMode(bool enable)231 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
232 {
233     if (enable != m_compositing) {
234         m_compositing = enable;
235 
236         if (m_compositing) {
237             ensureRootLayer();
238             notifyIFramesOfCompositingChange();
239         } else
240             destroyRootLayer();
241     }
242 }
243 
cacheAcceleratedCompositingFlags()244 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
245 {
246     bool hasAcceleratedCompositing = false;
247     bool showRepaintCounter = false;
248     bool forceCompositingMode = false;
249 
250     if (Settings* settings = m_renderView->document().settings()) {
251         hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
252 
253         // We allow the chrome to override the settings, in case the page is rendered
254         // on a chrome that doesn't allow accelerated compositing.
255         if (hasAcceleratedCompositing) {
256             if (Page* page = this->page()) {
257                 m_compositingTriggers = page->chrome().client().allowedCompositingTriggers();
258                 hasAcceleratedCompositing = m_compositingTriggers;
259             }
260         }
261 
262         showRepaintCounter = settings->showRepaintCounter();
263         forceCompositingMode = settings->forceCompositingMode() && hasAcceleratedCompositing;
264 
265         if (forceCompositingMode && !isMainFrame())
266             forceCompositingMode = requiresCompositingForScrollableFrame();
267     }
268 
269     if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode)
270         setCompositingLayersNeedRebuild();
271 
272     m_hasAcceleratedCompositing = hasAcceleratedCompositing;
273     m_showRepaintCounter = showRepaintCounter;
274     m_forceCompositingMode = forceCompositingMode;
275 }
276 
layerSquashingEnabled() const277 bool RenderLayerCompositor::layerSquashingEnabled() const
278 {
279     if (Settings* settings = m_renderView->document().settings())
280         return settings->layerSquashingEnabled();
281 
282     return false;
283 }
284 
canRender3DTransforms() const285 bool RenderLayerCompositor::canRender3DTransforms() const
286 {
287     return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
288 }
289 
setCompositingLayersNeedRebuild(bool needRebuild)290 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
291 {
292     // FIXME: crbug,com/332248 ideally this could be merged with setNeedsCompositingUpdate().
293     if (inCompositingMode())
294         m_compositingLayersNeedRebuild = needRebuild;
295 
296     m_renderView->frameView()->scheduleAnimation();
297 }
298 
didChangeVisibleRect()299 void RenderLayerCompositor::didChangeVisibleRect()
300 {
301     GraphicsLayer* rootLayer = rootGraphicsLayer();
302     if (!rootLayer)
303         return;
304 
305     FrameView* frameView = m_renderView ? m_renderView->frameView() : 0;
306     if (!frameView)
307         return;
308 
309     IntRect visibleRect = m_containerLayer ? IntRect(IntPoint(), frameView->contentsSize()) : frameView->visibleContentRect();
310     if (rootLayer->visibleRectChangeRequiresFlush(visibleRect)) {
311         if (Page* page = this->page())
312             page->chrome().client().scheduleCompositingLayerFlush();
313     }
314 }
315 
updateCompositingRequirementsState()316 void RenderLayerCompositor::updateCompositingRequirementsState()
317 {
318     if (!m_needsUpdateCompositingRequirementsState)
319         return;
320 
321     TRACE_EVENT0("blink_rendering,comp-scroll", "RenderLayerCompositor::updateCompositingRequirementsState");
322 
323     m_needsUpdateCompositingRequirementsState = false;
324 
325     if (!rootRenderLayer() || !rootRenderLayer()->acceleratedCompositingForOverflowScrollEnabled())
326         return;
327 
328     for (HashSet<RenderLayer*>::iterator it = m_outOfFlowPositionedLayers.begin(); it != m_outOfFlowPositionedLayers.end(); ++it)
329         (*it)->updateHasUnclippedDescendant();
330 
331     const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas();
332     if (!scrollableAreas)
333         return;
334 
335     for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
336         (*it)->updateNeedsCompositedScrolling();
337 }
338 
findFullscreenVideoRenderer(Document * document)339 static RenderVideo* findFullscreenVideoRenderer(Document* document)
340 {
341     Element* fullscreenElement = FullscreenElementStack::currentFullScreenElementFrom(document);
342     while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) {
343         document = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
344         if (!document)
345             return 0;
346         fullscreenElement = FullscreenElementStack::currentFullScreenElementFrom(document);
347     }
348     if (!fullscreenElement || !isHTMLVideoElement(fullscreenElement))
349         return 0;
350     RenderObject* renderer = fullscreenElement->renderer();
351     if (!renderer)
352         return 0;
353     return toRenderVideo(renderer);
354 }
355 
finishCompositingUpdateForFrameTree(Frame * frame)356 void RenderLayerCompositor::finishCompositingUpdateForFrameTree(Frame* frame)
357 {
358     for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
359         finishCompositingUpdateForFrameTree(child);
360 
361     // Update compositing for current frame after all descendant frames are updated.
362     if (frame && frame->contentRenderer()) {
363         RenderLayerCompositor* frameCompositor = frame->contentRenderer()->compositor();
364         if (frameCompositor && !frameCompositor->isMainFrame())
365             frame->contentRenderer()->compositor()->updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
366     }
367 }
368 
updateCompositingLayers(CompositingUpdateType updateType)369 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType)
370 {
371     // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
372     if (m_renderView->needsLayout())
373         return;
374 
375     if (updateType == CompositingUpdateFinishAllDeferredWork && isMainFrame() && m_renderView->frameView())
376         finishCompositingUpdateForFrameTree(&m_renderView->frameView()->frame());
377 
378     if (m_forceCompositingMode && !m_compositing)
379         enableCompositingMode(true);
380 
381     if (!m_needsToRecomputeCompositingRequirements && !m_compositing)
382         return;
383 
384     AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame().animation());
385 
386     TemporaryChange<bool> postLayoutChange(m_inPostLayoutUpdate, true);
387 
388     bool needCompositingRequirementsUpdate = false;
389     bool needHierarchyAndGeometryUpdate = false;
390     bool needGeometryUpdate = false;
391     bool needsToUpdateScrollingCoordinator = false;
392 
393     // CompositingUpdateFinishAllDeferredWork is the only updateType that will actually do any work in this
394     // function. All other updateTypes will simply mark that something needed updating, and defer the actual
395     // update. This way we only need to compute all compositing state once for every frame drawn (if needed).
396     switch (updateType) {
397     case CompositingUpdateAfterStyleChange:
398     case CompositingUpdateAfterLayout:
399         m_needsToRecomputeCompositingRequirements = true;
400         break;
401     case CompositingUpdateOnScroll:
402         m_needsToRecomputeCompositingRequirements = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
403         m_needsToUpdateLayerTreeGeometry = true;
404         break;
405     case CompositingUpdateOnCompositedScroll:
406         m_needsToUpdateLayerTreeGeometry = true;
407         break;
408     case CompositingUpdateFinishAllDeferredWork:
409         needCompositingRequirementsUpdate = m_needsToRecomputeCompositingRequirements;
410         needHierarchyAndGeometryUpdate = m_compositingLayersNeedRebuild;
411         needGeometryUpdate = m_needsToUpdateLayerTreeGeometry;
412         needsToUpdateScrollingCoordinator = scrollingCoordinator() ? scrollingCoordinator()->needsToUpdateAfterCompositingChange() : false;
413         break;
414     }
415 
416     if (!needCompositingRequirementsUpdate && !needHierarchyAndGeometryUpdate && !needGeometryUpdate && !needsToUpdateScrollingCoordinator)
417         return;
418 
419     ASSERT(updateType == CompositingUpdateFinishAllDeferredWork);
420 
421     // Only clear the flags if we're updating the entire hierarchy.
422     m_compositingLayersNeedRebuild = false;
423     m_needsToUpdateLayerTreeGeometry = false;
424     m_needsToRecomputeCompositingRequirements = false;
425     RenderLayer* updateRoot = rootRenderLayer();
426 
427     if (needCompositingRequirementsUpdate) {
428         // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
429         // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
430         CompositingRecursionData recursionData(updateRoot, true);
431         bool layersChanged = false;
432         bool saw3DTransform = false;
433         {
434             TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::computeCompositingRequirements");
435             OverlapMap overlapTestRequestMap;
436 
437             // FIXME: Passing these unclippedDescendants down and keeping track
438             // of them dynamically, we are requiring a full tree walk. This
439             // should be removed as soon as proper overlap testing based on
440             // scrolling and animation bounds is implemented (crbug.com/252472).
441             Vector<RenderLayer*> unclippedDescendants;
442             computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants);
443         }
444 
445         {
446             TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::assignLayersToBackings");
447             assignLayersToBackings(updateRoot, layersChanged);
448         }
449 
450         {
451             TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateHasVisibleNonLayerContentLoop");
452             const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas();
453             if (scrollableAreas) {
454                 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
455                     (*it)->updateHasVisibleNonLayerContent();
456             }
457         }
458 
459         needHierarchyAndGeometryUpdate |= layersChanged;
460     }
461 
462     if (needHierarchyAndGeometryUpdate) {
463         // Update the hierarchy of the compositing layers.
464         Vector<GraphicsLayer*> childList;
465         {
466             TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::rebuildCompositingLayerTree");
467             rebuildCompositingLayerTree(updateRoot, childList, 0);
468         }
469 
470         // Host the document layer in the RenderView's root layer.
471         if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isMainFrame()) {
472             RenderVideo* video = findFullscreenVideoRenderer(&m_renderView->document());
473             if (video && video->hasCompositedLayerMapping()) {
474                 childList.clear();
475                 childList.append(video->compositedLayerMapping()->mainGraphicsLayer());
476             }
477         }
478 
479         if (childList.isEmpty())
480             destroyRootLayer();
481         else
482             m_rootContentLayer->setChildren(childList);
483     } else if (needGeometryUpdate) {
484         // We just need to do a geometry update. This is only used for position:fixed scrolling;
485         // most of the time, geometry is updated via RenderLayer::styleChanged().
486         updateLayerTreeGeometry(updateRoot);
487     }
488 
489     ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
490 
491     if (!hasAcceleratedCompositing())
492         enableCompositingMode(false);
493 
494     // The scrolling coordinator may realize that it needs updating while compositing was being updated in this function.
495     needsToUpdateScrollingCoordinator |= scrollingCoordinator() ? scrollingCoordinator()->needsToUpdateAfterCompositingChange() : false;
496     if (needsToUpdateScrollingCoordinator && isMainFrame() && scrollingCoordinator() && inCompositingMode())
497         scrollingCoordinator()->updateAfterCompositingChange();
498 
499     // Inform the inspector that the layer tree has changed.
500     if (isMainFrame())
501         InspectorInstrumentation::layerTreeDidChange(page());
502 }
503 
requiresCompositing(CompositingReasons reasons)504 static bool requiresCompositing(CompositingReasons reasons)
505 {
506     // Any reasons other than overlap or assumed overlap will require the layer to be separately compositing.
507     return reasons & ~CompositingReasonComboAllOverlapReasons;
508 }
509 
requiresSquashing(CompositingReasons reasons)510 static bool requiresSquashing(CompositingReasons reasons)
511 {
512     // If the layer has overlap or assumed overlap, but no other reasons, then it should be squashed.
513     return !requiresCompositing(reasons) && (reasons & CompositingReasonComboAllOverlapReasons);
514 }
515 
requiresCompositingOrSquashing(CompositingReasons reasons)516 static bool requiresCompositingOrSquashing(CompositingReasons reasons)
517 {
518 #ifndef NDEBUG
519     bool fastAnswer = reasons != CompositingReasonNone;
520     bool slowAnswer = requiresCompositing(reasons) || requiresSquashing(reasons);
521     ASSERT(fastAnswer == slowAnswer);
522 #endif
523     return reasons != CompositingReasonNone;
524 }
525 
addOutOfFlowPositionedLayer(RenderLayer * layer)526 void RenderLayerCompositor::addOutOfFlowPositionedLayer(RenderLayer* layer)
527 {
528     m_outOfFlowPositionedLayers.add(layer);
529 }
530 
removeOutOfFlowPositionedLayer(RenderLayer * layer)531 void RenderLayerCompositor::removeOutOfFlowPositionedLayer(RenderLayer* layer)
532 {
533     m_outOfFlowPositionedLayers.remove(layer);
534 }
535 
allocateOrClearCompositedLayerMapping(RenderLayer * layer)536 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer)
537 {
538     bool compositedLayerMappingChanged = false;
539     RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;
540     requiresCompositingForPosition(layer->renderer(), layer, &viewportConstrainedNotCompositedReason);
541 
542     // FIXME: It would be nice to directly use the layer's compositing reason,
543     // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
544     // requirements fully.
545     if (needsOwnBacking(layer)) {
546         enableCompositingMode();
547 
548         if (!layer->hasCompositedLayerMapping()) {
549             // If we need to repaint, do so before allocating the compositedLayerMapping
550             repaintOnCompositingChange(layer);
551 
552             layer->ensureCompositedLayerMapping();
553             compositedLayerMappingChanged = true;
554 
555             // At this time, the ScrollingCooridnator only supports the top-level frame.
556             if (layer->isRootLayer() && isMainFrame()) {
557                 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
558                     scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
559             }
560 
561             // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
562             // that computing repaint rects will know the layer's correct compositingState.
563             // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
564             // Need to create a test where a squashed layer pops into compositing. And also to cover all other
565             // sorts of compositingState transitions.
566             layer->setGroupedMapping(0);
567 
568             // FIXME: it seems premature to compute this before all compositing state has been updated?
569             // This layer and all of its descendants have cached repaints rects that are relative to
570             // the repaint container, so change when compositing changes; we need to update them here.
571             if (layer->parent())
572                 layer->repainter().computeRepaintRectsIncludingDescendants();
573         }
574 
575         if (layer->compositedLayerMapping()->updateRequiresOwnBackingStoreForIntrinsicReasons())
576             compositedLayerMappingChanged = true;
577     } else {
578         if (layer->hasCompositedLayerMapping()) {
579             // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to
580             // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
581             // are both either composited, or not composited.
582             if (layer->isReflection()) {
583                 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer();
584                 if (sourceLayer->hasCompositedLayerMapping()) {
585                     ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer());
586                     sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0);
587                 }
588             }
589 
590             removeViewportConstrainedLayer(layer);
591 
592             layer->clearCompositedLayerMapping();
593             compositedLayerMappingChanged = true;
594 
595             // This layer and all of its descendants have cached repaints rects that are relative to
596             // the repaint container, so change when compositing changes; we need to update them here.
597             layer->repainter().computeRepaintRectsIncludingDescendants();
598 
599             // If we need to repaint, do so now that we've removed the compositedLayerMapping
600             repaintOnCompositingChange(layer);
601         }
602     }
603 
604     if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) {
605         RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
606         if (innerCompositor && innerCompositor->inCompositingMode())
607             innerCompositor->updateRootLayerAttachment();
608     }
609 
610     if (compositedLayerMappingChanged)
611         layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
612 
613     // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed,
614     // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
615     bool nonCompositedReasonChanged = false;
616     if (layer->renderer()->style()->position() == FixedPosition) {
617         if (layer->viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
618             layer->setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason);
619             nonCompositedReasonChanged = true;
620         }
621         if (compositedLayerMappingChanged || nonCompositedReasonChanged) {
622             if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
623                 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView->frameView());
624         }
625     }
626 
627     return compositedLayerMappingChanged || nonCompositedReasonChanged;
628 }
629 
updateLayerCompositingState(RenderLayer * layer)630 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer)
631 {
632     updateDirectCompositingReasons(layer);
633     bool layerChanged = allocateOrClearCompositedLayerMapping(layer);
634 
635     if (layerSquashingEnabled()) {
636         // FIXME: this is not correct... info may be out of date and squashing returning true doesn't indicate that the layer changed
637         layerChanged = requiresSquashing(layer->compositingReasons());
638     }
639 
640     // See if we need content or clipping layers. Methods called here should assume
641     // that the compositing state of descendant layers has not been updated yet.
642     if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateGraphicsLayerConfiguration())
643         layerChanged = true;
644 
645     return layerChanged;
646 }
647 
repaintOnCompositingChange(RenderLayer * layer)648 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
649 {
650     // If the renderer is not attached yet, no need to repaint.
651     if (layer->renderer() != m_renderView && !layer->renderer()->parent())
652         return;
653 
654     RenderLayerModelObject* repaintContainer = layer->renderer()->containerForRepaint();
655     if (!repaintContainer)
656         repaintContainer = m_renderView;
657 
658     layer->repainter().repaintIncludingNonCompositingDescendants(repaintContainer);
659 }
660 
661 // This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
repaintInCompositedAncestor(RenderLayer * layer,const LayoutRect & rect)662 void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect)
663 {
664     RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(false /*exclude self*/);
665     if (compositedAncestor) {
666         // FIXME: make sure repaintRect is computed correctly for squashed scenario
667         LayoutPoint offset;
668         layer->convertToLayerCoords(compositedAncestor, offset);
669 
670         LayoutRect repaintRect = rect;
671         repaintRect.moveBy(offset);
672 
673         if (compositedAncestor->compositingState() == PaintsIntoOwnBacking) {
674             compositedAncestor->repainter().setBackingNeedsRepaintInRect(repaintRect);
675         } else if (compositedAncestor->compositingState() == PaintsIntoGroupedBacking) {
676             // FIXME: Need to perform the correct coordinate conversion for repaintRect here, including transforms
677             compositedAncestor->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(repaintRect);
678         } else {
679             ASSERT_NOT_REACHED();
680         }
681     }
682 }
683 
684 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
685 // RenderLayers that are rendered by the composited RenderLayer.
calculateCompositedBounds(const RenderLayer * layer,const RenderLayer * ancestorLayer) const686 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const
687 {
688     if (!canBeComposited(layer))
689         return IntRect();
690 
691     RenderLayer::CalculateLayerBoundsFlags flags = RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask;
692 #if HAVE(COMPOSITOR_FILTER_OUTSETS)
693     // If the compositor computes its own filter outsets, don't include them in the composited bounds.
694     if (!layer->paintsWithFilters())
695         flags &= ~RenderLayer::IncludeLayerFilterOutsets;
696 #endif
697     return layer->calculateLayerBounds(ancestorLayer, 0, flags);
698 }
699 
layerWasAdded(RenderLayer *,RenderLayer *)700 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
701 {
702     setCompositingLayersNeedRebuild();
703 }
704 
layerWillBeRemoved(RenderLayer * parent,RenderLayer * child)705 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
706 {
707     if (!child->hasCompositedLayerMapping() || parent->renderer()->documentBeingDestroyed())
708         return;
709 
710     removeViewportConstrainedLayer(child);
711     repaintInCompositedAncestor(child, child->compositedLayerMapping()->compositedBounds());
712 
713     setCompositingParent(child, 0);
714     setCompositingLayersNeedRebuild();
715 }
716 
enclosingNonStackingClippingLayer(const RenderLayer * layer) const717 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
718 {
719     for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
720         if (curr->stackingNode()->isStackingContainer())
721             return 0;
722 
723         if (curr->renderer()->hasClipOrOverflowClip())
724             return curr;
725     }
726     return 0;
727 }
728 
addToOverlapMap(OverlapMap & overlapMap,RenderLayer * layer,IntRect & layerBounds,bool & boundsComputed)729 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
730 {
731     if (layer->isRootLayer())
732         return;
733 
734     if (!boundsComputed) {
735         // FIXME: If this layer's overlap bounds include its children, we don't need to add its
736         // children's bounds to the overlap map.
737         layerBounds = enclosingIntRect(overlapMap.geometryMap().absoluteRect(layer->overlapBounds()));
738         // Empty rects never intersect, but we need them to for the purposes of overlap testing.
739         if (layerBounds.isEmpty())
740             layerBounds.setSize(IntSize(1, 1));
741         boundsComputed = true;
742     }
743 
744     IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(ClipRectsContext(rootRenderLayer(), 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
745     clipRect.intersect(layerBounds);
746     overlapMap.add(layer, clipRect);
747 }
748 
addToOverlapMapRecursive(OverlapMap & overlapMap,RenderLayer * layer,RenderLayer * ancestorLayer)749 void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, RenderLayer* layer, RenderLayer* ancestorLayer)
750 {
751     if (!canBeComposited(layer) || overlapMap.contains(layer))
752         return;
753 
754     // A null ancestorLayer is an indication that 'layer' has already been pushed.
755     if (ancestorLayer)
756         overlapMap.geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
757 
758     IntRect bounds;
759     bool haveComputedBounds = false;
760     addToOverlapMap(overlapMap, layer, bounds, haveComputedBounds);
761 
762 #if !ASSERT_DISABLED
763     LayerListMutationDetector mutationChecker(layer->stackingNode());
764 #endif
765 
766     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
767     while (RenderLayerStackingNode* curNode = iterator.next())
768         addToOverlapMapRecursive(overlapMap, curNode->layer(), layer);
769 
770     if (ancestorLayer)
771         overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
772 }
773 
774 //  Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
775 //  For the z-order children of a compositing layer:
776 //      If a child layers has a compositing layer, then all subsequent layers must
777 //      be compositing in order to render above that layer.
778 //
779 //      If a child in the negative z-order list is compositing, then the layer itself
780 //      must be compositing so that its contents render over that child.
781 //      This implies that its positive z-index children must also be compositing.
782 //
computeCompositingRequirements(RenderLayer * ancestorLayer,RenderLayer * layer,OverlapMap * overlapMap,CompositingRecursionData & currentRecursionData,bool & descendantHas3DTransform,Vector<RenderLayer * > & unclippedDescendants)783 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingRecursionData& currentRecursionData, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants)
784 {
785     layer->stackingNode()->updateLayerListsIfNeeded();
786 
787     if (overlapMap)
788         overlapMap->geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
789 
790     // Clear the flag
791     layer->setHasCompositingDescendant(false);
792     layer->setHasNonCompositedChild(false);
793 
794     // Start by assuming this layer will not need to composite.
795     CompositingReasons reasonsToComposite = CompositingReasonNone;
796 
797     // First accumulate the straightforward compositing reasons.
798     CompositingReasons directReasons = directReasonsForCompositing(layer);
799 
800     // Video is special. It's the only RenderLayer type that can both have
801     // RenderLayer children and whose children can't use its backing to render
802     // into. These children (the controls) always need to be promoted into their
803     // own layers to draw on top of the accelerated video.
804     if (currentRecursionData.m_compositingAncestor && currentRecursionData.m_compositingAncestor->renderer()->isVideo())
805         directReasons |= CompositingReasonLayerForVideoOverlay;
806 
807     if (canBeComposited(layer))
808         reasonsToComposite |= directReasons;
809 
810     // Next, accumulate reasons related to overlap.
811     // If overlap testing is used, this reason will be overridden. If overlap testing is not
812     // used, we must assume we overlap if there is anything composited behind us in paint-order.
813     CompositingReasons overlapCompositingReason = currentRecursionData.m_subtreeIsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone;
814 
815     if (rootRenderLayer()->compositorDrivenAcceleratedScrollingEnabled()) {
816         Vector<size_t> unclippedDescendantsToRemove;
817         for (size_t i = 0; i < unclippedDescendants.size(); i++) {
818             RenderLayer* unclippedDescendant = unclippedDescendants.at(i);
819             // If we've reached the containing block of one of the unclipped
820             // descendants, that element is no longer relevant to whether or not we
821             // should opt in. Unfortunately we can't easily remove from the list
822             // while we're iterating, so we have to store it for later removal.
823             if (unclippedDescendant->renderer()->containingBlock() == layer->renderer()) {
824                 unclippedDescendantsToRemove.append(i);
825                 continue;
826             }
827             if (layer->scrollsWithRespectTo(unclippedDescendant))
828                 reasonsToComposite |= CompositingReasonAssumedOverlap;
829         }
830 
831         // Remove irrelevant unclipped descendants in reverse order so our stored
832         // indices remain valid.
833         for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++)
834             unclippedDescendants.remove(unclippedDescendantsToRemove.at(unclippedDescendantsToRemove.size() - i - 1));
835 
836         if (reasonsToComposite & CompositingReasonOutOfFlowClipping)
837             unclippedDescendants.append(layer);
838     }
839 
840     bool haveComputedBounds = false;
841     IntRect absBounds;
842     // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map.
843     if (overlapMap && !overlapMap->isEmpty() && currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons)) {
844         // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
845         absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds()));
846 
847         // Empty rects never intersect, but we need them to for the purposes of overlap testing.
848         if (absBounds.isEmpty())
849             absBounds.setSize(IntSize(1, 1));
850         haveComputedBounds = true;
851         overlapCompositingReason = overlapMap->overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone;
852     }
853 
854     reasonsToComposite |= overlapCompositingReason;
855 
856     // The children of this layer don't need to composite, unless there is
857     // a compositing layer among them, so start by inheriting the compositing
858     // ancestor with m_subtreeIsCompositing set to false.
859     CompositingRecursionData childRecursionData(currentRecursionData);
860     childRecursionData.m_subtreeIsCompositing = false;
861 
862     bool willBeComposited = canBeComposited(layer) && requiresCompositingOrSquashing(reasonsToComposite);
863     if (willBeComposited) {
864         // Tell the parent it has compositing descendants.
865         currentRecursionData.m_subtreeIsCompositing = true;
866         // This layer now acts as the ancestor for kids.
867         childRecursionData.m_compositingAncestor = layer;
868 
869         // Here we know that all children and the layer's own contents can blindly paint into
870         // this layer's backing, until a descendant is composited. So, we don't need to check
871         // for overlap with anything behind this layer.
872         if (overlapMap)
873             overlapMap->beginNewOverlapTestingContext();
874         // This layer is going to be composited, so children can safely ignore the fact that there's an
875         // animation running behind this layer, meaning they can rely on the overlap map testing again.
876         childRecursionData.m_testingOverlap = true;
877     }
878 
879 #if !ASSERT_DISABLED
880     LayerListMutationDetector mutationChecker(layer->stackingNode());
881 #endif
882 
883     bool anyDescendantHas3DTransform = false;
884     bool willHaveForegroundLayer = false;
885 
886     if (layer->stackingNode()->isStackingContainer()) {
887         RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
888         while (RenderLayerStackingNode* curNode = iterator.next()) {
889             computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants);
890 
891             // If we have to make a layer for this child, make one now so we can have a contents layer
892             // (since we need to ensure that the -ve z-order child renders underneath our contents).
893             if (childRecursionData.m_subtreeIsCompositing) {
894                 reasonsToComposite |= CompositingReasonNegativeZIndexChildren;
895 
896                 if (!willBeComposited) {
897                     // make layer compositing
898                     childRecursionData.m_compositingAncestor = layer;
899                     overlapMap->beginNewOverlapTestingContext();
900                     willBeComposited = true;
901                     willHaveForegroundLayer = true;
902 
903                     // FIXME: temporary solution for the first negative z-index composited child:
904                     //        re-compute the absBounds for the child so that we can add the
905                     //        negative z-index child's bounds to the new overlap context.
906                     if (overlapMap) {
907                         overlapMap->geometryMap().pushMappingsToAncestor(curNode->layer(), layer);
908                         IntRect childAbsBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(curNode->layer()->overlapBounds()));
909                         bool boundsComputed = true;
910                         overlapMap->beginNewOverlapTestingContext();
911                         addToOverlapMap(*overlapMap, curNode->layer(), childAbsBounds, boundsComputed);
912                         overlapMap->finishCurrentOverlapTestingContext();
913                         overlapMap->geometryMap().popMappingsToAncestor(layer);
914                     }
915                 }
916             }
917         }
918     }
919 
920     if (overlapMap && willHaveForegroundLayer) {
921         ASSERT(willBeComposited);
922         // A foreground layer effectively is a new backing for all subsequent children, so
923         // we don't need to test for overlap with anything behind this. So, we can finish
924         // the previous context that was accumulating rects for the negative z-index
925         // children, and start with a fresh new empty context.
926         overlapMap->finishCurrentOverlapTestingContext();
927         overlapMap->beginNewOverlapTestingContext();
928         // This layer is going to be composited, so children can safely ignore the fact that there's an
929         // animation running behind this layer, meaning they can rely on the overlap map testing again
930         childRecursionData.m_testingOverlap = true;
931     }
932 
933     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
934     while (RenderLayerStackingNode* curNode = iterator.next())
935         computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants);
936 
937     // Now that the subtree has been traversed, we can check for compositing reasons that depended on the state of the subtree.
938 
939     // If we entered compositing mode during the recursion, the root will also need to be composited (as long as accelerated compositing is enabled).
940     if (layer->isRootLayer()) {
941         if (inCompositingMode() && m_hasAcceleratedCompositing)
942             willBeComposited = true;
943     }
944 
945     // All layers (even ones that aren't being composited) need to get added to
946     // the overlap map. Layers that are not separately composited will paint into their
947     // compositing ancestor's backing, and so are still considered for overlap.
948     if (overlapMap && childRecursionData.m_compositingAncestor && !childRecursionData.m_compositingAncestor->isRootLayer())
949         addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
950 
951     if (layer->stackingNode()->isStackingContext()) {
952         layer->setShouldIsolateCompositedDescendants(childRecursionData.m_hasUnisolatedCompositedBlendingDescendant);
953     } else {
954         layer->setShouldIsolateCompositedDescendants(false);
955         currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = childRecursionData.m_hasUnisolatedCompositedBlendingDescendant;
956     }
957 
958     // Now check for reasons to become composited that depend on the state of descendant layers.
959     CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(layer->renderer(), childRecursionData.m_subtreeIsCompositing, anyDescendantHas3DTransform);
960     reasonsToComposite |= subtreeCompositingReasons;
961     if (!willBeComposited && canBeComposited(layer) && requiresCompositingOrSquashing(subtreeCompositingReasons)) {
962         childRecursionData.m_compositingAncestor = layer;
963         if (overlapMap) {
964             // FIXME: this context push is effectively a no-op but needs to exist for
965             // now, because the code is designed to push overlap information to the
966             // second-from-top context of the stack.
967             overlapMap->beginNewOverlapTestingContext();
968             addToOverlapMapRecursive(*overlapMap, layer);
969         }
970         willBeComposited = true;
971     }
972 
973     // If the original layer is composited, the reflection needs to be, too.
974     if (layer->reflectionInfo()) {
975         // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
976         CompositingReasons reflectionCompositingReason = willBeComposited ? CompositingReasonReflectionOfCompositedParent : CompositingReasonNone;
977         layer->reflectionInfo()->reflectionLayer()->setCompositingReasons(layer->reflectionInfo()->reflectionLayer()->compositingReasons() | reflectionCompositingReason);
978     }
979 
980     // Subsequent layers in the parent's stacking context may also need to composite.
981     if (childRecursionData.m_subtreeIsCompositing)
982         currentRecursionData.m_subtreeIsCompositing = true;
983 
984     if (willBeComposited && layer->hasBlendMode())
985         currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = true;
986 
987     // Set the flag to say that this SC has compositing children.
988     layer->setHasCompositingDescendant(childRecursionData.m_subtreeIsCompositing);
989 
990     // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
991     // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
992     // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
993     bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposite & CompositingReasonClipsCompositingDescendants);
994     if ((!childRecursionData.m_testingOverlap && !isCompositedClippingLayer) || isRunningAcceleratedTransformAnimation(layer->renderer()))
995         currentRecursionData.m_testingOverlap = false;
996 
997     if (overlapMap && childRecursionData.m_compositingAncestor == layer && !layer->isRootLayer())
998         overlapMap->finishCurrentOverlapTestingContext();
999 
1000     if (layer->isRootLayer()) {
1001         // The root layer needs to be composited if anything else in the tree is composited.
1002         // Otherwise, we can disable compositing entirely.
1003         if (childRecursionData.m_subtreeIsCompositing || requiresCompositingOrSquashing(reasonsToComposite) || m_forceCompositingMode) {
1004             willBeComposited = true;
1005             reasonsToComposite |= CompositingReasonRoot;
1006         } else {
1007             enableCompositingMode(false);
1008             willBeComposited = false;
1009             reasonsToComposite = CompositingReasonNone;
1010         }
1011     }
1012 
1013     // At this point we have finished collecting all reasons to composite this layer.
1014     layer->setCompositingReasons(reasonsToComposite);
1015 
1016     if (!willBeComposited && layer->parent())
1017         layer->parent()->setHasNonCompositedChild(true);
1018 
1019     descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform();
1020 
1021     if (overlapMap)
1022         overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer);
1023 }
1024 
updateSquashingStateForNewMapping(CompositedLayerMappingPtr newCompositedLayerMapping,bool hasNewCompositedLayerMapping,IntPoint newOffsetFromAbsolute)1025 void RenderLayerCompositor::SquashingState::updateSquashingStateForNewMapping(CompositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMapping, IntPoint newOffsetFromAbsolute)
1026 {
1027     // The most recent backing is done accumulating any more squashing layers.
1028     if (hasMostRecentMapping)
1029         mostRecentMapping->finishAccumulatingSquashingLayers(nextSquashedLayerIndex);
1030 
1031     nextSquashedLayerIndex = 0;
1032     mostRecentMapping = newCompositedLayerMapping;
1033     hasMostRecentMapping = hasNewCompositedLayerMapping;
1034     offsetFromAbsolute = newOffsetFromAbsolute;
1035 }
1036 
computeOffsetFromAbsolute(RenderLayer * layer)1037 static IntPoint computeOffsetFromAbsolute(RenderLayer* layer)
1038 {
1039     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
1040     layer->renderer()->mapLocalToContainer(0, transformState, ApplyContainerFlip);
1041     transformState.flatten();
1042     return roundedIntPoint(transformState.lastPlanarPoint());
1043 }
1044 
assignLayersToBackings(RenderLayer * updateRoot,bool & layersChanged)1045 void RenderLayerCompositor::assignLayersToBackings(RenderLayer* updateRoot, bool& layersChanged)
1046 {
1047     SquashingState squashingState;
1048     assignLayersToBackingsInternal(updateRoot, squashingState, layersChanged);
1049     if (squashingState.hasMostRecentMapping)
1050         squashingState.mostRecentMapping->finishAccumulatingSquashingLayers(squashingState.nextSquashedLayerIndex);
1051 }
1052 
assignLayersToBackingsInternal(RenderLayer * layer,SquashingState & squashingState,bool & layersChanged)1053 void RenderLayerCompositor::assignLayersToBackingsInternal(RenderLayer* layer, SquashingState& squashingState, bool& layersChanged)
1054 {
1055     if (allocateOrClearCompositedLayerMapping(layer))
1056         layersChanged = true;
1057 
1058     if (layer->reflectionInfo() && updateLayerCompositingState(layer->reflectionInfo()->reflectionLayer()))
1059         layersChanged = true;
1060 
1061     // Add this layer to a squashing backing if needed.
1062     if (layerSquashingEnabled()) {
1063         // NOTE: In the future as we generalize this, the background of this layer may need to be assigned to a different backing than
1064         // the layer's own primary contents. This would happen when we have a composited negative z-index element that needs to
1065         // paint on top of the background, but below the layer's main contents. For now, because we always composite layers
1066         // when they have a composited negative z-index child, such layers will never need squashing so it is not yet an issue.
1067         if (requiresSquashing(layer->compositingReasons())) {
1068             // A layer that is squashed with other layers cannot have its own CompositedLayerMapping.
1069             ASSERT(!layer->hasCompositedLayerMapping());
1070             ASSERT(squashingState.hasMostRecentMapping);
1071 
1072             IntPoint offsetFromAbsolute = computeOffsetFromAbsolute(layer);
1073 
1074             // FIXME: see if we can refactor this to be clearer
1075             IntSize offsetFromTargetBacking(offsetFromAbsolute.x() - squashingState.offsetFromAbsolute.x(),
1076                 offsetFromAbsolute.y() - squashingState.offsetFromAbsolute.y());
1077 
1078             squashingState.mostRecentMapping->addRenderLayerToSquashingGraphicsLayer(layer, offsetFromTargetBacking, squashingState.nextSquashedLayerIndex);
1079             squashingState.nextSquashedLayerIndex++;
1080 
1081             // FIXME: does this need to be true here? Do we need more logic to decide when it should be true?
1082             layersChanged = true;
1083 
1084             // FIXME: this should be conditioned on whether this layer actually changed status
1085             layer->clipper().clearClipRectsIncludingDescendants();
1086         }
1087     }
1088 
1089     if (layer->stackingNode()->isStackingContainer()) {
1090         RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
1091         while (RenderLayerStackingNode* curNode = iterator.next())
1092             assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged);
1093     }
1094 
1095     if (layerSquashingEnabled()) {
1096         // At this point, if the layer is to be "separately" composited, then its backing becomes the most recent in paint-order.
1097         if (layer->compositingState() == PaintsIntoOwnBacking || layer->compositingState() == HasOwnBackingButPaintsIntoAncestor) {
1098             ASSERT(!requiresSquashing(layer->compositingReasons()));
1099             IntPoint offsetFromAbsolute = computeOffsetFromAbsolute(layer);
1100             squashingState.updateSquashingStateForNewMapping(layer->compositedLayerMapping(), layer->hasCompositedLayerMapping(), offsetFromAbsolute);
1101         }
1102     }
1103 
1104     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
1105     while (RenderLayerStackingNode* curNode = iterator.next())
1106         assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged);
1107 }
1108 
setCompositingParent(RenderLayer * childLayer,RenderLayer * parentLayer)1109 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
1110 {
1111     ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
1112     ASSERT(childLayer->hasCompositedLayerMapping());
1113 
1114     // It's possible to be called with a parent that isn't yet composited when we're doing
1115     // partial updates as required by painting or hit testing. Just bail in that case;
1116     // we'll do a full layer update soon.
1117     if (!parentLayer || !parentLayer->hasCompositedLayerMapping())
1118         return;
1119 
1120     if (parentLayer) {
1121         GraphicsLayer* hostingLayer = parentLayer->compositedLayerMapping()->parentForSublayers();
1122         GraphicsLayer* hostedLayer = childLayer->compositedLayerMapping()->childForSuperlayers();
1123 
1124         hostingLayer->addChild(hostedLayer);
1125     } else {
1126         childLayer->compositedLayerMapping()->childForSuperlayers()->removeFromParent();
1127     }
1128 }
1129 
removeCompositedChildren(RenderLayer * layer)1130 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
1131 {
1132     ASSERT(layer->hasCompositedLayerMapping());
1133 
1134     GraphicsLayer* hostingLayer = layer->compositedLayerMapping()->parentForSublayers();
1135     hostingLayer->removeAllChildren();
1136 }
1137 
canAccelerateVideoRendering(RenderVideo * o) const1138 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
1139 {
1140     if (!m_hasAcceleratedCompositing)
1141         return false;
1142 
1143     return o->supportsAcceleratedRendering();
1144 }
1145 
rebuildCompositingLayerTree(RenderLayer * layer,Vector<GraphicsLayer * > & childLayersOfEnclosingLayer,int depth)1146 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
1147 {
1148     // Make the layer compositing if necessary, and set up clipping and content layers.
1149     // Note that we can only do work here that is independent of whether the descendant layers
1150     // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
1151 
1152     layer->stackingNode()->updateLayerListsIfNeeded();
1153 
1154     // Used for gathering UMA data about the effect on memory usage of promoting all layers
1155     // that have a webkit-transition on opacity or transform and intersect the viewport.
1156     static double pixelsWithoutPromotingAllTransitions = 0.0;
1157     static double pixelsAddedByPromotingAllTransitions = 0.0;
1158 
1159     if (!depth) {
1160         pixelsWithoutPromotingAllTransitions = 0.0;
1161         pixelsAddedByPromotingAllTransitions = 0.0;
1162     }
1163 
1164     const bool hasCompositedLayerMapping = layer->hasCompositedLayerMapping();
1165     CompositedLayerMappingPtr currentCompositedLayerMapping = layer->compositedLayerMapping();
1166     if (hasCompositedLayerMapping) {
1167         // The compositing state of all our children has been updated already, so now
1168         // we can compute and cache the composited bounds for this layer.
1169         currentCompositedLayerMapping->updateCompositedBounds();
1170 
1171         if (layer->reflectionInfo()) {
1172             RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
1173             if (reflectionLayer->hasCompositedLayerMapping())
1174                 reflectionLayer->compositedLayerMapping()->updateCompositedBounds();
1175         }
1176 
1177         currentCompositedLayerMapping->updateGraphicsLayerConfiguration();
1178         currentCompositedLayerMapping->updateGraphicsLayerGeometry();
1179 
1180         if (!layer->parent())
1181             updateRootLayerPosition();
1182 
1183         if (currentCompositedLayerMapping->hasUnpositionedOverflowControlsLayers())
1184             layer->scrollableArea()->positionOverflowControls();
1185 
1186         pixelsWithoutPromotingAllTransitions += layer->size().height() * layer->size().width();
1187     } else {
1188         if ((layer->renderer()->style()->transitionForProperty(CSSPropertyOpacity) ||
1189              layer->renderer()->style()->transitionForProperty(CSSPropertyWebkitTransform)) &&
1190             m_renderView->viewRect().intersects(layer->absoluteBoundingBox()))
1191             pixelsAddedByPromotingAllTransitions += layer->size().height() * layer->size().width();
1192     }
1193 
1194     // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers.
1195     // Otherwise children continue to append to the child list of the enclosing layer.
1196     Vector<GraphicsLayer*> layerChildren;
1197     Vector<GraphicsLayer*>& childList = hasCompositedLayerMapping ? layerChildren : childLayersOfEnclosingLayer;
1198 
1199 #if !ASSERT_DISABLED
1200     LayerListMutationDetector mutationChecker(layer->stackingNode());
1201 #endif
1202 
1203     if (layer->stackingNode()->isStackingContainer()) {
1204         RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
1205         while (RenderLayerStackingNode* curNode = iterator.next())
1206             rebuildCompositingLayerTree(curNode->layer(), childList, depth + 1);
1207 
1208         // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
1209         if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
1210             childList.append(currentCompositedLayerMapping->foregroundLayer());
1211     }
1212 
1213     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
1214     while (RenderLayerStackingNode* curNode = iterator.next())
1215         rebuildCompositingLayerTree(curNode->layer(), childList, depth + 1);
1216 
1217     if (hasCompositedLayerMapping) {
1218         bool parented = false;
1219         if (layer->renderer()->isRenderPart())
1220             parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
1221 
1222         if (!parented)
1223             currentCompositedLayerMapping->parentForSublayers()->setChildren(layerChildren);
1224 
1225         // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
1226         // Otherwise, the overflow control layers are normal children.
1227         if (!currentCompositedLayerMapping->hasClippingLayer() && !currentCompositedLayerMapping->hasScrollingLayer()) {
1228             if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForHorizontalScrollbar()) {
1229                 overflowControlLayer->removeFromParent();
1230                 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
1231             }
1232 
1233             if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForVerticalScrollbar()) {
1234                 overflowControlLayer->removeFromParent();
1235                 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
1236             }
1237 
1238             if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForScrollCorner()) {
1239                 overflowControlLayer->removeFromParent();
1240                 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
1241             }
1242         }
1243 
1244         childLayersOfEnclosingLayer.append(currentCompositedLayerMapping->childForSuperlayers());
1245     }
1246 
1247     if (!depth) {
1248         int percentageIncreaseInPixels = static_cast<int>(pixelsAddedByPromotingAllTransitions / pixelsWithoutPromotingAllTransitions * 100);
1249         blink::Platform::current()->histogramCustomCounts("Renderer.PixelIncreaseFromTransitions", percentageIncreaseInPixels, 0, 1000, 50);
1250     }
1251 }
1252 
frameViewDidChangeLocation(const IntPoint & contentsOffset)1253 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
1254 {
1255     if (m_overflowControlsHostLayer)
1256         m_overflowControlsHostLayer->setPosition(contentsOffset);
1257 }
1258 
frameViewDidChangeSize()1259 void RenderLayerCompositor::frameViewDidChangeSize()
1260 {
1261     if (m_containerLayer) {
1262         FrameView* frameView = m_renderView->frameView();
1263         m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
1264 
1265         frameViewDidScroll();
1266         updateOverflowControlsLayers();
1267     }
1268 }
1269 
1270 enum AcceleratedFixedRootBackgroundHistogramBuckets {
1271     ScrolledMainFrameBucket = 0,
1272     ScrolledMainFrameWithAcceleratedFixedRootBackground = 1,
1273     ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2,
1274     AcceleratedFixedRootBackgroundHistogramMax = 3
1275 };
1276 
frameViewDidScroll()1277 void RenderLayerCompositor::frameViewDidScroll()
1278 {
1279     FrameView* frameView = m_renderView->frameView();
1280     IntPoint scrollPosition = frameView->scrollPosition();
1281 
1282     if (!m_scrollLayer)
1283         return;
1284 
1285     bool scrollingCoordinatorHandlesOffset = false;
1286     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
1287         if (Settings* settings = m_renderView->document().settings()) {
1288             if (isMainFrame() || settings->compositedScrollingForFramesEnabled())
1289                 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView);
1290         }
1291     }
1292 
1293     // Scroll position = scroll minimum + scroll offset. Adjust the layer's
1294     // position to handle whatever the scroll coordinator isn't handling.
1295     // The minimum scroll position is non-zero for RTL pages with overflow.
1296     if (scrollingCoordinatorHandlesOffset)
1297         m_scrollLayer->setPosition(-frameView->minimumScrollPosition());
1298     else
1299         m_scrollLayer->setPosition(-scrollPosition);
1300 
1301 
1302     blink::Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
1303         ScrolledMainFrameBucket,
1304         AcceleratedFixedRootBackgroundHistogramMax);
1305 
1306     if (!m_renderView->rootBackgroundIsEntirelyFixed())
1307         return;
1308 
1309     blink::Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
1310         !!fixedRootBackgroundLayer()
1311             ? ScrolledMainFrameWithAcceleratedFixedRootBackground
1312             : ScrolledMainFrameWithUnacceleratedFixedRootBackground,
1313         AcceleratedFixedRootBackgroundHistogramMax);
1314 }
1315 
frameViewDidLayout()1316 void RenderLayerCompositor::frameViewDidLayout()
1317 {
1318 }
1319 
frameViewScrollbarsExistenceDidChange()1320 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
1321 {
1322     if (m_containerLayer)
1323         updateOverflowControlsLayers();
1324 }
1325 
rootFixedBackgroundsChanged()1326 void RenderLayerCompositor::rootFixedBackgroundsChanged()
1327 {
1328     if (!supportsFixedRootBackgroundCompositing())
1329         return;
1330 
1331     // To avoid having to make the fixed root background layer fixed positioned to
1332     // stay put, we position it in the layer tree as follows:
1333     //
1334     // + Overflow controls host
1335     //   + Frame clip
1336     //     + (Fixed root background) <-- Here.
1337     //     + Frame scroll
1338     //       + Root content layer
1339     //   + Scrollbars
1340     //
1341     // That is, it needs to be the first child of the frame clip, the sibling of
1342     // the frame scroll layer. The compositor does not own the background layer, it
1343     // just positions it (like the foreground layer).
1344     if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
1345         m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get());
1346 }
1347 
scrollingLayerDidChange(RenderLayer * layer)1348 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
1349 {
1350     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1351         return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
1352     return false;
1353 }
1354 
layerTreeAsText(LayerTreeFlags flags)1355 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
1356 {
1357     // Before dumping the layer tree, finish any pending compositing update.
1358     updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
1359 
1360     if (!m_rootContentLayer)
1361         return String();
1362 
1363     // We skip dumping the scroll and clip layers to keep layerTreeAsText output
1364     // similar between platforms (unless we explicitly request dumping from the
1365     // root.
1366     GraphicsLayer* rootLayer = m_rootContentLayer.get();
1367     if (flags & LayerTreeIncludesRootLayer)
1368         rootLayer = rootGraphicsLayer();
1369 
1370     String layerTreeText = rootLayer->layerTreeAsText(flags);
1371 
1372     // The true root layer is not included in the dump, so if we want to report
1373     // its repaint rects, they must be included here.
1374     if (flags & LayerTreeIncludesRepaintRects)
1375         return m_renderView->frameView()->trackedRepaintRectsAsText() + layerTreeText;
1376 
1377     return layerTreeText;
1378 }
1379 
frameContentsCompositor(RenderPart * renderer)1380 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
1381 {
1382     if (!renderer->node()->isFrameOwnerElement())
1383         return 0;
1384 
1385     HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node());
1386     if (Document* contentDocument = element->contentDocument()) {
1387         if (RenderView* view = contentDocument->renderView())
1388             return view->compositor();
1389     }
1390     return 0;
1391 }
1392 
parentFrameContentLayers(RenderPart * renderer)1393 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
1394 {
1395     RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
1396     if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
1397         return false;
1398 
1399     RenderLayer* layer = renderer->layer();
1400     if (!layer->hasCompositedLayerMapping())
1401         return false;
1402 
1403     CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
1404     GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers();
1405     GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
1406     if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
1407         hostingLayer->removeAllChildren();
1408         hostingLayer->addChild(rootLayer);
1409     }
1410     return true;
1411 }
1412 
1413 // This just updates layer geometry without changing the hierarchy.
updateLayerTreeGeometry(RenderLayer * layer)1414 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
1415 {
1416     if (layer->hasCompositedLayerMapping()) {
1417         CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
1418         // The compositing state of all our children has been updated already, so now
1419         // we can compute and cache the composited bounds for this layer.
1420         compositedLayerMapping->updateCompositedBounds();
1421 
1422         if (layer->reflectionInfo()) {
1423             RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
1424             if (reflectionLayer->hasCompositedLayerMapping())
1425                 reflectionLayer->compositedLayerMapping()->updateCompositedBounds();
1426         }
1427 
1428         compositedLayerMapping->updateGraphicsLayerConfiguration();
1429         compositedLayerMapping->updateGraphicsLayerGeometry();
1430 
1431         if (!layer->parent())
1432             updateRootLayerPosition();
1433     }
1434 
1435 #if !ASSERT_DISABLED
1436     LayerListMutationDetector mutationChecker(layer->stackingNode());
1437 #endif
1438 
1439     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
1440     while (RenderLayerStackingNode* curNode = iterator.next())
1441         updateLayerTreeGeometry(curNode->layer());
1442 }
1443 
1444 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
updateCompositingDescendantGeometry(RenderLayerStackingNode * compositingAncestor,RenderLayer * layer,bool compositedChildrenOnly)1445 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayerStackingNode* compositingAncestor, RenderLayer* layer, bool compositedChildrenOnly)
1446 {
1447     if (layer->stackingNode() != compositingAncestor) {
1448         if (layer->hasCompositedLayerMapping()) {
1449             CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
1450             compositedLayerMapping->updateCompositedBounds();
1451 
1452             if (layer->reflectionInfo()) {
1453                 RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
1454                 if (reflectionLayer->hasCompositedLayerMapping())
1455                     reflectionLayer->compositedLayerMapping()->updateCompositedBounds();
1456             }
1457 
1458             compositedLayerMapping->updateGraphicsLayerGeometry();
1459             if (compositedChildrenOnly)
1460                 return;
1461         }
1462     }
1463 
1464     if (layer->reflectionInfo())
1465         updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionInfo()->reflectionLayer(), compositedChildrenOnly);
1466 
1467     if (!layer->hasCompositingDescendant())
1468         return;
1469 
1470 #if !ASSERT_DISABLED
1471     LayerListMutationDetector mutationChecker(layer->stackingNode());
1472 #endif
1473 
1474     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
1475     while (RenderLayerStackingNode* curNode = iterator.next())
1476         updateCompositingDescendantGeometry(compositingAncestor, curNode->layer(), compositedChildrenOnly);
1477 }
1478 
1479 
repaintCompositedLayers(const IntRect * absRect)1480 void RenderLayerCompositor::repaintCompositedLayers(const IntRect* absRect)
1481 {
1482     recursiveRepaintLayer(rootRenderLayer(), absRect);
1483 }
1484 
recursiveRepaintLayer(RenderLayer * layer,const IntRect * rect)1485 void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer, const IntRect* rect)
1486 {
1487     // FIXME: This method does not work correctly with transforms.
1488     if (layer->compositingState() == PaintsIntoOwnBacking) {
1489         if (rect)
1490             layer->repainter().setBackingNeedsRepaintInRect(*rect);
1491         else
1492             layer->repainter().setBackingNeedsRepaint();
1493     }
1494 
1495 #if !ASSERT_DISABLED
1496     LayerListMutationDetector mutationChecker(layer->stackingNode());
1497 #endif
1498 
1499     unsigned childrenToVisit = NormalFlowChildren;
1500     if (layer->hasCompositingDescendant())
1501         childrenToVisit |= PositiveZOrderChildren | NegativeZOrderChildren;
1502     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), childrenToVisit);
1503     while (RenderLayerStackingNode* curNode = iterator.next()) {
1504         if (rect) {
1505             IntRect childRect(*rect);
1506             curNode->layer()->convertToPixelSnappedLayerCoords(layer, childRect);
1507             recursiveRepaintLayer(curNode->layer(), &childRect);
1508         } else {
1509             recursiveRepaintLayer(curNode->layer());
1510         }
1511     }
1512 }
1513 
rootRenderLayer() const1514 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
1515 {
1516     return m_renderView->layer();
1517 }
1518 
rootGraphicsLayer() const1519 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
1520 {
1521     if (m_overflowControlsHostLayer)
1522         return m_overflowControlsHostLayer.get();
1523     return m_rootContentLayer.get();
1524 }
1525 
scrollLayer() const1526 GraphicsLayer* RenderLayerCompositor::scrollLayer() const
1527 {
1528     return m_scrollLayer.get();
1529 }
1530 
setIsInWindow(bool isInWindow)1531 void RenderLayerCompositor::setIsInWindow(bool isInWindow)
1532 {
1533     if (!inCompositingMode())
1534         return;
1535 
1536     if (isInWindow) {
1537         if (m_rootLayerAttachment != RootLayerUnattached)
1538             return;
1539 
1540         RootLayerAttachment attachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
1541         attachRootLayer(attachment);
1542     } else {
1543         if (m_rootLayerAttachment == RootLayerUnattached)
1544             return;
1545 
1546         detachRootLayer();
1547     }
1548 }
1549 
clearMappingForRenderLayerIncludingDescendants(RenderLayer * layer)1550 void RenderLayerCompositor::clearMappingForRenderLayerIncludingDescendants(RenderLayer* layer)
1551 {
1552     if (!layer)
1553         return;
1554 
1555     if (layer->hasCompositedLayerMapping()) {
1556         removeViewportConstrainedLayer(layer);
1557         layer->clearCompositedLayerMapping();
1558     }
1559 
1560     for (RenderLayer* currLayer = layer->firstChild(); currLayer; currLayer = currLayer->nextSibling())
1561         clearMappingForRenderLayerIncludingDescendants(currLayer);
1562 }
1563 
clearMappingForAllRenderLayers()1564 void RenderLayerCompositor::clearMappingForAllRenderLayers()
1565 {
1566     clearMappingForRenderLayerIncludingDescendants(m_renderView->layer());
1567 }
1568 
updateRootLayerPosition()1569 void RenderLayerCompositor::updateRootLayerPosition()
1570 {
1571     if (m_rootContentLayer) {
1572         const IntRect& documentRect = m_renderView->documentRect();
1573         m_rootContentLayer->setSize(documentRect.size());
1574         m_rootContentLayer->setPosition(documentRect.location());
1575 #if USE(RUBBER_BANDING)
1576         if (m_layerForOverhangShadow)
1577             OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
1578 #endif
1579     }
1580     if (m_containerLayer) {
1581         FrameView* frameView = m_renderView->frameView();
1582         m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
1583     }
1584 }
1585 
has3DContent() const1586 bool RenderLayerCompositor::has3DContent() const
1587 {
1588     return layerHas3DContent(rootRenderLayer());
1589 }
1590 
updateDirectCompositingReasons(RenderLayer * layer)1591 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer)
1592 {
1593     CompositingReasons layerReasons = layer->compositingReasons();
1594 
1595     layerReasons &= ~CompositingReasonComboAllDirectReasons;
1596     layerReasons |= directReasonsForCompositing(layer);
1597     layer->setCompositingReasons(layerReasons);
1598 }
1599 
needsOwnBacking(const RenderLayer * layer) const1600 bool RenderLayerCompositor::needsOwnBacking(const RenderLayer* layer) const
1601 {
1602     if (!canBeComposited(layer))
1603         return false;
1604 
1605     // If squashing is disabled, then layers that would have been squashed should just be separately composited.
1606     bool needsOwnBackingForDisabledSquashing = !layerSquashingEnabled() && requiresSquashing(layer->compositingReasons());
1607 
1608     return requiresCompositing(layer->compositingReasons()) || needsOwnBackingForDisabledSquashing || (inCompositingMode() && layer->isRootLayer());
1609 }
1610 
canBeComposited(const RenderLayer * layer) const1611 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
1612 {
1613     // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
1614     // See http://webkit.org/b/84900 to re-enable it.
1615     return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread;
1616 }
1617 
directReasonsForCompositing(const RenderLayer * layer) const1618 CompositingReasons RenderLayerCompositor::directReasonsForCompositing(const RenderLayer* layer) const
1619 {
1620     RenderObject* renderer = layer->renderer();
1621     CompositingReasons directReasons = CompositingReasonNone;
1622 
1623     if (requiresCompositingForTransform(renderer))
1624         directReasons |= CompositingReason3DTransform;
1625 
1626     // Only zero or one of the following conditions will be true for a given RenderLayer.
1627     if (requiresCompositingForVideo(renderer))
1628         directReasons |= CompositingReasonVideo;
1629     else if (requiresCompositingForCanvas(renderer))
1630         directReasons |= CompositingReasonCanvas;
1631     else if (requiresCompositingForPlugin(renderer))
1632         directReasons |= CompositingReasonPlugin;
1633     else if (requiresCompositingForFrame(renderer))
1634         directReasons |= CompositingReasonIFrame;
1635 
1636     if (requiresCompositingForBackfaceVisibilityHidden(renderer))
1637         directReasons |= CompositingReasonBackfaceVisibilityHidden;
1638 
1639     if (requiresCompositingForAnimation(renderer))
1640         directReasons |= CompositingReasonAnimation;
1641 
1642     if (requiresCompositingForTransition(renderer))
1643         directReasons |= CompositingReasonAnimation;
1644 
1645     if (requiresCompositingForFilters(renderer))
1646         directReasons |= CompositingReasonFilters;
1647 
1648     if (requiresCompositingForPosition(renderer, layer))
1649         directReasons |= renderer->style()->position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky;
1650 
1651     if (requiresCompositingForOverflowScrolling(layer))
1652         directReasons |= CompositingReasonOverflowScrollingTouch;
1653 
1654     if (requiresCompositingForOverflowScrollingParent(layer))
1655         directReasons |= CompositingReasonOverflowScrollingParent;
1656 
1657     if (requiresCompositingForOutOfFlowClipping(layer))
1658         directReasons |= CompositingReasonOutOfFlowClipping;
1659 
1660     return directReasons;
1661 }
1662 
1663 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1664 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1665 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1666 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1667 // but a sibling in the z-order hierarchy.
clippedByAncestor(const RenderLayer * layer) const1668 bool RenderLayerCompositor::clippedByAncestor(const RenderLayer* layer) const
1669 {
1670     if (!layer->hasCompositedLayerMapping() || !layer->parent())
1671         return false;
1672 
1673     // FIXME: need to double-check if semantics of ancestorCompositingLayer() work correctly here?
1674     const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1675     if (!compositingAncestor)
1676         return false;
1677 
1678     // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
1679     // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
1680     // and layer.
1681     const RenderLayer* computeClipRoot = 0;
1682     const RenderLayer* curr = layer;
1683     while (curr) {
1684         const RenderLayer* next = curr->parent();
1685         if (next == compositingAncestor) {
1686             computeClipRoot = curr;
1687             break;
1688         }
1689         curr = next;
1690     }
1691 
1692     if (!computeClipRoot || computeClipRoot == layer)
1693         return false;
1694 
1695     return layer->backgroundClipRect(ClipRectsContext(computeClipRoot, 0, TemporaryClipRects)).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
1696 }
1697 
1698 // Return true if the given layer is a stacking context and has compositing child
1699 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1700 // into the hierarchy between this layer and its children in the z-order hierarchy.
clipsCompositingDescendants(const RenderLayer * layer) const1701 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1702 {
1703     return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
1704 }
1705 
requiresCompositingForScrollableFrame() const1706 bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
1707 {
1708     // Need this done first to determine overflow.
1709     ASSERT(!m_renderView->needsLayout());
1710     if (isMainFrame())
1711         return false;
1712 
1713     if (!(m_compositingTriggers & ChromeClient::ScrollableInnerFrameTrigger))
1714         return false;
1715 
1716     FrameView* frameView = m_renderView->frameView();
1717     return frameView->isScrollable();
1718 }
1719 
requiresCompositingForTransform(RenderObject * renderer) const1720 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
1721 {
1722     if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
1723         return false;
1724 
1725     RenderStyle* style = renderer->style();
1726     // Note that we ask the renderer if it has a transform, because the style may have transforms,
1727     // but the renderer may be an inline that doesn't suppport them.
1728     return renderer->hasTransform() && style->transform().has3DOperation();
1729 }
1730 
requiresCompositingForVideo(RenderObject * renderer) const1731 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
1732 {
1733     if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer->isVideo()) {
1734         HTMLMediaElement* media = toHTMLMediaElement(renderer->node());
1735         if (media->isFullscreen())
1736             return true;
1737     }
1738 
1739     if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
1740         return false;
1741 
1742     if (renderer->isVideo()) {
1743         RenderVideo* video = toRenderVideo(renderer);
1744         return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
1745     }
1746     return false;
1747 }
1748 
requiresCompositingForCanvas(RenderObject * renderer) const1749 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
1750 {
1751     if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
1752         return false;
1753 
1754     if (renderer->isCanvas()) {
1755         HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
1756         return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
1757     }
1758     return false;
1759 }
1760 
requiresCompositingForPlugin(RenderObject * renderer) const1761 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
1762 {
1763     if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
1764         return false;
1765 
1766     bool composite = renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
1767     if (!composite)
1768         return false;
1769 
1770     // FIXME: this seems bogus. If we don't know the layout position/size of the plugin yet, would't that be handled elsewhere?
1771     m_needsToRecomputeCompositingRequirements = true;
1772 
1773     RenderWidget* pluginRenderer = toRenderWidget(renderer);
1774     // If we can't reliably know the size of the plugin yet, don't change compositing state.
1775     if (pluginRenderer->needsLayout())
1776         return pluginRenderer->hasLayer() && pluginRenderer->layer()->hasCompositedLayerMapping();
1777 
1778     // Don't go into compositing mode if height or width are zero, or size is 1x1.
1779     IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect());
1780     return contentBox.height() * contentBox.width() > 1;
1781 }
1782 
requiresCompositingForFrame(RenderObject * renderer) const1783 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
1784 {
1785     if (!renderer->isRenderPart())
1786         return false;
1787 
1788     RenderPart* frameRenderer = toRenderPart(renderer);
1789 
1790     if (!frameRenderer->requiresAcceleratedCompositing())
1791         return false;
1792 
1793     if (frameRenderer->node() && frameRenderer->node()->isFrameOwnerElement() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame()->remotePlatformLayer())
1794         return true;
1795 
1796     // FIXME: this seems bogus. If we don't know the layout position/size of the frame yet, wouldn't that be handled elsehwere?
1797     m_needsToRecomputeCompositingRequirements = true;
1798 
1799     RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
1800     if (!innerCompositor)
1801         return false;
1802 
1803     // If we can't reliably know the size of the iframe yet, don't change compositing state.
1804     if (renderer->needsLayout())
1805         return frameRenderer->hasLayer() && frameRenderer->layer()->hasCompositedLayerMapping();
1806 
1807     // Don't go into compositing mode if height or width are zero.
1808     IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect());
1809     return contentBox.height() * contentBox.width() > 0;
1810 }
1811 
requiresCompositingForBackfaceVisibilityHidden(RenderObject * renderer) const1812 bool RenderLayerCompositor::requiresCompositingForBackfaceVisibilityHidden(RenderObject* renderer) const
1813 {
1814     return canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden;
1815 }
1816 
requiresCompositingForAnimation(RenderObject * renderer) const1817 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
1818 {
1819     if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1820         return false;
1821 
1822     if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
1823         return renderer->animation().isRunningAcceleratableAnimationOnRenderer(renderer);
1824 
1825     return shouldCompositeForActiveAnimations(*renderer);
1826 }
1827 
requiresCompositingForTransition(RenderObject * renderer) const1828 bool RenderLayerCompositor::requiresCompositingForTransition(RenderObject* renderer) const
1829 {
1830     if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1831         return false;
1832 
1833     if (Settings* settings = m_renderView->document().settings()) {
1834         if (!settings->acceleratedCompositingForTransitionEnabled())
1835             return false;
1836     }
1837 
1838     return renderer->style()->transitionForProperty(CSSPropertyOpacity)
1839         || renderer->style()->transitionForProperty(CSSPropertyWebkitFilter)
1840         || renderer->style()->transitionForProperty(CSSPropertyWebkitTransform);
1841 }
1842 
subtreeReasonsForCompositing(RenderObject * renderer,bool hasCompositedDescendants,bool has3DTransformedDescendants) const1843 CompositingReasons RenderLayerCompositor::subtreeReasonsForCompositing(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants) const
1844 {
1845     CompositingReasons subtreeReasons = CompositingReasonNone;
1846 
1847     // FIXME: this seems to be a potentially different layer than the layer for which this was called. May not be an error, but is very confusing.
1848     RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1849 
1850     // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
1851     // via compositing so that they also apply to those composited descdendants.
1852     if (hasCompositedDescendants) {
1853         if (layer->transform())
1854             subtreeReasons |= CompositingReasonTransformWithCompositedDescendants;
1855 
1856         if (layer->shouldIsolateCompositedDescendants()) {
1857             ASSERT(layer->stackingNode()->isStackingContext());
1858             subtreeReasons |= CompositingReasonIsolateCompositedDescendants;
1859         }
1860 
1861         // If the implementation of createsGroup changes, we need to be aware of that in this part of code.
1862         ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->hasFilter() || renderer->hasBlendMode()) == renderer->createsGroup());
1863         if (renderer->isTransparent())
1864             subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants;
1865         if (renderer->hasMask())
1866             subtreeReasons |= CompositingReasonMaskWithCompositedDescendants;
1867         if (renderer->hasFilter())
1868             subtreeReasons |= CompositingReasonFilterWithCompositedDescendants;
1869         if (renderer->hasBlendMode())
1870             subtreeReasons |= CompositingReasonBlendingWithCompositedDescendants;
1871 
1872         if (renderer->hasReflection())
1873             subtreeReasons |= CompositingReasonReflectionWithCompositedDescendants;
1874 
1875         if (renderer->hasClipOrOverflowClip())
1876             subtreeReasons |= CompositingReasonClipsCompositingDescendants;
1877     }
1878 
1879 
1880     // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
1881     // will be affected by the preserve-3d or perspective.
1882     if (has3DTransformedDescendants) {
1883         if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D)
1884             subtreeReasons |= CompositingReasonPreserve3D;
1885 
1886         if (renderer->style()->hasPerspective())
1887             subtreeReasons |= CompositingReasonPerspective;
1888     }
1889 
1890     return subtreeReasons;
1891 }
1892 
requiresCompositingForFilters(RenderObject * renderer) const1893 bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const
1894 {
1895     if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
1896         return false;
1897 
1898     return renderer->hasFilter();
1899 }
1900 
requiresCompositingForOverflowScrollingParent(const RenderLayer * layer) const1901 bool RenderLayerCompositor::requiresCompositingForOverflowScrollingParent(const RenderLayer* layer) const
1902 {
1903     return !!layer->scrollParent();
1904 }
1905 
requiresCompositingForOutOfFlowClipping(const RenderLayer * layer) const1906 bool RenderLayerCompositor::requiresCompositingForOutOfFlowClipping(const RenderLayer* layer) const
1907 {
1908     return layer->compositorDrivenAcceleratedScrollingEnabled() && layer->isUnclippedDescendant();
1909 }
1910 
requiresCompositingForPosition(RenderObject * renderer,const RenderLayer * layer,RenderLayer::ViewportConstrainedNotCompositedReason * viewportConstrainedNotCompositedReason) const1911 bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
1912 {
1913     // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
1914     // opacity, transform) can get their own composited layer. A stacking context is required otherwise
1915     // z-index and clipping will be broken.
1916     if (!renderer->isPositioned())
1917         return false;
1918 
1919     EPosition position = renderer->style()->position();
1920     bool isFixed = renderer->isOutOfFlowPositioned() && position == FixedPosition;
1921     if (isFixed && !layer->stackingNode()->isStackingContainer())
1922         return false;
1923 
1924     bool isSticky = renderer->isInFlowPositioned() && position == StickyPosition;
1925     if (!isFixed && !isSticky)
1926         return false;
1927 
1928     // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
1929     if (Settings* settings = m_renderView->document().settings()) {
1930         if (!settings->acceleratedCompositingForFixedPositionEnabled())
1931             return false;
1932     }
1933 
1934     if (isSticky)
1935         return true;
1936 
1937     RenderObject* container = renderer->container();
1938     // If the renderer is not hooked up yet then we have to wait until it is.
1939     if (!container) {
1940         m_needsToRecomputeCompositingRequirements = true;
1941         return false;
1942     }
1943 
1944     // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
1945     // They will stay fixed wrt the container rather than the enclosing frame.
1946     if (container != m_renderView) {
1947         if (viewportConstrainedNotCompositedReason)
1948             *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer;
1949         return false;
1950     }
1951 
1952     // If the fixed-position element does not have any scrollable ancestor between it and
1953     // its container, then we do not need to spend compositor resources for it. Start by
1954     // assuming we can opt-out (i.e. no scrollable ancestor), and refine the answer below.
1955     bool hasScrollableAncestor = false;
1956 
1957     // The FrameView has the scrollbars associated with the top level viewport, so we have to
1958     // check the FrameView in addition to the hierarchy of ancestors.
1959     FrameView* frameView = m_renderView->frameView();
1960     if (frameView && frameView->isScrollable())
1961         hasScrollableAncestor = true;
1962 
1963     RenderLayer* ancestor = layer->parent();
1964     while (ancestor && !hasScrollableAncestor) {
1965         if (frameView->containsScrollableArea(ancestor->scrollableArea()))
1966             hasScrollableAncestor = true;
1967         if (ancestor->renderer() == m_renderView)
1968             break;
1969         ancestor = ancestor->parent();
1970     }
1971 
1972     if (!hasScrollableAncestor) {
1973         if (viewportConstrainedNotCompositedReason)
1974             *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForUnscrollableAncestors;
1975         return false;
1976     }
1977 
1978     // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done.
1979     if (!m_inPostLayoutUpdate) {
1980         m_needsToRecomputeCompositingRequirements = true;
1981         return layer->hasCompositedLayerMapping();
1982     }
1983 
1984     bool paintsContent = layer->isVisuallyNonEmpty() || layer->hasVisibleDescendant();
1985     if (!paintsContent) {
1986         if (viewportConstrainedNotCompositedReason)
1987             *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent;
1988         return false;
1989     }
1990 
1991     // Fixed position elements that are invisible in the current view don't get their own layer.
1992     if (FrameView* frameView = m_renderView->frameView()) {
1993         LayoutRect viewBounds = frameView->viewportConstrainedVisibleContentRect();
1994         LayoutRect layerBounds = layer->calculateLayerBounds(rootRenderLayer(), 0,
1995             RenderLayer::DefaultCalculateLayerBoundsFlags
1996             | RenderLayer::ExcludeHiddenDescendants
1997             | RenderLayer::DontConstrainForMask
1998             | RenderLayer::IncludeCompositedDescendants
1999             | RenderLayer::PretendLayerHasOwnBacking);
2000         if (!viewBounds.intersects(enclosingIntRect(layerBounds))) {
2001             if (viewportConstrainedNotCompositedReason) {
2002                 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView;
2003                 m_needsToRecomputeCompositingRequirements = true;
2004             }
2005             return false;
2006         }
2007     }
2008 
2009     return true;
2010 }
2011 
requiresCompositingForOverflowScrolling(const RenderLayer * layer) const2012 bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer* layer) const
2013 {
2014     return layer->needsCompositedScrolling();
2015 }
2016 
isRunningAcceleratedTransformAnimation(RenderObject * renderer) const2017 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const
2018 {
2019     if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
2020         return false;
2021     if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
2022         return renderer->animation().isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
2023     return hasActiveAnimations(*renderer, CSSPropertyWebkitTransform);
2024 }
2025 
2026 // If an element has negative z-index children, those children render in front of the
2027 // layer background, so we need an extra 'contents' layer for the foreground of the layer
2028 // object.
needsContentsCompositingLayer(const RenderLayer * layer) const2029 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
2030 {
2031     return layer->stackingNode()->hasNegativeZOrderList();
2032 }
2033 
paintScrollbar(Scrollbar * scrollbar,GraphicsContext & context,const IntRect & clip)2034 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
2035 {
2036     if (!scrollbar)
2037         return;
2038 
2039     context.save();
2040     const IntRect& scrollbarRect = scrollbar->frameRect();
2041     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
2042     IntRect transformedClip = clip;
2043     transformedClip.moveBy(scrollbarRect.location());
2044     scrollbar->paint(&context, transformedClip);
2045     context.restore();
2046 }
2047 
paintContents(const GraphicsLayer * graphicsLayer,GraphicsContext & context,GraphicsLayerPaintingPhase,const IntRect & clip)2048 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
2049 {
2050     if (graphicsLayer == layerForHorizontalScrollbar())
2051         paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
2052     else if (graphicsLayer == layerForVerticalScrollbar())
2053         paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
2054     else if (graphicsLayer == layerForScrollCorner()) {
2055         const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
2056         context.save();
2057         context.translate(-scrollCorner.x(), -scrollCorner.y());
2058         IntRect transformedClip = clip;
2059         transformedClip.moveBy(scrollCorner.location());
2060         m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
2061         context.restore();
2062     }
2063 }
2064 
supportsFixedRootBackgroundCompositing() const2065 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
2066 {
2067     if (Settings* settings = m_renderView->document().settings()) {
2068         if (settings->acceleratedCompositingForFixedRootBackgroundEnabled())
2069             return true;
2070     }
2071     return false;
2072 }
2073 
needsFixedRootBackgroundLayer(const RenderLayer * layer) const2074 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const
2075 {
2076     if (layer != m_renderView->layer())
2077         return false;
2078 
2079     return supportsFixedRootBackgroundCompositing() && m_renderView->rootBackgroundIsEntirelyFixed();
2080 }
2081 
fixedRootBackgroundLayer() const2082 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
2083 {
2084     // Get the fixed root background from the RenderView layer's compositedLayerMapping.
2085     RenderLayer* viewLayer = m_renderView->layer();
2086     if (!viewLayer)
2087         return 0;
2088 
2089     if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground())
2090         return viewLayer->compositedLayerMapping()->backgroundLayer();
2091 
2092     return 0;
2093 }
2094 
resetTrackedRepaintRectsRecursive(GraphicsLayer * graphicsLayer)2095 static void resetTrackedRepaintRectsRecursive(GraphicsLayer* graphicsLayer)
2096 {
2097     if (!graphicsLayer)
2098         return;
2099 
2100     graphicsLayer->resetTrackedRepaints();
2101 
2102     for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
2103         resetTrackedRepaintRectsRecursive(graphicsLayer->children()[i]);
2104 
2105     if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
2106         resetTrackedRepaintRectsRecursive(replicaLayer);
2107 
2108     if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
2109         resetTrackedRepaintRectsRecursive(maskLayer);
2110 
2111     if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer())
2112         resetTrackedRepaintRectsRecursive(clippingMaskLayer);
2113 }
2114 
resetTrackedRepaintRects()2115 void RenderLayerCompositor::resetTrackedRepaintRects()
2116 {
2117     if (GraphicsLayer* rootLayer = rootGraphicsLayer())
2118         resetTrackedRepaintRectsRecursive(rootLayer);
2119 }
2120 
setTracksRepaints(bool tracksRepaints)2121 void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints)
2122 {
2123     updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
2124     m_isTrackingRepaints = tracksRepaints;
2125 }
2126 
isTrackingRepaints() const2127 bool RenderLayerCompositor::isTrackingRepaints() const
2128 {
2129     return m_isTrackingRepaints;
2130 }
2131 
didCommitChangesForLayer(const GraphicsLayer *) const2132 void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const
2133 {
2134     // Nothing to do here yet.
2135 }
2136 
shouldCompositeOverflowControls(FrameView * view)2137 static bool shouldCompositeOverflowControls(FrameView* view)
2138 {
2139     if (Page* page = view->frame().page()) {
2140         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
2141             if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
2142                 return true;
2143     }
2144 
2145     return true;
2146 }
2147 
requiresHorizontalScrollbarLayer() const2148 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
2149 {
2150     FrameView* view = m_renderView->frameView();
2151     return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
2152 }
2153 
requiresVerticalScrollbarLayer() const2154 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
2155 {
2156     FrameView* view = m_renderView->frameView();
2157     return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
2158 }
2159 
requiresScrollCornerLayer() const2160 bool RenderLayerCompositor::requiresScrollCornerLayer() const
2161 {
2162     FrameView* view = m_renderView->frameView();
2163     return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
2164 }
2165 
2166 #if USE(RUBBER_BANDING)
requiresOverhangLayers() const2167 bool RenderLayerCompositor::requiresOverhangLayers() const
2168 {
2169     // We don't want a layer if this is a subframe.
2170     if (!isMainFrame())
2171         return false;
2172 
2173     // We do want a layer if we have a scrolling coordinator and can scroll.
2174     if (scrollingCoordinator() && m_renderView->frameView()->hasOpaqueBackground())
2175         return true;
2176 
2177     // Chromium always wants a layer.
2178     return true;
2179 }
2180 #endif
2181 
updateOverflowControlsLayers()2182 void RenderLayerCompositor::updateOverflowControlsLayers()
2183 {
2184 #if USE(RUBBER_BANDING)
2185     if (requiresOverhangLayers()) {
2186         if (!m_layerForOverhangShadow) {
2187             m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this);
2188             OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get());
2189             OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
2190             m_scrollLayer->addChild(m_layerForOverhangShadow.get());
2191         }
2192     } else {
2193         if (m_layerForOverhangShadow) {
2194             m_layerForOverhangShadow->removeFromParent();
2195             m_layerForOverhangShadow = nullptr;
2196         }
2197     }
2198 #endif
2199 
2200     if (requiresHorizontalScrollbarLayer()) {
2201         if (!m_layerForHorizontalScrollbar) {
2202             m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
2203             m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
2204 
2205             if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2206                 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar);
2207         }
2208     } else if (m_layerForHorizontalScrollbar) {
2209         m_layerForHorizontalScrollbar->removeFromParent();
2210         m_layerForHorizontalScrollbar = nullptr;
2211 
2212         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2213             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar);
2214     }
2215 
2216     if (requiresVerticalScrollbarLayer()) {
2217         if (!m_layerForVerticalScrollbar) {
2218             m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
2219             m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
2220 
2221             if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2222                 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar);
2223         }
2224     } else if (m_layerForVerticalScrollbar) {
2225         m_layerForVerticalScrollbar->removeFromParent();
2226         m_layerForVerticalScrollbar = nullptr;
2227 
2228         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2229             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar);
2230     }
2231 
2232     if (requiresScrollCornerLayer()) {
2233         if (!m_layerForScrollCorner) {
2234             m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
2235             m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
2236         }
2237     } else if (m_layerForScrollCorner) {
2238         m_layerForScrollCorner->removeFromParent();
2239         m_layerForScrollCorner = nullptr;
2240     }
2241 
2242     m_renderView->frameView()->positionScrollbarLayers();
2243 }
2244 
ensureRootLayer()2245 void RenderLayerCompositor::ensureRootLayer()
2246 {
2247     RootLayerAttachment expectedAttachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
2248     if (expectedAttachment == m_rootLayerAttachment)
2249          return;
2250 
2251     if (!m_rootContentLayer) {
2252         m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
2253         IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect();
2254         m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
2255         m_rootContentLayer->setPosition(FloatPoint());
2256 
2257         // Need to clip to prevent transformed content showing outside this frame
2258         m_rootContentLayer->setMasksToBounds(true);
2259     }
2260 
2261     if (!m_overflowControlsHostLayer) {
2262         ASSERT(!m_scrollLayer);
2263         ASSERT(!m_containerLayer);
2264 
2265         // Create a layer to host the clipping layer and the overflow controls layers.
2266         m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
2267 
2268         // Create a clipping layer if this is an iframe or settings require to clip.
2269         m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
2270         bool containerMasksToBounds = !isMainFrame();
2271         if (Settings* settings = m_renderView->document().settings()) {
2272             if (settings->mainFrameClipsContent())
2273                 containerMasksToBounds = true;
2274         }
2275         m_containerLayer->setMasksToBounds(containerMasksToBounds);
2276 
2277         m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
2278         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2279             scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
2280 
2281         // Hook them up
2282         m_overflowControlsHostLayer->addChild(m_containerLayer.get());
2283         m_containerLayer->addChild(m_scrollLayer.get());
2284         m_scrollLayer->addChild(m_rootContentLayer.get());
2285 
2286         frameViewDidChangeSize();
2287         frameViewDidScroll();
2288     }
2289 
2290     // Check to see if we have to change the attachment
2291     if (m_rootLayerAttachment != RootLayerUnattached)
2292         detachRootLayer();
2293 
2294     attachRootLayer(expectedAttachment);
2295 }
2296 
destroyRootLayer()2297 void RenderLayerCompositor::destroyRootLayer()
2298 {
2299     if (!m_rootContentLayer)
2300         return;
2301 
2302     detachRootLayer();
2303 
2304 #if USE(RUBBER_BANDING)
2305     if (m_layerForOverhangShadow) {
2306         m_layerForOverhangShadow->removeFromParent();
2307         m_layerForOverhangShadow = nullptr;
2308     }
2309 #endif
2310 
2311     if (m_layerForHorizontalScrollbar) {
2312         m_layerForHorizontalScrollbar->removeFromParent();
2313         m_layerForHorizontalScrollbar = nullptr;
2314         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2315             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar);
2316         if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
2317             m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
2318     }
2319 
2320     if (m_layerForVerticalScrollbar) {
2321         m_layerForVerticalScrollbar->removeFromParent();
2322         m_layerForVerticalScrollbar = nullptr;
2323         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2324             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar);
2325         if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
2326             m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
2327     }
2328 
2329     if (m_layerForScrollCorner) {
2330         m_layerForScrollCorner = nullptr;
2331         m_renderView->frameView()->invalidateScrollCorner(m_renderView->frameView()->scrollCornerRect());
2332     }
2333 
2334     if (m_overflowControlsHostLayer) {
2335         m_overflowControlsHostLayer = nullptr;
2336         m_containerLayer = nullptr;
2337         m_scrollLayer = nullptr;
2338     }
2339     ASSERT(!m_scrollLayer);
2340     m_rootContentLayer = nullptr;
2341 }
2342 
attachRootLayer(RootLayerAttachment attachment)2343 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
2344 {
2345     if (!m_rootContentLayer)
2346         return;
2347 
2348     switch (attachment) {
2349         case RootLayerUnattached:
2350             ASSERT_NOT_REACHED();
2351             break;
2352         case RootLayerAttachedViaChromeClient: {
2353             Frame& frame = m_renderView->frameView()->frame();
2354             Page* page = frame.page();
2355             if (!page)
2356                 return;
2357             page->chrome().client().attachRootGraphicsLayer(&frame, rootGraphicsLayer());
2358             break;
2359         }
2360         case RootLayerAttachedViaEnclosingFrame: {
2361             // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
2362             // for the frame's renderer in the parent document.
2363             m_renderView->document().ownerElement()->scheduleLayerUpdate();
2364             break;
2365         }
2366     }
2367 
2368     m_rootLayerAttachment = attachment;
2369 }
2370 
detachRootLayer()2371 void RenderLayerCompositor::detachRootLayer()
2372 {
2373     if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
2374         return;
2375 
2376     switch (m_rootLayerAttachment) {
2377     case RootLayerAttachedViaEnclosingFrame: {
2378         // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
2379         // for the frame's renderer in the parent document.
2380         if (m_overflowControlsHostLayer)
2381             m_overflowControlsHostLayer->removeFromParent();
2382         else
2383             m_rootContentLayer->removeFromParent();
2384 
2385         if (HTMLFrameOwnerElement* ownerElement = m_renderView->document().ownerElement())
2386             ownerElement->scheduleLayerUpdate();
2387         break;
2388     }
2389     case RootLayerAttachedViaChromeClient: {
2390         Frame& frame = m_renderView->frameView()->frame();
2391         Page* page = frame.page();
2392         if (!page)
2393             return;
2394         page->chrome().client().attachRootGraphicsLayer(&frame, 0);
2395     }
2396     break;
2397     case RootLayerUnattached:
2398         break;
2399     }
2400 
2401     m_rootLayerAttachment = RootLayerUnattached;
2402 }
2403 
updateRootLayerAttachment()2404 void RenderLayerCompositor::updateRootLayerAttachment()
2405 {
2406     ensureRootLayer();
2407 }
2408 
isMainFrame() const2409 bool RenderLayerCompositor::isMainFrame() const
2410 {
2411     // FIXME: Frame::isMainFrame() is probably better.
2412     return !m_renderView->document().ownerElement();
2413 }
2414 
2415 // IFrames are special, because we hook compositing layers together across iframe boundaries
2416 // when both parent and iframe content are composited. So when this frame becomes composited, we have
2417 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
notifyIFramesOfCompositingChange()2418 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
2419 {
2420     if (!m_renderView->frameView())
2421         return;
2422     Frame& frame = m_renderView->frameView()->frame();
2423 
2424     for (Frame* child = frame.tree().firstChild(); child; child = child->tree().traverseNext(&frame)) {
2425         if (child->document() && child->document()->ownerElement())
2426             child->document()->ownerElement()->scheduleLayerUpdate();
2427     }
2428 
2429     // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
2430     // we need to schedule a style recalc in our parent document.
2431     if (HTMLFrameOwnerElement* ownerElement = m_renderView->document().ownerElement())
2432         ownerElement->scheduleLayerUpdate();
2433 }
2434 
layerHas3DContent(const RenderLayer * layer) const2435 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
2436 {
2437     const RenderStyle* style = layer->renderer()->style();
2438     RenderLayerStackingNode* stackingNode = const_cast<RenderLayer*>(layer)->stackingNode();
2439 
2440     if (style &&
2441         (style->transformStyle3D() == TransformStyle3DPreserve3D ||
2442          style->hasPerspective() ||
2443          style->transform().has3DOperation()))
2444         return true;
2445 
2446     stackingNode->updateLayerListsIfNeeded();
2447 
2448 #if !ASSERT_DISABLED
2449     LayerListMutationDetector mutationChecker(stackingNode);
2450 #endif
2451 
2452     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
2453     while (RenderLayerStackingNode* curNode = iterator.next()) {
2454         if (layerHas3DContent(curNode->layer()))
2455             return true;
2456     }
2457 
2458     return false;
2459 }
2460 
isRootmostFixedOrStickyLayer(RenderLayer * layer)2461 static bool isRootmostFixedOrStickyLayer(RenderLayer* layer)
2462 {
2463     if (layer->renderer()->isStickyPositioned())
2464         return true;
2465 
2466     if (layer->renderer()->style()->position() != FixedPosition)
2467         return false;
2468 
2469     for (RenderLayerStackingNode* stackingContainerNode = layer->stackingNode()->ancestorStackingContainerNode(); stackingContainerNode; stackingContainerNode = stackingContainerNode->ancestorStackingContainerNode()) {
2470         if (stackingContainerNode->layer()->hasCompositedLayerMapping() && stackingContainerNode->layer()->renderer()->style()->position() == FixedPosition)
2471             return false;
2472     }
2473 
2474     return true;
2475 }
2476 
updateViewportConstraintStatus(RenderLayer * layer)2477 void RenderLayerCompositor::updateViewportConstraintStatus(RenderLayer* layer)
2478 {
2479     if (isRootmostFixedOrStickyLayer(layer))
2480         addViewportConstrainedLayer(layer);
2481     else
2482         removeViewportConstrainedLayer(layer);
2483 }
2484 
addViewportConstrainedLayer(RenderLayer * layer)2485 void RenderLayerCompositor::addViewportConstrainedLayer(RenderLayer* layer)
2486 {
2487     m_viewportConstrainedLayers.add(layer);
2488 }
2489 
removeViewportConstrainedLayer(RenderLayer * layer)2490 void RenderLayerCompositor::removeViewportConstrainedLayer(RenderLayer* layer)
2491 {
2492     if (!m_viewportConstrainedLayers.contains(layer))
2493         return;
2494 
2495     m_viewportConstrainedLayers.remove(layer);
2496 }
2497 
computeFixedViewportConstraints(RenderLayer * layer) const2498 FixedPositionViewportConstraints RenderLayerCompositor::computeFixedViewportConstraints(RenderLayer* layer) const
2499 {
2500     ASSERT(layer->hasCompositedLayerMapping());
2501 
2502     FrameView* frameView = m_renderView->frameView();
2503     LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect();
2504 
2505     FixedPositionViewportConstraints constraints;
2506 
2507     GraphicsLayer* graphicsLayer = layer->compositedLayerMapping()->mainGraphicsLayer();
2508 
2509     constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
2510     constraints.setViewportRectAtLastLayout(viewportRect);
2511 
2512     RenderStyle* style = layer->renderer()->style();
2513     if (!style->left().isAuto())
2514         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
2515 
2516     if (!style->right().isAuto())
2517         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight);
2518 
2519     if (!style->top().isAuto())
2520         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
2521 
2522     if (!style->bottom().isAuto())
2523         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom);
2524 
2525     // If left and right are auto, use left.
2526     if (style->left().isAuto() && style->right().isAuto())
2527         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
2528 
2529     // If top and bottom are auto, use top.
2530     if (style->top().isAuto() && style->bottom().isAuto())
2531         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
2532 
2533     return constraints;
2534 }
2535 
computeStickyViewportConstraints(RenderLayer * layer) const2536 StickyPositionViewportConstraints RenderLayerCompositor::computeStickyViewportConstraints(RenderLayer* layer) const
2537 {
2538     ASSERT(layer->hasCompositedLayerMapping());
2539 
2540     FrameView* frameView = m_renderView->frameView();
2541     LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect();
2542 
2543     StickyPositionViewportConstraints constraints;
2544 
2545     RenderBoxModelObject* renderer = toRenderBoxModelObject(layer->renderer());
2546 
2547     renderer->computeStickyPositionConstraints(constraints, viewportRect);
2548 
2549     GraphicsLayer* graphicsLayer = layer->compositedLayerMapping()->mainGraphicsLayer();
2550 
2551     constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
2552     constraints.setStickyOffsetAtLastLayout(renderer->stickyPositionOffset());
2553 
2554     return constraints;
2555 }
2556 
scrollingCoordinator() const2557 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
2558 {
2559     if (Page* page = this->page())
2560         return page->scrollingCoordinator();
2561 
2562     return 0;
2563 }
2564 
graphicsLayerFactory() const2565 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
2566 {
2567     if (Page* page = this->page())
2568         return page->chrome().client().graphicsLayerFactory();
2569     return 0;
2570 }
2571 
page() const2572 Page* RenderLayerCompositor::page() const
2573 {
2574     return m_renderView->frameView()->frame().page();
2575 }
2576 
debugName(const GraphicsLayer * graphicsLayer)2577 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
2578 {
2579     String name;
2580     if (graphicsLayer == m_rootContentLayer.get()) {
2581         name = "Content Root Layer";
2582 #if USE(RUBBER_BANDING)
2583     } else if (graphicsLayer == m_layerForOverhangShadow.get()) {
2584         name = "Overhang Areas Shadow";
2585 #endif
2586     } else if (graphicsLayer == m_overflowControlsHostLayer.get()) {
2587         name = "Overflow Controls Host Layer";
2588     } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
2589         name = "Horizontal Scrollbar Layer";
2590     } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
2591         name = "Vertical Scrollbar Layer";
2592     } else if (graphicsLayer == m_layerForScrollCorner.get()) {
2593         name = "Scroll Corner Layer";
2594     } else if (graphicsLayer == m_containerLayer.get()) {
2595         name = "Frame Clipping Layer";
2596     } else if (graphicsLayer == m_scrollLayer.get()) {
2597         name = "Frame Scrolling Layer";
2598     } else {
2599         ASSERT_NOT_REACHED();
2600     }
2601 
2602     return name;
2603 }
2604 
2605 } // namespace WebCore
2606