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"
45 #include "RenderApplet.h"
46 #include "RenderEmbeddedObject.h"
47 #include "RenderFullScreen.h"
48 #include "RenderIFrame.h"
49 #include "RenderLayerBacking.h"
50 #include "RenderReplica.h"
51 #include "RenderVideo.h"
52 #include "RenderView.h"
55 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
56 #include "HTMLMediaElement.h"
59 #if PROFILE_LAYER_REBUILD
60 #include <wtf/CurrentTime.h>
64 #include "RenderTreeAsText.h"
67 #if ENABLE(3D_RENDERING)
68 // This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm').
69 bool WebCoreHas3DRendering = true;
74 using namespace HTMLNames;
76 struct CompositingState {
77 CompositingState(RenderLayer* compAncestor)
78 : m_compositingAncestor(compAncestor)
79 , m_subtreeIsCompositing(false)
80 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
81 , m_fixedSibling(false)
89 RenderLayer* m_compositingAncestor;
90 bool m_subtreeIsCompositing;
91 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
99 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
100 : m_renderView(renderView)
101 , m_rootPlatformLayer(0)
102 , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
103 , m_hasAcceleratedCompositing(true)
104 , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
105 , m_showDebugBorders(false)
106 , m_showRepaintCounter(false)
107 , m_compositingConsultsOverlap(true)
108 , m_compositingDependsOnGeometry(false)
109 , m_compositing(false)
110 , m_compositingLayersNeedRebuild(false)
111 , m_flushingLayers(false)
112 , m_forceCompositingMode(false)
113 , m_rootLayerAttachment(RootLayerUnattached)
114 #if PROFILE_LAYER_REBUILD
115 , m_rootLayerUpdateCount(0)
116 #endif // PROFILE_LAYER_REBUILD
118 Settings* settings = m_renderView->document()->settings();
120 // Even when forcing compositing mode, ignore child frames, or this will trigger
121 // layer creation from the enclosing RenderIFrame.
122 ASSERT(m_renderView->document()->frame());
123 if (settings && settings->forceCompositingMode() && settings->acceleratedCompositingEnabled()
124 && !m_renderView->document()->frame()->tree()->parent()) {
125 m_forceCompositingMode = true;
126 enableCompositingMode();
130 RenderLayerCompositor::~RenderLayerCompositor()
132 ASSERT(m_rootLayerAttachment == RootLayerUnattached);
135 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
137 if (enable != m_compositing) {
138 m_compositing = enable;
141 ensureRootPlatformLayer();
142 notifyIFramesOfCompositingChange();
144 destroyRootPlatformLayer();
148 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
150 bool hasAcceleratedCompositing = false;
151 bool showDebugBorders = false;
152 bool showRepaintCounter = false;
154 if (Settings* settings = m_renderView->document()->settings()) {
155 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
156 showDebugBorders = settings->showDebugBorders();
157 showRepaintCounter = settings->showRepaintCounter();
160 // We allow the chrome to override the settings, in case the page is rendered
161 // on a chrome that doesn't allow accelerated compositing.
162 if (hasAcceleratedCompositing) {
163 Frame* frame = m_renderView->frameView()->frame();
164 Page* page = frame ? frame->page() : 0;
166 ChromeClient* chromeClient = page->chrome()->client();
167 m_compositingTriggers = chromeClient->allowedCompositingTriggers();
168 hasAcceleratedCompositing = m_compositingTriggers;
172 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter)
173 setCompositingLayersNeedRebuild();
175 m_hasAcceleratedCompositing = hasAcceleratedCompositing;
176 m_showDebugBorders = showDebugBorders;
177 m_showRepaintCounter = showRepaintCounter;
180 bool RenderLayerCompositor::canRender3DTransforms() const
182 return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
185 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
187 if (inCompositingMode())
188 m_compositingLayersNeedRebuild = needRebuild;
191 void RenderLayerCompositor::scheduleLayerFlush()
193 Frame* frame = m_renderView->frameView()->frame();
194 Page* page = frame ? frame->page() : 0;
198 page->chrome()->client()->scheduleCompositingLayerSync();
201 void RenderLayerCompositor::flushPendingLayerChanges()
203 ASSERT(!m_flushingLayers);
204 m_flushingLayers = true;
206 // FIXME: FrameView::syncCompositingStateRecursive() calls this for each
207 // frame, so when compositing layers are connected between frames, we'll
208 // end up syncing subframe's layers multiple times.
209 // https://bugs.webkit.org/show_bug.cgi?id=52489
210 if (GraphicsLayer* rootLayer = rootPlatformLayer())
211 rootLayer->syncCompositingState();
213 ASSERT(m_flushingLayers);
214 m_flushingLayers = false;
217 RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const
219 if (!m_renderView->frameView())
222 for (Frame* frame = m_renderView->frameView()->frame(); frame; frame = frame->tree()->parent()) {
223 RenderLayerCompositor* compositor = frame->contentRenderer() ? frame->contentRenderer()->compositor() : 0;
224 if (compositor->isFlushingLayers())
231 void RenderLayerCompositor::scheduleCompositingLayerUpdate()
233 if (!m_updateCompositingLayersTimer.isActive())
234 m_updateCompositingLayersTimer.startOneShot(0);
237 bool RenderLayerCompositor::compositingLayerUpdatePending() const
239 return m_updateCompositingLayersTimer.isActive();
242 void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*)
244 updateCompositingLayers();
247 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
249 m_updateCompositingLayersTimer.stop();
251 if (!m_compositingDependsOnGeometry && !m_compositing)
254 bool checkForHierarchyUpdate = m_compositingDependsOnGeometry;
255 bool needGeometryUpdate = false;
257 switch (updateType) {
258 case CompositingUpdateAfterLayoutOrStyleChange:
259 case CompositingUpdateOnPaitingOrHitTest:
260 checkForHierarchyUpdate = true;
262 case CompositingUpdateOnScroll:
263 if (m_compositingConsultsOverlap)
264 checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
266 needGeometryUpdate = true;
270 if (!checkForHierarchyUpdate && !needGeometryUpdate)
273 bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
274 if (!updateRoot || m_compositingConsultsOverlap) {
275 // Only clear the flag if we're updating the entire hierarchy.
276 m_compositingLayersNeedRebuild = false;
277 updateRoot = rootRenderLayer();
280 #if PROFILE_LAYER_REBUILD
281 ++m_rootLayerUpdateCount;
283 double startTime = WTF::currentTime();
286 if (checkForHierarchyUpdate) {
287 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
288 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
289 CompositingState compState(updateRoot);
290 bool layersChanged = false;
291 if (m_compositingConsultsOverlap) {
292 OverlapMap overlapTestRequestMap;
293 computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged);
295 computeCompositingRequirements(updateRoot, 0, compState, layersChanged);
297 needHierarchyUpdate |= layersChanged;
300 if (needHierarchyUpdate) {
301 // Update the hierarchy of the compositing layers.
302 CompositingState compState(updateRoot);
303 Vector<GraphicsLayer*> childList;
304 rebuildCompositingLayerTree(updateRoot, compState, childList);
306 // Host the document layer in the RenderView's root layer.
307 if (updateRoot == rootRenderLayer()) {
308 if (childList.isEmpty())
309 destroyRootPlatformLayer();
311 m_rootPlatformLayer->setChildren(childList);
313 } else if (needGeometryUpdate) {
314 // We just need to do a geometry update. This is only used for position:fixed scrolling;
315 // most of the time, geometry is updated via RenderLayer::styleChanged().
316 updateLayerTreeGeometry(updateRoot);
319 #if PROFILE_LAYER_REBUILD
320 double endTime = WTF::currentTime();
321 if (updateRoot == rootRenderLayer())
322 fprintf(stderr, "Update %d: computeCompositingRequirements for the world took %fms\n",
323 m_rootLayerUpdateCount, 1000.0 * (endTime - startTime));
325 ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
327 if (!hasAcceleratedCompositing())
328 enableCompositingMode(false);
331 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
333 bool layerChanged = false;
335 if (needsToBeComposited(layer)) {
336 enableCompositingMode();
338 // 3D transforms turn off the testing of overlap.
339 if (requiresCompositingForTransform(layer->renderer()))
340 setCompositingConsultsOverlap(false);
341 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
342 // If we are a child of a scrollable layer, ignore the overlap from the
343 // scrollable layer as it can cause child layers to become composited
344 // siblings and will not scroll with the main content layer.
345 if (layer->hasOverflowParent())
346 setCompositingConsultsOverlap(false);
349 if (!layer->backing()) {
351 // If we need to repaint, do so before making backing
352 if (shouldRepaint == CompositingChangeRepaintNow)
353 repaintOnCompositingChange(layer);
355 layer->ensureBacking();
357 #if PLATFORM(MAC) && USE(CA)
358 if (m_renderView->document()->settings()->acceleratedDrawingEnabled())
359 layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
360 else if (layer->renderer()->isCanvas()) {
361 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(layer->renderer()->node());
362 if (canvas->renderingContext() && canvas->renderingContext()->isAccelerated())
363 layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
369 if (layer->backing()) {
370 // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
371 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
372 // are both either composited, or not composited.
373 if (layer->isReflection()) {
374 RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer();
375 if (RenderLayerBacking* backing = sourceLayer->backing()) {
376 ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer());
377 backing->graphicsLayer()->setReplicatedByLayer(0);
381 layer->clearBacking();
384 // The layer's cached repaints rects are relative to the repaint container, so change when
385 // compositing changes; we need to update them here.
386 layer->computeRepaintRects();
388 // If we need to repaint, do so now that we've removed the backing
389 if (shouldRepaint == CompositingChangeRepaintNow)
390 repaintOnCompositingChange(layer);
395 if (layerChanged && layer->renderer()->isVideo()) {
396 // If it's a video, give the media player a chance to hook up to the layer.
397 RenderVideo* video = toRenderVideo(layer->renderer());
398 video->acceleratedRenderingStateChanged();
402 if (layerChanged && layer->renderer()->isRenderPart()) {
403 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
404 if (innerCompositor && innerCompositor->inCompositingMode())
405 innerCompositor->updateRootLayerAttachment();
411 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
413 bool layerChanged = updateBacking(layer, shouldRepaint);
415 // See if we need content or clipping layers. Methods called here should assume
416 // that the compositing state of descendant layers has not been updated yet.
417 if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration())
423 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
425 // If the renderer is not attached yet, no need to repaint.
426 if (layer->renderer() != m_renderView && !layer->renderer()->parent())
429 RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint();
430 if (!repaintContainer)
431 repaintContainer = m_renderView;
433 layer->repaintIncludingNonCompositingDescendants(repaintContainer);
434 if (repaintContainer == m_renderView) {
435 // The contents of this layer may be moving between the window
436 // and a GraphicsLayer, so we need to make sure the window system
437 // synchronizes those changes on the screen.
438 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
442 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
443 // RenderLayers that are rendered by the composited RenderLayer.
444 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
446 if (!canBeComposited(layer))
449 IntRect boundingBoxRect = layer->localBoundingBox();
450 if (layer->renderer()->isRoot()) {
451 // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited),
452 // then it has to be big enough to cover the viewport in order to display the background. This is akin
453 // to the code in RenderBox::paintRootBoxFillLayers().
454 if (m_renderView->frameView()) {
455 int rw = m_renderView->frameView()->contentsWidth();
456 int rh = m_renderView->frameView()->contentsHeight();
458 boundingBoxRect.setWidth(max(boundingBoxRect.width(), rw - boundingBoxRect.x()));
459 boundingBoxRect.setHeight(max(boundingBoxRect.height(), rh - boundingBoxRect.y()));
463 IntRect unionBounds = boundingBoxRect;
465 if (layer->renderer()->hasOverflowClip() || layer->renderer()->hasMask()) {
466 int ancestorRelX = 0, ancestorRelY = 0;
467 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
468 boundingBoxRect.move(ancestorRelX, ancestorRelY);
469 return boundingBoxRect;
472 if (RenderLayer* reflection = layer->reflectionLayer()) {
473 if (!reflection->isComposited()) {
474 IntRect childUnionBounds = calculateCompositedBounds(reflection, layer);
475 unionBounds.unite(childUnionBounds);
479 ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0));
481 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
482 size_t listSize = negZOrderList->size();
483 for (size_t i = 0; i < listSize; ++i) {
484 RenderLayer* curLayer = negZOrderList->at(i);
485 if (!curLayer->isComposited()) {
486 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
487 unionBounds.unite(childUnionBounds);
492 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
493 size_t listSize = posZOrderList->size();
494 for (size_t i = 0; i < listSize; ++i) {
495 RenderLayer* curLayer = posZOrderList->at(i);
496 if (!curLayer->isComposited()) {
497 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
498 unionBounds.unite(childUnionBounds);
503 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
504 size_t listSize = normalFlowList->size();
505 for (size_t i = 0; i < listSize; ++i) {
506 RenderLayer* curLayer = normalFlowList->at(i);
507 if (!curLayer->isComposited()) {
508 IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer);
509 unionBounds.unite(curAbsBounds);
514 if (layer->paintsWithTransform(PaintBehaviorNormal)) {
515 TransformationMatrix* affineTrans = layer->transform();
516 boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
517 unionBounds = affineTrans->mapRect(unionBounds);
520 int ancestorRelX = 0, ancestorRelY = 0;
521 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
522 unionBounds.move(ancestorRelX, ancestorRelY);
527 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
529 setCompositingLayersNeedRebuild();
532 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
534 if (!child->isComposited() || parent->renderer()->documentBeingDestroyed())
537 setCompositingParent(child, 0);
539 RenderLayer* compLayer = parent->enclosingCompositingLayer();
541 ASSERT(compLayer->backing());
542 IntRect compBounds = child->backing()->compositedBounds();
544 int offsetX = 0, offsetY = 0;
545 child->convertToLayerCoords(compLayer, offsetX, offsetY);
546 compBounds.move(offsetX, offsetY);
548 compLayer->setBackingNeedsRepaintInRect(compBounds);
550 // The contents of this layer may be moving from a GraphicsLayer to the window,
551 // so we need to make sure the window system synchronizes those changes on the screen.
552 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
555 setCompositingLayersNeedRebuild();
558 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
560 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
561 if (curr->isStackingContext())
564 if (curr->renderer()->hasOverflowClip() || curr->renderer()->hasClip())
570 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
572 if (layer->isRootLayer())
575 if (!boundsComputed) {
576 layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
577 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
578 if (layerBounds.isEmpty())
579 layerBounds.setSize(IntSize(1, 1));
580 boundsComputed = true;
583 overlapMap.add(layer, layerBounds);
586 bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds)
588 RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end();
589 for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {
590 const IntRect& bounds = it->second;
591 if (layerBounds.intersects(bounds)) {
592 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
593 RenderLayer* intersectedLayer = it->first;
594 if (intersectedLayer && intersectedLayer->isFixed()) {
595 if (bounds.contains(layerBounds)) {
607 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
608 // For the z-order children of a compositing layer:
609 // If a child layers has a compositing layer, then all subsequent layers must
610 // be compositing in order to render above that layer.
612 // If a child in the negative z-order list is compositing, then the layer itself
613 // must be compositing so that its contents render over that child.
614 // This implies that its positive z-index children must also be compositing.
616 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, OverlapMap* overlapMap, struct CompositingState& compositingState, bool& layersChanged)
618 layer->updateLayerPosition();
619 layer->updateZOrderLists();
620 layer->updateNormalFlowList();
623 layer->setHasCompositingDescendant(false);
625 bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing;
627 bool haveComputedBounds = false;
629 if (overlapMap && !overlapMap->isEmpty()) {
630 // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
631 absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
632 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
633 if (absBounds.isEmpty())
634 absBounds.setSize(IntSize(1, 1));
635 haveComputedBounds = true;
636 mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
639 layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
641 // The children of this layer don't need to composite, unless there is
642 // a compositing layer among them, so start by inheriting the compositing
643 // ancestor with m_subtreeIsCompositing set to false.
644 CompositingState childState(compositingState.m_compositingAncestor);
646 ++childState.m_depth;
649 bool willBeComposited = needsToBeComposited(layer);
651 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
652 // If we are a fixed layer, signal it to our siblings
653 if (willBeComposited && layer->isFixed())
654 compositingState.m_fixedSibling = true;
656 if (!willBeComposited && compositingState.m_fixedSibling) {
657 layer->setMustOverlapCompositedLayers(true);
658 willBeComposited = true;
661 if (willBeComposited) {
662 // Tell the parent it has compositing descendants.
663 compositingState.m_subtreeIsCompositing = true;
664 // This layer now acts as the ancestor for kids.
665 childState.m_compositingAncestor = layer;
667 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
671 // Video is special. It's a replaced element with a content layer, but has shadow content
672 // for the controller that must render in front. Without this, the controls fail to show
673 // when the video element is a stacking context (e.g. due to opacity or transform).
674 if (willBeComposited && layer->renderer()->isVideo())
675 childState.m_subtreeIsCompositing = true;
678 if (layer->isStackingContext()) {
679 ASSERT(!layer->m_zOrderListsDirty);
680 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
681 size_t listSize = negZOrderList->size();
682 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
683 childState.m_fixedSibling = false;
685 // For the negative z-order, if we have a fixed layer
686 // we need to make all the siblings composited layers.
687 // Otherwise a negative layer (below the fixed layer) could
688 // still be drawn onto a higher z-order layer (e.g. the body)
689 // if not immediately intersecting with our fixed layer.
690 // So it's not enough here to only set m_fixedSibling for
691 // subsequent siblings as we do for the normal flow
692 // and positive z-order.
693 for (size_t j = 0; j < listSize; ++j) {
694 if ((negZOrderList->at(j))->isFixed() &&
695 needsToBeComposited(negZOrderList->at(j))) {
696 childState.m_fixedSibling = true;
702 for (size_t i = 0; i < listSize; ++i) {
703 RenderLayer* curLayer = negZOrderList->at(i);
704 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
706 // If we have to make a layer for this child, make one now so we can have a contents layer
707 // (since we need to ensure that the -ve z-order child renders underneath our contents).
708 if (!willBeComposited && childState.m_subtreeIsCompositing) {
709 // make layer compositing
710 layer->setMustOverlapCompositedLayers(true);
711 childState.m_compositingAncestor = layer;
713 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
714 willBeComposited = true;
720 ASSERT(!layer->m_normalFlowListDirty);
721 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
722 size_t listSize = normalFlowList->size();
723 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
724 childState.m_fixedSibling = false;
726 for (size_t i = 0; i < listSize; ++i) {
727 RenderLayer* curLayer = normalFlowList->at(i);
728 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
732 if (layer->isStackingContext()) {
733 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
734 size_t listSize = posZOrderList->size();
735 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
736 childState.m_fixedSibling = false;
738 for (size_t i = 0; i < listSize; ++i) {
739 RenderLayer* curLayer = posZOrderList->at(i);
740 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
745 // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
746 if (layer->isRootLayer()) {
747 if (inCompositingMode() && m_hasAcceleratedCompositing)
748 willBeComposited = true;
751 ASSERT(willBeComposited == needsToBeComposited(layer));
753 // If we have a software transform, and we have layers under us, we need to also
754 // be composited. Also, if we have opacity < 1, then we need to be a layer so that
755 // the child layers are opaque, then rendered with opacity on this layer.
756 if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
757 layer->setMustOverlapCompositedLayers(true);
759 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
760 willBeComposited = true;
763 ASSERT(willBeComposited == needsToBeComposited(layer));
764 if (layer->reflectionLayer())
765 layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
767 // Subsequent layers in the parent stacking context also need to composite.
768 if (childState.m_subtreeIsCompositing)
769 compositingState.m_subtreeIsCompositing = true;
771 // Set the flag to say that this SC has compositing children.
772 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
774 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
775 // so test that again.
776 if (!willBeComposited && canBeComposited(layer) && clipsCompositingDescendants(layer)) {
778 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
779 willBeComposited = true;
782 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
783 // to be composited, then we can drop out of compositing mode altogether.
784 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
785 enableCompositingMode(false);
786 willBeComposited = false;
789 // If the layer is going into compositing mode, repaint its old location.
790 ASSERT(willBeComposited == needsToBeComposited(layer));
791 if (!layer->isComposited() && willBeComposited)
792 repaintOnCompositingChange(layer);
794 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
795 if (updateBacking(layer, CompositingChangeRepaintNow))
796 layersChanged = true;
798 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
799 layersChanged = true;
802 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
804 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
805 ASSERT(childLayer->isComposited());
807 // It's possible to be called with a parent that isn't yet composited when we're doing
808 // partial updates as required by painting or hit testing. Just bail in that case;
809 // we'll do a full layer update soon.
810 if (!parentLayer || !parentLayer->isComposited())
814 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
815 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers();
817 hostingLayer->addChild(hostedLayer);
819 childLayer->backing()->childForSuperlayers()->removeFromParent();
822 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
824 ASSERT(layer->isComposited());
826 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers();
827 hostingLayer->removeAllChildren();
831 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
833 if (!m_hasAcceleratedCompositing)
836 return o->supportsAcceleratedRendering();
840 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer)
842 // Make the layer compositing if necessary, and set up clipping and content layers.
843 // Note that we can only do work here that is independent of whether the descendant layers
844 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
846 RenderLayerBacking* layerBacking = layer->backing();
848 // The compositing state of all our children has been updated already, so now
849 // we can compute and cache the composited bounds for this layer.
850 layerBacking->updateCompositedBounds();
852 if (RenderLayer* reflection = layer->reflectionLayer()) {
853 if (reflection->backing())
854 reflection->backing()->updateCompositedBounds();
857 layerBacking->updateGraphicsLayerConfiguration();
858 layerBacking->updateGraphicsLayerGeometry();
860 if (!layer->parent())
861 updateRootLayerPosition();
864 // If this layer has backing, then we are collecting its children, otherwise appending
865 // to the compositing child list of an enclosing layer.
866 Vector<GraphicsLayer*> layerChildren;
867 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
869 CompositingState childState = compositingState;
870 if (layer->isComposited())
871 childState.m_compositingAncestor = layer;
874 ++childState.m_depth;
877 // The children of this stacking context don't need to composite, unless there is
878 // a compositing layer among them, so start by assuming false.
879 childState.m_subtreeIsCompositing = false;
881 if (layer->isStackingContext()) {
882 ASSERT(!layer->m_zOrderListsDirty);
884 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
885 size_t listSize = negZOrderList->size();
886 for (size_t i = 0; i < listSize; ++i) {
887 RenderLayer* curLayer = negZOrderList->at(i);
888 rebuildCompositingLayerTree(curLayer, childState, childList);
892 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
893 if (layerBacking && layerBacking->foregroundLayer())
894 childList.append(layerBacking->foregroundLayer());
897 ASSERT(!layer->m_normalFlowListDirty);
898 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
899 size_t listSize = normalFlowList->size();
900 for (size_t i = 0; i < listSize; ++i) {
901 RenderLayer* curLayer = normalFlowList->at(i);
902 rebuildCompositingLayerTree(curLayer, childState, childList);
906 if (layer->isStackingContext()) {
907 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
908 size_t listSize = posZOrderList->size();
909 for (size_t i = 0; i < listSize; ++i) {
910 RenderLayer* curLayer = posZOrderList->at(i);
911 rebuildCompositingLayerTree(curLayer, childState, childList);
917 bool parented = false;
918 if (layer->renderer()->isRenderPart())
919 parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
921 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
922 // Otherwise, the overflow control layers are normal children.
923 if (!layerBacking->hasClippingLayer()) {
924 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) {
925 overflowControlLayer->removeFromParent();
926 layerChildren.append(overflowControlLayer);
929 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) {
930 overflowControlLayer->removeFromParent();
931 layerChildren.append(overflowControlLayer);
934 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) {
935 overflowControlLayer->removeFromParent();
936 layerChildren.append(overflowControlLayer);
941 layerBacking->parentForSublayers()->setChildren(layerChildren);
943 #if ENABLE(FULLSCREEN_API)
944 // For the sake of clients of the full screen renderer, don't reparent
945 // the full screen layer out from under them if they're in the middle of
947 if (layer->renderer()->isRenderFullScreen() && toRenderFullScreen(layer->renderer())->isAnimating())
950 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
954 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
956 if (m_overflowControlsHostLayer)
957 m_overflowControlsHostLayer->setPosition(contentsOffset);
960 void RenderLayerCompositor::frameViewDidChangeSize()
963 FrameView* frameView = m_renderView->frameView();
964 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
966 IntPoint scrollPosition = frameView->scrollPosition();
967 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
968 updateOverflowControlsLayers();
972 void RenderLayerCompositor::frameViewDidScroll(const IntPoint& scrollPosition)
975 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
978 String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo)
980 if (compositingLayerUpdatePending())
981 updateCompositingLayers();
983 if (!m_rootPlatformLayer)
986 // We skip dumping the scroll and clip layers to keep layerTreeAsText output
987 // similar between platforms.
988 return m_rootPlatformLayer->layerTreeAsText(showDebugInfo ? LayerTreeAsTextDebug : LayerTreeAsTextBehaviorNormal);
991 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
993 if (!renderer->node()->isFrameOwnerElement())
996 HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(renderer->node());
997 if (Document* contentDocument = element->contentDocument()) {
998 if (RenderView* view = contentDocument->renderView())
999 return view->compositor();
1004 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
1006 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
1007 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
1010 RenderLayer* layer = renderer->layer();
1011 if (!layer->isComposited())
1014 RenderLayerBacking* backing = layer->backing();
1015 GraphicsLayer* hostingLayer = backing->parentForSublayers();
1016 GraphicsLayer* rootLayer = innerCompositor->rootPlatformLayer();
1017 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
1018 hostingLayer->removeAllChildren();
1019 hostingLayer->addChild(rootLayer);
1024 // This just updates layer geometry without changing the hierarchy.
1025 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
1027 if (RenderLayerBacking* layerBacking = layer->backing()) {
1028 // The compositing state of all our children has been updated already, so now
1029 // we can compute and cache the composited bounds for this layer.
1030 layerBacking->updateCompositedBounds();
1032 if (RenderLayer* reflection = layer->reflectionLayer()) {
1033 if (reflection->backing())
1034 reflection->backing()->updateCompositedBounds();
1037 layerBacking->updateGraphicsLayerConfiguration();
1038 layerBacking->updateGraphicsLayerGeometry();
1040 if (!layer->parent())
1041 updateRootLayerPosition();
1044 if (layer->isStackingContext()) {
1045 ASSERT(!layer->m_zOrderListsDirty);
1047 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1048 size_t listSize = negZOrderList->size();
1049 for (size_t i = 0; i < listSize; ++i)
1050 updateLayerTreeGeometry(negZOrderList->at(i));
1054 ASSERT(!layer->m_normalFlowListDirty);
1055 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1056 size_t listSize = normalFlowList->size();
1057 for (size_t i = 0; i < listSize; ++i)
1058 updateLayerTreeGeometry(normalFlowList->at(i));
1061 if (layer->isStackingContext()) {
1062 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1063 size_t listSize = posZOrderList->size();
1064 for (size_t i = 0; i < listSize; ++i)
1065 updateLayerTreeGeometry(posZOrderList->at(i));
1070 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
1071 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth)
1073 if (layer != compositingAncestor) {
1074 if (RenderLayerBacking* layerBacking = layer->backing()) {
1075 layerBacking->updateCompositedBounds();
1077 if (RenderLayer* reflection = layer->reflectionLayer()) {
1078 if (reflection->backing())
1079 reflection->backing()->updateCompositedBounds();
1082 layerBacking->updateGraphicsLayerGeometry();
1083 if (updateDepth == RenderLayerBacking::CompositingChildren)
1088 if (layer->reflectionLayer())
1089 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth);
1091 if (!layer->hasCompositingDescendant())
1094 if (layer->isStackingContext()) {
1095 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1096 size_t listSize = negZOrderList->size();
1097 for (size_t i = 0; i < listSize; ++i)
1098 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth);
1102 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1103 size_t listSize = normalFlowList->size();
1104 for (size_t i = 0; i < listSize; ++i)
1105 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth);
1108 if (layer->isStackingContext()) {
1109 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1110 size_t listSize = posZOrderList->size();
1111 for (size_t i = 0; i < listSize; ++i)
1112 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth);
1118 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect)
1120 recursiveRepaintLayerRect(rootRenderLayer(), absRect);
1123 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
1125 // FIXME: This method does not work correctly with transforms.
1126 if (layer->isComposited())
1127 layer->setBackingNeedsRepaintInRect(rect);
1129 if (layer->hasCompositingDescendant()) {
1130 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1131 size_t listSize = negZOrderList->size();
1132 for (size_t i = 0; i < listSize; ++i) {
1133 RenderLayer* curLayer = negZOrderList->at(i);
1136 curLayer->convertToLayerCoords(layer, x, y);
1137 IntRect childRect(rect);
1138 childRect.move(-x, -y);
1139 recursiveRepaintLayerRect(curLayer, childRect);
1143 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1144 size_t listSize = posZOrderList->size();
1145 for (size_t i = 0; i < listSize; ++i) {
1146 RenderLayer* curLayer = posZOrderList->at(i);
1149 curLayer->convertToLayerCoords(layer, x, y);
1150 IntRect childRect(rect);
1151 childRect.move(-x, -y);
1152 recursiveRepaintLayerRect(curLayer, childRect);
1156 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1157 size_t listSize = normalFlowList->size();
1158 for (size_t i = 0; i < listSize; ++i) {
1159 RenderLayer* curLayer = normalFlowList->at(i);
1162 curLayer->convertToLayerCoords(layer, x, y);
1163 IntRect childRect(rect);
1164 childRect.move(-x, -y);
1165 recursiveRepaintLayerRect(curLayer, childRect);
1170 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
1172 return m_renderView->layer();
1175 GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const
1177 if (m_overflowControlsHostLayer)
1178 return m_overflowControlsHostLayer.get();
1179 return m_rootPlatformLayer.get();
1182 void RenderLayerCompositor::didMoveOnscreen()
1184 if (!inCompositingMode() || m_rootLayerAttachment != RootLayerUnattached)
1187 RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1188 attachRootPlatformLayer(attachment);
1191 void RenderLayerCompositor::willMoveOffscreen()
1193 if (!inCompositingMode() || m_rootLayerAttachment == RootLayerUnattached)
1196 detachRootPlatformLayer();
1199 void RenderLayerCompositor::updateRootLayerPosition()
1201 if (m_rootPlatformLayer) {
1202 m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight()));
1203 m_rootPlatformLayer->setPosition(FloatPoint(m_renderView->docLeft(), m_renderView->docTop()));
1206 FrameView* frameView = m_renderView->frameView();
1207 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1211 void RenderLayerCompositor::didStartAcceleratedAnimation(CSSPropertyID property)
1213 // If an accelerated animation or transition runs, we have to turn off overlap checking because
1214 // we don't do layout for every frame, but we have to ensure that the layering is
1215 // correct between the animating object and other objects on the page.
1216 if (property == CSSPropertyWebkitTransform)
1217 setCompositingConsultsOverlap(false);
1220 bool RenderLayerCompositor::has3DContent() const
1222 return layerHas3DContent(rootRenderLayer());
1225 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)
1228 // frames are only independently composited in Mac pre-WebKit2.
1229 return view->platformWidget();
1234 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const
1236 #if PLATFORM(ANDROID)
1237 if (enclosingFrameElement() && !allowsIndependentlyCompositedFrames(m_renderView->frameView()))
1240 // Parent document content needs to be able to render on top of a composited frame, so correct behavior
1241 // is to have the parent document become composited too. However, this can cause problems on platforms that
1242 // use native views for frames (like Mac), so disable that behavior on those platforms for now.
1243 HTMLFrameOwnerElement* ownerElement = enclosingFrameElement();
1244 RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0;
1246 // If we are the top-level frame, don't propagate.
1250 if (!allowsIndependentlyCompositedFrames(m_renderView->frameView()))
1253 if (!renderer || !renderer->isRenderPart())
1256 // On Mac, only propagate compositing if the frame is overlapped in the parent
1257 // document, or the parent is already compositing, or the main frame is scaled.
1258 Frame* frame = m_renderView->frameView()->frame();
1259 Page* page = frame ? frame->page() : 0;
1260 if (page->mainFrame()->pageScaleFactor() != 1)
1263 RenderPart* frameRenderer = toRenderPart(renderer);
1264 if (frameRenderer->widget()) {
1265 ASSERT(frameRenderer->widget()->isFrameView());
1266 FrameView* view = static_cast<FrameView*>(frameRenderer->widget());
1267 if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor())
1274 HTMLFrameOwnerElement* RenderLayerCompositor::enclosingFrameElement() const
1276 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
1277 return (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(objectTag)) ? ownerElement : 0;
1282 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
1284 if (!canBeComposited(layer))
1287 // The root layer always has a compositing layer, but it may not have backing.
1288 return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
1291 #if PLATFORM(ANDROID)
1292 bool RenderLayerCompositor::requiresCompositingForAndroidLayers(const RenderLayer* layer) const
1294 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
1295 if (layer->hasOverflowScroll())
1297 if (layer->isRootLayer() && m_renderView->frameView()->hasOverflowScroll())
1300 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
1302 // Enable composited layers (for fixed elements)
1303 if (layer->isFixed())
1310 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
1311 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
1313 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
1315 RenderObject* renderer = layer->renderer();
1316 // The compositing state of a reflection should match that of its reflected layer.
1317 if (layer->isReflection()) {
1318 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
1319 layer = toRenderBoxModelObject(renderer)->layer();
1321 return requiresCompositingForTransform(renderer)
1322 #if PLATFORM(ANDROID)
1323 || requiresCompositingForAndroidLayers(layer)
1325 || requiresCompositingForVideo(renderer)
1326 || requiresCompositingForCanvas(renderer)
1327 || requiresCompositingForPlugin(renderer)
1328 || requiresCompositingForFrame(renderer)
1329 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1330 || clipsCompositingDescendants(layer)
1331 || requiresCompositingForAnimation(renderer)
1332 || requiresCompositingForFullScreen(renderer);
1335 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
1337 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer();
1340 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1341 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1342 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1343 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1344 // but a sibling in the z-order hierarchy.
1345 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
1347 if (!layer->isComposited() || !layer->parent())
1350 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1351 if (!compositingAncestor)
1354 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
1355 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
1357 RenderLayer* computeClipRoot = 0;
1358 RenderLayer* curr = layer;
1360 RenderLayer* next = curr->parent();
1361 if (next == compositingAncestor) {
1362 computeClipRoot = curr;
1368 if (!computeClipRoot || computeClipRoot == layer)
1371 IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true);
1372 return backgroundRect != PaintInfo::infiniteRect();
1375 // Return true if the given layer is a stacking context and has compositing child
1376 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1377 // into the hierarchy between this layer and its children in the z-order hierarchy.
1378 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1380 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
1381 if (layer->hasOverflowScroll())
1384 return layer->hasCompositingDescendant() &&
1385 (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip());
1388 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
1390 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
1393 RenderStyle* style = renderer->style();
1394 // Note that we ask the renderer if it has a transform, because the style may have transforms,
1395 // but the renderer may be an inline that doesn't suppport them.
1396 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
1399 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
1401 if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
1404 if (renderer->isVideo()) {
1405 RenderVideo* video = toRenderVideo(renderer);
1406 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
1408 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1409 else if (renderer->isRenderPart()) {
1410 if (!m_hasAcceleratedCompositing)
1413 Node* node = renderer->node();
1414 if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag)))
1417 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node);
1418 return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false;
1420 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1422 UNUSED_PARAM(renderer);
1427 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
1429 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
1432 if (renderer->isCanvas()) {
1433 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
1434 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
1439 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
1441 if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
1444 bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
1445 || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing());
1449 m_compositingDependsOnGeometry = true;
1451 RenderWidget* pluginRenderer = toRenderWidget(renderer);
1452 // If we can't reliably know the size of the plugin yet, don't change compositing state.
1453 if (pluginRenderer->needsLayout())
1454 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited();
1456 // Don't go into compositing mode if height or width are zero, or size is 1x1.
1457 IntRect contentBox = pluginRenderer->contentBoxRect();
1458 return contentBox.height() * contentBox.width() > 1;
1461 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
1463 if (!renderer->isRenderPart())
1466 RenderPart* frameRenderer = toRenderPart(renderer);
1468 if (!frameRenderer->requiresAcceleratedCompositing())
1471 m_compositingDependsOnGeometry = true;
1473 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
1474 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())
1477 // If we can't reliably know the size of the iframe yet, don't change compositing state.
1478 if (renderer->needsLayout())
1479 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited();
1481 // Don't go into compositing mode if height or width are zero.
1482 IntRect contentBox = frameRenderer->contentBoxRect();
1483 return contentBox.height() * contentBox.width() > 0;
1486 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
1488 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1491 if (AnimationController* animController = renderer->animation()) {
1492 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
1493 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1498 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
1500 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection();
1503 bool RenderLayerCompositor::requiresCompositingForFullScreen(RenderObject* renderer) const
1505 #if ENABLE(FULLSCREEN_API)
1506 return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating();
1508 UNUSED_PARAM(renderer);
1513 // If an element has negative z-index children, those children render in front of the
1514 // layer background, so we need an extra 'contents' layer for the foreground of the layer
1516 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
1518 return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0);
1521 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
1523 #if PLATFORM(ANDROID)
1524 // Recently, RenderLayerCompositor is changed to be a subclass of
1525 // GraphicsLayerClient, and it is used for iframe.
1526 // http://trac.webkit.org/changeset/75262
1527 // We have our own support for iframe, before we embrace this new approach,
1528 // we will disable it.
1529 // TODO: Investigate how to utilize this way to support iframe.
1532 // We need to handle our own scrolling if we're:
1533 return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
1534 || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
1537 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1543 const IntRect& scrollbarRect = scrollbar->frameRect();
1544 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1545 IntRect transformedClip = clip;
1546 transformedClip.move(scrollbarRect.x(), scrollbarRect.y());
1547 scrollbar->paint(&context, transformedClip);
1551 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
1553 if (graphicsLayer == layerForHorizontalScrollbar())
1554 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
1555 else if (graphicsLayer == layerForVerticalScrollbar())
1556 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
1557 else if (graphicsLayer == layerForScrollCorner()) {
1558 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
1560 context.translate(-scrollCorner.x(), -scrollCorner.y());
1561 IntRect transformedClip = clip;
1562 transformedClip.move(scrollCorner.x(), scrollCorner.y());
1563 m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
1568 static bool shouldCompositeOverflowControls(ScrollView* view)
1570 if (view->platformWidget())
1572 #if !PLATFORM(CHROMIUM)
1573 if (!view->hasOverlayScrollbars())
1579 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
1581 ScrollView* view = m_renderView->frameView();
1582 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
1585 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
1587 ScrollView* view = m_renderView->frameView();
1588 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
1591 bool RenderLayerCompositor::requiresScrollCornerLayer() const
1593 ScrollView* view = m_renderView->frameView();
1594 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
1597 void RenderLayerCompositor::updateOverflowControlsLayers()
1599 bool layersChanged = false;
1601 if (requiresHorizontalScrollbarLayer()) {
1602 m_layerForHorizontalScrollbar = GraphicsLayer::create(this);
1604 m_layerForHorizontalScrollbar->setName("horizontal scrollbar");
1606 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
1607 layersChanged = true;
1608 } else if (m_layerForHorizontalScrollbar) {
1609 m_layerForHorizontalScrollbar->removeFromParent();
1610 m_layerForHorizontalScrollbar = 0;
1611 layersChanged = true;
1614 if (requiresVerticalScrollbarLayer()) {
1615 m_layerForVerticalScrollbar = GraphicsLayer::create(this);
1617 m_layerForVerticalScrollbar->setName("vertical scrollbar");
1619 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
1620 layersChanged = true;
1621 } else if (m_layerForVerticalScrollbar) {
1622 m_layerForVerticalScrollbar->removeFromParent();
1623 m_layerForVerticalScrollbar = 0;
1624 layersChanged = true;
1627 if (requiresScrollCornerLayer()) {
1628 m_layerForScrollCorner = GraphicsLayer::create(this);
1630 m_layerForScrollCorner->setName("scroll corner");
1632 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
1633 layersChanged = true;
1634 } else if (m_layerForScrollCorner) {
1635 m_layerForScrollCorner->removeFromParent();
1636 m_layerForScrollCorner = 0;
1637 layersChanged = true;
1641 m_renderView->frameView()->positionScrollbarLayers();
1644 void RenderLayerCompositor::ensureRootPlatformLayer()
1646 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1647 if (expectedAttachment == m_rootLayerAttachment)
1650 if (!m_rootPlatformLayer) {
1651 m_rootPlatformLayer = GraphicsLayer::create(0);
1653 m_rootPlatformLayer->setName("Root platform");
1655 m_rootPlatformLayer->setSize(FloatSize(m_renderView->maxXLayoutOverflow(), m_renderView->maxYLayoutOverflow()));
1656 m_rootPlatformLayer->setPosition(FloatPoint());
1658 // Need to clip to prevent transformed content showing outside this frame
1659 m_rootPlatformLayer->setMasksToBounds(true);
1662 if (requiresScrollLayer(expectedAttachment)) {
1663 if (!m_overflowControlsHostLayer) {
1664 ASSERT(!m_scrollLayer);
1665 ASSERT(!m_clipLayer);
1667 // Create a layer to host the clipping layer and the overflow controls layers.
1668 m_overflowControlsHostLayer = GraphicsLayer::create(0);
1670 m_overflowControlsHostLayer->setName("overflow controls host");
1673 // Create a clipping layer if this is an iframe
1674 m_clipLayer = GraphicsLayer::create(this);
1676 m_clipLayer->setName("iframe Clipping");
1678 m_clipLayer->setMasksToBounds(true);
1680 m_scrollLayer = GraphicsLayer::create(this);
1682 m_scrollLayer->setName("iframe scrolling");
1686 m_overflowControlsHostLayer->addChild(m_clipLayer.get());
1687 m_clipLayer->addChild(m_scrollLayer.get());
1688 m_scrollLayer->addChild(m_rootPlatformLayer.get());
1690 frameViewDidChangeSize();
1691 frameViewDidScroll(m_renderView->frameView()->scrollPosition());
1694 if (m_overflowControlsHostLayer) {
1695 m_overflowControlsHostLayer = 0;
1701 // Check to see if we have to change the attachment
1702 if (m_rootLayerAttachment != RootLayerUnattached)
1703 detachRootPlatformLayer();
1705 attachRootPlatformLayer(expectedAttachment);
1708 void RenderLayerCompositor::destroyRootPlatformLayer()
1710 if (!m_rootPlatformLayer)
1713 detachRootPlatformLayer();
1715 if (m_layerForHorizontalScrollbar) {
1716 m_layerForHorizontalScrollbar->removeFromParent();
1717 m_layerForHorizontalScrollbar = 0;
1718 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
1719 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
1722 if (m_layerForVerticalScrollbar) {
1723 m_layerForVerticalScrollbar->removeFromParent();
1724 m_layerForVerticalScrollbar = 0;
1725 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
1726 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
1729 if (m_layerForScrollCorner) {
1730 m_layerForScrollCorner = 0;
1731 m_renderView->frameView()->invalidateScrollCorner();
1734 if (m_overflowControlsHostLayer) {
1735 m_overflowControlsHostLayer = 0;
1739 ASSERT(!m_scrollLayer);
1740 m_rootPlatformLayer = 0;
1743 void RenderLayerCompositor::attachRootPlatformLayer(RootLayerAttachment attachment)
1745 if (!m_rootPlatformLayer)
1748 switch (attachment) {
1749 case RootLayerUnattached:
1750 ASSERT_NOT_REACHED();
1752 case RootLayerAttachedViaChromeClient: {
1753 Frame* frame = m_renderView->frameView()->frame();
1754 Page* page = frame ? frame->page() : 0;
1758 page->chrome()->client()->attachRootGraphicsLayer(frame, rootPlatformLayer());
1761 case RootLayerAttachedViaEnclosingFrame: {
1762 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
1763 // for the frame's renderer in the parent document.
1764 scheduleNeedsStyleRecalc(m_renderView->document()->ownerElement());
1769 m_rootLayerAttachment = attachment;
1770 rootLayerAttachmentChanged();
1773 void RenderLayerCompositor::detachRootPlatformLayer()
1775 if (!m_rootPlatformLayer || m_rootLayerAttachment == RootLayerUnattached)
1778 switch (m_rootLayerAttachment) {
1779 case RootLayerAttachedViaEnclosingFrame: {
1780 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
1781 // for the frame's renderer in the parent document.
1782 if (m_overflowControlsHostLayer)
1783 m_overflowControlsHostLayer->removeFromParent();
1785 m_rootPlatformLayer->removeFromParent();
1787 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
1788 scheduleNeedsStyleRecalc(ownerElement);
1791 case RootLayerAttachedViaChromeClient: {
1792 Frame* frame = m_renderView->frameView()->frame();
1793 Page* page = frame ? frame->page() : 0;
1797 page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
1800 case RootLayerUnattached:
1804 m_rootLayerAttachment = RootLayerUnattached;
1805 rootLayerAttachmentChanged();
1808 void RenderLayerCompositor::updateRootLayerAttachment()
1810 ensureRootPlatformLayer();
1813 void RenderLayerCompositor::rootLayerAttachmentChanged()
1815 // The attachment can affect whether the RenderView layer's paintingGoesToWindow() behavior,
1816 // so call updateGraphicsLayerGeometry() to udpate that.
1817 RenderLayer* layer = m_renderView->layer();
1818 if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
1819 backing->updateDrawsContent();
1822 static void needsStyleRecalcCallback(Node* node)
1824 node->setNeedsStyleRecalc(SyntheticStyleChange);
1827 void RenderLayerCompositor::scheduleNeedsStyleRecalc(Element* element)
1829 if (ContainerNode::postAttachCallbacksAreSuspended())
1830 ContainerNode::queuePostAttachCallback(needsStyleRecalcCallback, element);
1832 element->setNeedsStyleRecalc(SyntheticStyleChange);
1835 // IFrames are special, because we hook compositing layers together across iframe boundaries
1836 // when both parent and iframe content are composited. So when this frame becomes composited, we have
1837 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
1838 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
1840 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0;
1844 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) {
1845 if (child->document() && child->document()->ownerElement())
1846 scheduleNeedsStyleRecalc(child->document()->ownerElement());
1849 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
1850 // we need to schedule a style recalc in our parent document.
1851 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
1852 scheduleNeedsStyleRecalc(ownerElement);
1855 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
1857 const RenderStyle* style = layer->renderer()->style();
1860 (style->transformStyle3D() == TransformStyle3DPreserve3D ||
1861 style->hasPerspective() ||
1862 style->transform().has3DOperation()))
1865 if (layer->isStackingContext()) {
1866 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1867 size_t listSize = negZOrderList->size();
1868 for (size_t i = 0; i < listSize; ++i) {
1869 RenderLayer* curLayer = negZOrderList->at(i);
1870 if (layerHas3DContent(curLayer))
1875 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1876 size_t listSize = posZOrderList->size();
1877 for (size_t i = 0; i < listSize; ++i) {
1878 RenderLayer* curLayer = posZOrderList->at(i);
1879 if (layerHas3DContent(curLayer))
1885 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1886 size_t listSize = normalFlowList->size();
1887 for (size_t i = 0; i < listSize; ++i) {
1888 RenderLayer* curLayer = normalFlowList->at(i);
1889 if (layerHas3DContent(curLayer))
1896 void RenderLayerCompositor::updateContentsScale(float scale, RenderLayer* layer)
1899 layer = rootRenderLayer();
1901 layer->updateContentsScale(scale);
1903 if (layer->isStackingContext()) {
1904 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1905 size_t listSize = negZOrderList->size();
1906 for (size_t i = 0; i < listSize; ++i)
1907 updateContentsScale(scale, negZOrderList->at(i));
1910 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1911 size_t listSize = posZOrderList->size();
1912 for (size_t i = 0; i < listSize; ++i)
1913 updateContentsScale(scale, posZOrderList->at(i));
1917 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1918 size_t listSize = normalFlowList->size();
1919 for (size_t i = 0; i < listSize; ++i)
1920 updateContentsScale(scale, normalFlowList->at(i));
1924 } // namespace WebCore
1926 #endif // USE(ACCELERATED_COMPOSITING)