2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
28 #if USE(ACCELERATED_COMPOSITING)
29 #include "RenderLayerCompositor.h"
31 #include "AnimationController.h"
32 #include "CanvasRenderingContext.h"
33 #include "CSSPropertyNames.h"
35 #include "ChromeClient.h"
37 #include "FrameView.h"
38 #include "GraphicsLayer.h"
39 #include "HTMLCanvasElement.h"
40 #include "HTMLIFrameElement.h"
41 #include "HTMLNames.h"
42 #include "HitTestResult.h"
43 #include "InspectorInstrumentation.h"
47 #include "RenderApplet.h"
48 #include "RenderEmbeddedObject.h"
49 #include "RenderFullScreen.h"
50 #include "RenderGeometryMap.h"
51 #include "RenderIFrame.h"
52 #include "RenderLayerBacking.h"
53 #include "RenderReplica.h"
54 #include "RenderVideo.h"
55 #include "RenderView.h"
56 #include "ScrollbarTheme.h"
57 #include "ScrollingConstraints.h"
58 #include "ScrollingCoordinator.h"
60 #include "TiledBacking.h"
61 #include "TransformState.h"
62 #include "WebCoreMemoryInstrumentation.h"
63 #include <wtf/MemoryInstrumentationHashMap.h>
65 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
66 #include "HTMLMediaElement.h"
70 #include <wtf/CurrentTime.h>
74 #include "RenderTreeAsText.h"
77 #if ENABLE(3D_RENDERING)
78 // This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm').
79 bool WebCoreHas3DRendering = true;
84 using namespace HTMLNames;
86 class RenderLayerCompositor::OverlapMap {
87 WTF_MAKE_NONCOPYABLE(OverlapMap);
90 : m_geometryMap(UseTransforms)
92 // Begin assuming the root layer will be composited so that there is
93 // something on the stack. The root layer should also never get an
94 // popCompositingContainer call.
95 pushCompositingContainer();
98 void add(const RenderLayer* layer, const IntRect& bounds)
100 // Layers do not contribute to overlap immediately--instead, they will
101 // contribute to overlap as soon as their composited ancestor has been
102 // recursively processed and popped off the stack.
103 ASSERT(m_overlapStack.size() >= 2);
104 m_overlapStack[m_overlapStack.size() - 2].append(bounds);
108 bool contains(const RenderLayer* layer)
110 return m_layers.contains(layer);
113 bool overlapsLayers(const IntRect& bounds) const
115 const RectList& layerRects = m_overlapStack.last();
116 for (unsigned i = 0; i < layerRects.size(); i++) {
117 if (layerRects[i].intersects(bounds))
125 return m_layers.isEmpty();
128 void pushCompositingContainer()
130 m_overlapStack.append(RectList());
133 void popCompositingContainer()
135 m_overlapStack[m_overlapStack.size() - 2].append(m_overlapStack.last());
136 m_overlapStack.removeLast();
139 RenderGeometryMap& geometryMap() { return m_geometryMap; }
142 typedef Vector<IntRect> RectList;
143 Vector<RectList> m_overlapStack;
144 HashSet<const RenderLayer*> m_layers;
145 RenderGeometryMap m_geometryMap;
148 struct CompositingState {
149 CompositingState(RenderLayer* compAncestor, bool testOverlap)
150 : m_compositingAncestor(compAncestor)
151 , m_subtreeIsCompositing(false)
152 , m_testingOverlap(testOverlap)
159 CompositingState(const CompositingState& other)
160 : m_compositingAncestor(other.m_compositingAncestor)
161 , m_subtreeIsCompositing(other.m_subtreeIsCompositing)
162 , m_testingOverlap(other.m_testingOverlap)
164 , m_depth(other.m_depth + 1)
169 RenderLayer* m_compositingAncestor;
170 bool m_subtreeIsCompositing;
171 bool m_testingOverlap;
178 static inline bool compositingLogEnabled()
181 return LogCompositing.state == WTFLogChannelOn;
187 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
188 : m_renderView(renderView)
189 , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
190 , m_hasAcceleratedCompositing(true)
191 , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
192 , m_compositedLayerCount(0)
193 , m_showDebugBorders(false)
194 , m_showRepaintCounter(false)
195 , m_acceleratedDrawingEnabled(false)
196 , m_compositingConsultsOverlap(true)
197 , m_reevaluateCompositingAfterLayout(false)
198 , m_compositing(false)
199 , m_compositingLayersNeedRebuild(false)
200 , m_flushingLayers(false)
201 , m_shouldFlushOnReattach(false)
202 , m_forceCompositingMode(false)
203 , m_isTrackingRepaints(false)
204 , m_rootLayerAttachment(RootLayerUnattached)
206 , m_rootLayerUpdateCount(0)
207 , m_obligateCompositedLayerCount(0)
208 , m_secondaryCompositedLayerCount(0)
209 , m_obligatoryBackingStoreBytes(0)
210 , m_secondaryBackingStoreBytes(0)
215 RenderLayerCompositor::~RenderLayerCompositor()
217 ASSERT(m_rootLayerAttachment == RootLayerUnattached);
220 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
222 if (enable != m_compositing) {
223 m_compositing = enable;
227 notifyIFramesOfCompositingChange();
233 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
235 bool hasAcceleratedCompositing = false;
236 bool showDebugBorders = false;
237 bool showRepaintCounter = false;
238 bool forceCompositingMode = false;
239 bool acceleratedDrawingEnabled = false;
241 if (Settings* settings = m_renderView->document()->settings()) {
242 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
244 // We allow the chrome to override the settings, in case the page is rendered
245 // on a chrome that doesn't allow accelerated compositing.
246 if (hasAcceleratedCompositing) {
247 if (Page* page = this->page()) {
248 ChromeClient* chromeClient = page->chrome()->client();
249 m_compositingTriggers = chromeClient->allowedCompositingTriggers();
250 hasAcceleratedCompositing = m_compositingTriggers;
254 showDebugBorders = settings->showDebugBorders();
255 showRepaintCounter = settings->showRepaintCounter();
256 forceCompositingMode = settings->forceCompositingMode() && hasAcceleratedCompositing;
258 if (forceCompositingMode && m_renderView->document()->ownerElement())
259 forceCompositingMode = requiresCompositingForScrollableFrame();
261 acceleratedDrawingEnabled = settings->acceleratedDrawingEnabled();
264 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode)
265 setCompositingLayersNeedRebuild();
267 bool debugBordersChanged = m_showDebugBorders != showDebugBorders;
268 m_hasAcceleratedCompositing = hasAcceleratedCompositing;
269 m_showDebugBorders = showDebugBorders;
270 m_showRepaintCounter = showRepaintCounter;
271 m_forceCompositingMode = forceCompositingMode;
272 m_acceleratedDrawingEnabled = acceleratedDrawingEnabled;
274 if (debugBordersChanged) {
275 if (m_layerForHorizontalScrollbar)
276 m_layerForHorizontalScrollbar->setShowDebugBorder(m_showDebugBorders);
278 if (m_layerForVerticalScrollbar)
279 m_layerForVerticalScrollbar->setShowDebugBorder(m_showDebugBorders);
281 if (m_layerForScrollCorner)
282 m_layerForScrollCorner->setShowDebugBorder(m_showDebugBorders);
286 bool RenderLayerCompositor::canRender3DTransforms() const
288 return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
291 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
293 if (inCompositingMode())
294 m_compositingLayersNeedRebuild = needRebuild;
297 void RenderLayerCompositor::scheduleLayerFlush()
299 if (Page* page = this->page())
300 page->chrome()->client()->scheduleCompositingLayerFlush();
303 void RenderLayerCompositor::flushPendingLayerChanges(bool isFlushRoot)
305 // FrameView::flushCompositingStateIncludingSubframes() flushes each subframe,
306 // but GraphicsLayer::flushCompositingState() will cross frame boundaries
307 // if the GraphicsLayers are connected (the RootLayerAttachedViaEnclosingFrame case).
308 // As long as we're not the root of the flush, we can bail.
309 if (!isFlushRoot && rootLayerAttachment() == RootLayerAttachedViaEnclosingFrame)
312 if (rootLayerAttachment() == RootLayerUnattached) {
313 m_shouldFlushOnReattach = true;
317 AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame()->animation());
319 ASSERT(!m_flushingLayers);
320 m_flushingLayers = true;
322 if (GraphicsLayer* rootLayer = rootGraphicsLayer()) {
323 FrameView* frameView = m_renderView ? m_renderView->frameView() : 0;
325 // Having a m_clipLayer indicates that we're doing scrolling via GraphicsLayers.
326 IntRect visibleRect = m_clipLayer ? IntRect(IntPoint(), frameView->contentsSize()) : frameView->visibleContentRect();
327 rootLayer->flushCompositingState(visibleRect);
331 ASSERT(m_flushingLayers);
332 m_flushingLayers = false;
334 if (!m_viewportConstrainedLayersNeedingUpdate.isEmpty()) {
335 HashSet<RenderLayer*>::const_iterator end = m_viewportConstrainedLayersNeedingUpdate.end();
336 for (HashSet<RenderLayer*>::const_iterator it = m_viewportConstrainedLayersNeedingUpdate.begin(); it != end; ++it)
337 registerOrUpdateViewportConstrainedLayer(*it);
339 m_viewportConstrainedLayersNeedingUpdate.clear();
343 void RenderLayerCompositor::didFlushChangesForLayer(RenderLayer* layer)
345 if (m_viewportConstrainedLayers.contains(layer))
346 m_viewportConstrainedLayersNeedingUpdate.add(layer);
349 void RenderLayerCompositor::notifyFlushBeforeDisplayRefresh(const GraphicsLayer*)
351 if (!m_layerUpdater) {
352 PlatformDisplayID displayID = 0;
353 if (Page* page = this->page())
354 displayID = page->displayID();
356 m_layerUpdater = adoptPtr(new GraphicsLayerUpdater(this, displayID));
359 m_layerUpdater->scheduleUpdate();
362 void RenderLayerCompositor::flushLayers(GraphicsLayerUpdater*)
364 flushPendingLayerChanges(true); // FIXME: deal with iframes
367 RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const
369 if (!m_renderView->frameView())
372 for (Frame* frame = m_renderView->frameView()->frame(); frame; frame = frame->tree()->parent()) {
373 RenderLayerCompositor* compositor = frame->contentRenderer() ? frame->contentRenderer()->compositor() : 0;
374 if (compositor->isFlushingLayers())
381 void RenderLayerCompositor::scheduleCompositingLayerUpdate()
383 if (!m_updateCompositingLayersTimer.isActive())
384 m_updateCompositingLayersTimer.startOneShot(0);
387 void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*)
389 updateCompositingLayers(CompositingUpdateAfterLayout);
392 bool RenderLayerCompositor::hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const
394 return m_compositedLayerCount > (rootLayer->isComposited() ? 1 : 0);
397 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
399 m_updateCompositingLayersTimer.stop();
401 // Compositing layers will be updated in Document::implicitClose() if suppressed here.
402 if (!m_renderView->document()->visualUpdatesAllowed())
405 // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
406 if (m_renderView->needsLayout())
409 if (m_forceCompositingMode && !m_compositing)
410 enableCompositingMode(true);
412 if (!m_reevaluateCompositingAfterLayout && !m_compositing)
415 AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame()->animation());
417 bool checkForHierarchyUpdate = m_reevaluateCompositingAfterLayout;
418 bool needGeometryUpdate = false;
420 switch (updateType) {
421 case CompositingUpdateAfterStyleChange:
422 case CompositingUpdateAfterLayout:
423 case CompositingUpdateOnHitTest:
424 checkForHierarchyUpdate = true;
426 case CompositingUpdateOnScroll:
427 if (m_compositingConsultsOverlap)
428 checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
430 needGeometryUpdate = true;
434 if (!checkForHierarchyUpdate && !needGeometryUpdate)
437 bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
438 bool isFullUpdate = !updateRoot;
439 if (!updateRoot || m_compositingConsultsOverlap) {
440 // Only clear the flag if we're updating the entire hierarchy.
441 m_compositingLayersNeedRebuild = false;
442 updateRoot = rootRenderLayer();
445 if (isFullUpdate && updateType == CompositingUpdateAfterLayout)
446 m_reevaluateCompositingAfterLayout = false;
449 double startTime = 0;
450 if (compositingLogEnabled()) {
451 ++m_rootLayerUpdateCount;
452 startTime = currentTime();
456 if (checkForHierarchyUpdate) {
457 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
458 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
459 CompositingState compState(updateRoot, m_compositingConsultsOverlap);
460 bool layersChanged = false;
461 bool saw3DTransform = false;
462 if (m_compositingConsultsOverlap) {
463 OverlapMap overlapTestRequestMap;
464 computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, compState, layersChanged, saw3DTransform);
466 computeCompositingRequirements(0, updateRoot, 0, compState, layersChanged, saw3DTransform);
468 needHierarchyUpdate |= layersChanged;
472 if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
473 m_obligateCompositedLayerCount = 0;
474 m_secondaryCompositedLayerCount = 0;
475 m_obligatoryBackingStoreBytes = 0;
476 m_secondaryBackingStoreBytes = 0;
478 Frame* frame = m_renderView->frameView()->frame();
479 bool isMainFrame = !m_renderView->document()->ownerElement();
480 LOG(Compositing, "\nUpdate %d of %s. Overlap testing is %s\n", m_rootLayerUpdateCount, isMainFrame ? "main frame" : frame->tree()->uniqueName().string().utf8().data(),
481 m_compositingConsultsOverlap ? "on" : "off");
485 if (needHierarchyUpdate) {
486 // Update the hierarchy of the compositing layers.
487 Vector<GraphicsLayer*> childList;
488 rebuildCompositingLayerTree(updateRoot, childList, 0);
490 // Host the document layer in the RenderView's root layer.
492 // Even when childList is empty, don't drop out of compositing mode if there are
493 // composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
494 if (childList.isEmpty() && !hasAnyAdditionalCompositedLayers(updateRoot))
497 m_rootContentLayer->setChildren(childList);
499 } else if (needGeometryUpdate) {
500 // We just need to do a geometry update. This is only used for position:fixed scrolling;
501 // most of the time, geometry is updated via RenderLayer::styleChanged().
502 updateLayerTreeGeometry(updateRoot, 0);
506 if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
507 double endTime = currentTime();
508 LOG(Compositing, "Total layers primary secondary obligatory backing (KB) secondary backing(KB) total backing (KB) update time (ms)\n");
510 LOG(Compositing, "%8d %11d %9d %20.2f %22.2f %22.2f %18.2f\n",
511 m_obligateCompositedLayerCount + m_secondaryCompositedLayerCount, m_obligateCompositedLayerCount,
512 m_secondaryCompositedLayerCount, m_obligatoryBackingStoreBytes / 1024, m_secondaryBackingStoreBytes / 1024, (m_obligatoryBackingStoreBytes + m_secondaryBackingStoreBytes) / 1024, 1000.0 * (endTime - startTime));
515 ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
517 if (!hasAcceleratedCompositing())
518 enableCompositingMode(false);
520 // Inform the inspector that the layer tree has changed.
521 InspectorInstrumentation::layerTreeDidChange(page());
524 void RenderLayerCompositor::layerBecameNonComposited(const RenderLayer* renderLayer)
526 // Inform the inspector that the given RenderLayer was destroyed.
527 InspectorInstrumentation::renderLayerDestroyed(page(), renderLayer);
529 ASSERT(m_compositedLayerCount > 0);
530 --m_compositedLayerCount;
534 void RenderLayerCompositor::logLayerInfo(const RenderLayer* layer, int depth)
536 if (!compositingLogEnabled())
539 RenderLayerBacking* backing = layer->backing();
540 if (requiresCompositingLayer(layer) || layer->isRootLayer()) {
541 ++m_obligateCompositedLayerCount;
542 m_obligatoryBackingStoreBytes += backing->backingStoreMemoryEstimate();
544 ++m_secondaryCompositedLayerCount;
545 m_secondaryBackingStoreBytes += backing->backingStoreMemoryEstimate();
548 LOG(Compositing, "%*p %dx%d %.2fKB (%s) %s\n", 12 + depth * 2, layer, backing->compositedBounds().width(), backing->compositedBounds().height(),
549 backing->backingStoreMemoryEstimate() / 1024,
550 reasonForCompositing(layer), layer->name().utf8().data());
554 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
556 bool layerChanged = false;
557 RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;
559 if (needsToBeComposited(layer, &viewportConstrainedNotCompositedReason)) {
560 enableCompositingMode();
562 if (!layer->backing()) {
563 // If we need to repaint, do so before making backing
564 if (shouldRepaint == CompositingChangeRepaintNow)
565 repaintOnCompositingChange(layer);
567 layer->ensureBacking();
569 // At this time, the ScrollingCooridnator only supports the top-level frame.
570 if (layer->isRootLayer() && !m_renderView->document()->ownerElement()) {
571 layer->backing()->attachToScrollingCoordinatorWithParent(0);
572 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
573 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
576 // This layer and all of its descendants have cached repaints rects that are relative to
577 // the repaint container, so change when compositing changes; we need to update them here.
579 layer->computeRepaintRectsIncludingDescendants();
584 // Need to add for every compositing layer, because a composited layer may change from being non-fixed to fixed.
585 updateViewportConstraintStatus(layer);
587 if (layer->backing()) {
588 // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
589 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
590 // are both either composited, or not composited.
591 if (layer->isReflection()) {
592 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer();
593 if (RenderLayerBacking* backing = sourceLayer->backing()) {
594 ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer());
595 backing->graphicsLayer()->setReplicatedByLayer(0);
599 removeViewportConstrainedLayer(layer);
601 layer->clearBacking();
604 // This layer and all of its descendants have cached repaints rects that are relative to
605 // the repaint container, so change when compositing changes; we need to update them here.
606 layer->computeRepaintRectsIncludingDescendants();
608 // If we need to repaint, do so now that we've removed the backing
609 if (shouldRepaint == CompositingChangeRepaintNow)
610 repaintOnCompositingChange(layer);
615 if (layerChanged && layer->renderer()->isVideo()) {
616 // If it's a video, give the media player a chance to hook up to the layer.
617 RenderVideo* video = toRenderVideo(layer->renderer());
618 video->acceleratedRenderingStateChanged();
622 if (layerChanged && layer->renderer()->isRenderPart()) {
623 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
624 if (innerCompositor && innerCompositor->inCompositingMode())
625 innerCompositor->updateRootLayerAttachment();
629 layer->clearClipRectsIncludingDescendants(PaintingClipRects);
631 // If a fixed position layer gained/lost a backing or the reason not compositing it changed,
632 // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
633 if (layer->renderer()->style()->position() == FixedPosition) {
634 if (layer->viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
635 layer->setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason);
639 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
640 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView->frameView());
644 if (layer->backing())
645 layer->backing()->updateDebugIndicators(m_showDebugBorders, m_showRepaintCounter);
650 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
652 bool layerChanged = updateBacking(layer, shouldRepaint);
654 // See if we need content or clipping layers. Methods called here should assume
655 // that the compositing state of descendant layers has not been updated yet.
656 if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration())
662 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
664 // If the renderer is not attached yet, no need to repaint.
665 if (layer->renderer() != m_renderView && !layer->renderer()->parent())
668 RenderLayerModelObject* repaintContainer = layer->renderer()->containerForRepaint();
669 if (!repaintContainer)
670 repaintContainer = m_renderView;
672 layer->repaintIncludingNonCompositingDescendants(repaintContainer);
673 if (repaintContainer == m_renderView) {
674 // The contents of this layer may be moving between the window
675 // and a GraphicsLayer, so we need to make sure the window system
676 // synchronizes those changes on the screen.
677 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
681 // This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
682 void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect)
684 RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(false /*exclude self*/);
685 if (compositedAncestor) {
686 ASSERT(compositedAncestor->backing());
689 layer->convertToLayerCoords(compositedAncestor, offset);
691 LayoutRect repaintRect = rect;
692 repaintRect.moveBy(offset);
694 compositedAncestor->setBackingNeedsRepaintInRect(repaintRect);
697 // The contents of this layer may be moving from a GraphicsLayer to the window,
698 // so we need to make sure the window system synchronizes those changes on the screen.
699 if (compositedAncestor == m_renderView->layer())
700 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
703 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
704 // RenderLayers that are rendered by the composited RenderLayer.
705 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const
707 if (!canBeComposited(layer))
709 return layer->calculateLayerBounds(ancestorLayer, 0, RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask);
712 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
714 setCompositingLayersNeedRebuild();
717 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
719 if (!child->isComposited() || parent->renderer()->documentBeingDestroyed())
722 removeViewportConstrainedLayer(child);
723 repaintInCompositedAncestor(child, child->backing()->compositedBounds());
725 setCompositingParent(child, 0);
726 setCompositingLayersNeedRebuild();
729 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
731 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
732 if (curr->isStackingContext())
735 if (curr->renderer()->hasClipOrOverflowClip())
741 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
743 if (layer->isRootLayer())
746 if (!boundsComputed) {
747 // FIXME: If this layer's overlap bounds include its children, we don't need to add its
748 // children's bounds to the overlap map.
749 layerBounds = enclosingIntRect(overlapMap.geometryMap().absoluteRect(layer->overlapBounds()));
750 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
751 if (layerBounds.isEmpty())
752 layerBounds.setSize(IntSize(1, 1));
753 boundsComputed = true;
756 IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(RenderLayer::ClipRectsContext(rootRenderLayer(), 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
757 clipRect.scale(pageScaleFactor());
758 clipRect.intersect(layerBounds);
759 overlapMap.add(layer, clipRect);
762 void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, RenderLayer* layer, RenderLayer* ancestorLayer)
764 if (!canBeComposited(layer) || overlapMap.contains(layer))
767 // A null ancestorLayer is an indication that 'layer' has already been pushed.
769 overlapMap.geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
772 bool haveComputedBounds = false;
773 addToOverlapMap(overlapMap, layer, bounds, haveComputedBounds);
776 LayerListMutationDetector mutationChecker(layer);
779 if (layer->isStackingContext()) {
780 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
781 size_t listSize = negZOrderList->size();
782 for (size_t i = 0; i < listSize; ++i) {
783 RenderLayer* curLayer = negZOrderList->at(i);
784 addToOverlapMapRecursive(overlapMap, curLayer, layer);
789 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
790 size_t listSize = normalFlowList->size();
791 for (size_t i = 0; i < listSize; ++i) {
792 RenderLayer* curLayer = normalFlowList->at(i);
793 addToOverlapMapRecursive(overlapMap, curLayer, layer);
797 if (layer->isStackingContext()) {
798 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
799 size_t listSize = posZOrderList->size();
800 for (size_t i = 0; i < listSize; ++i) {
801 RenderLayer* curLayer = posZOrderList->at(i);
802 addToOverlapMapRecursive(overlapMap, curLayer, layer);
808 overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
811 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
812 // For the z-order children of a compositing layer:
813 // If a child layers has a compositing layer, then all subsequent layers must
814 // be compositing in order to render above that layer.
816 // If a child in the negative z-order list is compositing, then the layer itself
817 // must be compositing so that its contents render over that child.
818 // This implies that its positive z-index children must also be compositing.
820 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged, bool& descendantHas3DTransform)
822 layer->updateLayerListsIfNeeded();
825 overlapMap->geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
828 layer->setHasCompositingDescendant(false);
830 RenderLayer::IndirectCompositingReason compositingReason = compositingState.m_subtreeIsCompositing ? RenderLayer::IndirectCompositingForStacking : RenderLayer::NoIndirectCompositingReason;
832 bool haveComputedBounds = false;
834 if (overlapMap && !overlapMap->isEmpty() && compositingState.m_testingOverlap) {
835 // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
836 absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds()));
838 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
839 if (absBounds.isEmpty())
840 absBounds.setSize(IntSize(1, 1));
841 haveComputedBounds = true;
842 compositingReason = overlapMap->overlapsLayers(absBounds) ? RenderLayer::IndirectCompositingForOverlap : RenderLayer::NoIndirectCompositingReason;
846 // Video is special. It's the only RenderLayer type that can both have
847 // RenderLayer children and whose children can't use its backing to render
848 // into. These children (the controls) always need to be promoted into their
849 // own layers to draw on top of the accelerated video.
850 if (compositingState.m_compositingAncestor && compositingState.m_compositingAncestor->renderer()->isVideo())
851 compositingReason = RenderLayer::IndirectCompositingForOverlap;
854 layer->setIndirectCompositingReason(compositingReason);
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 CompositingState childState(compositingState);
860 childState.m_subtreeIsCompositing = false;
862 bool willBeComposited = needsToBeComposited(layer);
863 if (willBeComposited) {
864 // Tell the parent it has compositing descendants.
865 compositingState.m_subtreeIsCompositing = true;
866 // This layer now acts as the ancestor for kids.
867 childState.m_compositingAncestor = layer;
870 overlapMap->pushCompositingContainer();
874 LayerListMutationDetector mutationChecker(layer);
877 bool anyDescendantHas3DTransform = false;
879 if (layer->isStackingContext()) {
880 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
881 size_t listSize = negZOrderList->size();
882 for (size_t i = 0; i < listSize; ++i) {
883 RenderLayer* curLayer = negZOrderList->at(i);
884 computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
886 // If we have to make a layer for this child, make one now so we can have a contents layer
887 // (since we need to ensure that the -ve z-order child renders underneath our contents).
888 if (!willBeComposited && childState.m_subtreeIsCompositing) {
889 // make layer compositing
890 layer->setIndirectCompositingReason(RenderLayer::IndirectCompositingForBackgroundLayer);
891 childState.m_compositingAncestor = layer;
893 overlapMap->pushCompositingContainer();
894 willBeComposited = true;
900 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
901 size_t listSize = normalFlowList->size();
902 for (size_t i = 0; i < listSize; ++i) {
903 RenderLayer* curLayer = normalFlowList->at(i);
904 computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
908 if (layer->isStackingContext()) {
909 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
910 size_t listSize = posZOrderList->size();
911 for (size_t i = 0; i < listSize; ++i) {
912 RenderLayer* curLayer = posZOrderList->at(i);
913 computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
918 // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
919 if (layer->isRootLayer()) {
920 if (inCompositingMode() && m_hasAcceleratedCompositing)
921 willBeComposited = true;
924 ASSERT(willBeComposited == needsToBeComposited(layer));
926 // All layers (even ones that aren't being composited) need to get added to
927 // the overlap map. Layers that do not composite will draw into their
928 // compositing ancestor's backing, and so are still considered for overlap.
929 if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer())
930 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
932 // Now check for reasons to become composited that depend on the state of descendant layers.
933 RenderLayer::IndirectCompositingReason indirectCompositingReason;
934 if (!willBeComposited && canBeComposited(layer)
935 && requiresCompositingForIndirectReason(layer->renderer(), childState.m_subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
936 layer->setIndirectCompositingReason(indirectCompositingReason);
937 childState.m_compositingAncestor = layer;
939 overlapMap->pushCompositingContainer();
940 addToOverlapMapRecursive(*overlapMap, layer);
942 willBeComposited = true;
945 ASSERT(willBeComposited == needsToBeComposited(layer));
946 if (layer->reflectionLayer()) {
947 // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
948 layer->reflectionLayer()->setIndirectCompositingReason(willBeComposited ? RenderLayer::IndirectCompositingForStacking : RenderLayer::NoIndirectCompositingReason);
951 // Subsequent layers in the parent stacking context also need to composite.
952 if (childState.m_subtreeIsCompositing)
953 compositingState.m_subtreeIsCompositing = true;
955 // Turn overlap testing off for later layers if it's already off, or if we have a 3D transform or an animating transform.
956 if (!childState.m_testingOverlap || layer->has3DTransform() || isRunningAcceleratedTransformAnimation(layer->renderer()))
957 compositingState.m_testingOverlap = false;
959 // Set the flag to say that this SC has compositing children.
960 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
962 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
963 // so test that again.
964 if (canBeComposited(layer) && clipsCompositingDescendants(layer)) {
965 if (!willBeComposited) {
966 childState.m_compositingAncestor = layer;
968 overlapMap->pushCompositingContainer();
969 addToOverlapMapRecursive(*overlapMap, layer);
971 willBeComposited = true;
974 // We're done processing an element that clips. The container can keep testing overlap.
975 compositingState.m_testingOverlap = true;
978 if (overlapMap && childState.m_compositingAncestor == layer && !layer->isRootLayer())
979 overlapMap->popCompositingContainer();
981 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
982 // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
983 // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
984 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) {
985 enableCompositingMode(false);
986 willBeComposited = false;
989 // If the layer is going into compositing mode, repaint its old location.
990 ASSERT(willBeComposited == needsToBeComposited(layer));
991 if (!layer->isComposited() && willBeComposited)
992 repaintOnCompositingChange(layer);
994 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
995 if (updateBacking(layer, CompositingChangeRepaintNow))
996 layersChanged = true;
998 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
999 layersChanged = true;
1001 descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform();
1004 overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer);
1007 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
1009 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
1010 ASSERT(childLayer->isComposited());
1012 // It's possible to be called with a parent that isn't yet composited when we're doing
1013 // partial updates as required by painting or hit testing. Just bail in that case;
1014 // we'll do a full layer update soon.
1015 if (!parentLayer || !parentLayer->isComposited())
1019 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
1020 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers();
1022 hostingLayer->addChild(hostedLayer);
1024 childLayer->backing()->childForSuperlayers()->removeFromParent();
1027 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
1029 ASSERT(layer->isComposited());
1031 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers();
1032 hostingLayer->removeAllChildren();
1036 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
1038 if (!m_hasAcceleratedCompositing)
1041 return o->supportsAcceleratedRendering();
1045 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
1047 // Make the layer compositing if necessary, and set up clipping and content layers.
1048 // Note that we can only do work here that is independent of whether the descendant layers
1049 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
1051 RenderLayerBacking* layerBacking = layer->backing();
1053 // The compositing state of all our children has been updated already, so now
1054 // we can compute and cache the composited bounds for this layer.
1055 layerBacking->updateCompositedBounds();
1057 if (RenderLayer* reflection = layer->reflectionLayer()) {
1058 if (reflection->backing())
1059 reflection->backing()->updateCompositedBounds();
1062 layerBacking->updateGraphicsLayerConfiguration();
1063 layerBacking->updateGraphicsLayerGeometry();
1065 if (!layer->parent())
1066 updateRootLayerPosition();
1069 logLayerInfo(layer, depth);
1071 UNUSED_PARAM(depth);
1073 if (layerBacking->hasUnpositionedOverflowControlsLayers())
1074 layer->positionNewlyCreatedOverflowControls();
1077 // If this layer has backing, then we are collecting its children, otherwise appending
1078 // to the compositing child list of an enclosing layer.
1079 Vector<GraphicsLayer*> layerChildren;
1080 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
1082 #if !ASSERT_DISABLED
1083 LayerListMutationDetector mutationChecker(layer);
1086 if (layer->isStackingContext()) {
1087 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1088 size_t listSize = negZOrderList->size();
1089 for (size_t i = 0; i < listSize; ++i) {
1090 RenderLayer* curLayer = negZOrderList->at(i);
1091 rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1095 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
1096 if (layerBacking && layerBacking->foregroundLayer())
1097 childList.append(layerBacking->foregroundLayer());
1100 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1101 size_t listSize = normalFlowList->size();
1102 for (size_t i = 0; i < listSize; ++i) {
1103 RenderLayer* curLayer = normalFlowList->at(i);
1104 rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1108 if (layer->isStackingContext()) {
1109 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1110 size_t listSize = posZOrderList->size();
1111 for (size_t i = 0; i < listSize; ++i) {
1112 RenderLayer* curLayer = posZOrderList->at(i);
1113 rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1119 bool parented = false;
1120 if (layer->renderer()->isRenderPart())
1121 parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
1124 layerBacking->parentForSublayers()->setChildren(layerChildren);
1126 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
1127 // Otherwise, the overflow control layers are normal children.
1128 if (!layerBacking->hasClippingLayer() && !layerBacking->hasScrollingLayer()) {
1129 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) {
1130 overflowControlLayer->removeFromParent();
1131 layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1134 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) {
1135 overflowControlLayer->removeFromParent();
1136 layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1139 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) {
1140 overflowControlLayer->removeFromParent();
1141 layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1145 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
1149 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
1151 if (m_overflowControlsHostLayer)
1152 m_overflowControlsHostLayer->setPosition(contentsOffset);
1155 void RenderLayerCompositor::frameViewDidChangeSize()
1158 FrameView* frameView = m_renderView->frameView();
1159 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1161 frameViewDidScroll();
1162 updateOverflowControlsLayers();
1164 #if ENABLE(RUBBER_BANDING)
1165 if (m_layerForOverhangAreas)
1166 m_layerForOverhangAreas->setSize(frameView->frameRect().size());
1171 void RenderLayerCompositor::frameViewDidScroll()
1173 FrameView* frameView = m_renderView->frameView();
1174 IntPoint scrollPosition = frameView->scrollPosition();
1179 // If there's a scrolling coordinator that manages scrolling for this frame view,
1180 // it will also manage updating the scroll layer position.
1181 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
1182 if (scrollingCoordinator->coordinatesScrollingForFrameView(frameView))
1184 if (Settings* settings = m_renderView->document()->settings())
1185 if (settings->compositedScrollingForFramesEnabled())
1186 scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView, m_scrollLayer.get());
1189 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
1192 void RenderLayerCompositor::frameViewDidLayout()
1194 RenderLayerBacking* renderViewBacking = m_renderView->layer()->backing();
1195 if (renderViewBacking)
1196 renderViewBacking->adjustTileCacheCoverage();
1199 void RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
1201 RenderLayerBacking* backing = layer->backing();
1202 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1203 scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer, backing ? backing->scrollingContentsLayer() : 0);
1206 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
1208 updateCompositingLayers(CompositingUpdateAfterLayout);
1210 if (!m_rootContentLayer)
1213 flushPendingLayerChanges(true);
1215 LayerTreeAsTextBehavior layerTreeBehavior = LayerTreeAsTextBehaviorNormal;
1216 if (flags & LayerTreeFlagsIncludeDebugInfo)
1217 layerTreeBehavior |= LayerTreeAsTextDebug;
1218 if (flags & LayerTreeFlagsIncludeVisibleRects)
1219 layerTreeBehavior |= LayerTreeAsTextIncludeVisibleRects;
1220 if (flags & LayerTreeFlagsIncludeTileCaches)
1221 layerTreeBehavior |= LayerTreeAsTextIncludeTileCaches;
1222 if (flags & LayerTreeFlagsIncludeRepaintRects)
1223 layerTreeBehavior |= LayerTreeAsTextIncludeRepaintRects;
1225 // We skip dumping the scroll and clip layers to keep layerTreeAsText output
1226 // similar between platforms.
1227 String layerTreeText = m_rootContentLayer->layerTreeAsText(layerTreeBehavior);
1229 // The true root layer is not included in the dump, so if we want to report
1230 // its repaint rects, they must be included here.
1231 if (flags & LayerTreeFlagsIncludeRepaintRects) {
1232 String layerTreeTextWithRootRepaintRects = m_renderView->frameView()->trackedRepaintRectsAsText();
1233 layerTreeTextWithRootRepaintRects.append(layerTreeText);
1234 return layerTreeTextWithRootRepaintRects;
1237 return layerTreeText;
1240 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
1242 if (!renderer->node()->isFrameOwnerElement())
1245 HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(renderer->node());
1246 if (Document* contentDocument = element->contentDocument()) {
1247 if (RenderView* view = contentDocument->renderView())
1248 return view->compositor();
1253 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
1255 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
1256 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
1259 RenderLayer* layer = renderer->layer();
1260 if (!layer->isComposited())
1263 RenderLayerBacking* backing = layer->backing();
1264 GraphicsLayer* hostingLayer = backing->parentForSublayers();
1265 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
1266 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
1267 hostingLayer->removeAllChildren();
1268 hostingLayer->addChild(rootLayer);
1273 // This just updates layer geometry without changing the hierarchy.
1274 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer, int depth)
1276 if (RenderLayerBacking* layerBacking = layer->backing()) {
1277 // The compositing state of all our children has been updated already, so now
1278 // we can compute and cache the composited bounds for this layer.
1279 layerBacking->updateCompositedBounds();
1281 if (RenderLayer* reflection = layer->reflectionLayer()) {
1282 if (reflection->backing())
1283 reflection->backing()->updateCompositedBounds();
1286 layerBacking->updateGraphicsLayerConfiguration();
1287 layerBacking->updateGraphicsLayerGeometry();
1289 if (!layer->parent())
1290 updateRootLayerPosition();
1293 logLayerInfo(layer, depth);
1295 UNUSED_PARAM(depth);
1299 #if !ASSERT_DISABLED
1300 LayerListMutationDetector mutationChecker(layer);
1303 if (layer->isStackingContext()) {
1304 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1305 size_t listSize = negZOrderList->size();
1306 for (size_t i = 0; i < listSize; ++i)
1307 updateLayerTreeGeometry(negZOrderList->at(i), depth + 1);
1311 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1312 size_t listSize = normalFlowList->size();
1313 for (size_t i = 0; i < listSize; ++i)
1314 updateLayerTreeGeometry(normalFlowList->at(i), depth + 1);
1317 if (layer->isStackingContext()) {
1318 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1319 size_t listSize = posZOrderList->size();
1320 for (size_t i = 0; i < listSize; ++i)
1321 updateLayerTreeGeometry(posZOrderList->at(i), depth + 1);
1326 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
1327 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, bool compositedChildrenOnly)
1329 if (layer != compositingAncestor) {
1330 if (RenderLayerBacking* layerBacking = layer->backing()) {
1331 layerBacking->updateCompositedBounds();
1333 if (RenderLayer* reflection = layer->reflectionLayer()) {
1334 if (reflection->backing())
1335 reflection->backing()->updateCompositedBounds();
1338 layerBacking->updateGraphicsLayerGeometry();
1339 if (compositedChildrenOnly)
1344 if (layer->reflectionLayer())
1345 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), compositedChildrenOnly);
1347 if (!layer->hasCompositingDescendant())
1350 #if !ASSERT_DISABLED
1351 LayerListMutationDetector mutationChecker(layer);
1354 if (layer->isStackingContext()) {
1355 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1356 size_t listSize = negZOrderList->size();
1357 for (size_t i = 0; i < listSize; ++i)
1358 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), compositedChildrenOnly);
1362 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1363 size_t listSize = normalFlowList->size();
1364 for (size_t i = 0; i < listSize; ++i)
1365 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), compositedChildrenOnly);
1368 if (layer->isStackingContext()) {
1369 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1370 size_t listSize = posZOrderList->size();
1371 for (size_t i = 0; i < listSize; ++i)
1372 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), compositedChildrenOnly);
1378 void RenderLayerCompositor::repaintCompositedLayers(const IntRect* absRect)
1380 recursiveRepaintLayer(rootRenderLayer(), absRect);
1383 void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer, const IntRect* rect)
1385 // FIXME: This method does not work correctly with transforms.
1386 if (layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor()) {
1388 layer->setBackingNeedsRepaintInRect(*rect);
1390 layer->setBackingNeedsRepaint();
1393 #if !ASSERT_DISABLED
1394 LayerListMutationDetector mutationChecker(layer);
1397 if (layer->hasCompositingDescendant()) {
1398 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1399 size_t listSize = negZOrderList->size();
1400 for (size_t i = 0; i < listSize; ++i) {
1401 RenderLayer* curLayer = negZOrderList->at(i);
1403 IntRect childRect(*rect);
1404 curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
1405 recursiveRepaintLayer(curLayer, &childRect);
1407 recursiveRepaintLayer(curLayer);
1411 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1412 size_t listSize = posZOrderList->size();
1413 for (size_t i = 0; i < listSize; ++i) {
1414 RenderLayer* curLayer = posZOrderList->at(i);
1416 IntRect childRect(*rect);
1417 curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
1418 recursiveRepaintLayer(curLayer, &childRect);
1420 recursiveRepaintLayer(curLayer);
1424 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1425 size_t listSize = normalFlowList->size();
1426 for (size_t i = 0; i < listSize; ++i) {
1427 RenderLayer* curLayer = normalFlowList->at(i);
1429 IntRect childRect(*rect);
1430 curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
1431 recursiveRepaintLayer(curLayer, &childRect);
1433 recursiveRepaintLayer(curLayer);
1438 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
1440 return m_renderView->layer();
1443 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
1445 if (m_overflowControlsHostLayer)
1446 return m_overflowControlsHostLayer.get();
1447 return m_rootContentLayer.get();
1450 GraphicsLayer* RenderLayerCompositor::scrollLayer() const
1452 return m_scrollLayer.get();
1455 TiledBacking* RenderLayerCompositor::pageTiledBacking() const
1457 RenderLayerBacking* renderViewBacking = m_renderView->layer()->backing();
1458 return renderViewBacking ? renderViewBacking->tiledBacking() : 0;
1461 void RenderLayerCompositor::didMoveOnscreen()
1463 if (TiledBacking* tiledBacking = pageTiledBacking())
1464 tiledBacking->setIsInWindow(true);
1466 if (!inCompositingMode() || m_rootLayerAttachment != RootLayerUnattached)
1469 RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1470 attachRootLayer(attachment);
1473 void RenderLayerCompositor::willMoveOffscreen()
1475 if (TiledBacking* tiledBacking = pageTiledBacking())
1476 tiledBacking->setIsInWindow(false);
1478 if (!inCompositingMode() || m_rootLayerAttachment == RootLayerUnattached)
1484 void RenderLayerCompositor::clearBackingForLayerIncludingDescendants(RenderLayer* layer)
1489 if (layer->isComposited()) {
1490 removeViewportConstrainedLayer(layer);
1491 layer->clearBacking();
1494 for (RenderLayer* currLayer = layer->firstChild(); currLayer; currLayer = currLayer->nextSibling())
1495 clearBackingForLayerIncludingDescendants(currLayer);
1498 void RenderLayerCompositor::clearBackingForAllLayers()
1500 clearBackingForLayerIncludingDescendants(m_renderView->layer());
1503 void RenderLayerCompositor::updateRootLayerPosition()
1505 if (m_rootContentLayer) {
1506 const IntRect& documentRect = m_renderView->documentRect();
1507 m_rootContentLayer->setSize(documentRect.size());
1508 m_rootContentLayer->setPosition(documentRect.location());
1511 FrameView* frameView = m_renderView->frameView();
1512 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1515 #if ENABLE(RUBBER_BANDING)
1516 if (m_contentShadowLayer) {
1517 m_contentShadowLayer->setPosition(m_rootContentLayer->position());
1519 FloatSize rootContentLayerSize = m_rootContentLayer->size();
1520 if (m_contentShadowLayer->size() != rootContentLayerSize) {
1521 m_contentShadowLayer->setSize(rootContentLayerSize);
1522 ScrollbarTheme::theme()->setUpContentShadowLayer(m_contentShadowLayer.get());
1528 bool RenderLayerCompositor::has3DContent() const
1530 return layerHas3DContent(rootRenderLayer());
1533 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)
1536 // frames are only independently composited in Mac pre-WebKit2.
1537 return view->platformWidget();
1544 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const
1546 // Parent document content needs to be able to render on top of a composited frame, so correct behavior
1547 // is to have the parent document become composited too. However, this can cause problems on platforms that
1548 // use native views for frames (like Mac), so disable that behavior on those platforms for now.
1549 HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement();
1550 RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0;
1552 // If we are the top-level frame, don't propagate.
1556 if (!allowsIndependentlyCompositedFrames(m_renderView->frameView()))
1559 if (!renderer || !renderer->isRenderPart())
1562 // On Mac, only propagate compositing if the frame is overlapped in the parent
1563 // document, or the parent is already compositing, or the main frame is scaled.
1564 Page* page = this->page();
1565 if (page && page->pageScaleFactor() != 1)
1568 RenderPart* frameRenderer = toRenderPart(renderer);
1569 if (frameRenderer->widget()) {
1570 ASSERT(frameRenderer->widget()->isFrameView());
1571 FrameView* view = static_cast<FrameView*>(frameRenderer->widget());
1572 if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor())
1579 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
1581 if (!canBeComposited(layer))
1584 return requiresCompositingLayer(layer, viewportConstrainedNotCompositedReason) || layer->mustCompositeForIndirectReasons() || (inCompositingMode() && layer->isRootLayer());
1587 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
1588 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
1590 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
1592 RenderObject* renderer = layer->renderer();
1593 // The compositing state of a reflection should match that of its reflected layer.
1594 if (layer->isReflection()) {
1595 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
1596 layer = toRenderLayerModelObject(renderer)->layer();
1598 // The root layer always has a compositing layer, but it may not have backing.
1599 return requiresCompositingForTransform(renderer)
1600 || requiresCompositingForVideo(renderer)
1601 || requiresCompositingForCanvas(renderer)
1602 || requiresCompositingForPlugin(renderer)
1603 || requiresCompositingForFrame(renderer)
1604 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1605 || clipsCompositingDescendants(layer)
1606 || requiresCompositingForAnimation(renderer)
1607 || requiresCompositingForFilters(renderer)
1608 || requiresCompositingForPosition(renderer, layer, viewportConstrainedNotCompositedReason)
1609 || requiresCompositingForOverflowScrolling(layer)
1610 || requiresCompositingForBlending(renderer);
1613 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
1615 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
1616 // See http://webkit.org/b/84900 to re-enable it.
1617 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->renderer()->inRenderFlowThread();
1620 bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer* layer, const RenderLayer* compositingAncestorLayer) const
1622 RenderObject* renderer = layer->renderer();
1623 if (compositingAncestorLayer
1624 && !(compositingAncestorLayer->backing()->graphicsLayer()->drawsContent()
1625 || compositingAncestorLayer->backing()->paintsIntoWindow()
1626 || compositingAncestorLayer->backing()->paintsIntoCompositedAncestor()))
1629 if (layer->isRootLayer()
1630 || layer->transform() // note: excludes perspective and transformStyle3D.
1631 || requiresCompositingForVideo(renderer)
1632 || requiresCompositingForCanvas(renderer)
1633 || requiresCompositingForPlugin(renderer)
1634 || requiresCompositingForFrame(renderer)
1635 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1636 || requiresCompositingForAnimation(renderer)
1637 || requiresCompositingForFilters(renderer)
1638 || requiresCompositingForBlending(renderer)
1639 || requiresCompositingForPosition(renderer, layer)
1640 || requiresCompositingForOverflowScrolling(layer)
1641 || renderer->isTransparent()
1642 || renderer->hasMask()
1643 || renderer->hasReflection()
1644 || renderer->hasFilter())
1648 if (layer->mustCompositeForIndirectReasons()) {
1649 RenderLayer::IndirectCompositingReason reason = layer->indirectCompositingReason();
1650 return reason == RenderLayer::IndirectCompositingForOverlap
1651 || reason == RenderLayer::IndirectCompositingForStacking
1652 || reason == RenderLayer::IndirectCompositingForBackgroundLayer
1653 || reason == RenderLayer::IndirectCompositingForGraphicalEffect
1654 || reason == RenderLayer::IndirectCompositingForPreserve3D; // preserve-3d has to create backing store to ensure that 3d-transformed elements intersect.
1660 const char* RenderLayerCompositor::reasonForCompositing(const RenderLayer* layer)
1662 RenderObject* renderer = layer->renderer();
1663 if (layer->isReflection()) {
1664 renderer = renderer->parent();
1665 layer = toRenderLayerModelObject(renderer)->layer();
1668 if (requiresCompositingForTransform(renderer))
1669 return "3D transform";
1671 if (requiresCompositingForVideo(renderer))
1674 if (requiresCompositingForCanvas(renderer))
1677 if (requiresCompositingForPlugin(renderer))
1680 if (requiresCompositingForFrame(renderer))
1683 if ((canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden))
1684 return "backface-visibility: hidden";
1686 if (clipsCompositingDescendants(layer))
1687 return "clips compositing descendants";
1689 if (requiresCompositingForAnimation(renderer))
1692 if (requiresCompositingForFilters(renderer))
1695 if (requiresCompositingForPosition(renderer, layer))
1696 return renderer->style()->position() == FixedPosition ? "position: fixed" : "position: sticky";
1698 if (requiresCompositingForOverflowScrolling(layer))
1699 return "-webkit-overflow-scrolling: touch";
1701 if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForStacking)
1704 if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForOverlap)
1707 if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForBackgroundLayer)
1708 return "negative z-index children";
1710 if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForGraphicalEffect) {
1711 if (layer->transform())
1712 return "transform with composited descendants";
1714 if (renderer->isTransparent())
1715 return "opacity with composited descendants";
1717 if (renderer->hasMask())
1718 return "mask with composited descendants";
1720 if (renderer->hasReflection())
1721 return "reflection with composited descendants";
1723 if (renderer->hasFilter())
1724 return "filter with composited descendants";
1726 if (renderer->hasBlendMode())
1727 return "blending with composited descendants";
1730 if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForPerspective)
1731 return "perspective";
1733 if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForPreserve3D)
1734 return "preserve-3d";
1736 if (inCompositingMode() && layer->isRootLayer())
1743 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1744 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1745 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1746 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1747 // but a sibling in the z-order hierarchy.
1748 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
1750 if (!layer->isComposited() || !layer->parent())
1753 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1754 if (!compositingAncestor)
1757 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
1758 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
1760 RenderLayer* computeClipRoot = 0;
1761 RenderLayer* curr = layer;
1763 RenderLayer* next = curr->parent();
1764 if (next == compositingAncestor) {
1765 computeClipRoot = curr;
1771 if (!computeClipRoot || computeClipRoot == layer)
1774 return layer->backgroundClipRect(RenderLayer::ClipRectsContext(computeClipRoot, 0, TemporaryClipRects)).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
1777 // Return true if the given layer is a stacking context and has compositing child
1778 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1779 // into the hierarchy between this layer and its children in the z-order hierarchy.
1780 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1782 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
1785 // Return true if there is an ancestor layer that is fixed positioned to the view.
1786 // Note that if the ancestor has a stacking context and is fixed position then this method
1787 // will return false.
1788 bool RenderLayerCompositor::fixedPositionedByAncestor(const RenderLayer* layer) const
1790 if (!layer->isComposited() || !layer->parent())
1793 const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1794 if (!compositingAncestor)
1797 const RenderLayer* curr = layer;
1799 const RenderLayer* next = curr->parent();
1800 if (next == compositingAncestor)
1803 if (next && next->renderer()->style()->position() == FixedPosition)
1810 bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
1812 // Need this done first to determine overflow.
1813 ASSERT(!m_renderView->needsLayout());
1814 HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement();
1818 if (!(m_compositingTriggers & ChromeClient::ScrollableInnerFrameTrigger))
1821 FrameView* frameView = m_renderView->frameView();
1822 return frameView->isScrollable();
1825 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
1827 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
1830 RenderStyle* style = renderer->style();
1831 // Note that we ask the renderer if it has a transform, because the style may have transforms,
1832 // but the renderer may be an inline that doesn't suppport them.
1833 return renderer->hasTransform() && style->transform().has3DOperation();
1836 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
1838 if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
1841 if (renderer->isVideo()) {
1842 RenderVideo* video = toRenderVideo(renderer);
1843 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
1845 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1846 else if (renderer->isRenderPart()) {
1847 if (!m_hasAcceleratedCompositing)
1850 Node* node = renderer->node();
1851 if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag)))
1854 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node);
1855 return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false;
1857 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1859 UNUSED_PARAM(renderer);
1864 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
1866 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
1869 if (renderer->isCanvas()) {
1870 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
1871 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
1876 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
1878 if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
1881 bool composite = renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
1885 m_reevaluateCompositingAfterLayout = true;
1887 RenderWidget* pluginRenderer = toRenderWidget(renderer);
1888 // If we can't reliably know the size of the plugin yet, don't change compositing state.
1889 if (pluginRenderer->needsLayout())
1890 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited();
1892 // Don't go into compositing mode if height or width are zero, or size is 1x1.
1893 IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect());
1894 return contentBox.height() * contentBox.width() > 1;
1897 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
1899 if (!renderer->isRenderPart())
1902 RenderPart* frameRenderer = toRenderPart(renderer);
1904 if (!frameRenderer->requiresAcceleratedCompositing())
1907 m_reevaluateCompositingAfterLayout = true;
1909 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
1910 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())
1913 // If we can't reliably know the size of the iframe yet, don't change compositing state.
1914 if (renderer->needsLayout())
1915 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited();
1917 // Don't go into compositing mode if height or width are zero.
1918 IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect());
1919 return contentBox.height() * contentBox.width() > 0;
1922 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
1924 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1927 if (AnimationController* animController = renderer->animation()) {
1928 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
1929 #if ENABLE(CSS_FILTERS)
1930 #if !PLATFORM(MAC) || (!PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080)
1931 // <rdar://problem/10907251> - WebKit2 doesn't support CA animations of CI filters on Lion and below
1932 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitFilter)
1933 #endif // !PLATFORM(MAC) || (!PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080)
1934 #endif // CSS_FILTERS
1935 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1940 bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const
1942 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1944 // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
1945 // via compositing so that they also apply to those composited descdendants.
1946 if (hasCompositedDescendants && (layer->transform() || renderer->createsGroup() || renderer->hasReflection())) {
1947 reason = RenderLayer::IndirectCompositingForGraphicalEffect;
1951 // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
1952 // will be affected by the preserve-3d or perspective.
1953 if (has3DTransformedDescendants) {
1954 if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D) {
1955 reason = RenderLayer::IndirectCompositingForPreserve3D;
1959 if (renderer->style()->hasPerspective()) {
1960 reason = RenderLayer::IndirectCompositingForPerspective;
1965 reason = RenderLayer::NoIndirectCompositingReason;
1969 bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const
1971 #if ENABLE(CSS_FILTERS)
1972 if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
1975 return renderer->hasFilter();
1977 UNUSED_PARAM(renderer);
1982 bool RenderLayerCompositor::requiresCompositingForBlending(RenderObject* renderer) const
1984 #if ENABLE(CSS_COMPOSITING)
1985 return renderer->hasBlendMode();
1987 UNUSED_PARAM(renderer);
1992 bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
1994 // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
1995 // opacity, transform) can get their own composited layer. A stacking context is required otherwise
1996 // z-index and clipping will be broken.
1997 if (!renderer->isPositioned())
2000 EPosition position = renderer->style()->position();
2001 bool isFixed = renderer->isOutOfFlowPositioned() && position == FixedPosition;
2002 if (isFixed && !layer->isStackingContext())
2005 bool isSticky = renderer->isInFlowPositioned() && position == StickyPosition;
2006 if (!isFixed && !isSticky)
2009 // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
2010 if (Settings* settings = m_renderView->document()->settings())
2011 if (!settings->acceleratedCompositingForFixedPositionEnabled())
2017 RenderObject* container = renderer->container();
2018 // If the renderer is not hooked up yet then we have to wait until it is.
2020 m_reevaluateCompositingAfterLayout = true;
2024 // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
2025 // They will stay fixed wrt the container rather than the enclosing frame.
2026 if (container != m_renderView) {
2027 if (viewportConstrainedNotCompositedReason)
2028 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer;
2032 // Fixed position elements that are invisible in the current view don't get their own layer.
2033 if (FrameView* frameView = m_renderView->frameView()) {
2034 IntRect viewBounds = frameView->visibleContentRect();
2035 LayoutRect layerBounds = layer->calculateLayerBounds(rootRenderLayer(), 0, RenderLayer::DefaultCalculateLayerBoundsFlags
2036 | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask | RenderLayer::IncludeCompositedDescendants);
2037 layerBounds.scale(frameView->frame()->frameScaleFactor());
2038 if (!viewBounds.intersects(enclosingIntRect(layerBounds))) {
2039 if (viewportConstrainedNotCompositedReason)
2040 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView;
2048 bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer* layer) const
2050 return layer->needsCompositedScrolling();
2053 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const
2055 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
2058 if (AnimationController* animController = renderer->animation())
2059 return animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
2064 // If an element has negative z-index children, those children render in front of the
2065 // layer background, so we need an extra 'contents' layer for the foreground of the layer
2067 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
2069 return layer->hasNegativeZOrderList();
2072 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
2074 // This applies when the application UI handles scrolling, in which case RenderLayerCompositor doesn't need to manage it.
2075 if (m_renderView->frameView()->delegatesScrolling())
2078 // We need to handle our own scrolling if we're:
2079 return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
2080 || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
2083 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
2089 const IntRect& scrollbarRect = scrollbar->frameRect();
2090 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
2091 IntRect transformedClip = clip;
2092 transformedClip.moveBy(scrollbarRect.location());
2093 scrollbar->paint(&context, transformedClip);
2097 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
2099 if (graphicsLayer == layerForHorizontalScrollbar())
2100 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
2101 else if (graphicsLayer == layerForVerticalScrollbar())
2102 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
2103 else if (graphicsLayer == layerForScrollCorner()) {
2104 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
2106 context.translate(-scrollCorner.x(), -scrollCorner.y());
2107 IntRect transformedClip = clip;
2108 transformedClip.moveBy(scrollCorner.location());
2109 m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
2111 #if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
2112 } else if (graphicsLayer == layerForOverhangAreas()) {
2113 ScrollView* view = m_renderView->frameView();
2114 view->calculateAndPaintOverhangAreas(&context, clip);
2119 static void resetTrackedRepaintRectsRecursive(GraphicsLayer* graphicsLayer)
2124 graphicsLayer->resetTrackedRepaints();
2126 for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
2127 resetTrackedRepaintRectsRecursive(graphicsLayer->children()[i]);
2129 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
2130 resetTrackedRepaintRectsRecursive(replicaLayer);
2132 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
2133 resetTrackedRepaintRectsRecursive(maskLayer);
2136 void RenderLayerCompositor::resetTrackedRepaintRects()
2138 if (GraphicsLayer* rootLayer = rootGraphicsLayer())
2139 resetTrackedRepaintRectsRecursive(rootLayer);
2142 void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints)
2144 m_isTrackingRepaints = tracksRepaints;
2147 bool RenderLayerCompositor::isTrackingRepaints() const
2149 return m_isTrackingRepaints;
2152 float RenderLayerCompositor::deviceScaleFactor() const
2154 Page* page = this->page();
2155 return page ? page->deviceScaleFactor() : 1;
2158 float RenderLayerCompositor::pageScaleFactor() const
2160 Page* page = this->page();
2161 return page ? page->pageScaleFactor() : 1;
2164 void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const
2166 // Nothing to do here yet.
2169 bool RenderLayerCompositor::keepLayersPixelAligned() const
2171 // When scaling, attempt to align compositing layers to pixel boundaries.
2175 static bool shouldCompositeOverflowControls(FrameView* view)
2177 if (view->platformWidget())
2180 if (Page* page = view->frame()->page()) {
2181 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
2182 if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
2186 #if !PLATFORM(CHROMIUM)
2187 if (!view->hasOverlayScrollbars())
2193 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
2195 FrameView* view = m_renderView->frameView();
2196 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
2199 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
2201 FrameView* view = m_renderView->frameView();
2202 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
2205 bool RenderLayerCompositor::requiresScrollCornerLayer() const
2207 FrameView* view = m_renderView->frameView();
2208 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
2211 #if ENABLE(RUBBER_BANDING)
2212 bool RenderLayerCompositor::requiresOverhangAreasLayer() const
2214 // We don't want a layer if this is a subframe.
2215 if (m_renderView->document()->ownerElement())
2218 // We do want a layer if we have a scrolling coordinator.
2219 if (scrollingCoordinator())
2222 // Chromium always wants a layer.
2223 #if PLATFORM(CHROMIUM)
2230 bool RenderLayerCompositor::requiresContentShadowLayer() const
2232 // We don't want a layer if this is a subframe.
2233 if (m_renderView->document()->ownerElement())
2237 // On Mac, we want a content shadow layer if we have a scrolling coordinator.
2238 if (scrollingCoordinator())
2246 void RenderLayerCompositor::updateOverflowControlsLayers()
2248 #if ENABLE(RUBBER_BANDING)
2249 if (requiresOverhangAreasLayer()) {
2250 if (!m_layerForOverhangAreas) {
2251 m_layerForOverhangAreas = GraphicsLayer::create(graphicsLayerFactory(), this);
2253 m_layerForOverhangAreas->setName("overhang areas");
2255 m_layerForOverhangAreas->setDrawsContent(false);
2256 m_layerForOverhangAreas->setSize(m_renderView->frameView()->frameRect().size());
2258 ScrollbarTheme::theme()->setUpOverhangAreasLayerContents(m_layerForOverhangAreas.get());
2260 // We want the overhang areas layer to be positioned below the frame contents,
2261 // so insert it below the clip layer.
2262 m_overflowControlsHostLayer->addChildBelow(m_layerForOverhangAreas.get(), m_clipLayer.get());
2264 } else if (m_layerForOverhangAreas) {
2265 m_layerForOverhangAreas->removeFromParent();
2266 m_layerForOverhangAreas = nullptr;
2269 if (requiresContentShadowLayer()) {
2270 if (!m_contentShadowLayer) {
2271 m_contentShadowLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
2273 m_contentShadowLayer->setName("content shadow");
2275 m_contentShadowLayer->setSize(m_rootContentLayer->size());
2276 m_contentShadowLayer->setPosition(m_rootContentLayer->position());
2277 ScrollbarTheme::theme()->setUpContentShadowLayer(m_contentShadowLayer.get());
2279 m_scrollLayer->addChildBelow(m_contentShadowLayer.get(), m_rootContentLayer.get());
2281 } else if (m_contentShadowLayer) {
2282 m_contentShadowLayer->removeFromParent();
2283 m_contentShadowLayer = nullptr;
2287 if (requiresHorizontalScrollbarLayer()) {
2288 if (!m_layerForHorizontalScrollbar) {
2289 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
2290 m_layerForHorizontalScrollbar->setShowDebugBorder(m_showDebugBorders);
2292 m_layerForHorizontalScrollbar->setName("horizontal scrollbar");
2294 #if PLATFORM(MAC) && USE(CA)
2295 m_layerForHorizontalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
2297 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
2299 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2300 scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForHorizontalScrollbar.get());
2302 } else if (m_layerForHorizontalScrollbar) {
2303 m_layerForHorizontalScrollbar->removeFromParent();
2304 m_layerForHorizontalScrollbar = nullptr;
2306 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2307 scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), 0);
2310 if (requiresVerticalScrollbarLayer()) {
2311 if (!m_layerForVerticalScrollbar) {
2312 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
2313 m_layerForVerticalScrollbar->setShowDebugBorder(m_showDebugBorders);
2315 m_layerForVerticalScrollbar->setName("vertical scrollbar");
2317 #if PLATFORM(MAC) && USE(CA)
2318 m_layerForVerticalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
2320 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
2322 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2323 scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForVerticalScrollbar.get());
2325 } else if (m_layerForVerticalScrollbar) {
2326 m_layerForVerticalScrollbar->removeFromParent();
2327 m_layerForVerticalScrollbar = nullptr;
2329 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2330 scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), 0);
2333 if (requiresScrollCornerLayer()) {
2334 if (!m_layerForScrollCorner) {
2335 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
2336 m_layerForScrollCorner->setShowDebugBorder(m_showDebugBorders);
2338 m_layerForScrollCorner->setName("scroll corner");
2340 #if PLATFORM(MAC) && USE(CA)
2341 m_layerForScrollCorner->setAcceleratesDrawing(acceleratedDrawingEnabled());
2343 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
2345 } else if (m_layerForScrollCorner) {
2346 m_layerForScrollCorner->removeFromParent();
2347 m_layerForScrollCorner = nullptr;
2350 m_renderView->frameView()->positionScrollbarLayers();
2353 void RenderLayerCompositor::ensureRootLayer()
2355 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
2356 if (expectedAttachment == m_rootLayerAttachment)
2359 if (!m_rootContentLayer) {
2360 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
2362 m_rootContentLayer->setName("content root");
2364 IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect();
2365 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
2366 m_rootContentLayer->setPosition(FloatPoint());
2368 // Need to clip to prevent transformed content showing outside this frame
2369 m_rootContentLayer->setMasksToBounds(true);
2372 if (requiresScrollLayer(expectedAttachment)) {
2373 if (!m_overflowControlsHostLayer) {
2374 ASSERT(!m_scrollLayer);
2375 ASSERT(!m_clipLayer);
2377 // Create a layer to host the clipping layer and the overflow controls layers.
2378 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
2380 m_overflowControlsHostLayer->setName("overflow controls host");
2383 // Create a clipping layer if this is an iframe
2384 m_clipLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
2386 m_clipLayer->setName("frame clipping");
2388 m_clipLayer->setMasksToBounds(true);
2390 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
2392 m_scrollLayer->setName("frame scrolling");
2394 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2395 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
2398 m_overflowControlsHostLayer->addChild(m_clipLayer.get());
2399 m_clipLayer->addChild(m_scrollLayer.get());
2400 m_scrollLayer->addChild(m_rootContentLayer.get());
2402 frameViewDidChangeSize();
2403 frameViewDidScroll();
2406 if (m_overflowControlsHostLayer) {
2407 m_overflowControlsHostLayer = nullptr;
2408 m_clipLayer = nullptr;
2409 m_scrollLayer = nullptr;
2413 // Check to see if we have to change the attachment
2414 if (m_rootLayerAttachment != RootLayerUnattached)
2417 attachRootLayer(expectedAttachment);
2420 void RenderLayerCompositor::destroyRootLayer()
2422 if (!m_rootContentLayer)
2427 #if ENABLE(RUBBER_BANDING)
2428 if (m_layerForOverhangAreas) {
2429 m_layerForOverhangAreas->removeFromParent();
2430 m_layerForOverhangAreas = nullptr;
2434 if (m_layerForHorizontalScrollbar) {
2435 m_layerForHorizontalScrollbar->removeFromParent();
2436 m_layerForHorizontalScrollbar = nullptr;
2437 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
2438 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
2441 if (m_layerForVerticalScrollbar) {
2442 m_layerForVerticalScrollbar->removeFromParent();
2443 m_layerForVerticalScrollbar = nullptr;
2444 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
2445 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
2448 if (m_layerForScrollCorner) {
2449 m_layerForScrollCorner = nullptr;
2450 m_renderView->frameView()->invalidateScrollCorner(m_renderView->frameView()->scrollCornerRect());
2453 if (m_overflowControlsHostLayer) {
2454 m_overflowControlsHostLayer = nullptr;
2455 m_clipLayer = nullptr;
2456 m_scrollLayer = nullptr;
2458 ASSERT(!m_scrollLayer);
2459 m_rootContentLayer = nullptr;
2461 m_layerUpdater = nullptr;
2464 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
2466 if (!m_rootContentLayer)
2469 switch (attachment) {
2470 case RootLayerUnattached:
2471 ASSERT_NOT_REACHED();
2473 case RootLayerAttachedViaChromeClient: {
2474 Frame* frame = m_renderView->frameView()->frame();
2475 Page* page = frame ? frame->page() : 0;
2479 page->chrome()->client()->attachRootGraphicsLayer(frame, rootGraphicsLayer());
2482 case RootLayerAttachedViaEnclosingFrame: {
2483 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
2484 // for the frame's renderer in the parent document.
2485 m_renderView->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2490 m_rootLayerAttachment = attachment;
2491 rootLayerAttachmentChanged();
2493 if (m_shouldFlushOnReattach) {
2494 flushPendingLayerChanges(true);
2495 m_shouldFlushOnReattach = false;
2499 void RenderLayerCompositor::detachRootLayer()
2501 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
2504 switch (m_rootLayerAttachment) {
2505 case RootLayerAttachedViaEnclosingFrame: {
2506 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
2507 // for the frame's renderer in the parent document.
2508 if (m_overflowControlsHostLayer)
2509 m_overflowControlsHostLayer->removeFromParent();
2511 m_rootContentLayer->removeFromParent();
2513 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
2514 ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2517 case RootLayerAttachedViaChromeClient: {
2518 Frame* frame = m_renderView->frameView()->frame();
2519 Page* page = frame ? frame->page() : 0;
2523 page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
2526 case RootLayerUnattached:
2530 m_rootLayerAttachment = RootLayerUnattached;
2531 rootLayerAttachmentChanged();
2534 void RenderLayerCompositor::updateRootLayerAttachment()
2539 void RenderLayerCompositor::rootLayerAttachmentChanged()
2541 // The attachment can affect whether the RenderView layer's paintsIntoWindow() behavior,
2542 // so call updateGraphicsLayerGeometry() to udpate that.
2543 RenderLayer* layer = m_renderView->layer();
2544 if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
2545 backing->updateDrawsContent();
2548 // IFrames are special, because we hook compositing layers together across iframe boundaries
2549 // when both parent and iframe content are composited. So when this frame becomes composited, we have
2550 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
2551 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
2553 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0;
2557 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) {
2558 if (child->document() && child->document()->ownerElement())
2559 child->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2562 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
2563 // we need to schedule a style recalc in our parent document.
2564 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
2565 ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2568 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
2570 const RenderStyle* style = layer->renderer()->style();
2573 (style->transformStyle3D() == TransformStyle3DPreserve3D ||
2574 style->hasPerspective() ||
2575 style->transform().has3DOperation()))
2578 const_cast<RenderLayer*>(layer)->updateLayerListsIfNeeded();
2580 #if !ASSERT_DISABLED
2581 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(layer));
2584 if (layer->isStackingContext()) {
2585 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
2586 size_t listSize = negZOrderList->size();
2587 for (size_t i = 0; i < listSize; ++i) {
2588 RenderLayer* curLayer = negZOrderList->at(i);
2589 if (layerHas3DContent(curLayer))
2594 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
2595 size_t listSize = posZOrderList->size();
2596 for (size_t i = 0; i < listSize; ++i) {
2597 RenderLayer* curLayer = posZOrderList->at(i);
2598 if (layerHas3DContent(curLayer))
2604 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
2605 size_t listSize = normalFlowList->size();
2606 for (size_t i = 0; i < listSize; ++i) {
2607 RenderLayer* curLayer = normalFlowList->at(i);
2608 if (layerHas3DContent(curLayer))
2615 void RenderLayerCompositor::deviceOrPageScaleFactorChanged()
2617 // Start at the RenderView's layer, since that's where the scale is applied.
2618 RenderLayer* viewLayer = m_renderView->layer();
2619 if (!viewLayer->isComposited())
2622 if (GraphicsLayer* rootLayer = viewLayer->backing()->graphicsLayer())
2623 rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
2626 static bool isRootmostFixedOrStickyLayer(RenderLayer* layer)
2628 if (layer->renderer()->isStickyPositioned())
2631 if (layer->renderer()->style()->position() != FixedPosition)
2634 for (RenderLayer* stackingContext = layer->stackingContext(); stackingContext; stackingContext = stackingContext->stackingContext()) {
2635 if (stackingContext->isComposited() && stackingContext->renderer()->style()->position() == FixedPosition)
2642 void RenderLayerCompositor::updateViewportConstraintStatus(RenderLayer* layer)
2644 if (isRootmostFixedOrStickyLayer(layer))
2645 addViewportConstrainedLayer(layer);
2647 removeViewportConstrainedLayer(layer);
2650 void RenderLayerCompositor::addViewportConstrainedLayer(RenderLayer* layer)
2652 m_viewportConstrainedLayers.add(layer);
2653 registerOrUpdateViewportConstrainedLayer(layer);
2656 void RenderLayerCompositor::removeViewportConstrainedLayer(RenderLayer* layer)
2658 if (!m_viewportConstrainedLayers.contains(layer))
2661 unregisterViewportConstrainedLayer(layer);
2662 m_viewportConstrainedLayers.remove(layer);
2665 FixedPositionViewportConstraints RenderLayerCompositor::computeFixedViewportConstraints(RenderLayer* layer) const
2667 ASSERT(layer->isComposited());
2669 FrameView* frameView = m_renderView->frameView();
2671 LayoutRect viewportRect = frameView->visibleContentRect();
2672 viewportRect.setLocation(toPoint(frameView->scrollOffsetForFixedPosition()));
2674 FixedPositionViewportConstraints constraints = FixedPositionViewportConstraints();
2676 GraphicsLayer* graphicsLayer = layer->backing()->graphicsLayer();
2678 constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
2679 constraints.setViewportRectAtLastLayout(viewportRect);
2681 RenderStyle* style = layer->renderer()->style();
2682 if (!style->left().isAuto())
2683 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
2685 if (!style->right().isAuto())
2686 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight);
2688 if (!style->top().isAuto())
2689 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
2691 if (!style->bottom().isAuto())
2692 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom);
2694 // If left and right are auto, use left.
2695 if (style->left().isAuto() && style->right().isAuto())
2696 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
2698 // If top and bottom are auto, use top.
2699 if (style->top().isAuto() && style->bottom().isAuto())
2700 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
2705 StickyPositionViewportConstraints RenderLayerCompositor::computeStickyViewportConstraints(RenderLayer* layer) const
2707 ASSERT(layer->isComposited());
2709 FrameView* frameView = m_renderView->frameView();
2710 LayoutRect viewportRect = frameView->visibleContentRect();
2712 StickyPositionViewportConstraints constraints = StickyPositionViewportConstraints();
2714 RenderBoxModelObject* renderer = toRenderBoxModelObject(layer->renderer());
2716 renderer->computeStickyPositionConstraints(constraints, viewportRect);
2718 GraphicsLayer* graphicsLayer = layer->backing()->graphicsLayer();
2720 constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
2721 constraints.setStickyOffsetAtLastLayout(renderer->stickyPositionOffset());
2726 static RenderLayerBacking* nearestScrollingCoordinatorAncestor(RenderLayer* layer)
2728 RenderLayer* ancestor = layer->parent();
2730 if (RenderLayerBacking* backing = ancestor->backing()) {
2731 if (backing->scrollLayerID() && !ancestor->scrollsOverflow())
2734 ancestor = ancestor->parent();
2740 void RenderLayerCompositor::registerOrUpdateViewportConstrainedLayer(RenderLayer* layer)
2742 // FIXME: We should support sticky position here! And we should eventuall support fixed/sticky elements
2743 // that are inside non-main frames once we get non-main frames scrolling with the ScrollingCoordinator.
2744 if (m_renderView->document()->ownerElement())
2747 ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator();
2748 if (!scrollingCoordinator)
2751 // FIXME: rename to supportsViewportConstrainedPositionLayers()?
2752 if (!scrollingCoordinator->supportsFixedPositionLayers() || !layer->parent())
2755 ASSERT(m_viewportConstrainedLayers.contains(layer));
2756 ASSERT(layer->isComposited());
2758 RenderLayerBacking* backing = layer->backing();
2762 ScrollingNodeID nodeID = backing->scrollLayerID();
2763 RenderLayerBacking* parent = nearestScrollingCoordinatorAncestor(layer);
2767 // Always call this even if the backing is already attached because the parent may have changed.
2768 backing->attachToScrollingCoordinatorWithParent(parent);
2769 nodeID = backing->scrollLayerID();
2771 if (layer->renderer()->isStickyPositioned())
2772 scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeStickyViewportConstraints(layer), backing->graphicsLayer());
2774 scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeFixedViewportConstraints(layer), backing->graphicsLayer());
2777 void RenderLayerCompositor::unregisterViewportConstrainedLayer(RenderLayer* layer)
2779 ASSERT(m_viewportConstrainedLayers.contains(layer));
2781 if (RenderLayerBacking* backing = layer->backing())
2782 backing->detachFromScrollingCoordinator();
2785 void RenderLayerCompositor::windowScreenDidChange(PlatformDisplayID displayID)
2788 m_layerUpdater->screenDidChange(displayID);
2791 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
2793 if (Page* page = this->page())
2794 return page->scrollingCoordinator();
2799 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
2801 if (Page* page = this->page())
2802 return page->chrome()->client()->graphicsLayerFactory();
2807 Page* RenderLayerCompositor::page() const
2809 if (Frame* frame = m_renderView->frameView()->frame())
2810 return frame->page();
2815 void RenderLayerCompositor::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
2817 MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Rendering);
2818 info.addWeakPointer(m_renderView);
2819 info.addMember(m_rootContentLayer);
2820 info.addMember(m_updateCompositingLayersTimer);
2821 info.addMember(m_clipLayer);
2822 info.addMember(m_scrollLayer);
2823 info.addMember(m_viewportConstrainedLayers);
2824 info.addMember(m_viewportConstrainedLayersNeedingUpdate);
2825 info.addMember(m_overflowControlsHostLayer);
2826 info.addMember(m_layerForHorizontalScrollbar);
2827 info.addMember(m_layerForVerticalScrollbar);
2828 info.addMember(m_layerForScrollCorner);
2829 #if ENABLE(RUBBER_BANDING)
2830 info.addMember(m_layerForOverhangAreas);
2831 info.addMember(m_contentShadowLayer);
2833 info.addMember(m_layerUpdater);
2836 } // namespace WebCore
2838 #endif // USE(ACCELERATED_COMPOSITING)