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)
202 RenderLayerCompositor::~RenderLayerCompositor()
204 ASSERT(m_rootLayerAttachment == RootLayerUnattached);
207 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
209 if (enable != m_compositing) {
210 m_compositing = enable;
214 notifyIFramesOfCompositingChange();
220 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
222 bool hasAcceleratedCompositing = false;
223 bool showDebugBorders = false;
224 bool showRepaintCounter = false;
225 bool forceCompositingMode = false;
226 bool acceleratedDrawingEnabled = false;
228 if (Settings* settings = m_renderView->document()->settings()) {
229 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
231 // We allow the chrome to override the settings, in case the page is rendered
232 // on a chrome that doesn't allow accelerated compositing.
233 if (hasAcceleratedCompositing) {
234 Frame* frame = m_renderView->frameView()->frame();
235 Page* page = frame ? frame->page() : 0;
237 ChromeClient* chromeClient = page->chrome()->client();
238 m_compositingTriggers = chromeClient->allowedCompositingTriggers();
239 hasAcceleratedCompositing = m_compositingTriggers;
243 showDebugBorders = settings->showDebugBorders();
244 showRepaintCounter = settings->showRepaintCounter();
245 forceCompositingMode = settings->forceCompositingMode() && hasAcceleratedCompositing;
247 if (forceCompositingMode && m_renderView->document()->ownerElement())
248 forceCompositingMode = settings->acceleratedCompositingForScrollableFramesEnabled() && requiresCompositingForScrollableFrame();
250 acceleratedDrawingEnabled = settings->acceleratedDrawingEnabled();
253 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode)
254 setCompositingLayersNeedRebuild();
256 m_hasAcceleratedCompositing = hasAcceleratedCompositing;
257 m_showDebugBorders = showDebugBorders;
258 m_showRepaintCounter = showRepaintCounter;
259 m_forceCompositingMode = forceCompositingMode;
260 m_acceleratedDrawingEnabled = acceleratedDrawingEnabled;
263 bool RenderLayerCompositor::canRender3DTransforms() const
265 return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
268 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
270 if (inCompositingMode())
271 m_compositingLayersNeedRebuild = needRebuild;
274 void RenderLayerCompositor::scheduleLayerFlush()
276 Frame* frame = m_renderView->frameView()->frame();
277 Page* page = frame ? frame->page() : 0;
281 page->chrome()->client()->scheduleCompositingLayerSync();
284 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
285 ChromeClient* RenderLayerCompositor::chromeClient() const
287 Frame* frame = m_renderView->frameView()->frame();
288 Page* page = frame ? frame->page() : 0;
292 return page->chrome()->client();
296 void RenderLayerCompositor::flushPendingLayerChanges(bool isFlushRoot)
298 // FrameView::syncCompositingStateIncludingSubframes() flushes each subframe,
299 // but GraphicsLayer::syncCompositingState() will cross frame boundaries
300 // if the GraphicsLayers are connected (the RootLayerAttachedViaEnclosingFrame case).
301 // As long as we're not the root of the flush, we can bail.
302 if (!isFlushRoot && rootLayerAttachment() == RootLayerAttachedViaEnclosingFrame)
305 ASSERT(!m_flushingLayers);
306 m_flushingLayers = true;
308 if (GraphicsLayer* rootLayer = rootGraphicsLayer()) {
309 FrameView* frameView = m_renderView ? m_renderView->frameView() : 0;
311 // FIXME: Passing frameRect() is correct only when RenderLayerCompositor uses a ScrollLayer (as in WebKit2)
312 // otherwise, the passed clip rect needs to take scrolling into account
313 rootLayer->syncCompositingState(frameView->frameRect());
317 ASSERT(m_flushingLayers);
318 m_flushingLayers = false;
321 void RenderLayerCompositor::didFlushChangesForLayer(RenderLayer*)
325 RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const
327 if (!m_renderView->frameView())
330 for (Frame* frame = m_renderView->frameView()->frame(); frame; frame = frame->tree()->parent()) {
331 RenderLayerCompositor* compositor = frame->contentRenderer() ? frame->contentRenderer()->compositor() : 0;
332 if (compositor->isFlushingLayers())
339 void RenderLayerCompositor::scheduleCompositingLayerUpdate()
341 if (!m_updateCompositingLayersTimer.isActive())
342 m_updateCompositingLayersTimer.startOneShot(0);
345 void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*)
347 updateCompositingLayers(CompositingUpdateAfterLayout);
350 bool RenderLayerCompositor::hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const
352 return m_compositedLayerCount > (rootLayer->isComposited() ? 1 : 0);
355 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
357 m_updateCompositingLayersTimer.stop();
359 // Compositing layers will be updated in Document::implicitClose() if suppressed here.
360 if (!m_renderView->document()->visualUpdatesAllowed())
363 if (m_forceCompositingMode && !m_compositing)
364 enableCompositingMode(true);
366 if (!m_reevaluateCompositingAfterLayout && !m_compositing)
369 AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame()->animation());
371 bool checkForHierarchyUpdate = m_reevaluateCompositingAfterLayout;
372 bool needGeometryUpdate = false;
374 switch (updateType) {
375 case CompositingUpdateAfterStyleChange:
376 case CompositingUpdateAfterLayout:
377 case CompositingUpdateOnHitTest:
378 checkForHierarchyUpdate = true;
380 case CompositingUpdateOnScroll:
381 if (m_compositingConsultsOverlap)
382 checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
384 needGeometryUpdate = true;
388 if (!checkForHierarchyUpdate && !needGeometryUpdate)
391 bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
392 bool isFullUpdate = !updateRoot;
393 if (!updateRoot || m_compositingConsultsOverlap) {
394 // Only clear the flag if we're updating the entire hierarchy.
395 m_compositingLayersNeedRebuild = false;
396 updateRoot = rootRenderLayer();
399 if (isFullUpdate && updateType == CompositingUpdateAfterLayout)
400 m_reevaluateCompositingAfterLayout = false;
403 double startTime = 0;
404 if (compositingLogEnabled()) {
405 ++m_rootLayerUpdateCount;
406 startTime = currentTime();
410 if (checkForHierarchyUpdate) {
411 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
412 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
413 CompositingState compState(updateRoot, m_compositingConsultsOverlap);
414 bool layersChanged = false;
415 if (m_compositingConsultsOverlap) {
416 OverlapMap overlapTestRequestMap;
417 RenderGeometryMap geometryMap;
418 computeCompositingRequirements(0, updateRoot, &geometryMap, &overlapTestRequestMap, compState, layersChanged);
420 computeCompositingRequirements(0, updateRoot, 0, 0, compState, layersChanged);
422 needHierarchyUpdate |= layersChanged;
426 if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
427 m_obligateCompositedLayerCount = 0;
428 m_secondaryCompositedLayerCount = 0;
429 m_obligatoryBackingAreaMegaPixels = 0;
430 m_secondaryBackingAreaMegaPixels = 0;
432 Frame* frame = m_renderView->frameView()->frame();
433 bool isMainFrame = !m_renderView->document()->ownerElement();
434 LOG(Compositing, "\nUpdate %d of %s. Overlap testing is %s\n", m_rootLayerUpdateCount, isMainFrame ? "main frame" : frame->tree()->uniqueName().string().utf8().data(),
435 m_compositingConsultsOverlap ? "on" : "off");
439 if (needHierarchyUpdate) {
440 // Update the hierarchy of the compositing layers.
441 Vector<GraphicsLayer*> childList;
442 rebuildCompositingLayerTree(updateRoot, childList, 0);
444 // Host the document layer in the RenderView's root layer.
446 // Even when childList is empty, don't drop out of compositing mode if there are
447 // composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
448 if (childList.isEmpty() && !hasAnyAdditionalCompositedLayers(updateRoot))
451 m_rootContentLayer->setChildren(childList);
453 } else if (needGeometryUpdate) {
454 // We just need to do a geometry update. This is only used for position:fixed scrolling;
455 // most of the time, geometry is updated via RenderLayer::styleChanged().
456 updateLayerTreeGeometry(updateRoot, 0);
460 if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
461 double endTime = currentTime();
462 LOG(Compositing, "Total layers primary secondary obligatory backing (MP) secondary backing(MP) total backing (MP) update time (ms)\n");
464 LOG(Compositing, "%8d %11d %9d %20.2f %22.2f %22.2f %18.2f\n",
465 m_obligateCompositedLayerCount + m_secondaryCompositedLayerCount, m_obligateCompositedLayerCount,
466 m_secondaryCompositedLayerCount, m_obligatoryBackingAreaMegaPixels, m_secondaryBackingAreaMegaPixels, m_obligatoryBackingAreaMegaPixels + m_secondaryBackingAreaMegaPixels, 1000.0 * (endTime - startTime));
469 ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
471 if (!hasAcceleratedCompositing())
472 enableCompositingMode(false);
476 void RenderLayerCompositor::logLayerInfo(const RenderLayer* layer, int depth)
478 if (!compositingLogEnabled())
481 RenderLayerBacking* backing = layer->backing();
482 if (requiresCompositingLayer(layer) || layer->isRootLayer()) {
483 ++m_obligateCompositedLayerCount;
484 m_obligatoryBackingAreaMegaPixels += backing->backingStoreArea() / PIXELS_PER_MEGAPIXEL;
486 ++m_secondaryCompositedLayerCount;
487 m_secondaryBackingAreaMegaPixels += backing->backingStoreArea() / PIXELS_PER_MEGAPIXEL;
490 LOG(Compositing, "%*p %dx%d %.3fMP (%s) %s\n", 12 + depth * 2, layer, backing->compositedBounds().width(), backing->compositedBounds().height(),
491 backing->backingStoreArea() / PIXELS_PER_MEGAPIXEL,
492 reasonForCompositing(layer), layer->backing()->nameForLayer().utf8().data());
496 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
498 bool layerChanged = false;
499 if (needsToBeComposited(layer)) {
500 enableCompositingMode();
502 if (!layer->backing()) {
503 // If we need to repaint, do so before making backing
504 if (shouldRepaint == CompositingChangeRepaintNow)
505 repaintOnCompositingChange(layer);
507 layer->ensureBacking();
509 // The RenderLayer's needs to update repaint rects here, because the target
510 // repaintContainer may have changed after becoming a composited layer.
511 // https://bugs.webkit.org/show_bug.cgi?id=80641
513 layer->computeRepaintRects();
518 if (layer->backing()) {
519 // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
520 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
521 // are both either composited, or not composited.
522 if (layer->isReflection()) {
523 RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer();
524 if (RenderLayerBacking* backing = sourceLayer->backing()) {
525 ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer());
526 backing->graphicsLayer()->setReplicatedByLayer(0);
530 layer->clearBacking();
533 // The layer's cached repaints rects are relative to the repaint container, so change when
534 // compositing changes; we need to update them here.
535 layer->computeRepaintRects();
537 // If we need to repaint, do so now that we've removed the backing
538 if (shouldRepaint == CompositingChangeRepaintNow)
539 repaintOnCompositingChange(layer);
544 if (layerChanged && layer->renderer()->isVideo()) {
545 // If it's a video, give the media player a chance to hook up to the layer.
546 RenderVideo* video = toRenderVideo(layer->renderer());
547 video->acceleratedRenderingStateChanged();
551 if (layerChanged && layer->renderer()->isRenderPart()) {
552 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
553 if (innerCompositor && innerCompositor->inCompositingMode())
554 innerCompositor->updateRootLayerAttachment();
558 layer->clearClipRectsIncludingDescendants(PaintingClipRects);
563 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
565 bool layerChanged = updateBacking(layer, shouldRepaint);
567 // See if we need content or clipping layers. Methods called here should assume
568 // that the compositing state of descendant layers has not been updated yet.
569 if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration())
575 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
577 // If the renderer is not attached yet, no need to repaint.
578 if (layer->renderer() != m_renderView && !layer->renderer()->parent())
581 RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint();
582 if (!repaintContainer)
583 repaintContainer = m_renderView;
585 layer->repaintIncludingNonCompositingDescendants(repaintContainer);
586 if (repaintContainer == m_renderView) {
587 // The contents of this layer may be moving between the window
588 // and a GraphicsLayer, so we need to make sure the window system
589 // synchronizes those changes on the screen.
590 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
594 // This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
595 void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect)
597 RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(false /*exclude self*/);
598 if (compositedAncestor) {
599 ASSERT(compositedAncestor->backing());
602 layer->convertToLayerCoords(compositedAncestor, offset);
604 LayoutRect repaintRect = rect;
605 repaintRect.moveBy(offset);
607 compositedAncestor->setBackingNeedsRepaintInRect(repaintRect);
610 // The contents of this layer may be moving from a GraphicsLayer to the window,
611 // so we need to make sure the window system synchronizes those changes on the screen.
612 if (compositedAncestor == m_renderView->layer())
613 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
616 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
617 // RenderLayers that are rendered by the composited RenderLayer.
618 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
620 if (!canBeComposited(layer))
622 return RenderLayer::calculateLayerBounds(layer, ancestorLayer);
625 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
627 setCompositingLayersNeedRebuild();
630 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
632 if (!child->isComposited() || parent->renderer()->documentBeingDestroyed())
635 repaintInCompositedAncestor(child, child->backing()->compositedBounds());
637 setCompositingParent(child, 0);
638 setCompositingLayersNeedRebuild();
641 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
643 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
644 if (curr->isStackingContext())
647 if (curr->renderer()->hasOverflowClip() || curr->renderer()->hasClip())
653 void RenderLayerCompositor::addToOverlapMap(RenderGeometryMap& geometryMap, OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
655 if (layer->isRootLayer())
658 if (!boundsComputed) {
659 layerBounds = enclosingIntRect(geometryMap.absoluteRect(layer->localBoundingBox()));
660 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
661 if (layerBounds.isEmpty())
662 layerBounds.setSize(IntSize(1, 1));
663 boundsComputed = true;
666 IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(rootRenderLayer(), 0, AbsoluteClipRects).rect()); // FIXME: Incorrect for CSS regions.
667 clipRect.scale(pageScaleFactor());
668 clipRect.intersect(layerBounds);
669 overlapMap.add(layer, clipRect);
672 void RenderLayerCompositor::addToOverlapMapRecursive(RenderGeometryMap& geometryMap, OverlapMap& overlapMap, RenderLayer* layer, RenderLayer* ancestorLayer)
674 if (!canBeComposited(layer) || overlapMap.contains(layer))
677 // A null ancestorLayer is an indication that 'layer' has already been pushed.
679 geometryMap.pushMappingsToAncestor(layer->renderer(), ancestorLayer->renderer());
682 bool haveComputedBounds = false;
683 addToOverlapMap(geometryMap, overlapMap, layer, bounds, haveComputedBounds);
686 LayerListMutationDetector mutationChecker(layer);
689 if (layer->isStackingContext()) {
690 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
691 size_t listSize = negZOrderList->size();
692 for (size_t i = 0; i < listSize; ++i) {
693 RenderLayer* curLayer = negZOrderList->at(i);
694 addToOverlapMapRecursive(geometryMap, overlapMap, curLayer, layer);
699 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
700 size_t listSize = normalFlowList->size();
701 for (size_t i = 0; i < listSize; ++i) {
702 RenderLayer* curLayer = normalFlowList->at(i);
703 addToOverlapMapRecursive(geometryMap, overlapMap, curLayer, layer);
707 if (layer->isStackingContext()) {
708 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
709 size_t listSize = posZOrderList->size();
710 for (size_t i = 0; i < listSize; ++i) {
711 RenderLayer* curLayer = posZOrderList->at(i);
712 addToOverlapMapRecursive(geometryMap, overlapMap, curLayer, layer);
718 geometryMap.popMappingsToAncestor(ancestorLayer->renderer());
721 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
722 // For the z-order children of a compositing layer:
723 // If a child layers has a compositing layer, then all subsequent layers must
724 // be compositing in order to render above that layer.
726 // If a child in the negative z-order list is compositing, then the layer itself
727 // must be compositing so that its contents render over that child.
728 // This implies that its positive z-index children must also be compositing.
730 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, RenderGeometryMap* geometryMap, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged)
732 layer->updateLayerListsIfNeeded();
734 // Should geometryMap be part of the overlap map?
736 geometryMap->pushMappingsToAncestor(layer->renderer(), ancestorLayer ? ancestorLayer->renderer() : 0);
739 layer->setHasCompositingDescendant(false);
741 bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing;
743 bool haveComputedBounds = false;
745 if (overlapMap && !overlapMap->isEmpty() && compositingState.m_testingOverlap) {
746 // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
747 absBounds = enclosingIntRect(geometryMap->absoluteRect(layer->localBoundingBox()));
749 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
750 if (absBounds.isEmpty())
751 absBounds.setSize(IntSize(1, 1));
752 haveComputedBounds = true;
753 mustOverlapCompositedLayers = overlapMap->overlapsLayers(absBounds);
756 layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
758 // The children of this layer don't need to composite, unless there is
759 // a compositing layer among them, so start by inheriting the compositing
760 // ancestor with m_subtreeIsCompositing set to false.
761 CompositingState childState(compositingState);
762 childState.m_subtreeIsCompositing = false;
764 bool willBeComposited = needsToBeComposited(layer);
765 if (willBeComposited) {
766 // Tell the parent it has compositing descendants.
767 compositingState.m_subtreeIsCompositing = true;
768 // This layer now acts as the ancestor for kids.
769 childState.m_compositingAncestor = layer;
772 overlapMap->pushCompositingContainer();
774 if (hasNonAffineTransform(layer->renderer()) || isRunningAcceleratedTransformAnimation(layer->renderer())) {
775 // If we have a 3D transform, or are animating transform, then turn overlap testing off.
776 childState.m_testingOverlap = false;
781 // Video is special. It's a replaced element with a content layer, but has shadow content
782 // for the controller that must render in front. Without this, the controls fail to show
783 // when the video element is a stacking context (e.g. due to opacity or transform).
784 if (willBeComposited && layer->renderer()->isVideo())
785 childState.m_subtreeIsCompositing = true;
789 LayerListMutationDetector mutationChecker(layer);
792 if (layer->isStackingContext()) {
793 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
794 size_t listSize = negZOrderList->size();
795 for (size_t i = 0; i < listSize; ++i) {
796 RenderLayer* curLayer = negZOrderList->at(i);
797 computeCompositingRequirements(layer, curLayer, geometryMap, overlapMap, childState, layersChanged);
799 // If we have to make a layer for this child, make one now so we can have a contents layer
800 // (since we need to ensure that the -ve z-order child renders underneath our contents).
801 if (!willBeComposited && childState.m_subtreeIsCompositing) {
802 // make layer compositing
803 layer->setMustOverlapCompositedLayers(true);
804 childState.m_compositingAncestor = layer;
806 overlapMap->pushCompositingContainer();
807 willBeComposited = true;
813 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
814 size_t listSize = normalFlowList->size();
815 for (size_t i = 0; i < listSize; ++i) {
816 RenderLayer* curLayer = normalFlowList->at(i);
817 computeCompositingRequirements(layer, curLayer, geometryMap, overlapMap, childState, layersChanged);
821 if (layer->isStackingContext()) {
822 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
823 size_t listSize = posZOrderList->size();
824 for (size_t i = 0; i < listSize; ++i) {
825 RenderLayer* curLayer = posZOrderList->at(i);
826 computeCompositingRequirements(layer, curLayer, geometryMap, overlapMap, childState, layersChanged);
831 // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
832 if (layer->isRootLayer()) {
833 if (inCompositingMode() && m_hasAcceleratedCompositing)
834 willBeComposited = true;
837 ASSERT(willBeComposited == needsToBeComposited(layer));
839 // All layers (even ones that aren't being composited) need to get added to
840 // the overlap map. Layers that do not composite will draw into their
841 // compositing ancestor's backing, and so are still considered for overlap.
842 if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer())
843 addToOverlapMap(*geometryMap, *overlapMap, layer, absBounds, haveComputedBounds);
845 // If we have a software transform, and we have layers under us, we need to also
846 // be composited. Also, if we have opacity < 1, then we need to be a layer so that
847 // the child layers are opaque, then rendered with opacity on this layer.
848 if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
849 layer->setMustOverlapCompositedLayers(true);
850 childState.m_compositingAncestor = layer;
852 overlapMap->pushCompositingContainer();
853 addToOverlapMapRecursive(*geometryMap, *overlapMap, layer);
855 willBeComposited = true;
858 ASSERT(willBeComposited == needsToBeComposited(layer));
859 if (layer->reflectionLayer()) {
860 // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
861 layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
864 // Subsequent layers in the parent stacking context also need to composite.
865 if (childState.m_subtreeIsCompositing)
866 compositingState.m_subtreeIsCompositing = true;
868 // We have to keep overlap testing disabled for later layers.
869 if (!childState.m_testingOverlap)
870 compositingState.m_testingOverlap = false;
872 // Set the flag to say that this SC has compositing children.
873 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
875 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
876 // so test that again.
877 if (canBeComposited(layer) && clipsCompositingDescendants(layer)) {
878 if (!willBeComposited) {
879 childState.m_compositingAncestor = layer;
881 overlapMap->pushCompositingContainer();
882 addToOverlapMapRecursive(*geometryMap, *overlapMap, layer);
884 willBeComposited = true;
887 // We're done processing an element that clips. The container can keep testing overlap.
888 compositingState.m_testingOverlap = true;
891 if (overlapMap && childState.m_compositingAncestor == layer && !layer->isRootLayer())
892 overlapMap->popCompositingContainer();
894 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
895 // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
896 // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
897 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) {
898 enableCompositingMode(false);
899 willBeComposited = false;
902 // If the layer is going into compositing mode, repaint its old location.
903 ASSERT(willBeComposited == needsToBeComposited(layer));
904 if (!layer->isComposited() && willBeComposited)
905 repaintOnCompositingChange(layer);
907 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
908 if (updateBacking(layer, CompositingChangeRepaintNow))
909 layersChanged = true;
911 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
912 layersChanged = true;
915 geometryMap->popMappingsToAncestor(ancestorLayer ? ancestorLayer->renderer() : 0);
918 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
920 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
921 ASSERT(childLayer->isComposited());
923 // It's possible to be called with a parent that isn't yet composited when we're doing
924 // partial updates as required by painting or hit testing. Just bail in that case;
925 // we'll do a full layer update soon.
926 if (!parentLayer || !parentLayer->isComposited())
930 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
931 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers();
933 hostingLayer->addChild(hostedLayer);
935 childLayer->backing()->childForSuperlayers()->removeFromParent();
938 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
940 ASSERT(layer->isComposited());
942 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers();
943 hostingLayer->removeAllChildren();
947 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
949 if (!m_hasAcceleratedCompositing)
952 return o->supportsAcceleratedRendering();
956 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
958 // Make the layer compositing if necessary, and set up clipping and content layers.
959 // Note that we can only do work here that is independent of whether the descendant layers
960 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
962 RenderLayerBacking* layerBacking = layer->backing();
964 // The compositing state of all our children has been updated already, so now
965 // we can compute and cache the composited bounds for this layer.
966 layerBacking->updateCompositedBounds();
968 if (RenderLayer* reflection = layer->reflectionLayer()) {
969 if (reflection->backing())
970 reflection->backing()->updateCompositedBounds();
973 layerBacking->updateGraphicsLayerConfiguration();
974 layerBacking->updateGraphicsLayerGeometry();
976 if (!layer->parent())
977 updateRootLayerPosition();
980 logLayerInfo(layer, depth);
986 // If this layer has backing, then we are collecting its children, otherwise appending
987 // to the compositing child list of an enclosing layer.
988 Vector<GraphicsLayer*> layerChildren;
989 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
992 LayerListMutationDetector mutationChecker(layer);
995 if (layer->isStackingContext()) {
996 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
997 size_t listSize = negZOrderList->size();
998 for (size_t i = 0; i < listSize; ++i) {
999 RenderLayer* curLayer = negZOrderList->at(i);
1000 rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1004 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
1005 if (layerBacking && layerBacking->foregroundLayer())
1006 childList.append(layerBacking->foregroundLayer());
1009 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1010 size_t listSize = normalFlowList->size();
1011 for (size_t i = 0; i < listSize; ++i) {
1012 RenderLayer* curLayer = normalFlowList->at(i);
1013 rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1017 if (layer->isStackingContext()) {
1018 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1019 size_t listSize = posZOrderList->size();
1020 for (size_t i = 0; i < listSize; ++i) {
1021 RenderLayer* curLayer = posZOrderList->at(i);
1022 rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1028 bool parented = false;
1029 if (layer->renderer()->isRenderPart())
1030 parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
1032 #if !ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1034 layerBacking->parentForSublayers()->setChildren(layerChildren);
1037 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
1038 // Otherwise, the overflow control layers are normal children.
1039 if (!layerBacking->hasClippingLayer()) {
1040 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) {
1041 overflowControlLayer->removeFromParent();
1042 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1043 layerChildren.append(overflowControlLayer);
1045 layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1049 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) {
1050 overflowControlLayer->removeFromParent();
1051 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1052 layerChildren.append(overflowControlLayer);
1054 layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1058 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) {
1059 overflowControlLayer->removeFromParent();
1060 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1061 layerChildren.append(overflowControlLayer);
1063 layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1068 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1070 layerBacking->parentForSublayers()->setChildren(layerChildren);
1073 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
1077 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
1079 if (m_overflowControlsHostLayer)
1080 m_overflowControlsHostLayer->setPosition(contentsOffset);
1083 void RenderLayerCompositor::frameViewDidChangeSize()
1086 FrameView* frameView = m_renderView->frameView();
1087 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1089 frameViewDidScroll();
1090 updateOverflowControlsLayers();
1092 #if ENABLE(RUBBER_BANDING)
1093 if (m_layerForOverhangAreas)
1094 m_layerForOverhangAreas->setSize(frameView->frameRect().size());
1099 void RenderLayerCompositor::frameViewDidScroll()
1101 FrameView* frameView = m_renderView->frameView();
1102 IntPoint scrollPosition = frameView->scrollPosition();
1104 if (TiledBacking* tiledBacking = frameView->tiledBacking()) {
1105 IntRect visibleContentRect = frameView->visibleContentRect(false /* exclude scrollbars */);
1106 visibleContentRect.move(toSize(frameView->scrollOrigin()));
1107 tiledBacking->visibleRectChanged(visibleContentRect);
1113 // If there's a scrolling coordinator that manages scrolling for this frame view,
1114 // it will also manage updating the scroll layer position.
1115 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
1116 if (scrollingCoordinator->coordinatesScrollingForFrameView(frameView))
1120 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
1123 String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo)
1125 updateCompositingLayers(CompositingUpdateAfterLayout);
1127 if (!m_rootContentLayer)
1130 // We skip dumping the scroll and clip layers to keep layerTreeAsText output
1131 // similar between platforms.
1132 return m_rootContentLayer->layerTreeAsText(showDebugInfo ? LayerTreeAsTextDebug : LayerTreeAsTextBehaviorNormal);
1135 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
1137 if (!renderer->node()->isFrameOwnerElement())
1140 HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(renderer->node());
1141 if (Document* contentDocument = element->contentDocument()) {
1142 if (RenderView* view = contentDocument->renderView())
1143 return view->compositor();
1148 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
1150 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
1151 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
1154 RenderLayer* layer = renderer->layer();
1155 if (!layer->isComposited())
1158 RenderLayerBacking* backing = layer->backing();
1159 GraphicsLayer* hostingLayer = backing->parentForSublayers();
1160 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
1161 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
1162 hostingLayer->removeAllChildren();
1163 hostingLayer->addChild(rootLayer);
1168 // This just updates layer geometry without changing the hierarchy.
1169 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer, int depth)
1171 if (RenderLayerBacking* layerBacking = layer->backing()) {
1172 // The compositing state of all our children has been updated already, so now
1173 // we can compute and cache the composited bounds for this layer.
1174 layerBacking->updateCompositedBounds();
1176 if (RenderLayer* reflection = layer->reflectionLayer()) {
1177 if (reflection->backing())
1178 reflection->backing()->updateCompositedBounds();
1181 layerBacking->updateGraphicsLayerConfiguration();
1182 layerBacking->updateGraphicsLayerGeometry();
1184 if (!layer->parent())
1185 updateRootLayerPosition();
1188 logLayerInfo(layer, depth);
1190 UNUSED_PARAM(depth);
1194 #if !ASSERT_DISABLED
1195 LayerListMutationDetector mutationChecker(layer);
1198 if (layer->isStackingContext()) {
1199 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1200 size_t listSize = negZOrderList->size();
1201 for (size_t i = 0; i < listSize; ++i)
1202 updateLayerTreeGeometry(negZOrderList->at(i), depth + 1);
1206 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1207 size_t listSize = normalFlowList->size();
1208 for (size_t i = 0; i < listSize; ++i)
1209 updateLayerTreeGeometry(normalFlowList->at(i), depth + 1);
1212 if (layer->isStackingContext()) {
1213 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1214 size_t listSize = posZOrderList->size();
1215 for (size_t i = 0; i < listSize; ++i)
1216 updateLayerTreeGeometry(posZOrderList->at(i), depth + 1);
1221 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
1222 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth)
1224 if (layer != compositingAncestor) {
1225 if (RenderLayerBacking* layerBacking = layer->backing()) {
1226 layerBacking->updateCompositedBounds();
1228 if (RenderLayer* reflection = layer->reflectionLayer()) {
1229 if (reflection->backing())
1230 reflection->backing()->updateCompositedBounds();
1233 layerBacking->updateGraphicsLayerGeometry();
1234 if (updateDepth == RenderLayerBacking::CompositingChildren)
1239 if (layer->reflectionLayer())
1240 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth);
1242 if (!layer->hasCompositingDescendant())
1245 #if !ASSERT_DISABLED
1246 LayerListMutationDetector mutationChecker(layer);
1249 if (layer->isStackingContext()) {
1250 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1251 size_t listSize = negZOrderList->size();
1252 for (size_t i = 0; i < listSize; ++i)
1253 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth);
1257 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1258 size_t listSize = normalFlowList->size();
1259 for (size_t i = 0; i < listSize; ++i)
1260 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth);
1263 if (layer->isStackingContext()) {
1264 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1265 size_t listSize = posZOrderList->size();
1266 for (size_t i = 0; i < listSize; ++i)
1267 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth);
1273 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect)
1275 recursiveRepaintLayerRect(rootRenderLayer(), absRect);
1278 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
1280 // FIXME: This method does not work correctly with transforms.
1281 if (layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor())
1282 layer->setBackingNeedsRepaintInRect(rect);
1284 #if !ASSERT_DISABLED
1285 LayerListMutationDetector mutationChecker(layer);
1288 if (layer->hasCompositingDescendant()) {
1289 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1290 size_t listSize = negZOrderList->size();
1291 for (size_t i = 0; i < listSize; ++i) {
1292 RenderLayer* curLayer = negZOrderList->at(i);
1293 IntRect childRect(rect);
1294 curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
1295 recursiveRepaintLayerRect(curLayer, childRect);
1299 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1300 size_t listSize = posZOrderList->size();
1301 for (size_t i = 0; i < listSize; ++i) {
1302 RenderLayer* curLayer = posZOrderList->at(i);
1303 IntRect childRect(rect);
1304 curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
1305 recursiveRepaintLayerRect(curLayer, childRect);
1309 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1310 size_t listSize = normalFlowList->size();
1311 for (size_t i = 0; i < listSize; ++i) {
1312 RenderLayer* curLayer = normalFlowList->at(i);
1313 IntRect childRect(rect);
1314 curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
1315 recursiveRepaintLayerRect(curLayer, childRect);
1320 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
1322 return m_renderView->layer();
1325 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
1327 if (m_overflowControlsHostLayer)
1328 return m_overflowControlsHostLayer.get();
1329 return m_rootContentLayer.get();
1332 GraphicsLayer* RenderLayerCompositor::scrollLayer() const
1334 return m_scrollLayer.get();
1337 void RenderLayerCompositor::didMoveOnscreen()
1339 if (!inCompositingMode() || m_rootLayerAttachment != RootLayerUnattached)
1342 RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1343 attachRootLayer(attachment);
1345 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1346 registerAllScrollingLayers();
1350 void RenderLayerCompositor::willMoveOffscreen()
1352 if (!inCompositingMode() || m_rootLayerAttachment == RootLayerUnattached)
1356 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1357 unregisterAllScrollingLayers();
1361 void RenderLayerCompositor::clearBackingForLayerIncludingDescendants(RenderLayer* layer)
1366 if (layer->isComposited())
1367 layer->clearBacking();
1369 for (RenderLayer* currLayer = layer->firstChild(); currLayer; currLayer = currLayer->nextSibling())
1370 clearBackingForLayerIncludingDescendants(currLayer);
1373 void RenderLayerCompositor::clearBackingForAllLayers()
1375 clearBackingForLayerIncludingDescendants(m_renderView->layer());
1378 void RenderLayerCompositor::updateRootLayerPosition()
1380 if (m_rootContentLayer) {
1381 const IntRect& documentRect = m_renderView->documentRect();
1382 m_rootContentLayer->setSize(documentRect.size());
1383 m_rootContentLayer->setPosition(documentRect.location());
1386 FrameView* frameView = m_renderView->frameView();
1387 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1390 #if ENABLE(RUBBER_BANDING)
1391 if (m_contentShadowLayer) {
1392 m_contentShadowLayer->setPosition(m_rootContentLayer->position());
1394 FloatSize rootContentLayerSize = m_rootContentLayer->size();
1395 if (m_contentShadowLayer->size() != rootContentLayerSize) {
1396 m_contentShadowLayer->setSize(rootContentLayerSize);
1397 ScrollbarTheme::theme()->setUpContentShadowLayer(m_contentShadowLayer.get());
1403 bool RenderLayerCompositor::has3DContent() const
1405 return layerHas3DContent(rootRenderLayer());
1408 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)
1411 // frames are only independently composited in Mac pre-WebKit2.
1412 return view->platformWidget();
1417 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const
1419 // Parent document content needs to be able to render on top of a composited frame, so correct behavior
1420 // is to have the parent document become composited too. However, this can cause problems on platforms that
1421 // use native views for frames (like Mac), so disable that behavior on those platforms for now.
1422 HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement();
1423 RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0;
1425 // If we are the top-level frame, don't propagate.
1429 if (!allowsIndependentlyCompositedFrames(m_renderView->frameView()))
1432 if (!renderer || !renderer->isRenderPart())
1435 // On Mac, only propagate compositing if the frame is overlapped in the parent
1436 // document, or the parent is already compositing, or the main frame is scaled.
1437 Frame* frame = m_renderView->frameView()->frame();
1438 Page* page = frame ? frame->page() : 0;
1439 if (page && page->pageScaleFactor() != 1)
1442 RenderPart* frameRenderer = toRenderPart(renderer);
1443 if (frameRenderer->widget()) {
1444 ASSERT(frameRenderer->widget()->isFrameView());
1445 FrameView* view = static_cast<FrameView*>(frameRenderer->widget());
1446 if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor())
1453 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
1455 if (!canBeComposited(layer))
1458 return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
1461 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
1462 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
1464 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
1466 RenderObject* renderer = layer->renderer();
1467 // The compositing state of a reflection should match that of its reflected layer.
1468 if (layer->isReflection()) {
1469 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
1470 layer = toRenderBoxModelObject(renderer)->layer();
1472 // The root layer always has a compositing layer, but it may not have backing.
1473 return requiresCompositingForTransform(renderer)
1474 || requiresCompositingForVideo(renderer)
1475 || requiresCompositingForCanvas(renderer)
1476 || requiresCompositingForPlugin(renderer)
1477 || requiresCompositingForFrame(renderer)
1478 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1479 || clipsCompositingDescendants(layer)
1480 || requiresCompositingForAnimation(renderer)
1481 || requiresCompositingForFilters(renderer)
1482 || requiresCompositingForPosition(renderer, layer)
1483 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1484 || requiresCompositingForScrolling(renderer)
1489 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
1491 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
1492 // See http://webkit.org/b/84900 to re-enable it.
1493 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->renderer()->inRenderFlowThread();
1496 bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer* layer, const RenderLayer* compositingAncestorLayer) const
1498 RenderObject* renderer = layer->renderer();
1499 if (compositingAncestorLayer
1500 && !(compositingAncestorLayer->backing()->graphicsLayer()->drawsContent()
1501 || compositingAncestorLayer->backing()->paintsIntoWindow()
1502 || compositingAncestorLayer->backing()->paintsIntoCompositedAncestor()))
1505 return layer->isRootLayer()
1506 || layer->transform() // note: excludes perspective and transformStyle3D.
1507 || requiresCompositingForVideo(renderer)
1508 || requiresCompositingForCanvas(renderer)
1509 || requiresCompositingForPlugin(renderer)
1510 || requiresCompositingForFrame(renderer)
1511 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1512 || requiresCompositingForAnimation(renderer)
1513 || requiresCompositingForFilters(renderer)
1514 || requiresCompositingForPosition(renderer, layer)
1515 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1516 || requiresCompositingForScrolling(renderer)
1518 || renderer->isTransparent()
1519 || renderer->hasMask()
1520 || renderer->hasReflection()
1521 || renderer->hasFilter()
1522 || layer->mustOverlapCompositedLayers();
1526 const char* RenderLayerCompositor::reasonForCompositing(const RenderLayer* layer)
1528 RenderObject* renderer = layer->renderer();
1529 if (layer->isReflection()) {
1530 renderer = renderer->parent();
1531 layer = toRenderBoxModelObject(renderer)->layer();
1534 if (renderer->hasTransform() && renderer->style()->hasPerspective())
1535 return "perspective";
1537 if (renderer->hasTransform() && (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D))
1538 return "preserve-3d";
1540 if (renderer->hasTransform())
1543 if (requiresCompositingForVideo(renderer))
1546 if (requiresCompositingForCanvas(renderer))
1549 if (requiresCompositingForPlugin(renderer))
1552 if (requiresCompositingForFrame(renderer))
1555 if ((canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden))
1556 return "backface-visibility: hidden";
1558 if (clipsCompositingDescendants(layer))
1559 return "clips compositing descendants";
1561 if (requiresCompositingForAnimation(renderer))
1564 if (requiresCompositingForFilters(renderer))
1567 if (requiresCompositingForPosition(renderer, layer))
1568 return "position: fixed";
1570 // This includes layers made composited by requiresCompositingWhenDescendantsAreCompositing().
1571 if (layer->mustOverlapCompositedLayers())
1572 return "overlap/stacking";
1574 if (inCompositingMode() && layer->isRootLayer())
1581 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1582 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1583 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1584 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1585 // but a sibling in the z-order hierarchy.
1586 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
1588 if (!layer->isComposited() || !layer->parent())
1591 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1592 if (!compositingAncestor)
1595 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
1596 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
1598 RenderLayer* computeClipRoot = 0;
1599 RenderLayer* curr = layer;
1601 RenderLayer* next = curr->parent();
1602 if (next == compositingAncestor) {
1603 computeClipRoot = curr;
1609 if (!computeClipRoot || computeClipRoot == layer)
1612 return layer->backgroundClipRect(computeClipRoot, 0, TemporaryClipRects).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
1615 // Return true if the given layer is a stacking context and has compositing child
1616 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1617 // into the hierarchy between this layer and its children in the z-order hierarchy.
1618 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1620 return layer->hasCompositingDescendant() &&
1621 (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip());
1624 bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
1626 // Need this done first to determine overflow.
1627 ASSERT(!m_renderView->needsLayout());
1629 ScrollView* scrollView = m_renderView->frameView();
1630 return scrollView->verticalScrollbar() || scrollView->horizontalScrollbar();
1633 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
1635 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
1638 RenderStyle* style = renderer->style();
1639 // Note that we ask the renderer if it has a transform, because the style may have transforms,
1640 // but the renderer may be an inline that doesn't suppport them.
1641 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
1644 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
1646 if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
1649 if (renderer->isVideo()) {
1650 RenderVideo* video = toRenderVideo(renderer);
1651 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
1653 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1654 else if (renderer->isRenderPart()) {
1655 if (!m_hasAcceleratedCompositing)
1658 Node* node = renderer->node();
1659 if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag)))
1662 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node);
1663 return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false;
1665 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1667 UNUSED_PARAM(renderer);
1672 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
1674 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
1677 if (renderer->isCanvas()) {
1678 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
1679 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
1684 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
1686 if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
1689 bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
1690 || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing());
1694 m_reevaluateCompositingAfterLayout = true;
1696 RenderWidget* pluginRenderer = toRenderWidget(renderer);
1697 // If we can't reliably know the size of the plugin yet, don't change compositing state.
1698 if (pluginRenderer->needsLayout())
1699 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited();
1701 // Don't go into compositing mode if height or width are zero, or size is 1x1.
1702 IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect());
1703 return contentBox.height() * contentBox.width() > 1;
1706 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
1708 if (!renderer->isRenderPart())
1711 RenderPart* frameRenderer = toRenderPart(renderer);
1713 if (!frameRenderer->requiresAcceleratedCompositing())
1716 m_reevaluateCompositingAfterLayout = true;
1718 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
1719 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())
1722 // If we can't reliably know the size of the iframe yet, don't change compositing state.
1723 if (renderer->needsLayout())
1724 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited();
1726 // Don't go into compositing mode if height or width are zero.
1727 IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect());
1728 return contentBox.height() * contentBox.width() > 0;
1731 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
1733 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1736 if (AnimationController* animController = renderer->animation()) {
1737 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
1738 #if ENABLE(CSS_FILTERS)
1739 #if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION)
1740 // <rdar://problem/10907251> - WebKit2 doesn't support CA animations of CI filters on Lion and below
1741 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitFilter)
1742 #endif // !SNOW_LEOPARD && !LION
1743 #endif // CSS_FILTERS
1744 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1749 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
1751 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection() || renderer->hasFilter();
1754 bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const
1756 #if ENABLE(CSS_FILTERS)
1757 if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
1760 return renderer->hasFilter();
1762 UNUSED_PARAM(renderer);
1767 bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer) const
1769 // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
1770 // opacity, transform) can get their own composited layer. A stacking context is required otherwise
1771 // z-index and clipping will be broken.
1772 if (!(renderer->isPositioned() && renderer->style()->position() == FixedPosition && layer->isStackingContext()))
1775 if (Settings* settings = m_renderView->document()->settings())
1776 if (!settings->acceleratedCompositingForFixedPositionEnabled())
1779 RenderObject* container = renderer->container();
1780 // If the renderer is not hooked up yet then we have to wait until it is.
1782 m_reevaluateCompositingAfterLayout = true;
1786 // Don't promote fixed position elements that are descendants of transformed elements.
1787 // They will stay fixed wrt the transformed element rather than the enclosing frame.
1788 if (container != m_renderView)
1791 // Fixed position elements that are invisible in the current view don't get their own layer.
1792 FrameView* frameView = m_renderView->frameView();
1793 if (frameView && !layer->absoluteBoundingBox().intersects(IntRect(frameView->scrollXForFixedPosition(), frameView->scrollYForFixedPosition(), frameView->layoutWidth(), frameView->layoutHeight())))
1799 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1800 bool RenderLayerCompositor::requiresCompositingForScrolling(RenderObject* renderer) const
1802 return renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->hasAcceleratedTouchScrolling();
1807 bool RenderLayerCompositor::hasNonAffineTransform(RenderObject* renderer) const
1809 if (!renderer->hasTransform())
1812 if (TransformationMatrix* transform = toRenderBoxModelObject(renderer)->layer()->transform())
1813 return !transform->isAffine();
1818 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const
1820 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1823 if (AnimationController* animController = renderer->animation())
1824 return animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1829 // If an element has negative z-index children, those children render in front of the
1830 // layer background, so we need an extra 'contents' layer for the foreground of the layer
1832 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
1834 return layer->hasNegativeZOrderList();
1837 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
1839 // This applies when the application UI handles scrolling, in which case RenderLayerCompositor doesn't need to manage it.
1840 if (m_renderView->frameView()->delegatesScrolling())
1843 // We need to handle our own scrolling if we're:
1844 return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
1845 || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
1848 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1854 const IntRect& scrollbarRect = scrollbar->frameRect();
1855 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1856 IntRect transformedClip = clip;
1857 transformedClip.moveBy(scrollbarRect.location());
1858 scrollbar->paint(&context, transformedClip);
1862 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
1864 if (graphicsLayer == layerForHorizontalScrollbar())
1865 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
1866 else if (graphicsLayer == layerForVerticalScrollbar())
1867 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
1868 else if (graphicsLayer == layerForScrollCorner()) {
1869 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
1871 context.translate(-scrollCorner.x(), -scrollCorner.y());
1872 IntRect transformedClip = clip;
1873 transformedClip.moveBy(scrollCorner.location());
1874 m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
1876 #if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
1877 } else if (graphicsLayer == layerForOverhangAreas()) {
1878 ScrollView* view = m_renderView->frameView();
1879 view->calculateAndPaintOverhangAreas(&context, clip);
1884 void RenderLayerCompositor::documentBackgroundColorDidChange()
1886 RenderLayerBacking* backing = rootRenderLayer()->backing();
1890 GraphicsLayer* graphicsLayer = backing->graphicsLayer();
1891 if (!graphicsLayer->client()->shouldUseTileCache(graphicsLayer))
1894 Color backgroundColor = m_renderView->frameView()->documentBackgroundColor();
1895 if (!backgroundColor.isValid() || backgroundColor.hasAlpha())
1896 backgroundColor = Color::white;
1898 graphicsLayer->setBackgroundColor(backgroundColor);
1901 bool RenderLayerCompositor::showDebugBorders(const GraphicsLayer* layer) const
1903 if (layer == m_layerForHorizontalScrollbar || layer == m_layerForVerticalScrollbar || layer == m_layerForScrollCorner)
1904 return m_showDebugBorders;
1909 bool RenderLayerCompositor::showRepaintCounter(const GraphicsLayer* layer) const
1911 if (layer == m_layerForHorizontalScrollbar || layer == m_layerForVerticalScrollbar || layer == m_layerForScrollCorner)
1912 return m_showDebugBorders;
1917 float RenderLayerCompositor::deviceScaleFactor() const
1919 Frame* frame = m_renderView->frameView()->frame();
1922 Page* page = frame->page();
1925 return page->deviceScaleFactor();
1928 float RenderLayerCompositor::pageScaleFactor() const
1930 Frame* frame = m_renderView->frameView()->frame();
1933 Page* page = frame->page();
1936 return page->pageScaleFactor();
1939 void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const
1941 // Nothing to do here yet.
1944 bool RenderLayerCompositor::keepLayersPixelAligned() const
1946 // When scaling, attempt to align compositing layers to pixel boundaries.
1950 static bool shouldCompositeOverflowControls(FrameView* view)
1952 if (view->platformWidget())
1955 if (Page* page = view->frame()->page()) {
1956 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1957 if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
1961 #if !PLATFORM(CHROMIUM)
1962 if (!view->hasOverlayScrollbars())
1968 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
1970 FrameView* view = m_renderView->frameView();
1971 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
1974 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
1976 FrameView* view = m_renderView->frameView();
1977 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
1980 bool RenderLayerCompositor::requiresScrollCornerLayer() const
1982 FrameView* view = m_renderView->frameView();
1983 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
1986 #if ENABLE(RUBBER_BANDING)
1987 bool RenderLayerCompositor::requiresOverhangAreasLayer() const
1989 // We don't want a layer if this is a subframe.
1990 if (m_renderView->document()->ownerElement())
1993 // We do want a layer if we have a scrolling coordinator.
1994 if (scrollingCoordinator())
1997 // Chromium always wants a layer.
1998 #if PLATFORM(CHROMIUM)
2005 bool RenderLayerCompositor::requiresContentShadowLayer() const
2007 // We don't want a layer if this is a subframe.
2008 if (m_renderView->document()->ownerElement())
2012 // On Mac, we want a content shadow layer if we have a scrolling coordinator.
2013 if (scrollingCoordinator())
2021 void RenderLayerCompositor::updateOverflowControlsLayers()
2023 #if ENABLE(RUBBER_BANDING)
2024 if (requiresOverhangAreasLayer()) {
2025 if (!m_layerForOverhangAreas) {
2026 m_layerForOverhangAreas = GraphicsLayer::create(this);
2028 m_layerForOverhangAreas->setName("overhang areas");
2030 m_layerForOverhangAreas->setDrawsContent(false);
2031 m_layerForOverhangAreas->setSize(m_renderView->frameView()->frameRect().size());
2033 ScrollbarTheme::theme()->setUpOverhangAreasLayerContents(m_layerForOverhangAreas.get());
2035 // We want the overhang areas layer to be positioned below the frame contents,
2036 // so insert it below the clip layer.
2037 m_overflowControlsHostLayer->addChildBelow(m_layerForOverhangAreas.get(), m_clipLayer.get());
2039 } else if (m_layerForOverhangAreas) {
2040 m_layerForOverhangAreas->removeFromParent();
2041 m_layerForOverhangAreas = nullptr;
2044 if (requiresContentShadowLayer()) {
2045 if (!m_contentShadowLayer) {
2046 m_contentShadowLayer = GraphicsLayer::create(this);
2048 m_contentShadowLayer->setName("content shadow");
2050 m_contentShadowLayer->setSize(m_rootContentLayer->size());
2051 m_contentShadowLayer->setPosition(m_rootContentLayer->position());
2052 ScrollbarTheme::theme()->setUpContentShadowLayer(m_contentShadowLayer.get());
2054 m_scrollLayer->addChildBelow(m_contentShadowLayer.get(), m_rootContentLayer.get());
2056 } else if (m_contentShadowLayer) {
2057 m_contentShadowLayer->removeFromParent();
2058 m_contentShadowLayer = nullptr;
2062 if (requiresHorizontalScrollbarLayer()) {
2063 if (!m_layerForHorizontalScrollbar) {
2064 m_layerForHorizontalScrollbar = GraphicsLayer::create(this);
2066 m_layerForHorizontalScrollbar->setName("horizontal scrollbar");
2068 #if PLATFORM(MAC) && USE(CA)
2069 m_layerForHorizontalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
2071 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
2073 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2074 scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForHorizontalScrollbar.get());
2076 } else if (m_layerForHorizontalScrollbar) {
2077 m_layerForHorizontalScrollbar->removeFromParent();
2078 m_layerForHorizontalScrollbar = nullptr;
2080 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2081 scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), 0);
2084 if (requiresVerticalScrollbarLayer()) {
2085 if (!m_layerForVerticalScrollbar) {
2086 m_layerForVerticalScrollbar = GraphicsLayer::create(this);
2088 m_layerForVerticalScrollbar->setName("vertical scrollbar");
2090 #if PLATFORM(MAC) && USE(CA)
2091 m_layerForVerticalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
2093 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
2095 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2096 scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForVerticalScrollbar.get());
2098 } else if (m_layerForVerticalScrollbar) {
2099 m_layerForVerticalScrollbar->removeFromParent();
2100 m_layerForVerticalScrollbar = nullptr;
2102 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2103 scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), 0);
2106 if (requiresScrollCornerLayer()) {
2107 if (!m_layerForScrollCorner) {
2108 m_layerForScrollCorner = GraphicsLayer::create(this);
2110 m_layerForScrollCorner->setName("scroll corner");
2112 #if PLATFORM(MAC) && USE(CA)
2113 m_layerForScrollCorner->setAcceleratesDrawing(acceleratedDrawingEnabled());
2115 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
2117 } else if (m_layerForScrollCorner) {
2118 m_layerForScrollCorner->removeFromParent();
2119 m_layerForScrollCorner = nullptr;
2122 m_renderView->frameView()->positionScrollbarLayers();
2125 void RenderLayerCompositor::ensureRootLayer()
2127 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
2128 if (expectedAttachment == m_rootLayerAttachment)
2131 if (!m_rootContentLayer) {
2132 m_rootContentLayer = GraphicsLayer::create(this);
2134 m_rootContentLayer->setName("content root");
2136 IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect();
2137 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
2138 m_rootContentLayer->setPosition(FloatPoint());
2140 // Need to clip to prevent transformed content showing outside this frame
2141 m_rootContentLayer->setMasksToBounds(true);
2144 if (requiresScrollLayer(expectedAttachment)) {
2145 if (!m_overflowControlsHostLayer) {
2146 ASSERT(!m_scrollLayer);
2147 ASSERT(!m_clipLayer);
2149 // Create a layer to host the clipping layer and the overflow controls layers.
2150 m_overflowControlsHostLayer = GraphicsLayer::create(this);
2152 m_overflowControlsHostLayer->setName("overflow controls host");
2155 // Create a clipping layer if this is an iframe
2156 m_clipLayer = GraphicsLayer::create(this);
2158 m_clipLayer->setName("frame clipping");
2160 m_clipLayer->setMasksToBounds(true);
2162 m_scrollLayer = GraphicsLayer::create(this);
2164 m_scrollLayer->setName("frame scrolling");
2168 m_overflowControlsHostLayer->addChild(m_clipLayer.get());
2169 m_clipLayer->addChild(m_scrollLayer.get());
2170 m_scrollLayer->addChild(m_rootContentLayer.get());
2172 frameViewDidChangeSize();
2173 frameViewDidScroll();
2176 if (m_overflowControlsHostLayer) {
2177 m_overflowControlsHostLayer = nullptr;
2178 m_clipLayer = nullptr;
2179 m_scrollLayer = nullptr;
2183 // Check to see if we have to change the attachment
2184 if (m_rootLayerAttachment != RootLayerUnattached)
2187 attachRootLayer(expectedAttachment);
2190 void RenderLayerCompositor::destroyRootLayer()
2192 if (!m_rootContentLayer)
2197 #if ENABLE(RUBBER_BANDING)
2198 if (m_layerForOverhangAreas) {
2199 m_layerForOverhangAreas->removeFromParent();
2200 m_layerForOverhangAreas = nullptr;
2204 if (m_layerForHorizontalScrollbar) {
2205 m_layerForHorizontalScrollbar->removeFromParent();
2206 m_layerForHorizontalScrollbar = nullptr;
2207 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
2208 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
2211 if (m_layerForVerticalScrollbar) {
2212 m_layerForVerticalScrollbar->removeFromParent();
2213 m_layerForVerticalScrollbar = nullptr;
2214 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
2215 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
2218 if (m_layerForScrollCorner) {
2219 m_layerForScrollCorner = nullptr;
2220 m_renderView->frameView()->invalidateScrollCorner(m_renderView->frameView()->scrollCornerRect());
2223 if (m_overflowControlsHostLayer) {
2224 m_overflowControlsHostLayer = nullptr;
2225 m_clipLayer = nullptr;
2226 m_scrollLayer = nullptr;
2228 ASSERT(!m_scrollLayer);
2229 m_rootContentLayer = nullptr;
2232 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
2234 if (!m_rootContentLayer)
2237 switch (attachment) {
2238 case RootLayerUnattached:
2239 ASSERT_NOT_REACHED();
2241 case RootLayerAttachedViaChromeClient: {
2242 Frame* frame = m_renderView->frameView()->frame();
2243 Page* page = frame ? frame->page() : 0;
2247 page->chrome()->client()->attachRootGraphicsLayer(frame, rootGraphicsLayer());
2250 case RootLayerAttachedViaEnclosingFrame: {
2251 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
2252 // for the frame's renderer in the parent document.
2253 m_renderView->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2258 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2259 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
2261 m_rootLayerAttachment = attachment;
2262 rootLayerAttachmentChanged();
2265 void RenderLayerCompositor::detachRootLayer()
2267 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
2270 switch (m_rootLayerAttachment) {
2271 case RootLayerAttachedViaEnclosingFrame: {
2272 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
2273 // for the frame's renderer in the parent document.
2274 if (m_overflowControlsHostLayer)
2275 m_overflowControlsHostLayer->removeFromParent();
2277 m_rootContentLayer->removeFromParent();
2279 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
2280 ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2283 case RootLayerAttachedViaChromeClient: {
2284 Frame* frame = m_renderView->frameView()->frame();
2285 Page* page = frame ? frame->page() : 0;
2289 page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
2292 case RootLayerUnattached:
2296 m_rootLayerAttachment = RootLayerUnattached;
2297 rootLayerAttachmentChanged();
2300 void RenderLayerCompositor::updateRootLayerAttachment()
2305 void RenderLayerCompositor::rootLayerAttachmentChanged()
2307 // The attachment can affect whether the RenderView layer's paintsIntoWindow() behavior,
2308 // so call updateGraphicsLayerGeometry() to udpate that.
2309 RenderLayer* layer = m_renderView->layer();
2310 if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
2311 backing->updateDrawsContent();
2314 // IFrames are special, because we hook compositing layers together across iframe boundaries
2315 // when both parent and iframe content are composited. So when this frame becomes composited, we have
2316 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
2317 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
2319 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0;
2323 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) {
2324 if (child->document() && child->document()->ownerElement())
2325 child->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2328 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
2329 // we need to schedule a style recalc in our parent document.
2330 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
2331 ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2334 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
2336 const RenderStyle* style = layer->renderer()->style();
2339 (style->transformStyle3D() == TransformStyle3DPreserve3D ||
2340 style->hasPerspective() ||
2341 style->transform().has3DOperation()))
2344 const_cast<RenderLayer*>(layer)->updateLayerListsIfNeeded();
2346 #if !ASSERT_DISABLED
2347 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(layer));
2350 if (layer->isStackingContext()) {
2351 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
2352 size_t listSize = negZOrderList->size();
2353 for (size_t i = 0; i < listSize; ++i) {
2354 RenderLayer* curLayer = negZOrderList->at(i);
2355 if (layerHas3DContent(curLayer))
2360 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
2361 size_t listSize = posZOrderList->size();
2362 for (size_t i = 0; i < listSize; ++i) {
2363 RenderLayer* curLayer = posZOrderList->at(i);
2364 if (layerHas3DContent(curLayer))
2370 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
2371 size_t listSize = normalFlowList->size();
2372 for (size_t i = 0; i < listSize; ++i) {
2373 RenderLayer* curLayer = normalFlowList->at(i);
2374 if (layerHas3DContent(curLayer))
2381 void RenderLayerCompositor::deviceOrPageScaleFactorChanged()
2383 // Start at the RenderView's layer, since that's where the scale is applied.
2384 RenderLayer* viewLayer = m_renderView->layer();
2385 if (!viewLayer->isComposited())
2388 if (GraphicsLayer* rootLayer = viewLayer->backing()->graphicsLayer())
2389 rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
2392 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
2394 if (Frame* frame = m_renderView->frameView()->frame()) {
2395 if (Page* page = frame->page())
2396 return page->scrollingCoordinator();
2402 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
2403 void RenderLayerCompositor::platformLayerChanged(RenderLayer* renderLayer, PlatformLayer* oldLayer, PlatformLayer* newLayer)
2405 if (m_scrollingLayers.contains(renderLayer)) {
2406 RenderLayerBacking* backing = renderLayer->backing();
2408 scrollingLayerAddedOrUpdated(renderLayer, backing->scrollingLayer(), backing->scrollingContentsLayer(), IntSize(renderLayer->scrollWidth(), renderLayer->scrollHeight()));
2412 void RenderLayerCompositor::registerAllScrollingLayers()
2414 ChromeClient* chromeClient = this->chromeClient();
2418 HashSet<RenderLayer*>::const_iterator end = m_scrollingLayers.end();
2419 for (HashSet<RenderLayer*>::const_iterator it = m_scrollingLayers.begin(); it != end; ++it) {
2420 RenderLayer* layer = *it;
2421 RenderLayerBacking* backing = layer->backing();
2423 chromeClient->addOrUpdateScrollingLayer(layer->renderer()->node(), backing->scrollingLayer(), backing->scrollingContentsLayer(), IntSize(layer->scrollWidth(), layer->scrollHeight()));
2427 void RenderLayerCompositor::unregisterAllScrollingLayers()
2429 ChromeClient* chromeClient = this->chromeClient();
2433 HashSet<RenderLayer*>::const_iterator end = m_scrollingLayers.end();
2434 for (HashSet<RenderLayer*>::const_iterator it = m_scrollingLayers.begin(); it != end; ++it) {
2435 RenderLayer* layer = *it;
2436 RenderLayerBacking* backing = layer->backing();
2438 chromeClient->removeScrollingLayer(layer->renderer()->node(), backing->scrollingLayer(), backing->scrollingContentsLayer());
2442 // Called when the size of the contentsLayer changes, and when the contentsLayer is replaced by another layer.
2443 void RenderLayerCompositor::scrollingLayerAddedOrUpdated(RenderLayer* layer, GraphicsLayer* scrollingLayer, GraphicsLayer* contentsLayer, const IntSize& scrollSize)
2445 m_scrollingLayers.add(layer);
2447 ASSERT(!m_renderView->document()->inPageCache());
2449 if (ChromeClient* chromeClient = this->chromeClient())
2450 chromeClient->addOrUpdateScrollingLayer(layer->renderer()->node(), scrollingLayer, contentsLayer, scrollSize);
2453 void RenderLayerCompositor::scrollingLayerRemoved(RenderLayer* layer, GraphicsLayer* scrollingLayer, GraphicsLayer* contentsLayer)
2455 m_scrollingLayers.remove(layer);
2457 if (m_renderView->document()->inPageCache())
2460 if (ChromeClient* chromeClient = this->chromeClient())
2461 chromeClient->removeScrollingLayer(layer->renderer()->node(), scrollingLayer, contentsLayer);
2465 } // namespace WebCore
2467 #endif // USE(ACCELERATED_COMPOSITING)