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();
1474 // The root layer always has a compositing layer, but it may not have backing.
1475 return requiresCompositingForTransform(renderer)
1476 || requiresCompositingForVideo(renderer)
1477 || requiresCompositingForCanvas(renderer)
1478 || requiresCompositingForPlugin(renderer)
1479 || requiresCompositingForFrame(renderer)
1480 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1481 || clipsCompositingDescendants(layer)
1482 || requiresCompositingForAnimation(renderer)
1483 || requiresCompositingForFilters(renderer)
1484 || requiresCompositingForPosition(renderer, layer)
1485 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1486 || requiresCompositingForScrolling(renderer)
1491 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
1493 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
1494 if (m_compositedLayerCount > 40)
1498 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
1499 // See http://webkit.org/b/84900 to re-enable it.
1500 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->renderer()->inRenderFlowThread();
1503 bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer* layer, const RenderLayer* compositingAncestorLayer) const
1505 RenderObject* renderer = layer->renderer();
1506 if (compositingAncestorLayer
1507 && !(compositingAncestorLayer->backing()->graphicsLayer()->drawsContent()
1508 || compositingAncestorLayer->backing()->paintsIntoWindow()
1509 || compositingAncestorLayer->backing()->paintsIntoCompositedAncestor()))
1512 return layer->isRootLayer()
1513 || layer->transform() // note: excludes perspective and transformStyle3D.
1514 || requiresCompositingForVideo(renderer)
1515 || requiresCompositingForCanvas(renderer)
1516 || requiresCompositingForPlugin(renderer)
1517 || requiresCompositingForFrame(renderer)
1518 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1519 || requiresCompositingForAnimation(renderer)
1520 || requiresCompositingForFilters(renderer)
1521 || requiresCompositingForPosition(renderer, layer)
1522 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1523 || requiresCompositingForScrolling(renderer)
1525 || renderer->isTransparent()
1526 || renderer->hasMask()
1527 || renderer->hasReflection()
1528 || renderer->hasFilter()
1529 || layer->mustOverlapCompositedLayers();
1533 const char* RenderLayerCompositor::reasonForCompositing(const RenderLayer* layer)
1535 RenderObject* renderer = layer->renderer();
1536 if (layer->isReflection()) {
1537 renderer = renderer->parent();
1538 layer = toRenderBoxModelObject(renderer)->layer();
1541 if (renderer->hasTransform() && renderer->style()->hasPerspective())
1542 return "perspective";
1544 if (renderer->hasTransform() && (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D))
1545 return "preserve-3d";
1547 if (renderer->hasTransform())
1550 if (requiresCompositingForVideo(renderer))
1553 if (requiresCompositingForCanvas(renderer))
1556 if (requiresCompositingForPlugin(renderer))
1559 if (requiresCompositingForFrame(renderer))
1562 if ((canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden))
1563 return "backface-visibility: hidden";
1565 if (clipsCompositingDescendants(layer))
1566 return "clips compositing descendants";
1568 if (requiresCompositingForAnimation(renderer))
1571 if (requiresCompositingForFilters(renderer))
1574 if (requiresCompositingForPosition(renderer, layer))
1575 return "position: fixed";
1577 // This includes layers made composited by requiresCompositingWhenDescendantsAreCompositing().
1578 if (layer->mustOverlapCompositedLayers())
1579 return "overlap/stacking";
1581 if (inCompositingMode() && layer->isRootLayer())
1588 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1589 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1590 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1591 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1592 // but a sibling in the z-order hierarchy.
1593 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
1595 if (!layer->isComposited() || !layer->parent())
1598 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1599 if (!compositingAncestor)
1602 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
1603 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
1605 RenderLayer* computeClipRoot = 0;
1606 RenderLayer* curr = layer;
1608 RenderLayer* next = curr->parent();
1609 if (next == compositingAncestor) {
1610 computeClipRoot = curr;
1616 if (!computeClipRoot || computeClipRoot == layer)
1619 return layer->backgroundClipRect(computeClipRoot, 0, TemporaryClipRects).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
1622 // Return true if the given layer is a stacking context and has compositing child
1623 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1624 // into the hierarchy between this layer and its children in the z-order hierarchy.
1625 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1627 return layer->hasCompositingDescendant() &&
1628 (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip());
1631 bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
1633 // Need this done first to determine overflow.
1634 ASSERT(!m_renderView->needsLayout());
1636 ScrollView* scrollView = m_renderView->frameView();
1637 return scrollView->verticalScrollbar() || scrollView->horizontalScrollbar();
1640 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
1642 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
1645 RenderStyle* style = renderer->style();
1646 // Note that we ask the renderer if it has a transform, because the style may have transforms,
1647 // but the renderer may be an inline that doesn't suppport them.
1648 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
1651 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
1653 if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
1656 if (renderer->isVideo()) {
1657 RenderVideo* video = toRenderVideo(renderer);
1658 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
1660 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1661 else if (renderer->isRenderPart()) {
1662 if (!m_hasAcceleratedCompositing)
1665 Node* node = renderer->node();
1666 if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag)))
1669 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node);
1670 return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false;
1672 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1674 UNUSED_PARAM(renderer);
1679 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
1681 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
1684 if (renderer->isCanvas()) {
1685 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
1686 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
1691 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
1693 if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
1696 bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
1697 || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing());
1701 m_reevaluateCompositingAfterLayout = true;
1703 RenderWidget* pluginRenderer = toRenderWidget(renderer);
1704 // If we can't reliably know the size of the plugin yet, don't change compositing state.
1705 if (pluginRenderer->needsLayout())
1706 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited();
1708 // Don't go into compositing mode if height or width are zero, or size is 1x1.
1709 IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect());
1710 return contentBox.height() * contentBox.width() > 1;
1713 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
1715 if (!renderer->isRenderPart())
1718 RenderPart* frameRenderer = toRenderPart(renderer);
1720 if (!frameRenderer->requiresAcceleratedCompositing())
1723 m_reevaluateCompositingAfterLayout = true;
1725 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
1726 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())
1729 // If we can't reliably know the size of the iframe yet, don't change compositing state.
1730 if (renderer->needsLayout())
1731 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited();
1733 // Don't go into compositing mode if height or width are zero.
1734 IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect());
1735 return contentBox.height() * contentBox.width() > 0;
1738 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
1740 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1743 if (AnimationController* animController = renderer->animation()) {
1744 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
1745 #if ENABLE(CSS_FILTERS)
1746 #if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION)
1747 // <rdar://problem/10907251> - WebKit2 doesn't support CA animations of CI filters on Lion and below
1748 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitFilter)
1749 #endif // !SNOW_LEOPARD && !LION
1750 #endif // CSS_FILTERS
1751 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1756 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
1758 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection() || renderer->hasFilter();
1761 bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const
1763 #if ENABLE(CSS_FILTERS)
1764 if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
1767 return renderer->hasFilter();
1769 UNUSED_PARAM(renderer);
1774 bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer) const
1776 // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
1777 // opacity, transform) can get their own composited layer. A stacking context is required otherwise
1778 // z-index and clipping will be broken.
1779 if (!(renderer->isPositioned() && renderer->style()->position() == FixedPosition && layer->isStackingContext()))
1782 if (Settings* settings = m_renderView->document()->settings())
1783 if (!settings->acceleratedCompositingForFixedPositionEnabled())
1786 RenderObject* container = renderer->container();
1787 // If the renderer is not hooked up yet then we have to wait until it is.
1789 m_reevaluateCompositingAfterLayout = true;
1793 // Don't promote fixed position elements that are descendants of transformed elements.
1794 // They will stay fixed wrt the transformed element rather than the enclosing frame.
1795 if (container != m_renderView)
1798 // Fixed position elements that are invisible in the current view don't get their own layer.
1799 FrameView* frameView = m_renderView->frameView();
1800 if (frameView && !layer->absoluteBoundingBox().intersects(IntRect(frameView->scrollXForFixedPosition(), frameView->scrollYForFixedPosition(), frameView->layoutWidth(), frameView->layoutHeight())))
1806 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1807 bool RenderLayerCompositor::requiresCompositingForScrolling(RenderObject* renderer) const
1809 return renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->hasAcceleratedTouchScrolling();
1814 bool RenderLayerCompositor::hasNonAffineTransform(RenderObject* renderer) const
1816 if (!renderer->hasTransform())
1819 if (TransformationMatrix* transform = toRenderBoxModelObject(renderer)->layer()->transform())
1820 return !transform->isAffine();
1825 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const
1827 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1830 if (AnimationController* animController = renderer->animation())
1831 return animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1836 // If an element has negative z-index children, those children render in front of the
1837 // layer background, so we need an extra 'contents' layer for the foreground of the layer
1839 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
1841 return layer->hasNegativeZOrderList();
1844 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
1846 // This applies when the application UI handles scrolling, in which case RenderLayerCompositor doesn't need to manage it.
1847 if (m_renderView->frameView()->delegatesScrolling())
1850 // We need to handle our own scrolling if we're:
1851 return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
1852 || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
1855 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1861 const IntRect& scrollbarRect = scrollbar->frameRect();
1862 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1863 IntRect transformedClip = clip;
1864 transformedClip.moveBy(scrollbarRect.location());
1865 scrollbar->paint(&context, transformedClip);
1869 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
1871 if (graphicsLayer == layerForHorizontalScrollbar())
1872 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
1873 else if (graphicsLayer == layerForVerticalScrollbar())
1874 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
1875 else if (graphicsLayer == layerForScrollCorner()) {
1876 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
1878 context.translate(-scrollCorner.x(), -scrollCorner.y());
1879 IntRect transformedClip = clip;
1880 transformedClip.moveBy(scrollCorner.location());
1881 m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
1883 #if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
1884 } else if (graphicsLayer == layerForOverhangAreas()) {
1885 ScrollView* view = m_renderView->frameView();
1886 view->calculateAndPaintOverhangAreas(&context, clip);
1891 void RenderLayerCompositor::documentBackgroundColorDidChange()
1893 RenderLayerBacking* backing = rootRenderLayer()->backing();
1897 GraphicsLayer* graphicsLayer = backing->graphicsLayer();
1898 if (!graphicsLayer->client()->shouldUseTileCache(graphicsLayer))
1901 Color backgroundColor = m_renderView->frameView()->documentBackgroundColor();
1902 if (!backgroundColor.isValid() || backgroundColor.hasAlpha())
1903 backgroundColor = Color::white;
1905 graphicsLayer->setBackgroundColor(backgroundColor);
1908 bool RenderLayerCompositor::showDebugBorders(const GraphicsLayer* layer) const
1910 if (layer == m_layerForHorizontalScrollbar || layer == m_layerForVerticalScrollbar || layer == m_layerForScrollCorner)
1911 return m_showDebugBorders;
1916 bool RenderLayerCompositor::showRepaintCounter(const GraphicsLayer* layer) const
1918 if (layer == m_layerForHorizontalScrollbar || layer == m_layerForVerticalScrollbar || layer == m_layerForScrollCorner)
1919 return m_showDebugBorders;
1924 float RenderLayerCompositor::deviceScaleFactor() const
1926 Frame* frame = m_renderView->frameView()->frame();
1929 Page* page = frame->page();
1932 return page->deviceScaleFactor();
1935 float RenderLayerCompositor::pageScaleFactor() const
1937 Frame* frame = m_renderView->frameView()->frame();
1940 Page* page = frame->page();
1943 return page->pageScaleFactor();
1946 void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const
1948 // Nothing to do here yet.
1951 bool RenderLayerCompositor::keepLayersPixelAligned() const
1953 // When scaling, attempt to align compositing layers to pixel boundaries.
1957 static bool shouldCompositeOverflowControls(FrameView* view)
1959 if (view->platformWidget())
1962 if (Page* page = view->frame()->page()) {
1963 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1964 if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
1968 #if !PLATFORM(CHROMIUM)
1969 if (!view->hasOverlayScrollbars())
1975 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
1977 FrameView* view = m_renderView->frameView();
1978 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
1981 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
1983 FrameView* view = m_renderView->frameView();
1984 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
1987 bool RenderLayerCompositor::requiresScrollCornerLayer() const
1989 FrameView* view = m_renderView->frameView();
1990 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
1993 #if ENABLE(RUBBER_BANDING)
1994 bool RenderLayerCompositor::requiresOverhangAreasLayer() const
1996 // We don't want a layer if this is a subframe.
1997 if (m_renderView->document()->ownerElement())
2000 // We do want a layer if we have a scrolling coordinator.
2001 if (scrollingCoordinator())
2004 // Chromium always wants a layer.
2005 #if PLATFORM(CHROMIUM)
2012 bool RenderLayerCompositor::requiresContentShadowLayer() const
2014 // We don't want a layer if this is a subframe.
2015 if (m_renderView->document()->ownerElement())
2019 // On Mac, we want a content shadow layer if we have a scrolling coordinator.
2020 if (scrollingCoordinator())
2028 void RenderLayerCompositor::updateOverflowControlsLayers()
2030 #if ENABLE(RUBBER_BANDING)
2031 if (requiresOverhangAreasLayer()) {
2032 if (!m_layerForOverhangAreas) {
2033 m_layerForOverhangAreas = GraphicsLayer::create(this);
2035 m_layerForOverhangAreas->setName("overhang areas");
2037 m_layerForOverhangAreas->setDrawsContent(false);
2038 m_layerForOverhangAreas->setSize(m_renderView->frameView()->frameRect().size());
2040 ScrollbarTheme::theme()->setUpOverhangAreasLayerContents(m_layerForOverhangAreas.get());
2042 // We want the overhang areas layer to be positioned below the frame contents,
2043 // so insert it below the clip layer.
2044 m_overflowControlsHostLayer->addChildBelow(m_layerForOverhangAreas.get(), m_clipLayer.get());
2046 } else if (m_layerForOverhangAreas) {
2047 m_layerForOverhangAreas->removeFromParent();
2048 m_layerForOverhangAreas = nullptr;
2051 if (requiresContentShadowLayer()) {
2052 if (!m_contentShadowLayer) {
2053 m_contentShadowLayer = GraphicsLayer::create(this);
2055 m_contentShadowLayer->setName("content shadow");
2057 m_contentShadowLayer->setSize(m_rootContentLayer->size());
2058 m_contentShadowLayer->setPosition(m_rootContentLayer->position());
2059 ScrollbarTheme::theme()->setUpContentShadowLayer(m_contentShadowLayer.get());
2061 m_scrollLayer->addChildBelow(m_contentShadowLayer.get(), m_rootContentLayer.get());
2063 } else if (m_contentShadowLayer) {
2064 m_contentShadowLayer->removeFromParent();
2065 m_contentShadowLayer = nullptr;
2069 if (requiresHorizontalScrollbarLayer()) {
2070 if (!m_layerForHorizontalScrollbar) {
2071 m_layerForHorizontalScrollbar = GraphicsLayer::create(this);
2073 m_layerForHorizontalScrollbar->setName("horizontal scrollbar");
2075 #if PLATFORM(MAC) && USE(CA)
2076 m_layerForHorizontalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
2078 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
2080 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2081 scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForHorizontalScrollbar.get());
2083 } else if (m_layerForHorizontalScrollbar) {
2084 m_layerForHorizontalScrollbar->removeFromParent();
2085 m_layerForHorizontalScrollbar = nullptr;
2087 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2088 scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), 0);
2091 if (requiresVerticalScrollbarLayer()) {
2092 if (!m_layerForVerticalScrollbar) {
2093 m_layerForVerticalScrollbar = GraphicsLayer::create(this);
2095 m_layerForVerticalScrollbar->setName("vertical scrollbar");
2097 #if PLATFORM(MAC) && USE(CA)
2098 m_layerForVerticalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
2100 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
2102 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2103 scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForVerticalScrollbar.get());
2105 } else if (m_layerForVerticalScrollbar) {
2106 m_layerForVerticalScrollbar->removeFromParent();
2107 m_layerForVerticalScrollbar = nullptr;
2109 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2110 scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), 0);
2113 if (requiresScrollCornerLayer()) {
2114 if (!m_layerForScrollCorner) {
2115 m_layerForScrollCorner = GraphicsLayer::create(this);
2117 m_layerForScrollCorner->setName("scroll corner");
2119 #if PLATFORM(MAC) && USE(CA)
2120 m_layerForScrollCorner->setAcceleratesDrawing(acceleratedDrawingEnabled());
2122 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
2124 } else if (m_layerForScrollCorner) {
2125 m_layerForScrollCorner->removeFromParent();
2126 m_layerForScrollCorner = nullptr;
2129 m_renderView->frameView()->positionScrollbarLayers();
2132 void RenderLayerCompositor::ensureRootLayer()
2134 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
2135 if (expectedAttachment == m_rootLayerAttachment)
2138 if (!m_rootContentLayer) {
2139 m_rootContentLayer = GraphicsLayer::create(this);
2141 m_rootContentLayer->setName("content root");
2143 IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect();
2144 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
2145 m_rootContentLayer->setPosition(FloatPoint());
2147 // Need to clip to prevent transformed content showing outside this frame
2148 m_rootContentLayer->setMasksToBounds(true);
2151 if (requiresScrollLayer(expectedAttachment)) {
2152 if (!m_overflowControlsHostLayer) {
2153 ASSERT(!m_scrollLayer);
2154 ASSERT(!m_clipLayer);
2156 // Create a layer to host the clipping layer and the overflow controls layers.
2157 m_overflowControlsHostLayer = GraphicsLayer::create(this);
2159 m_overflowControlsHostLayer->setName("overflow controls host");
2162 // Create a clipping layer if this is an iframe
2163 m_clipLayer = GraphicsLayer::create(this);
2165 m_clipLayer->setName("frame clipping");
2167 m_clipLayer->setMasksToBounds(true);
2169 m_scrollLayer = GraphicsLayer::create(this);
2171 m_scrollLayer->setName("frame scrolling");
2175 m_overflowControlsHostLayer->addChild(m_clipLayer.get());
2176 m_clipLayer->addChild(m_scrollLayer.get());
2177 m_scrollLayer->addChild(m_rootContentLayer.get());
2179 frameViewDidChangeSize();
2180 frameViewDidScroll();
2183 if (m_overflowControlsHostLayer) {
2184 m_overflowControlsHostLayer = nullptr;
2185 m_clipLayer = nullptr;
2186 m_scrollLayer = nullptr;
2190 // Check to see if we have to change the attachment
2191 if (m_rootLayerAttachment != RootLayerUnattached)
2194 attachRootLayer(expectedAttachment);
2197 void RenderLayerCompositor::destroyRootLayer()
2199 if (!m_rootContentLayer)
2204 #if ENABLE(RUBBER_BANDING)
2205 if (m_layerForOverhangAreas) {
2206 m_layerForOverhangAreas->removeFromParent();
2207 m_layerForOverhangAreas = nullptr;
2211 if (m_layerForHorizontalScrollbar) {
2212 m_layerForHorizontalScrollbar->removeFromParent();
2213 m_layerForHorizontalScrollbar = nullptr;
2214 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
2215 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
2218 if (m_layerForVerticalScrollbar) {
2219 m_layerForVerticalScrollbar->removeFromParent();
2220 m_layerForVerticalScrollbar = nullptr;
2221 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
2222 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
2225 if (m_layerForScrollCorner) {
2226 m_layerForScrollCorner = nullptr;
2227 m_renderView->frameView()->invalidateScrollCorner(m_renderView->frameView()->scrollCornerRect());
2230 if (m_overflowControlsHostLayer) {
2231 m_overflowControlsHostLayer = nullptr;
2232 m_clipLayer = nullptr;
2233 m_scrollLayer = nullptr;
2235 ASSERT(!m_scrollLayer);
2236 m_rootContentLayer = nullptr;
2239 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
2241 if (!m_rootContentLayer)
2244 switch (attachment) {
2245 case RootLayerUnattached:
2246 ASSERT_NOT_REACHED();
2248 case RootLayerAttachedViaChromeClient: {
2249 Frame* frame = m_renderView->frameView()->frame();
2250 Page* page = frame ? frame->page() : 0;
2254 page->chrome()->client()->attachRootGraphicsLayer(frame, rootGraphicsLayer());
2257 case RootLayerAttachedViaEnclosingFrame: {
2258 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
2259 // for the frame's renderer in the parent document.
2260 m_renderView->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2265 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
2266 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
2268 m_rootLayerAttachment = attachment;
2269 rootLayerAttachmentChanged();
2272 void RenderLayerCompositor::detachRootLayer()
2274 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
2277 switch (m_rootLayerAttachment) {
2278 case RootLayerAttachedViaEnclosingFrame: {
2279 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
2280 // for the frame's renderer in the parent document.
2281 if (m_overflowControlsHostLayer)
2282 m_overflowControlsHostLayer->removeFromParent();
2284 m_rootContentLayer->removeFromParent();
2286 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
2287 ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2290 case RootLayerAttachedViaChromeClient: {
2291 Frame* frame = m_renderView->frameView()->frame();
2292 Page* page = frame ? frame->page() : 0;
2296 page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
2299 case RootLayerUnattached:
2303 m_rootLayerAttachment = RootLayerUnattached;
2304 rootLayerAttachmentChanged();
2307 void RenderLayerCompositor::updateRootLayerAttachment()
2312 void RenderLayerCompositor::rootLayerAttachmentChanged()
2314 // The attachment can affect whether the RenderView layer's paintsIntoWindow() behavior,
2315 // so call updateGraphicsLayerGeometry() to udpate that.
2316 RenderLayer* layer = m_renderView->layer();
2317 if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
2318 backing->updateDrawsContent();
2321 // IFrames are special, because we hook compositing layers together across iframe boundaries
2322 // when both parent and iframe content are composited. So when this frame becomes composited, we have
2323 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
2324 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
2326 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0;
2330 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) {
2331 if (child->document() && child->document()->ownerElement())
2332 child->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2335 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
2336 // we need to schedule a style recalc in our parent document.
2337 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
2338 ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
2341 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
2343 const RenderStyle* style = layer->renderer()->style();
2346 (style->transformStyle3D() == TransformStyle3DPreserve3D ||
2347 style->hasPerspective() ||
2348 style->transform().has3DOperation()))
2351 const_cast<RenderLayer*>(layer)->updateLayerListsIfNeeded();
2353 #if !ASSERT_DISABLED
2354 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(layer));
2357 if (layer->isStackingContext()) {
2358 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
2359 size_t listSize = negZOrderList->size();
2360 for (size_t i = 0; i < listSize; ++i) {
2361 RenderLayer* curLayer = negZOrderList->at(i);
2362 if (layerHas3DContent(curLayer))
2367 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
2368 size_t listSize = posZOrderList->size();
2369 for (size_t i = 0; i < listSize; ++i) {
2370 RenderLayer* curLayer = posZOrderList->at(i);
2371 if (layerHas3DContent(curLayer))
2377 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
2378 size_t listSize = normalFlowList->size();
2379 for (size_t i = 0; i < listSize; ++i) {
2380 RenderLayer* curLayer = normalFlowList->at(i);
2381 if (layerHas3DContent(curLayer))
2388 void RenderLayerCompositor::deviceOrPageScaleFactorChanged()
2390 // Start at the RenderView's layer, since that's where the scale is applied.
2391 RenderLayer* viewLayer = m_renderView->layer();
2392 if (!viewLayer->isComposited())
2395 if (GraphicsLayer* rootLayer = viewLayer->backing()->graphicsLayer())
2396 rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
2399 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
2401 if (Frame* frame = m_renderView->frameView()->frame()) {
2402 if (Page* page = frame->page())
2403 return page->scrollingCoordinator();
2409 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
2410 void RenderLayerCompositor::platformLayerChanged(RenderLayer* renderLayer, PlatformLayer* oldLayer, PlatformLayer* newLayer)
2412 if (m_scrollingLayers.contains(renderLayer)) {
2413 RenderLayerBacking* backing = renderLayer->backing();
2415 scrollingLayerAddedOrUpdated(renderLayer, backing->scrollingLayer(), backing->scrollingContentsLayer(), IntSize(renderLayer->scrollWidth(), renderLayer->scrollHeight()));
2419 void RenderLayerCompositor::registerAllScrollingLayers()
2421 ChromeClient* chromeClient = this->chromeClient();
2425 HashSet<RenderLayer*>::const_iterator end = m_scrollingLayers.end();
2426 for (HashSet<RenderLayer*>::const_iterator it = m_scrollingLayers.begin(); it != end; ++it) {
2427 RenderLayer* layer = *it;
2428 RenderLayerBacking* backing = layer->backing();
2430 chromeClient->addOrUpdateScrollingLayer(layer->renderer()->node(), backing->scrollingLayer(), backing->scrollingContentsLayer(), IntSize(layer->scrollWidth(), layer->scrollHeight()));
2434 void RenderLayerCompositor::unregisterAllScrollingLayers()
2436 ChromeClient* chromeClient = this->chromeClient();
2440 HashSet<RenderLayer*>::const_iterator end = m_scrollingLayers.end();
2441 for (HashSet<RenderLayer*>::const_iterator it = m_scrollingLayers.begin(); it != end; ++it) {
2442 RenderLayer* layer = *it;
2443 RenderLayerBacking* backing = layer->backing();
2445 chromeClient->removeScrollingLayer(layer->renderer()->node(), backing->scrollingLayer(), backing->scrollingContentsLayer());
2449 // Called when the size of the contentsLayer changes, and when the contentsLayer is replaced by another layer.
2450 void RenderLayerCompositor::scrollingLayerAddedOrUpdated(RenderLayer* layer, GraphicsLayer* scrollingLayer, GraphicsLayer* contentsLayer, const IntSize& scrollSize)
2452 m_scrollingLayers.add(layer);
2454 ASSERT(!m_renderView->document()->inPageCache());
2456 if (ChromeClient* chromeClient = this->chromeClient())
2457 chromeClient->addOrUpdateScrollingLayer(layer->renderer()->node(), scrollingLayer, contentsLayer, scrollSize);
2460 void RenderLayerCompositor::scrollingLayerRemoved(RenderLayer* layer, GraphicsLayer* scrollingLayer, GraphicsLayer* contentsLayer)
2462 m_scrollingLayers.remove(layer);
2464 if (m_renderView->document()->inPageCache())
2467 if (ChromeClient* chromeClient = this->chromeClient())
2468 chromeClient->removeScrollingLayer(layer->renderer()->node(), scrollingLayer, contentsLayer);
2472 } // namespace WebCore
2474 #endif // USE(ACCELERATED_COMPOSITING)