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"
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 "ScrollingCoordinator.h"
59 #include "TiledBacking.h"
60 #include "TransformState.h"
62 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
63 #include "HTMLMediaElement.h"
67 #include <wtf/CurrentTime.h>
71 #include "RenderTreeAsText.h"
74 #if ENABLE(3D_RENDERING)
75 // This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm').
76 bool WebCoreHas3DRendering = true;
81 using namespace HTMLNames;
83 class RenderLayerCompositor::OverlapMap {
84 WTF_MAKE_NONCOPYABLE(OverlapMap);
88 // Begin assuming the root layer will be composited so that there is
89 // something on the stack. The root layer should also never get an
90 // popCompositingContainer call.
91 pushCompositingContainer();
94 void add(const RenderLayer* layer, const IntRect& bounds)
96 // Layers do not contribute to overlap immediately--instead, they will
97 // contribute to overlap as soon as their composited ancestor has been
98 // recursively processed and popped off the stack.
99 ASSERT(m_overlapStack.size() >= 2);
100 m_overlapStack[m_overlapStack.size() - 2].unite(bounds);
104 bool contains(const RenderLayer* layer)
106 return m_layers.contains(layer);
109 bool overlapsLayers(const IntRect& bounds) const
111 return m_overlapStack.last().intersects(bounds);
116 return m_layers.isEmpty();
119 void pushCompositingContainer()
121 m_overlapStack.append(Region());
124 void popCompositingContainer()
126 m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
127 m_overlapStack.removeLast();
131 Vector<Region> m_overlapStack;
132 HashSet<const RenderLayer*> m_layers;
135 struct CompositingState {
136 CompositingState(RenderLayer* compAncestor, bool testOverlap)
137 : m_compositingAncestor(compAncestor)
138 , m_subtreeIsCompositing(false)
139 , m_testingOverlap(testOverlap)
146 CompositingState(const CompositingState& other)
147 : m_compositingAncestor(other.m_compositingAncestor)
148 , m_subtreeIsCompositing(other.m_subtreeIsCompositing)
149 , m_testingOverlap(other.m_testingOverlap)
151 , m_depth(other.m_depth + 1)
156 RenderLayer* m_compositingAncestor;
157 bool m_subtreeIsCompositing;
158 bool m_testingOverlap;
165 static inline bool compositingLogEnabled()
168 return LogCompositing.state == WTFLogChannelOn;
174 #define PIXELS_PER_MEGAPIXEL 1000000.0
176 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
177 : m_renderView(renderView)
178 , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
179 , m_hasAcceleratedCompositing(true)
180 , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
181 , m_compositedLayerCount(0)
182 , m_showDebugBorders(false)
183 , m_showRepaintCounter(false)
184 , m_acceleratedDrawingEnabled(false)
185 , m_compositingConsultsOverlap(true)
186 , m_reevaluateCompositingAfterLayout(false)
187 , m_compositing(false)
188 , m_compositingLayersNeedRebuild(false)
189 , m_flushingLayers(false)
190 , m_forceCompositingMode(false)
191 , m_rootLayerAttachment(RootLayerUnattached)
193 , m_rootLayerUpdateCount(0)
194 , m_obligateCompositedLayerCount(0)
195 , m_secondaryCompositedLayerCount(0)
196 , m_obligatoryBackingAreaMegaPixels(0)
197 , m_secondaryBackingAreaMegaPixels(0)
199 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_LIMIT_COMPOSITING)
200 , m_compositingAllowed(true)
205 RenderLayerCompositor::~RenderLayerCompositor()
207 ASSERT(m_rootLayerAttachment == RootLayerUnattached);
210 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
212 if (enable != m_compositing) {
213 m_compositing = enable;
217 notifyIFramesOfCompositingChange();
223 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
225 bool hasAcceleratedCompositing = false;
226 bool showDebugBorders = false;
227 bool showRepaintCounter = false;
228 bool forceCompositingMode = false;
229 bool acceleratedDrawingEnabled = false;
231 if (Settings* settings = m_renderView->document()->settings()) {
232 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
234 // We allow the chrome to override the settings, in case the page is rendered
235 // on a chrome that doesn't allow accelerated compositing.
236 if (hasAcceleratedCompositing) {
237 Frame* frame = m_renderView->frameView()->frame();
238 Page* page = frame ? frame->page() : 0;
240 ChromeClient* chromeClient = page->chrome()->client();
241 m_compositingTriggers = chromeClient->allowedCompositingTriggers();
242 hasAcceleratedCompositing = m_compositingTriggers;
246 showDebugBorders = settings->showDebugBorders();
247 showRepaintCounter = settings->showRepaintCounter();
248 forceCompositingMode = settings->forceCompositingMode() && hasAcceleratedCompositing;
250 if (forceCompositingMode && m_renderView->document()->ownerElement())
251 forceCompositingMode = settings->acceleratedCompositingForScrollableFramesEnabled() && requiresCompositingForScrollableFrame();
253 acceleratedDrawingEnabled = settings->acceleratedDrawingEnabled();
256 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode)
257 setCompositingLayersNeedRebuild();
259 m_hasAcceleratedCompositing = hasAcceleratedCompositing;
260 m_showDebugBorders = showDebugBorders;
261 m_showRepaintCounter = showRepaintCounter;
262 m_forceCompositingMode = forceCompositingMode;
263 m_acceleratedDrawingEnabled = acceleratedDrawingEnabled;
266 bool RenderLayerCompositor::canRender3DTransforms() const
268 return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
271 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
273 if (inCompositingMode())
274 m_compositingLayersNeedRebuild = needRebuild;
277 void RenderLayerCompositor::scheduleLayerFlush()
279 Frame* frame = m_renderView->frameView()->frame();
280 Page* page = frame ? frame->page() : 0;
284 page->chrome()->client()->scheduleCompositingLayerSync();
287 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
288 ChromeClient* RenderLayerCompositor::chromeClient() const
290 Frame* frame = m_renderView->frameView()->frame();
291 Page* page = frame ? frame->page() : 0;
295 return page->chrome()->client();
299 void RenderLayerCompositor::flushPendingLayerChanges(bool isFlushRoot)
301 // FrameView::syncCompositingStateIncludingSubframes() flushes each subframe,
302 // but GraphicsLayer::syncCompositingState() will cross frame boundaries
303 // if the GraphicsLayers are connected (the RootLayerAttachedViaEnclosingFrame case).
304 // As long as we're not the root of the flush, we can bail.
305 if (!isFlushRoot && rootLayerAttachment() == RootLayerAttachedViaEnclosingFrame)
308 ASSERT(!m_flushingLayers);
309 m_flushingLayers = true;
311 if (GraphicsLayer* rootLayer = rootGraphicsLayer()) {
312 FrameView* frameView = m_renderView ? m_renderView->frameView() : 0;
314 // FIXME: Passing frameRect() is correct only when RenderLayerCompositor uses a ScrollLayer (as in WebKit2)
315 // otherwise, the passed clip rect needs to take scrolling into account
316 rootLayer->syncCompositingState(frameView->frameRect());
320 ASSERT(m_flushingLayers);
321 m_flushingLayers = false;
324 void RenderLayerCompositor::didFlushChangesForLayer(RenderLayer*)
328 RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const
330 if (!m_renderView->frameView())
333 for (Frame* frame = m_renderView->frameView()->frame(); frame; frame = frame->tree()->parent()) {
334 RenderLayerCompositor* compositor = frame->contentRenderer() ? frame->contentRenderer()->compositor() : 0;
335 if (compositor->isFlushingLayers())
342 void RenderLayerCompositor::scheduleCompositingLayerUpdate()
344 if (!m_updateCompositingLayersTimer.isActive())
345 m_updateCompositingLayersTimer.startOneShot(0);
348 void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*)
350 updateCompositingLayers(CompositingUpdateAfterLayout);
353 bool RenderLayerCompositor::hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const
355 return m_compositedLayerCount > (rootLayer->isComposited() ? 1 : 0);
358 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_LIMIT_COMPOSITING)
359 void RenderLayerCompositor::countLayersWhichWillBeComposited(RenderLayer* layer, int& count)
364 if (needsToBeComposited(layer))
367 for (RenderLayer* currLayer = layer->firstChild(); currLayer; currLayer = currLayer->nextSibling())
368 countLayersWhichWillBeComposited(currLayer, count);
371 void RenderLayerCompositor::disallowCompositingIfNeeded()
373 m_compositingAllowed = true;
375 int willBeCompositedLayersCount = 0;
376 countLayersWhichWillBeComposited(rootRenderLayer(), willBeCompositedLayersCount);
377 if (willBeCompositedLayersCount > 100)
378 m_compositingAllowed = false;
382 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
384 m_updateCompositingLayersTimer.stop();
386 // Compositing layers will be updated in Document::implicitClose() if suppressed here.
387 if (!m_renderView->document()->visualUpdatesAllowed())
390 if (m_forceCompositingMode && !m_compositing)
391 enableCompositingMode(true);
393 if (!m_reevaluateCompositingAfterLayout && !m_compositing)
396 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_LIMIT_COMPOSITING)
397 disallowCompositingIfNeeded();
400 AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame()->animation());
402 bool checkForHierarchyUpdate = m_reevaluateCompositingAfterLayout;
403 bool needGeometryUpdate = false;
405 switch (updateType) {
406 case CompositingUpdateAfterStyleChange:
407 case CompositingUpdateAfterLayout:
408 case CompositingUpdateOnHitTest:
409 checkForHierarchyUpdate = true;
411 case CompositingUpdateOnScroll:
412 if (m_compositingConsultsOverlap)
413 checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
415 needGeometryUpdate = true;
419 if (!checkForHierarchyUpdate && !needGeometryUpdate)
422 bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
423 bool isFullUpdate = !updateRoot;
424 if (!updateRoot || m_compositingConsultsOverlap) {
425 // Only clear the flag if we're updating the entire hierarchy.
426 m_compositingLayersNeedRebuild = false;
427 updateRoot = rootRenderLayer();
430 if (isFullUpdate && updateType == CompositingUpdateAfterLayout)
431 m_reevaluateCompositingAfterLayout = false;
434 double startTime = 0;
435 if (compositingLogEnabled()) {
436 ++m_rootLayerUpdateCount;
437 startTime = currentTime();
441 if (checkForHierarchyUpdate) {
442 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
443 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
444 CompositingState compState(updateRoot, m_compositingConsultsOverlap);
445 bool layersChanged = false;
446 if (m_compositingConsultsOverlap) {
447 OverlapMap overlapTestRequestMap;
448 RenderGeometryMap geometryMap;
449 computeCompositingRequirements(0, updateRoot, &geometryMap, &overlapTestRequestMap, compState, layersChanged);
451 computeCompositingRequirements(0, updateRoot, 0, 0, compState, layersChanged);
453 needHierarchyUpdate |= layersChanged;
457 if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
458 m_obligateCompositedLayerCount = 0;
459 m_secondaryCompositedLayerCount = 0;
460 m_obligatoryBackingAreaMegaPixels = 0;
461 m_secondaryBackingAreaMegaPixels = 0;
463 Frame* frame = m_renderView->frameView()->frame();
464 bool isMainFrame = !m_renderView->document()->ownerElement();
465 LOG(Compositing, "\nUpdate %d of %s. Overlap testing is %s\n", m_rootLayerUpdateCount, isMainFrame ? "main frame" : frame->tree()->uniqueName().string().utf8().data(),
466 m_compositingConsultsOverlap ? "on" : "off");
470 if (needHierarchyUpdate) {
471 // Update the hierarchy of the compositing layers.
472 Vector<GraphicsLayer*> childList;
473 rebuildCompositingLayerTree(updateRoot, childList, 0);
475 // Host the document layer in the RenderView's root layer.
477 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_LIMIT_COMPOSITING)
480 // Even when childList is empty, don't drop out of compositing mode if there are
481 // composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
482 if (childList.isEmpty() && !hasAnyAdditionalCompositedLayers(updateRoot))
485 m_rootContentLayer->setChildren(childList);
487 } else if (needGeometryUpdate) {
488 // We just need to do a geometry update. This is only used for position:fixed scrolling;
489 // most of the time, geometry is updated via RenderLayer::styleChanged().
490 updateLayerTreeGeometry(updateRoot, 0);
494 if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
495 double endTime = currentTime();
496 LOG(Compositing, "Total layers primary secondary obligatory backing (MP) secondary backing(MP) total backing (MP) update time (ms)\n");
498 LOG(Compositing, "%8d %11d %9d %20.2f %22.2f %22.2f %18.2f\n",
499 m_obligateCompositedLayerCount + m_secondaryCompositedLayerCount, m_obligateCompositedLayerCount,
500 m_secondaryCompositedLayerCount, m_obligatoryBackingAreaMegaPixels, m_secondaryBackingAreaMegaPixels, m_obligatoryBackingAreaMegaPixels + m_secondaryBackingAreaMegaPixels, 1000.0 * (endTime - startTime));
503 ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
505 if (!hasAcceleratedCompositing())
506 enableCompositingMode(false);
510 void RenderLayerCompositor::logLayerInfo(const RenderLayer* layer, int depth)
512 if (!compositingLogEnabled())
515 RenderLayerBacking* backing = layer->backing();
516 if (requiresCompositingLayer(layer) || layer->isRootLayer()) {
517 ++m_obligateCompositedLayerCount;
518 m_obligatoryBackingAreaMegaPixels += backing->backingStoreArea() / PIXELS_PER_MEGAPIXEL;
520 ++m_secondaryCompositedLayerCount;
521 m_secondaryBackingAreaMegaPixels += backing->backingStoreArea() / PIXELS_PER_MEGAPIXEL;
524 LOG(Compositing, "%*p %dx%d %.3fMP (%s) %s\n", 12 + depth * 2, layer, backing->compositedBounds().width(), backing->compositedBounds().height(),
525 backing->backingStoreArea() / PIXELS_PER_MEGAPIXEL,
526 reasonForCompositing(layer), layer->backing()->nameForLayer().utf8().data());
530 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
532 bool layerChanged = false;
533 if (needsToBeComposited(layer)) {
534 enableCompositingMode();
536 if (!layer->backing()) {
537 // If we need to repaint, do so before making backing
538 if (shouldRepaint == CompositingChangeRepaintNow)
539 repaintOnCompositingChange(layer);
541 layer->ensureBacking();
543 // The RenderLayer's needs to update repaint rects here, because the target
544 // repaintContainer may have changed after becoming a composited layer.
545 // https://bugs.webkit.org/show_bug.cgi?id=80641
547 layer->computeRepaintRects();
552 if (layer->backing()) {
553 // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
554 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
555 // are both either composited, or not composited.
556 if (layer->isReflection()) {
557 RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer();
558 if (RenderLayerBacking* backing = sourceLayer->backing()) {
559 ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer());
560 backing->graphicsLayer()->setReplicatedByLayer(0);
564 layer->clearBacking();
567 // The layer's cached repaints rects are relative to the repaint container, so change when
568 // compositing changes; we need to update them here.
569 layer->computeRepaintRects();
571 // If we need to repaint, do so now that we've removed the backing
572 if (shouldRepaint == CompositingChangeRepaintNow)
573 repaintOnCompositingChange(layer);
578 if (layerChanged && layer->renderer()->isVideo()) {
579 // If it's a video, give the media player a chance to hook up to the layer.
580 RenderVideo* video = toRenderVideo(layer->renderer());
581 video->acceleratedRenderingStateChanged();
585 if (layerChanged && layer->renderer()->isRenderPart()) {
586 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
587 if (innerCompositor && innerCompositor->inCompositingMode())
588 innerCompositor->updateRootLayerAttachment();
592 layer->clearClipRectsIncludingDescendants(PaintingClipRects);
597 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
599 bool layerChanged = updateBacking(layer, shouldRepaint);
601 // See if we need content or clipping layers. Methods called here should assume
602 // that the compositing state of descendant layers has not been updated yet.
603 if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration())
609 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
611 // If the renderer is not attached yet, no need to repaint.
612 if (layer->renderer() != m_renderView && !layer->renderer()->parent())
615 RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint();
616 if (!repaintContainer)
617 repaintContainer = m_renderView;
619 layer->repaintIncludingNonCompositingDescendants(repaintContainer);
620 if (repaintContainer == m_renderView) {
621 // The contents of this layer may be moving between the window
622 // and a GraphicsLayer, so we need to make sure the window system
623 // synchronizes those changes on the screen.
624 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
628 // This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
629 void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect)
631 RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(false /*exclude self*/);
632 if (compositedAncestor) {
633 ASSERT(compositedAncestor->backing());
636 layer->convertToLayerCoords(compositedAncestor, offset);
638 LayoutRect repaintRect = rect;
639 repaintRect.moveBy(offset);
641 compositedAncestor->setBackingNeedsRepaintInRect(repaintRect);
644 // The contents of this layer may be moving from a GraphicsLayer to the window,
645 // so we need to make sure the window system synchronizes those changes on the screen.
646 if (compositedAncestor == m_renderView->layer())
647 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
650 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
651 // RenderLayers that are rendered by the composited RenderLayer.
652 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
654 if (!canBeComposited(layer))
656 return RenderLayer::calculateLayerBounds(layer, ancestorLayer);
659 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
661 setCompositingLayersNeedRebuild();
664 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
666 if (!child->isComposited() || parent->renderer()->documentBeingDestroyed())
669 repaintInCompositedAncestor(child, child->backing()->compositedBounds());
671 setCompositingParent(child, 0);
672 setCompositingLayersNeedRebuild();
675 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
677 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
678 if (curr->isStackingContext())
681 if (curr->renderer()->hasOverflowClip() || curr->renderer()->hasClip())
687 void RenderLayerCompositor::addToOverlapMap(RenderGeometryMap& geometryMap, OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
689 if (layer->isRootLayer())
692 if (!boundsComputed) {
693 layerBounds = enclosingIntRect(geometryMap.absoluteRect(layer->localBoundingBox()));
694 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
695 if (layerBounds.isEmpty())
696 layerBounds.setSize(IntSize(1, 1));
697 boundsComputed = true;
700 IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(rootRenderLayer(), 0, AbsoluteClipRects).rect()); // FIXME: Incorrect for CSS regions.
701 clipRect.scale(pageScaleFactor());
702 clipRect.intersect(layerBounds);
703 overlapMap.add(layer, clipRect);
706 void RenderLayerCompositor::addToOverlapMapRecursive(RenderGeometryMap& geometryMap, OverlapMap& overlapMap, RenderLayer* layer, RenderLayer* ancestorLayer)
708 if (!canBeComposited(layer) || overlapMap.contains(layer))
711 // A null ancestorLayer is an indication that 'layer' has already been pushed.
713 geometryMap.pushMappingsToAncestor(layer->renderer(), ancestorLayer->renderer());
716 bool haveComputedBounds = false;
717 addToOverlapMap(geometryMap, overlapMap, layer, bounds, haveComputedBounds);
720 LayerListMutationDetector mutationChecker(layer);
723 if (layer->isStackingContext()) {
724 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
725 size_t listSize = negZOrderList->size();
726 for (size_t i = 0; i < listSize; ++i) {
727 RenderLayer* curLayer = negZOrderList->at(i);
728 addToOverlapMapRecursive(geometryMap, overlapMap, curLayer, layer);
733 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
734 size_t listSize = normalFlowList->size();
735 for (size_t i = 0; i < listSize; ++i) {
736 RenderLayer* curLayer = normalFlowList->at(i);
737 addToOverlapMapRecursive(geometryMap, overlapMap, curLayer, layer);
741 if (layer->isStackingContext()) {
742 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
743 size_t listSize = posZOrderList->size();
744 for (size_t i = 0; i < listSize; ++i) {
745 RenderLayer* curLayer = posZOrderList->at(i);
746 addToOverlapMapRecursive(geometryMap, overlapMap, curLayer, layer);
752 geometryMap.popMappingsToAncestor(ancestorLayer->renderer());
755 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
756 // For the z-order children of a compositing layer:
757 // If a child layers has a compositing layer, then all subsequent layers must
758 // be compositing in order to render above that layer.
760 // If a child in the negative z-order list is compositing, then the layer itself
761 // must be compositing so that its contents render over that child.
762 // This implies that its positive z-index children must also be compositing.
764 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, RenderGeometryMap* geometryMap, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged)
766 layer->updateLayerListsIfNeeded();
768 // Should geometryMap be part of the overlap map?
770 geometryMap->pushMappingsToAncestor(layer->renderer(), ancestorLayer ? ancestorLayer->renderer() : 0);
773 layer->setHasCompositingDescendant(false);
775 bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing;
777 bool haveComputedBounds = false;
779 if (overlapMap && !overlapMap->isEmpty() && compositingState.m_testingOverlap) {
780 // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
781 absBounds = enclosingIntRect(geometryMap->absoluteRect(layer->localBoundingBox()));
783 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
784 if (absBounds.isEmpty())
785 absBounds.setSize(IntSize(1, 1));
786 haveComputedBounds = true;
787 mustOverlapCompositedLayers = overlapMap->overlapsLayers(absBounds);
790 layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
792 // The children of this layer don't need to composite, unless there is
793 // a compositing layer among them, so start by inheriting the compositing
794 // ancestor with m_subtreeIsCompositing set to false.
795 CompositingState childState(compositingState);
796 childState.m_subtreeIsCompositing = false;
798 bool willBeComposited = needsToBeComposited(layer);
799 if (willBeComposited) {
800 // Tell the parent it has compositing descendants.
801 compositingState.m_subtreeIsCompositing = true;
802 // This layer now acts as the ancestor for kids.
803 childState.m_compositingAncestor = layer;
806 overlapMap->pushCompositingContainer();
808 if (hasNonAffineTransform(layer->renderer()) || isRunningAcceleratedTransformAnimation(layer->renderer())) {
809 // If we have a 3D transform, or are animating transform, then turn overlap testing off.
810 childState.m_testingOverlap = false;
815 // Video is special. It's a replaced element with a content layer, but has shadow content
816 // for the controller that must render in front. Without this, the controls fail to show
817 // when the video element is a stacking context (e.g. due to opacity or transform).
818 if (willBeComposited && layer->renderer()->isVideo())
819 childState.m_subtreeIsCompositing = true;
823 LayerListMutationDetector mutationChecker(layer);
826 if (layer->isStackingContext()) {
827 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
828 size_t listSize = negZOrderList->size();
829 for (size_t i = 0; i < listSize; ++i) {
830 RenderLayer* curLayer = negZOrderList->at(i);
831 computeCompositingRequirements(layer, curLayer, geometryMap, overlapMap, childState, layersChanged);
833 // If we have to make a layer for this child, make one now so we can have a contents layer
834 // (since we need to ensure that the -ve z-order child renders underneath our contents).
835 if (!willBeComposited && childState.m_subtreeIsCompositing) {
836 // make layer compositing
837 layer->setMustOverlapCompositedLayers(true);
838 childState.m_compositingAncestor = layer;
840 overlapMap->pushCompositingContainer();
841 willBeComposited = true;
847 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
848 size_t listSize = normalFlowList->size();
849 for (size_t i = 0; i < listSize; ++i) {
850 RenderLayer* curLayer = normalFlowList->at(i);
851 computeCompositingRequirements(layer, curLayer, geometryMap, overlapMap, childState, layersChanged);
855 if (layer->isStackingContext()) {
856 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
857 size_t listSize = posZOrderList->size();
858 for (size_t i = 0; i < listSize; ++i) {
859 RenderLayer* curLayer = posZOrderList->at(i);
860 computeCompositingRequirements(layer, curLayer, geometryMap, overlapMap, childState, layersChanged);
865 // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
866 if (layer->isRootLayer()) {
867 if (inCompositingMode() && m_hasAcceleratedCompositing)
868 willBeComposited = true;
871 ASSERT(willBeComposited == needsToBeComposited(layer));
873 // All layers (even ones that aren't being composited) need to get added to
874 // the overlap map. Layers that do not composite will draw into their
875 // compositing ancestor's backing, and so are still considered for overlap.
876 if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer())
877 addToOverlapMap(*geometryMap, *overlapMap, layer, absBounds, haveComputedBounds);
879 // If we have a software transform, and we have layers under us, we need to also
880 // be composited. Also, if we have opacity < 1, then we need to be a layer so that
881 // the child layers are opaque, then rendered with opacity on this layer.
882 if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
883 layer->setMustOverlapCompositedLayers(true);
884 childState.m_compositingAncestor = layer;
886 overlapMap->pushCompositingContainer();
887 addToOverlapMapRecursive(*geometryMap, *overlapMap, layer);
889 willBeComposited = true;
892 ASSERT(willBeComposited == needsToBeComposited(layer));
893 if (layer->reflectionLayer()) {
894 // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
895 layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
898 // Subsequent layers in the parent stacking context also need to composite.
899 if (childState.m_subtreeIsCompositing)
900 compositingState.m_subtreeIsCompositing = true;
902 // We have to keep overlap testing disabled for later layers.
903 if (!childState.m_testingOverlap)
904 compositingState.m_testingOverlap = false;
906 // Set the flag to say that this SC has compositing children.
907 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
909 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
910 // so test that again.
911 if (canBeComposited(layer) && clipsCompositingDescendants(layer)) {
912 if (!willBeComposited) {
913 childState.m_compositingAncestor = layer;
915 overlapMap->pushCompositingContainer();
916 addToOverlapMapRecursive(*geometryMap, *overlapMap, layer);
918 willBeComposited = true;
921 // We're done processing an element that clips. The container can keep testing overlap.
922 compositingState.m_testingOverlap = true;
925 if (overlapMap && childState.m_compositingAncestor == layer && !layer->isRootLayer())
926 overlapMap->popCompositingContainer();
928 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
929 // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
930 // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
931 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) {
932 enableCompositingMode(false);
933 willBeComposited = false;
936 // If the layer is going into compositing mode, repaint its old location.
937 ASSERT(willBeComposited == needsToBeComposited(layer));
938 if (!layer->isComposited() && willBeComposited)
939 repaintOnCompositingChange(layer);
941 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
942 if (updateBacking(layer, CompositingChangeRepaintNow))
943 layersChanged = true;
945 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
946 layersChanged = true;
949 geometryMap->popMappingsToAncestor(ancestorLayer ? ancestorLayer->renderer() : 0);
952 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
954 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
955 ASSERT(childLayer->isComposited());
957 // It's possible to be called with a parent that isn't yet composited when we're doing
958 // partial updates as required by painting or hit testing. Just bail in that case;
959 // we'll do a full layer update soon.
960 if (!parentLayer || !parentLayer->isComposited())
964 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
965 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers();
967 hostingLayer->addChild(hostedLayer);
969 childLayer->backing()->childForSuperlayers()->removeFromParent();
972 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
974 ASSERT(layer->isComposited());
976 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers();
977 hostingLayer->removeAllChildren();
981 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
983 if (!m_hasAcceleratedCompositing)
986 return o->supportsAcceleratedRendering();
990 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
992 // Make the layer compositing if necessary, and set up clipping and content layers.
993 // Note that we can only do work here that is independent of whether the descendant layers
994 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
996 RenderLayerBacking* layerBacking = layer->backing();
998 // The compositing state of all our children has been updated already, so now
999 // we can compute and cache the composited bounds for this layer.
1000 layerBacking->updateCompositedBounds();
1002 if (RenderLayer* reflection = layer->reflectionLayer()) {
1003 if (reflection->backing())
1004 reflection->backing()->updateCompositedBounds();
1007 layerBacking->updateGraphicsLayerConfiguration();
1008 layerBacking->updateGraphicsLayerGeometry();
1010 if (!layer->parent())
1011 updateRootLayerPosition();
1014 logLayerInfo(layer, depth);
1016 UNUSED_PARAM(depth);
1020 // If this layer has backing, then we are collecting its children, otherwise appending
1021 // to the compositing child list of an enclosing layer.
1022 Vector<GraphicsLayer*> layerChildren;
1023 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
1025 #if !ASSERT_DISABLED
1026 LayerListMutationDetector mutationChecker(layer);
1029 if (layer->isStackingContext()) {
1030 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1031 size_t listSize = negZOrderList->size();
1032 for (size_t i = 0; i < listSize; ++i) {
1033 RenderLayer* curLayer = negZOrderList->at(i);
1034 rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1038 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
1039 if (layerBacking && layerBacking->foregroundLayer())
1040 childList.append(layerBacking->foregroundLayer());
1043 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1044 size_t listSize = normalFlowList->size();
1045 for (size_t i = 0; i < listSize; ++i) {
1046 RenderLayer* curLayer = normalFlowList->at(i);
1047 rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1051 if (layer->isStackingContext()) {
1052 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1053 size_t listSize = posZOrderList->size();
1054 for (size_t i = 0; i < listSize; ++i) {
1055 RenderLayer* curLayer = posZOrderList->at(i);
1056 rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1062 bool parented = false;
1063 if (layer->renderer()->isRenderPart())
1064 parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
1066 #if !ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1068 layerBacking->parentForSublayers()->setChildren(layerChildren);
1071 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
1072 // Otherwise, the overflow control layers are normal children.
1073 if (!layerBacking->hasClippingLayer()) {
1074 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) {
1075 overflowControlLayer->removeFromParent();
1076 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1077 layerChildren.append(overflowControlLayer);
1079 layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1083 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) {
1084 overflowControlLayer->removeFromParent();
1085 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1086 layerChildren.append(overflowControlLayer);
1088 layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1092 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) {
1093 overflowControlLayer->removeFromParent();
1094 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1095 layerChildren.append(overflowControlLayer);
1097 layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1102 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1104 layerBacking->parentForSublayers()->setChildren(layerChildren);
1107 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
1111 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
1113 if (m_overflowControlsHostLayer)
1114 m_overflowControlsHostLayer->setPosition(contentsOffset);
1117 void RenderLayerCompositor::frameViewDidChangeSize()
1120 FrameView* frameView = m_renderView->frameView();
1121 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1123 frameViewDidScroll();
1124 updateOverflowControlsLayers();
1126 #if ENABLE(RUBBER_BANDING)
1127 if (m_layerForOverhangAreas)
1128 m_layerForOverhangAreas->setSize(frameView->frameRect().size());
1133 void RenderLayerCompositor::frameViewDidScroll()
1135 FrameView* frameView = m_renderView->frameView();
1136 IntPoint scrollPosition = frameView->scrollPosition();
1138 if (TiledBacking* tiledBacking = frameView->tiledBacking()) {
1139 IntRect visibleContentRect = frameView->visibleContentRect(false /* exclude scrollbars */);
1140 visibleContentRect.move(toSize(frameView->scrollOrigin()));
1141 tiledBacking->visibleRectChanged(visibleContentRect);
1147 // If there's a scrolling coordinator that manages scrolling for this frame view,
1148 // it will also manage updating the scroll layer position.
1149 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
1150 if (scrollingCoordinator->coordinatesScrollingForFrameView(frameView))
1154 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
1157 String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo)
1159 updateCompositingLayers(CompositingUpdateAfterLayout);
1161 if (!m_rootContentLayer)
1164 // We skip dumping the scroll and clip layers to keep layerTreeAsText output
1165 // similar between platforms.
1166 return m_rootContentLayer->layerTreeAsText(showDebugInfo ? LayerTreeAsTextDebug : LayerTreeAsTextBehaviorNormal);
1169 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
1171 if (!renderer->node()->isFrameOwnerElement())
1174 HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(renderer->node());
1175 if (Document* contentDocument = element->contentDocument()) {
1176 if (RenderView* view = contentDocument->renderView())
1177 return view->compositor();
1182 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
1184 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
1185 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
1188 RenderLayer* layer = renderer->layer();
1189 if (!layer->isComposited())
1192 RenderLayerBacking* backing = layer->backing();
1193 GraphicsLayer* hostingLayer = backing->parentForSublayers();
1194 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
1195 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
1196 hostingLayer->removeAllChildren();
1197 hostingLayer->addChild(rootLayer);
1202 // This just updates layer geometry without changing the hierarchy.
1203 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer, int depth)
1205 if (RenderLayerBacking* layerBacking = layer->backing()) {
1206 // The compositing state of all our children has been updated already, so now
1207 // we can compute and cache the composited bounds for this layer.
1208 layerBacking->updateCompositedBounds();
1210 if (RenderLayer* reflection = layer->reflectionLayer()) {
1211 if (reflection->backing())
1212 reflection->backing()->updateCompositedBounds();
1215 layerBacking->updateGraphicsLayerConfiguration();
1216 layerBacking->updateGraphicsLayerGeometry();
1218 if (!layer->parent())
1219 updateRootLayerPosition();
1222 logLayerInfo(layer, depth);
1224 UNUSED_PARAM(depth);
1228 #if !ASSERT_DISABLED
1229 LayerListMutationDetector mutationChecker(layer);
1232 if (layer->isStackingContext()) {
1233 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1234 size_t listSize = negZOrderList->size();
1235 for (size_t i = 0; i < listSize; ++i)
1236 updateLayerTreeGeometry(negZOrderList->at(i), depth + 1);
1240 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1241 size_t listSize = normalFlowList->size();
1242 for (size_t i = 0; i < listSize; ++i)
1243 updateLayerTreeGeometry(normalFlowList->at(i), depth + 1);
1246 if (layer->isStackingContext()) {
1247 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1248 size_t listSize = posZOrderList->size();
1249 for (size_t i = 0; i < listSize; ++i)
1250 updateLayerTreeGeometry(posZOrderList->at(i), depth + 1);
1255 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
1256 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth)
1258 if (layer != compositingAncestor) {
1259 if (RenderLayerBacking* layerBacking = layer->backing()) {
1260 layerBacking->updateCompositedBounds();
1262 if (RenderLayer* reflection = layer->reflectionLayer()) {
1263 if (reflection->backing())
1264 reflection->backing()->updateCompositedBounds();
1267 layerBacking->updateGraphicsLayerGeometry();
1268 if (updateDepth == RenderLayerBacking::CompositingChildren)
1273 if (layer->reflectionLayer())
1274 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth);
1276 if (!layer->hasCompositingDescendant())
1279 #if !ASSERT_DISABLED
1280 LayerListMutationDetector mutationChecker(layer);
1283 if (layer->isStackingContext()) {
1284 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1285 size_t listSize = negZOrderList->size();
1286 for (size_t i = 0; i < listSize; ++i)
1287 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth);
1291 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1292 size_t listSize = normalFlowList->size();
1293 for (size_t i = 0; i < listSize; ++i)
1294 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth);
1297 if (layer->isStackingContext()) {
1298 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1299 size_t listSize = posZOrderList->size();
1300 for (size_t i = 0; i < listSize; ++i)
1301 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth);
1307 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect)
1309 recursiveRepaintLayerRect(rootRenderLayer(), absRect);
1312 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
1314 // FIXME: This method does not work correctly with transforms.
1315 if (layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor())
1316 layer->setBackingNeedsRepaintInRect(rect);
1318 #if !ASSERT_DISABLED
1319 LayerListMutationDetector mutationChecker(layer);
1322 if (layer->hasCompositingDescendant()) {
1323 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1324 size_t listSize = negZOrderList->size();
1325 for (size_t i = 0; i < listSize; ++i) {
1326 RenderLayer* curLayer = negZOrderList->at(i);
1327 IntRect childRect(rect);
1328 curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
1329 recursiveRepaintLayerRect(curLayer, childRect);
1333 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1334 size_t listSize = posZOrderList->size();
1335 for (size_t i = 0; i < listSize; ++i) {
1336 RenderLayer* curLayer = posZOrderList->at(i);
1337 IntRect childRect(rect);
1338 curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
1339 recursiveRepaintLayerRect(curLayer, childRect);
1343 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1344 size_t listSize = normalFlowList->size();
1345 for (size_t i = 0; i < listSize; ++i) {
1346 RenderLayer* curLayer = normalFlowList->at(i);
1347 IntRect childRect(rect);
1348 curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
1349 recursiveRepaintLayerRect(curLayer, childRect);
1354 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
1356 return m_renderView->layer();
1359 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
1361 if (m_overflowControlsHostLayer)
1362 return m_overflowControlsHostLayer.get();
1363 return m_rootContentLayer.get();
1366 GraphicsLayer* RenderLayerCompositor::scrollLayer() const
1368 return m_scrollLayer.get();
1371 void RenderLayerCompositor::didMoveOnscreen()
1373 if (!inCompositingMode() || m_rootLayerAttachment != RootLayerUnattached)
1376 RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1377 attachRootLayer(attachment);
1379 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1380 registerAllScrollingLayers();
1384 void RenderLayerCompositor::willMoveOffscreen()
1386 if (!inCompositingMode() || m_rootLayerAttachment == RootLayerUnattached)
1390 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1391 unregisterAllScrollingLayers();
1395 void RenderLayerCompositor::clearBackingForLayerIncludingDescendants(RenderLayer* layer)
1400 if (layer->isComposited())
1401 layer->clearBacking();
1403 for (RenderLayer* currLayer = layer->firstChild(); currLayer; currLayer = currLayer->nextSibling())
1404 clearBackingForLayerIncludingDescendants(currLayer);
1407 void RenderLayerCompositor::clearBackingForAllLayers()
1409 clearBackingForLayerIncludingDescendants(m_renderView->layer());
1412 void RenderLayerCompositor::updateRootLayerPosition()
1414 if (m_rootContentLayer) {
1415 const IntRect& documentRect = m_renderView->documentRect();
1416 m_rootContentLayer->setSize(documentRect.size());
1417 m_rootContentLayer->setPosition(documentRect.location());
1420 FrameView* frameView = m_renderView->frameView();
1421 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1424 #if ENABLE(RUBBER_BANDING)
1425 if (m_contentShadowLayer) {
1426 m_contentShadowLayer->setPosition(m_rootContentLayer->position());
1428 FloatSize rootContentLayerSize = m_rootContentLayer->size();
1429 if (m_contentShadowLayer->size() != rootContentLayerSize) {
1430 m_contentShadowLayer->setSize(rootContentLayerSize);
1431 ScrollbarTheme::theme()->setUpContentShadowLayer(m_contentShadowLayer.get());
1437 bool RenderLayerCompositor::has3DContent() const
1439 return layerHas3DContent(rootRenderLayer());
1442 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)
1445 // frames are only independently composited in Mac pre-WebKit2.
1446 return view->platformWidget();
1451 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const
1453 // Parent document content needs to be able to render on top of a composited frame, so correct behavior
1454 // is to have the parent document become composited too. However, this can cause problems on platforms that
1455 // use native views for frames (like Mac), so disable that behavior on those platforms for now.
1456 HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement();
1457 RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0;
1459 // If we are the top-level frame, don't propagate.
1463 if (!allowsIndependentlyCompositedFrames(m_renderView->frameView()))
1466 if (!renderer || !renderer->isRenderPart())
1469 // On Mac, only propagate compositing if the frame is overlapped in the parent
1470 // document, or the parent is already compositing, or the main frame is scaled.
1471 Frame* frame = m_renderView->frameView()->frame();
1472 Page* page = frame ? frame->page() : 0;
1473 if (page && page->pageScaleFactor() != 1)
1476 RenderPart* frameRenderer = toRenderPart(renderer);
1477 if (frameRenderer->widget()) {
1478 ASSERT(frameRenderer->widget()->isFrameView());
1479 FrameView* view = static_cast<FrameView*>(frameRenderer->widget());
1480 if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor())
1487 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
1489 if (!canBeComposited(layer))
1492 return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
1495 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
1496 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
1498 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
1500 RenderObject* renderer = layer->renderer();
1501 // The compositing state of a reflection should match that of its reflected layer.
1502 if (layer->isReflection()) {
1503 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
1504 layer = toRenderBoxModelObject(renderer)->layer();
1507 // The root layer always has a compositing layer, but it may not have backing.
1508 return requiresCompositingForTransform(renderer)
1509 || requiresCompositingForVideo(renderer)
1510 || requiresCompositingForCanvas(renderer)
1511 || requiresCompositingForPlugin(renderer)
1512 || requiresCompositingForFrame(renderer)
1513 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1514 || clipsCompositingDescendants(layer)
1515 || requiresCompositingForAnimation(renderer)
1516 || requiresCompositingForFilters(renderer)
1517 || requiresCompositingForPosition(renderer, layer)
1518 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1519 || requiresCompositingForScrolling(renderer)
1524 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
1526 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_LIMIT_COMPOSITING)
1527 if (!m_compositingAllowed) return false;
1529 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
1530 // See http://webkit.org/b/84900 to re-enable it.
1531 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->renderer()->inRenderFlowThread();
1534 bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer* layer, const RenderLayer* compositingAncestorLayer) const
1536 RenderObject* renderer = layer->renderer();
1537 if (compositingAncestorLayer
1538 && !(compositingAncestorLayer->backing()->graphicsLayer()->drawsContent()
1539 || compositingAncestorLayer->backing()->paintsIntoWindow()
1540 || compositingAncestorLayer->backing()->paintsIntoCompositedAncestor()))
1543 return layer->isRootLayer()
1544 || layer->transform() // note: excludes perspective and transformStyle3D.
1545 || requiresCompositingForVideo(renderer)
1546 || requiresCompositingForCanvas(renderer)
1547 || requiresCompositingForPlugin(renderer)
1548 || requiresCompositingForFrame(renderer)
1549 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1550 || requiresCompositingForAnimation(renderer)
1551 || requiresCompositingForFilters(renderer)
1552 || requiresCompositingForPosition(renderer, layer)
1553 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1554 || requiresCompositingForScrolling(renderer)
1556 || renderer->isTransparent()
1557 || renderer->hasMask()
1558 || renderer->hasReflection()
1559 || renderer->hasFilter()
1560 || layer->mustOverlapCompositedLayers();
1564 const char* RenderLayerCompositor::reasonForCompositing(const RenderLayer* layer)
1566 RenderObject* renderer = layer->renderer();
1567 if (layer->isReflection()) {
1568 renderer = renderer->parent();
1569 layer = toRenderBoxModelObject(renderer)->layer();
1572 if (renderer->hasTransform() && renderer->style()->hasPerspective())
1573 return "perspective";
1575 if (renderer->hasTransform() && (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D))
1576 return "preserve-3d";
1578 if (renderer->hasTransform())
1581 if (requiresCompositingForVideo(renderer))
1584 if (requiresCompositingForCanvas(renderer))
1587 if (requiresCompositingForPlugin(renderer))
1590 if (requiresCompositingForFrame(renderer))
1593 if ((canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden))
1594 return "backface-visibility: hidden";
1596 if (clipsCompositingDescendants(layer))
1597 return "clips compositing descendants";
1599 if (requiresCompositingForAnimation(renderer))
1602 if (requiresCompositingForFilters(renderer))
1605 if (requiresCompositingForPosition(renderer, layer))
1606 return "position: fixed";
1608 // This includes layers made composited by requiresCompositingWhenDescendantsAreCompositing().
1609 if (layer->mustOverlapCompositedLayers())
1610 return "overlap/stacking";
1612 if (inCompositingMode() && layer->isRootLayer())
1619 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1620 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1621 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1622 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1623 // but a sibling in the z-order hierarchy.
1624 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
1626 if (!layer->isComposited() || !layer->parent())
1629 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1630 if (!compositingAncestor)
1633 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
1634 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
1636 RenderLayer* computeClipRoot = 0;
1637 RenderLayer* curr = layer;
1639 RenderLayer* next = curr->parent();
1640 if (next == compositingAncestor) {
1641 computeClipRoot = curr;
1647 if (!computeClipRoot || computeClipRoot == layer)
1650 return layer->backgroundClipRect(computeClipRoot, 0, TemporaryClipRects).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
1653 // Return true if the given layer is a stacking context and has compositing child
1654 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1655 // into the hierarchy between this layer and its children in the z-order hierarchy.
1656 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1658 return layer->hasCompositingDescendant() &&
1659 (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip());
1662 bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
1664 // Need this done first to determine overflow.
1665 ASSERT(!m_renderView->needsLayout());
1667 ScrollView* scrollView = m_renderView->frameView();
1668 return scrollView->verticalScrollbar() || scrollView->horizontalScrollbar();
1671 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
1673 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
1676 RenderStyle* style = renderer->style();
1677 // Note that we ask the renderer if it has a transform, because the style may have transforms,
1678 // but the renderer may be an inline that doesn't suppport them.
1679 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
1682 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
1684 if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
1687 if (renderer->isVideo()) {
1688 RenderVideo* video = toRenderVideo(renderer);
1689 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
1691 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1692 else if (renderer->isRenderPart()) {
1693 if (!m_hasAcceleratedCompositing)
1696 Node* node = renderer->node();
1697 if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag)))
1700 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node);
1701 return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false;
1703 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1705 UNUSED_PARAM(renderer);
1710 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
1712 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
1715 if (renderer->isCanvas()) {
1716 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
1717 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
1722 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
1724 if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
1727 bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
1728 || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing());
1732 m_reevaluateCompositingAfterLayout = true;
1734 RenderWidget* pluginRenderer = toRenderWidget(renderer);
1735 // If we can't reliably know the size of the plugin yet, don't change compositing state.
1736 if (pluginRenderer->needsLayout())
1737 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited();
1739 // Don't go into compositing mode if height or width are zero, or size is 1x1.
1740 IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect());
1741 return contentBox.height() * contentBox.width() > 1;
1744 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
1746 if (!renderer->isRenderPart())
1749 RenderPart* frameRenderer = toRenderPart(renderer);
1751 if (!frameRenderer->requiresAcceleratedCompositing())
1754 m_reevaluateCompositingAfterLayout = true;
1756 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
1757 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())
1760 // If we can't reliably know the size of the iframe yet, don't change compositing state.
1761 if (renderer->needsLayout())
1762 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited();
1764 // Don't go into compositing mode if height or width are zero.
1765 IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect());
1766 return contentBox.height() * contentBox.width() > 0;
1769 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
1771 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1774 if (AnimationController* animController = renderer->animation()) {
1775 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
1776 #if ENABLE(CSS_FILTERS)
1777 #if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION)
1778 // <rdar://problem/10907251> - WebKit2 doesn't support CA animations of CI filters on Lion and below
1779 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitFilter)
1780 #endif // !SNOW_LEOPARD && !LION
1781 #endif // CSS_FILTERS
1782 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1787 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
1789 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection() || renderer->hasFilter();
1792 bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const
1794 #if ENABLE(CSS_FILTERS)
1795 if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
1798 return renderer->hasFilter();
1800 UNUSED_PARAM(renderer);
1805 bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer) const
1807 // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
1808 // opacity, transform) can get their own composited layer. A stacking context is required otherwise
1809 // z-index and clipping will be broken.
1810 if (!(renderer->isPositioned() && renderer->style()->position() == FixedPosition && layer->isStackingContext()))
1813 if (Settings* settings = m_renderView->document()->settings())
1814 if (!settings->acceleratedCompositingForFixedPositionEnabled())
1817 RenderObject* container = renderer->container();
1818 // If the renderer is not hooked up yet then we have to wait until it is.
1820 m_reevaluateCompositingAfterLayout = true;
1824 // Don't promote fixed position elements that are descendants of transformed elements.
1825 // They will stay fixed wrt the transformed element rather than the enclosing frame.
1826 if (container != m_renderView)
1829 // Fixed position elements that are invisible in the current view don't get their own layer.
1830 FrameView* frameView = m_renderView->frameView();
1831 if (frameView && !layer->absoluteBoundingBox().intersects(IntRect(frameView->scrollXForFixedPosition(), frameView->scrollYForFixedPosition(), frameView->layoutWidth(), frameView->layoutHeight())))
1837 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1838 bool RenderLayerCompositor::requiresCompositingForScrolling(RenderObject* renderer) const
1840 return renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->hasAcceleratedTouchScrolling();
1845 bool RenderLayerCompositor::hasNonAffineTransform(RenderObject* renderer) const
1847 if (!renderer->hasTransform())
1850 if (TransformationMatrix* transform = toRenderBoxModelObject(renderer)->layer()->transform())
1851 return !transform->isAffine();
1856 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const
1858 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1861 if (AnimationController* animController = renderer->animation())
1862 return animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1867 // If an element has negative z-index children, those children render in front of the
1868 // layer background, so we need an extra 'contents' layer for the foreground of the layer
1870 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
1872 return layer->hasNegativeZOrderList();
1875 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
1877 // This applies when the application UI handles scrolling, in which case RenderLayerCompositor doesn't need to manage it.
1878 if (m_renderView->frameView()->delegatesScrolling())
1881 // We need to handle our own scrolling if we're:
1882 return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
1883 || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
1886 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1892 const IntRect& scrollbarRect = scrollbar->frameRect();
1893 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1894 IntRect transformedClip = clip;
1895 transformedClip.moveBy(scrollbarRect.location());
1896 scrollbar->paint(&context, transformedClip);
1900 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
1902 if (graphicsLayer == layerForHorizontalScrollbar())
1903 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
1904 else if (graphicsLayer == layerForVerticalScrollbar())
1905 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
1906 else if (graphicsLayer == layerForScrollCorner()) {
1907 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
1909 context.translate(-scrollCorner.x(), -scrollCorner.y());
1910 IntRect transformedClip = clip;
1911 transformedClip.moveBy(scrollCorner.location());
1912 m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
1914 #if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
1915 } else if (graphicsLayer == layerForOverhangAreas()) {
1916 ScrollView* view = m_renderView->frameView();
1917 view->calculateAndPaintOverhangAreas(&context, clip);
1922 void RenderLayerCompositor::documentBackgroundColorDidChange()
1924 RenderLayerBacking* backing = rootRenderLayer()->backing();
1928 GraphicsLayer* graphicsLayer = backing->graphicsLayer();
1929 if (!graphicsLayer->client()->shouldUseTileCache(graphicsLayer))
1932 Color backgroundColor = m_renderView->frameView()->documentBackgroundColor();
1933 if (!backgroundColor.isValid() || backgroundColor.hasAlpha())
1934 backgroundColor = Color::white;
1936 graphicsLayer->setBackgroundColor(backgroundColor);
1939 bool RenderLayerCompositor::showDebugBorders(const GraphicsLayer* layer) const
1941 if (layer == m_layerForHorizontalScrollbar || layer == m_layerForVerticalScrollbar || layer == m_layerForScrollCorner)
1942 return m_showDebugBorders;
1947 bool RenderLayerCompositor::showRepaintCounter(const GraphicsLayer* layer) const
1949 if (layer == m_layerForHorizontalScrollbar || layer == m_layerForVerticalScrollbar || layer == m_layerForScrollCorner)
1950 return m_showDebugBorders;
1955 float RenderLayerCompositor::deviceScaleFactor() const
1957 Frame* frame = m_renderView->frameView()->frame();
1960 Page* page = frame->page();
1963 return page->deviceScaleFactor();
1966 float RenderLayerCompositor::pageScaleFactor() const
1968 Frame* frame = m_renderView->frameView()->frame();
1971 Page* page = frame->page();
1974 return page->pageScaleFactor();
1977 void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const
1979 // Nothing to do here yet.
1982 bool RenderLayerCompositor::keepLayersPixelAligned() const
1984 // When scaling, attempt to align compositing layers to pixel boundaries.
1988 static bool shouldCompositeOverflowControls(FrameView* view)
1990 if (view->platformWidget())
1993 if (Page* page = view->frame()->page()) {
1994 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1995 if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
1999 #if !PLATFORM(CHROMIUM)
2000 if (!view->hasOverlayScrollbars())
2006 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
2008 FrameView* view = m_renderView->frameView();
2009 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
2012 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
2014 FrameView* view = m_renderView->frameView();
2015 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
2018 bool RenderLayerCompositor::requiresScrollCornerLayer() const
2020 FrameView* view = m_renderView->frameView();
2021 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
2024 #if ENABLE(RUBBER_BANDING)
2025 bool RenderLayerCompositor::requiresOverhangAreasLayer() const
2027 // We don't want a layer if this is a subframe.
2028 if (m_renderView->document()->ownerElement())
2031 // We do want a layer if we have a scrolling coordinator.
2032 if (scrollingCoordinator())
2035 // Chromium always wants a layer.
2036 #if PLATFORM(CHROMIUM)
2043 bool RenderLayerCompositor::requiresContentShadowLayer() const
2045 // We don't want a layer if this is a subframe.
2046 if (m_renderView->document()->ownerElement())
2050 // On Mac, we want a content shadow layer if we have a scrolling coordinator.
2051 if (scrollingCoordinator())
2059 void RenderLayerCompositor::updateOverflowControlsLayers()
2061 #if ENABLE(RUBBER_BANDING)
2062 if (requiresOverhangAreasLayer()) {
2063 if (!m_layerForOverhangAreas) {
2064 m_layerForOverhangAreas = GraphicsLayer::create(this);
2066 m_layerForOverhangAreas->setName("overhang areas");
2068 m_layerForOverhangAreas->setDrawsContent(false);
2069 m_layerForOverhangAreas->setSize(m_renderView->frameView()->frameRect().size());
2071 ScrollbarTheme::theme()->setUpOverhangAreasLayerContents(m_layerForOverhangAreas.get());
2073 // We want the overhang areas layer to be positioned below the frame contents,
2074 // so insert it below the clip layer.
2075 m_overflowControlsHostLayer->addChildBelow(m_layerForOverhangAreas.get(), m_clipLayer.get());
2077 } else if (m_layerForOverhangAreas) {
2078 m_layerForOverhangAreas->removeFromParent();
2079 m_layerForOverhangAreas = nullptr;
2082 if (requiresContentShadowLayer()) {
2083 if (!m_contentShadowLayer) {
2084 m_contentShadowLayer = GraphicsLayer::create(this);
2086 m_contentShadowLayer->setName("content shadow");
2088 m_contentShadowLayer->setSize(m_rootContentLayer->size());
2089 m_contentShadowLayer->setPosition(m_rootContentLayer->position());
2090 ScrollbarTheme::theme()->setUpContentShadowLayer(m_contentShadowLayer.get());
2092 m_scrollLayer->addChildBelow(m_contentShadowLayer.get(), m_rootContentLayer.get());
2094 } else if (m_contentShadowLayer) {
2095 m_contentShadowLayer->removeFromParent();
2096 m_contentShadowLayer = nullptr;
2100 if (requiresHorizontalScrollbarLayer()) {
2101 if (!m_layerForHorizontalScrollbar) {
2102 m_layerForHorizontalScrollbar = GraphicsLayer::create(this);
2104 m_layerForHorizontalScrollbar->setName("horizontal scrollbar");
2106 #if PLATFORM(MAC) && USE(CA)
2107 m_layerForHorizontalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
2109 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
2111 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2112 scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForHorizontalScrollbar.get());
2114 } else if (m_layerForHorizontalScrollbar) {
2115 m_layerForHorizontalScrollbar->removeFromParent();
2116 m_layerForHorizontalScrollbar = nullptr;
2118 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2119 scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), 0);
2122 if (requiresVerticalScrollbarLayer()) {
2123 if (!m_layerForVerticalScrollbar) {
2124 m_layerForVerticalScrollbar = GraphicsLayer::create(this);
2126 m_layerForVerticalScrollbar->setName("vertical scrollbar");
2128 #if PLATFORM(MAC) && USE(CA)
2129 m_layerForVerticalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
2131 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
2133 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2134 scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForVerticalScrollbar.get());
2136 } else if (m_layerForVerticalScrollbar) {
2137 m_layerForVerticalScrollbar->removeFromParent();
2138 m_layerForVerticalScrollbar = nullptr;
2140 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2141 scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), 0);
2144 if (requiresScrollCornerLayer()) {
2145 if (!m_layerForScrollCorner) {
2146 m_layerForScrollCorner = GraphicsLayer::create(this);
2148 m_layerForScrollCorner->setName("scroll corner");
2150 #if PLATFORM(MAC) && USE(CA)
2151 m_layerForScrollCorner->setAcceleratesDrawing(acceleratedDrawingEnabled());
2153 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
2155 } else if (m_layerForScrollCorner) {
2156 m_layerForScrollCorner->removeFromParent();
2157 m_layerForScrollCorner = nullptr;
2160 m_renderView->frameView()->positionScrollbarLayers();
2163 void RenderLayerCompositor::ensureRootLayer()
2165 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
2166 if (expectedAttachment == m_rootLayerAttachment)
2169 if (!m_rootContentLayer) {
2170 m_rootContentLayer = GraphicsLayer::create(this);
2172 m_rootContentLayer->setName("content root");
2174 IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect();
2175 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
2176 m_rootContentLayer->setPosition(FloatPoint());
2178 // Need to clip to prevent transformed content showing outside this frame
2179 m_rootContentLayer->setMasksToBounds(true);
2182 if (requiresScrollLayer(expectedAttachment)) {
2183 if (!m_overflowControlsHostLayer) {
2184 ASSERT(!m_scrollLayer);
2185 ASSERT(!m_clipLayer);
2187 // Create a layer to host the clipping layer and the overflow controls layers.
2188 m_overflowControlsHostLayer = GraphicsLayer::create(this);
2190 m_overflowControlsHostLayer->setName("overflow controls host");
2193 // Create a clipping layer if this is an iframe
2194 m_clipLayer = GraphicsLayer::create(this);
2196 m_clipLayer->setName("frame clipping");
2198 m_clipLayer->setMasksToBounds(true);
2200 m_scrollLayer = GraphicsLayer::create(this);
2202 m_scrollLayer->setName("frame scrolling");
2206 m_overflowControlsHostLayer->addChild(m_clipLayer.get());
2207 m_clipLayer->addChild(m_scrollLayer.get());
2208 m_scrollLayer->addChild(m_rootContentLayer.get());
2210 frameViewDidChangeSize();
2211 frameViewDidScroll();
2214 if (m_overflowControlsHostLayer) {
2215 m_overflowControlsHostLayer = nullptr;
2216 m_clipLayer = nullptr;
2217 m_scrollLayer = nullptr;
2221 // Check to see if we have to change the attachment
2222 if (m_rootLayerAttachment != RootLayerUnattached)
2225 attachRootLayer(expectedAttachment);
2228 void RenderLayerCompositor::destroyRootLayer()
2230 if (!m_rootContentLayer)
2235 #if ENABLE(RUBBER_BANDING)
2236 if (m_layerForOverhangAreas) {
2237 m_layerForOverhangAreas->removeFromParent();
2238 m_layerForOverhangAreas = nullptr;
2242 if (m_layerForHorizontalScrollbar) {
2243 m_layerForHorizontalScrollbar->removeFromParent();
2244 m_layerForHorizontalScrollbar = nullptr;
2245 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
2246 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
2249 if (m_layerForVerticalScrollbar) {
2250 m_layerForVerticalScrollbar->removeFromParent();
2251 m_layerForVerticalScrollbar = nullptr;
2252 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
2253 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
2256 if (m_layerForScrollCorner) {
2257 m_layerForScrollCorner = nullptr;
2258 m_renderView->frameView()->invalidateScrollCorner(m_renderView->frameView()->scrollCornerRect());
2261 if (m_overflowControlsHostLayer) {
2262 m_overflowControlsHostLayer = nullptr;
2263 m_clipLayer = nullptr;
2264 m_scrollLayer = nullptr;
2266 ASSERT(!m_scrollLayer);
2267 m_rootContentLayer = nullptr;
2270 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
2272 if (!m_rootContentLayer)
2275 switch (attachment) {
2276 case RootLayerUnattached:
2277 ASSERT_NOT_REACHED();
2279 case RootLayerAttachedViaChromeClient: {
2280 Frame* frame = m_renderView->frameView()->frame();
2281 Page* page = frame ? frame->page() : 0;
2285 page->chrome()->client()->attachRootGraphicsLayer(frame, rootGraphicsLayer());
2288 case RootLayerAttachedViaEnclosingFrame: {
2289 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
2290 // for the frame's renderer in the parent document.
2291 m_renderView->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2296 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2297 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
2299 m_rootLayerAttachment = attachment;
2300 rootLayerAttachmentChanged();
2303 void RenderLayerCompositor::detachRootLayer()
2305 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
2308 switch (m_rootLayerAttachment) {
2309 case RootLayerAttachedViaEnclosingFrame: {
2310 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
2311 // for the frame's renderer in the parent document.
2312 if (m_overflowControlsHostLayer)
2313 m_overflowControlsHostLayer->removeFromParent();
2315 m_rootContentLayer->removeFromParent();
2317 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
2318 ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2321 case RootLayerAttachedViaChromeClient: {
2322 Frame* frame = m_renderView->frameView()->frame();
2323 Page* page = frame ? frame->page() : 0;
2327 page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
2330 case RootLayerUnattached:
2334 m_rootLayerAttachment = RootLayerUnattached;
2335 rootLayerAttachmentChanged();
2338 void RenderLayerCompositor::updateRootLayerAttachment()
2343 void RenderLayerCompositor::rootLayerAttachmentChanged()
2345 // The attachment can affect whether the RenderView layer's paintsIntoWindow() behavior,
2346 // so call updateGraphicsLayerGeometry() to udpate that.
2347 RenderLayer* layer = m_renderView->layer();
2348 if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
2349 backing->updateDrawsContent();
2352 // IFrames are special, because we hook compositing layers together across iframe boundaries
2353 // when both parent and iframe content are composited. So when this frame becomes composited, we have
2354 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
2355 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
2357 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0;
2361 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) {
2362 if (child->document() && child->document()->ownerElement())
2363 child->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2366 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
2367 // we need to schedule a style recalc in our parent document.
2368 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
2369 ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2372 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
2374 const RenderStyle* style = layer->renderer()->style();
2377 (style->transformStyle3D() == TransformStyle3DPreserve3D ||
2378 style->hasPerspective() ||
2379 style->transform().has3DOperation()))
2382 const_cast<RenderLayer*>(layer)->updateLayerListsIfNeeded();
2384 #if !ASSERT_DISABLED
2385 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(layer));
2388 if (layer->isStackingContext()) {
2389 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
2390 size_t listSize = negZOrderList->size();
2391 for (size_t i = 0; i < listSize; ++i) {
2392 RenderLayer* curLayer = negZOrderList->at(i);
2393 if (layerHas3DContent(curLayer))
2398 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
2399 size_t listSize = posZOrderList->size();
2400 for (size_t i = 0; i < listSize; ++i) {
2401 RenderLayer* curLayer = posZOrderList->at(i);
2402 if (layerHas3DContent(curLayer))
2408 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
2409 size_t listSize = normalFlowList->size();
2410 for (size_t i = 0; i < listSize; ++i) {
2411 RenderLayer* curLayer = normalFlowList->at(i);
2412 if (layerHas3DContent(curLayer))
2419 void RenderLayerCompositor::deviceOrPageScaleFactorChanged()
2421 // Start at the RenderView's layer, since that's where the scale is applied.
2422 RenderLayer* viewLayer = m_renderView->layer();
2423 if (!viewLayer->isComposited())
2426 if (GraphicsLayer* rootLayer = viewLayer->backing()->graphicsLayer())
2427 rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
2430 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
2432 if (Frame* frame = m_renderView->frameView()->frame()) {
2433 if (Page* page = frame->page())
2434 return page->scrollingCoordinator();
2440 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
2441 void RenderLayerCompositor::platformLayerChanged(RenderLayer* renderLayer, PlatformLayer* oldLayer, PlatformLayer* newLayer)
2443 if (m_scrollingLayers.contains(renderLayer)) {
2444 RenderLayerBacking* backing = renderLayer->backing();
2446 scrollingLayerAddedOrUpdated(renderLayer, backing->scrollingLayer(), backing->scrollingContentsLayer(), IntSize(renderLayer->scrollWidth(), renderLayer->scrollHeight()));
2450 void RenderLayerCompositor::registerAllScrollingLayers()
2452 ChromeClient* chromeClient = this->chromeClient();
2456 HashSet<RenderLayer*>::const_iterator end = m_scrollingLayers.end();
2457 for (HashSet<RenderLayer*>::const_iterator it = m_scrollingLayers.begin(); it != end; ++it) {
2458 RenderLayer* layer = *it;
2459 RenderLayerBacking* backing = layer->backing();
2461 chromeClient->addOrUpdateScrollingLayer(layer->renderer()->node(), backing->scrollingLayer(), backing->scrollingContentsLayer(), IntSize(layer->scrollWidth(), layer->scrollHeight()));
2465 void RenderLayerCompositor::unregisterAllScrollingLayers()
2467 ChromeClient* chromeClient = this->chromeClient();
2471 HashSet<RenderLayer*>::const_iterator end = m_scrollingLayers.end();
2472 for (HashSet<RenderLayer*>::const_iterator it = m_scrollingLayers.begin(); it != end; ++it) {
2473 RenderLayer* layer = *it;
2474 RenderLayerBacking* backing = layer->backing();
2476 chromeClient->removeScrollingLayer(layer->renderer()->node(), backing->scrollingLayer(), backing->scrollingContentsLayer());
2480 // Called when the size of the contentsLayer changes, and when the contentsLayer is replaced by another layer.
2481 void RenderLayerCompositor::scrollingLayerAddedOrUpdated(RenderLayer* layer, GraphicsLayer* scrollingLayer, GraphicsLayer* contentsLayer, const IntSize& scrollSize)
2483 m_scrollingLayers.add(layer);
2485 ASSERT(!m_renderView->document()->inPageCache());
2487 if (ChromeClient* chromeClient = this->chromeClient())
2488 chromeClient->addOrUpdateScrollingLayer(layer->renderer()->node(), scrollingLayer, contentsLayer, scrollSize);
2491 void RenderLayerCompositor::scrollingLayerRemoved(RenderLayer* layer, GraphicsLayer* scrollingLayer, GraphicsLayer* contentsLayer)
2493 m_scrollingLayers.remove(layer);
2495 if (m_renderView->document()->inPageCache())
2498 if (ChromeClient* chromeClient = this->chromeClient())
2499 chromeClient->removeScrollingLayer(layer->renderer()->node(), scrollingLayer, contentsLayer);
2503 } // namespace WebCore
2505 #endif // USE(ACCELERATED_COMPOSITING)