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