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)
82 , m_hasFixedElement(false)
84 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
85 , m_hasScrollableElement(false)
93 RenderLayer* m_compositingAncestor;
94 bool m_subtreeIsCompositing;
95 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
97 bool m_hasFixedElement;
99 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
100 bool m_hasScrollableElement;
107 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
108 : m_renderView(renderView)
109 , m_rootPlatformLayer(0)
110 , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
111 , m_hasAcceleratedCompositing(true)
112 , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
113 , m_showDebugBorders(false)
114 , m_showRepaintCounter(false)
115 , m_compositingConsultsOverlap(true)
116 , m_compositingDependsOnGeometry(false)
117 , m_compositing(false)
118 , m_compositingLayersNeedRebuild(false)
119 , m_flushingLayers(false)
120 , m_forceCompositingMode(false)
121 , m_rootLayerAttachment(RootLayerUnattached)
122 #if PROFILE_LAYER_REBUILD
123 , m_rootLayerUpdateCount(0)
124 #endif // PROFILE_LAYER_REBUILD
126 Settings* settings = m_renderView->document()->settings();
128 // Even when forcing compositing mode, ignore child frames, or this will trigger
129 // layer creation from the enclosing RenderIFrame.
130 ASSERT(m_renderView->document()->frame());
131 if (settings && settings->forceCompositingMode() && settings->acceleratedCompositingEnabled()
132 && !m_renderView->document()->frame()->tree()->parent()) {
133 m_forceCompositingMode = true;
134 enableCompositingMode();
138 RenderLayerCompositor::~RenderLayerCompositor()
140 ASSERT(m_rootLayerAttachment == RootLayerUnattached);
143 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
145 if (enable != m_compositing) {
146 m_compositing = enable;
149 ensureRootPlatformLayer();
150 notifyIFramesOfCompositingChange();
152 destroyRootPlatformLayer();
156 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
158 bool hasAcceleratedCompositing = false;
159 bool showDebugBorders = false;
160 bool showRepaintCounter = false;
162 if (Settings* settings = m_renderView->document()->settings()) {
163 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
164 showDebugBorders = settings->showDebugBorders();
165 showRepaintCounter = settings->showRepaintCounter();
168 // We allow the chrome to override the settings, in case the page is rendered
169 // on a chrome that doesn't allow accelerated compositing.
170 if (hasAcceleratedCompositing) {
171 Frame* frame = m_renderView->frameView()->frame();
172 Page* page = frame ? frame->page() : 0;
174 ChromeClient* chromeClient = page->chrome()->client();
175 m_compositingTriggers = chromeClient->allowedCompositingTriggers();
176 hasAcceleratedCompositing = m_compositingTriggers;
180 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter)
181 setCompositingLayersNeedRebuild();
183 m_hasAcceleratedCompositing = hasAcceleratedCompositing;
184 m_showDebugBorders = showDebugBorders;
185 m_showRepaintCounter = showRepaintCounter;
188 bool RenderLayerCompositor::canRender3DTransforms() const
190 return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
193 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
195 if (inCompositingMode())
196 m_compositingLayersNeedRebuild = needRebuild;
199 void RenderLayerCompositor::scheduleLayerFlush()
201 Frame* frame = m_renderView->frameView()->frame();
202 Page* page = frame ? frame->page() : 0;
206 page->chrome()->client()->scheduleCompositingLayerSync();
209 void RenderLayerCompositor::flushPendingLayerChanges()
211 ASSERT(!m_flushingLayers);
212 m_flushingLayers = true;
214 // FIXME: FrameView::syncCompositingStateRecursive() calls this for each
215 // frame, so when compositing layers are connected between frames, we'll
216 // end up syncing subframe's layers multiple times.
217 // https://bugs.webkit.org/show_bug.cgi?id=52489
218 if (GraphicsLayer* rootLayer = rootPlatformLayer())
219 rootLayer->syncCompositingState();
221 ASSERT(m_flushingLayers);
222 m_flushingLayers = false;
225 RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const
227 if (!m_renderView->frameView())
230 for (Frame* frame = m_renderView->frameView()->frame(); frame; frame = frame->tree()->parent()) {
231 RenderLayerCompositor* compositor = frame->contentRenderer() ? frame->contentRenderer()->compositor() : 0;
232 if (compositor->isFlushingLayers())
239 void RenderLayerCompositor::scheduleCompositingLayerUpdate()
241 if (!m_updateCompositingLayersTimer.isActive())
242 m_updateCompositingLayersTimer.startOneShot(0);
245 bool RenderLayerCompositor::compositingLayerUpdatePending() const
247 return m_updateCompositingLayersTimer.isActive();
250 void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*)
252 updateCompositingLayers();
255 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
257 m_updateCompositingLayersTimer.stop();
259 if (!m_compositingDependsOnGeometry && !m_compositing)
262 bool checkForHierarchyUpdate = m_compositingDependsOnGeometry;
263 bool needGeometryUpdate = false;
265 switch (updateType) {
266 case CompositingUpdateAfterLayoutOrStyleChange:
267 case CompositingUpdateOnPaitingOrHitTest:
268 checkForHierarchyUpdate = true;
270 case CompositingUpdateOnScroll:
271 if (m_compositingConsultsOverlap)
272 checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
274 needGeometryUpdate = true;
278 if (!checkForHierarchyUpdate && !needGeometryUpdate)
281 bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
282 if (!updateRoot || m_compositingConsultsOverlap) {
283 // Only clear the flag if we're updating the entire hierarchy.
284 m_compositingLayersNeedRebuild = false;
285 updateRoot = rootRenderLayer();
288 #if PROFILE_LAYER_REBUILD
289 ++m_rootLayerUpdateCount;
291 double startTime = WTF::currentTime();
294 if (checkForHierarchyUpdate) {
295 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
296 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
297 CompositingState compState(updateRoot);
298 bool layersChanged = false;
300 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
301 compState.m_hasFixedElement = false;
303 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
304 compState.m_hasScrollableElement = false;
306 if (m_compositingConsultsOverlap) {
307 OverlapMap overlapTestRequestMap;
308 computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged);
310 computeCompositingRequirements(updateRoot, 0, compState, layersChanged);
312 needHierarchyUpdate |= layersChanged;
315 if (needHierarchyUpdate) {
316 // Update the hierarchy of the compositing layers.
317 CompositingState compState(updateRoot);
318 Vector<GraphicsLayer*> childList;
319 rebuildCompositingLayerTree(updateRoot, compState, childList);
321 // Host the document layer in the RenderView's root layer.
322 if (updateRoot == rootRenderLayer()) {
323 if (childList.isEmpty())
324 destroyRootPlatformLayer();
326 m_rootPlatformLayer->setChildren(childList);
328 } else if (needGeometryUpdate) {
329 // We just need to do a geometry update. This is only used for position:fixed scrolling;
330 // most of the time, geometry is updated via RenderLayer::styleChanged().
331 updateLayerTreeGeometry(updateRoot);
334 #if PROFILE_LAYER_REBUILD
335 double endTime = WTF::currentTime();
336 if (updateRoot == rootRenderLayer())
337 fprintf(stderr, "Update %d: computeCompositingRequirements for the world took %fms\n",
338 m_rootLayerUpdateCount, 1000.0 * (endTime - startTime));
340 ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
342 if (!hasAcceleratedCompositing())
343 enableCompositingMode(false);
346 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
348 bool layerChanged = false;
350 if (needsToBeComposited(layer)) {
351 enableCompositingMode();
353 // 3D transforms turn off the testing of overlap.
354 if (requiresCompositingForTransform(layer->renderer()))
355 setCompositingConsultsOverlap(false);
356 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
357 // If we are a child of a scrollable layer, ignore the overlap from the
358 // scrollable layer as it can cause child layers to become composited
359 // siblings and will not scroll with the main content layer.
360 if (layer->hasOverflowParent())
361 setCompositingConsultsOverlap(false);
364 if (!layer->backing()) {
366 // If we need to repaint, do so before making backing
367 if (shouldRepaint == CompositingChangeRepaintNow)
368 repaintOnCompositingChange(layer);
370 layer->ensureBacking();
372 #if PLATFORM(MAC) && USE(CA)
373 if (m_renderView->document()->settings()->acceleratedDrawingEnabled())
374 layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
375 else if (layer->renderer()->isCanvas()) {
376 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(layer->renderer()->node());
377 if (canvas->renderingContext() && canvas->renderingContext()->isAccelerated())
378 layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
384 if (layer->backing()) {
385 // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
386 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
387 // are both either composited, or not composited.
388 if (layer->isReflection()) {
389 RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer();
390 if (RenderLayerBacking* backing = sourceLayer->backing()) {
391 ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer());
392 backing->graphicsLayer()->setReplicatedByLayer(0);
396 layer->clearBacking();
399 // The layer's cached repaints rects are relative to the repaint container, so change when
400 // compositing changes; we need to update them here.
401 layer->computeRepaintRects();
403 // If we need to repaint, do so now that we've removed the backing
404 if (shouldRepaint == CompositingChangeRepaintNow)
405 repaintOnCompositingChange(layer);
410 if (layerChanged && layer->renderer()->isVideo()) {
411 // If it's a video, give the media player a chance to hook up to the layer.
412 RenderVideo* video = toRenderVideo(layer->renderer());
413 video->acceleratedRenderingStateChanged();
417 if (layerChanged && layer->renderer()->isRenderPart()) {
418 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
419 if (innerCompositor && innerCompositor->inCompositingMode())
420 innerCompositor->updateRootLayerAttachment();
426 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
428 bool layerChanged = updateBacking(layer, shouldRepaint);
430 // See if we need content or clipping layers. Methods called here should assume
431 // that the compositing state of descendant layers has not been updated yet.
432 if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration())
438 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
440 // If the renderer is not attached yet, no need to repaint.
441 if (layer->renderer() != m_renderView && !layer->renderer()->parent())
444 RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint();
445 if (!repaintContainer)
446 repaintContainer = m_renderView;
448 layer->repaintIncludingNonCompositingDescendants(repaintContainer);
449 if (repaintContainer == m_renderView) {
450 // The contents of this layer may be moving between the window
451 // and a GraphicsLayer, so we need to make sure the window system
452 // synchronizes those changes on the screen.
453 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
457 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
458 // RenderLayers that are rendered by the composited RenderLayer.
459 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
461 if (!canBeComposited(layer))
464 IntRect boundingBoxRect = layer->localBoundingBox();
465 if (layer->renderer()->isRoot()) {
466 // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited),
467 // then it has to be big enough to cover the viewport in order to display the background. This is akin
468 // to the code in RenderBox::paintRootBoxFillLayers().
469 if (m_renderView->frameView()) {
470 int rw = m_renderView->frameView()->contentsWidth();
471 int rh = m_renderView->frameView()->contentsHeight();
473 boundingBoxRect.setWidth(max(boundingBoxRect.width(), rw - boundingBoxRect.x()));
474 boundingBoxRect.setHeight(max(boundingBoxRect.height(), rh - boundingBoxRect.y()));
478 IntRect unionBounds = boundingBoxRect;
480 if (layer->renderer()->hasOverflowClip() || layer->renderer()->hasMask()) {
481 int ancestorRelX = 0, ancestorRelY = 0;
482 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
483 boundingBoxRect.move(ancestorRelX, ancestorRelY);
484 return boundingBoxRect;
487 if (RenderLayer* reflection = layer->reflectionLayer()) {
488 if (!reflection->isComposited()) {
489 IntRect childUnionBounds = calculateCompositedBounds(reflection, layer);
490 unionBounds.unite(childUnionBounds);
494 ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0));
496 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
497 size_t listSize = negZOrderList->size();
498 for (size_t i = 0; i < listSize; ++i) {
499 RenderLayer* curLayer = negZOrderList->at(i);
500 if (!curLayer->isComposited()) {
501 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
502 unionBounds.unite(childUnionBounds);
507 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
508 size_t listSize = posZOrderList->size();
509 for (size_t i = 0; i < listSize; ++i) {
510 RenderLayer* curLayer = posZOrderList->at(i);
511 if (!curLayer->isComposited()) {
512 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
513 unionBounds.unite(childUnionBounds);
518 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
519 size_t listSize = normalFlowList->size();
520 for (size_t i = 0; i < listSize; ++i) {
521 RenderLayer* curLayer = normalFlowList->at(i);
522 if (!curLayer->isComposited()) {
523 IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer);
524 unionBounds.unite(curAbsBounds);
529 if (layer->paintsWithTransform(PaintBehaviorNormal)) {
530 TransformationMatrix* affineTrans = layer->transform();
531 boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
532 unionBounds = affineTrans->mapRect(unionBounds);
535 int ancestorRelX = 0, ancestorRelY = 0;
536 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
537 unionBounds.move(ancestorRelX, ancestorRelY);
542 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
544 setCompositingLayersNeedRebuild();
547 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
549 if (!child->isComposited() || parent->renderer()->documentBeingDestroyed())
552 setCompositingParent(child, 0);
554 RenderLayer* compLayer = parent->enclosingCompositingLayer();
556 ASSERT(compLayer->backing());
557 IntRect compBounds = child->backing()->compositedBounds();
559 int offsetX = 0, offsetY = 0;
560 child->convertToLayerCoords(compLayer, offsetX, offsetY);
561 compBounds.move(offsetX, offsetY);
563 compLayer->setBackingNeedsRepaintInRect(compBounds);
565 // The contents of this layer may be moving from a GraphicsLayer to the window,
566 // so we need to make sure the window system synchronizes those changes on the screen.
567 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
570 setCompositingLayersNeedRebuild();
573 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
575 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
576 if (curr->isStackingContext())
579 if (curr->renderer()->hasOverflowClip() || curr->renderer()->hasClip())
585 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
587 if (layer->isRootLayer())
590 if (!boundsComputed) {
591 layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
592 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
593 if (layerBounds.isEmpty())
594 layerBounds.setSize(IntSize(1, 1));
595 boundsComputed = true;
598 overlapMap.add(layer, layerBounds);
601 bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds)
603 RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end();
604 for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {
605 const IntRect& bounds = it->second;
606 if (layerBounds.intersects(bounds)) {
614 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
616 // to properly support z-index with composited fixed elements, we need to turn
617 // layers following a fixed layer into compositing mode; but if a layer is fully
618 // contained into a previous layer already composited (that is not the fixed
619 // layer), we don't need to composite it. This saves up quite a bit on the
620 // number of layers we have to composite.
622 bool RenderLayerCompositor::checkForFixedLayers(Vector<RenderLayer*>* list, bool stopAtFixedLayer)
624 int listSize = list->size();
625 int haveFixedLayer = -1;
626 bool fixedSibling = false;
627 for (int j = 0; j < listSize; ++j) {
628 RenderLayer* currentLayer = list->at(j);
629 if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) {
633 IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad(
634 FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox();
635 if ((currentLayerBounds.width() <= 1
636 || currentLayerBounds.height() <= 1)
637 && haveFixedLayer == j) {
639 fixedSibling = false;
641 if (haveFixedLayer != -1 && haveFixedLayer != j) {
642 bool needComposite = true;
644 if (stopAtFixedLayer)
645 stop = haveFixedLayer + 1;
647 for (int k = j - 1; k >= stop; --k) {
648 RenderLayer* aLayer = list->at(k);
649 if (aLayer && aLayer->renderer()) {
650 IntRect bounds = aLayer->renderer()->localToAbsoluteQuad(
651 FloatRect(aLayer->localBoundingBox())).enclosingBoundingBox();
652 if (bounds.contains(currentLayerBounds)
653 && needsToBeComposited(aLayer) && aLayer->isStackingContext()) {
654 needComposite = false;
659 currentLayer->setShouldComposite(needComposite);
667 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
668 // For the z-order children of a compositing layer:
669 // If a child layers has a compositing layer, then all subsequent layers must
670 // be compositing in order to render above that layer.
672 // If a child in the negative z-order list is compositing, then the layer itself
673 // must be compositing so that its contents render over that child.
674 // This implies that its positive z-index children must also be compositing.
676 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, OverlapMap* overlapMap, struct CompositingState& compositingState, bool& layersChanged)
678 layer->updateLayerPosition();
679 layer->updateZOrderLists();
680 layer->updateNormalFlowList();
683 layer->setHasCompositingDescendant(false);
685 bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing;
687 bool haveComputedBounds = false;
689 if (overlapMap && !overlapMap->isEmpty()) {
690 // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
691 absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
692 // Empty rects never intersect, but we need them to for the purposes of overlap testing.
693 if (absBounds.isEmpty())
694 absBounds.setSize(IntSize(1, 1));
695 haveComputedBounds = true;
696 mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
699 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
700 if (compositingState.m_fixedSibling)
701 layer->setMustOverlapCompositedLayers(layer->shouldComposite());
703 layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
705 layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
708 // The children of this layer don't need to composite, unless there is
709 // a compositing layer among them, so start by inheriting the compositing
710 // ancestor with m_subtreeIsCompositing set to false.
711 CompositingState childState(compositingState.m_compositingAncestor);
713 ++childState.m_depth;
716 bool willBeComposited = needsToBeComposited(layer);
718 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
719 // tell the parent it has scrollable descendants.
720 if (layer->hasOverflowScroll())
721 compositingState.m_hasScrollableElement = true;
723 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
724 if (layer->isFixed())
725 compositingState.m_hasFixedElement = true;
727 if (willBeComposited) {
728 // Tell the parent it has compositing descendants.
729 compositingState.m_subtreeIsCompositing = true;
730 // This layer now acts as the ancestor for kids.
731 childState.m_compositingAncestor = layer;
733 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
737 // Video is special. It's a replaced element with a content layer, but has shadow content
738 // for the controller that must render in front. Without this, the controls fail to show
739 // when the video element is a stacking context (e.g. due to opacity or transform).
740 if (willBeComposited && layer->renderer()->isVideo())
741 childState.m_subtreeIsCompositing = true;
744 if (layer->isStackingContext()) {
745 ASSERT(!layer->m_zOrderListsDirty);
746 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
747 size_t listSize = negZOrderList->size();
748 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
749 childState.m_fixedSibling = compositingState.m_fixedSibling;
750 if (checkForFixedLayers(negZOrderList, false))
751 childState.m_fixedSibling = true;
753 for (size_t i = 0; i < listSize; ++i) {
754 RenderLayer* curLayer = negZOrderList->at(i);
755 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
757 // If we have to make a layer for this child, make one now so we can have a contents layer
758 // (since we need to ensure that the -ve z-order child renders underneath our contents).
760 // Normally we try to reduce the number of layers by not promoting all fixed
761 // or scrollable elements to their own compositing layer. But in the case that
762 // we have such an element in the negative z-order, we must make it a layer
763 // otherwise the content will be painted at a higher z-index. This breaks pages
764 // that set a large image with a z-index of -1 to implement a background image,
766 bool childRequiresCompositing = childState.m_hasFixedElement || childState.m_hasScrollableElement;
767 if (!willBeComposited && (childState.m_subtreeIsCompositing || childRequiresCompositing)) {
769 if (!willBeComposited && childState.m_subtreeIsCompositing) {
771 // make layer compositing
772 layer->setMustOverlapCompositedLayers(true);
773 childState.m_compositingAncestor = layer;
775 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
776 willBeComposited = true;
782 ASSERT(!layer->m_normalFlowListDirty);
783 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
784 size_t listSize = normalFlowList->size();
785 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
786 childState.m_fixedSibling = compositingState.m_fixedSibling;
787 if (checkForFixedLayers(normalFlowList, true))
788 childState.m_fixedSibling = true;
790 for (size_t i = 0; i < listSize; ++i) {
791 RenderLayer* curLayer = normalFlowList->at(i);
792 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
796 if (layer->isStackingContext()) {
797 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
798 size_t listSize = posZOrderList->size();
799 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
800 childState.m_fixedSibling = compositingState.m_fixedSibling;
801 if (checkForFixedLayers(posZOrderList, true))
802 childState.m_fixedSibling = true;
804 for (size_t i = 0; i < listSize; ++i) {
805 RenderLayer* curLayer = posZOrderList->at(i);
806 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
811 // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
812 if (layer->isRootLayer()) {
813 if (inCompositingMode() && m_hasAcceleratedCompositing)
814 willBeComposited = true;
817 ASSERT(willBeComposited == needsToBeComposited(layer));
819 // If we have a software transform, and we have layers under us, we need to also
820 // be composited. Also, if we have opacity < 1, then we need to be a layer so that
821 // the child layers are opaque, then rendered with opacity on this layer.
822 if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
823 layer->setMustOverlapCompositedLayers(true);
825 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
826 willBeComposited = true;
829 ASSERT(willBeComposited == needsToBeComposited(layer));
830 if (layer->reflectionLayer())
831 layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
833 // Subsequent layers in the parent stacking context also need to composite.
834 if (childState.m_subtreeIsCompositing)
835 compositingState.m_subtreeIsCompositing = true;
837 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
838 if (childState.m_hasFixedElement)
839 compositingState.m_hasFixedElement = true;
841 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
842 if (childState.m_hasScrollableElement)
843 compositingState.m_hasScrollableElement = true;
846 // Set the flag to say that this SC has compositing children.
847 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
849 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
850 // so test that again.
851 if (!willBeComposited && canBeComposited(layer) && clipsCompositingDescendants(layer)) {
853 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
854 willBeComposited = true;
857 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
858 // to be composited, then we can drop out of compositing mode altogether.
859 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
860 // We also need to check that we don't have a scrollable layer, as this
861 // would not have set the m_subtreeIsCompositing flag
862 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !childState.m_hasScrollableElement && !childState.m_hasFixedElement && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
864 if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
866 enableCompositingMode(false);
867 willBeComposited = false;
870 // If the layer is going into compositing mode, repaint its old location.
871 ASSERT(willBeComposited == needsToBeComposited(layer));
872 if (!layer->isComposited() && willBeComposited)
873 repaintOnCompositingChange(layer);
875 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
876 if (updateBacking(layer, CompositingChangeRepaintNow))
877 layersChanged = true;
879 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
880 layersChanged = true;
883 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
885 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
886 ASSERT(childLayer->isComposited());
888 // It's possible to be called with a parent that isn't yet composited when we're doing
889 // partial updates as required by painting or hit testing. Just bail in that case;
890 // we'll do a full layer update soon.
891 if (!parentLayer || !parentLayer->isComposited())
895 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
896 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers();
898 hostingLayer->addChild(hostedLayer);
900 childLayer->backing()->childForSuperlayers()->removeFromParent();
903 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
905 ASSERT(layer->isComposited());
907 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers();
908 hostingLayer->removeAllChildren();
912 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
914 if (!m_hasAcceleratedCompositing)
917 return o->supportsAcceleratedRendering();
921 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer)
923 // Make the layer compositing if necessary, and set up clipping and content layers.
924 // Note that we can only do work here that is independent of whether the descendant layers
925 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
927 RenderLayerBacking* layerBacking = layer->backing();
929 // The compositing state of all our children has been updated already, so now
930 // we can compute and cache the composited bounds for this layer.
931 layerBacking->updateCompositedBounds();
933 if (RenderLayer* reflection = layer->reflectionLayer()) {
934 if (reflection->backing())
935 reflection->backing()->updateCompositedBounds();
938 layerBacking->updateGraphicsLayerConfiguration();
939 layerBacking->updateGraphicsLayerGeometry();
941 if (!layer->parent())
942 updateRootLayerPosition();
945 // If this layer has backing, then we are collecting its children, otherwise appending
946 // to the compositing child list of an enclosing layer.
947 Vector<GraphicsLayer*> layerChildren;
948 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
950 CompositingState childState = compositingState;
951 if (layer->isComposited())
952 childState.m_compositingAncestor = layer;
955 ++childState.m_depth;
958 // The children of this stacking context don't need to composite, unless there is
959 // a compositing layer among them, so start by assuming false.
960 childState.m_subtreeIsCompositing = false;
962 if (layer->isStackingContext()) {
963 ASSERT(!layer->m_zOrderListsDirty);
965 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
966 size_t listSize = negZOrderList->size();
967 for (size_t i = 0; i < listSize; ++i) {
968 RenderLayer* curLayer = negZOrderList->at(i);
969 rebuildCompositingLayerTree(curLayer, childState, childList);
973 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
974 if (layerBacking && layerBacking->foregroundLayer())
975 childList.append(layerBacking->foregroundLayer());
978 ASSERT(!layer->m_normalFlowListDirty);
979 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
980 size_t listSize = normalFlowList->size();
981 for (size_t i = 0; i < listSize; ++i) {
982 RenderLayer* curLayer = normalFlowList->at(i);
983 rebuildCompositingLayerTree(curLayer, childState, childList);
987 if (layer->isStackingContext()) {
988 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
989 size_t listSize = posZOrderList->size();
990 for (size_t i = 0; i < listSize; ++i) {
991 RenderLayer* curLayer = posZOrderList->at(i);
992 rebuildCompositingLayerTree(curLayer, childState, childList);
998 bool parented = false;
999 if (layer->renderer()->isRenderPart())
1000 parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
1002 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
1003 // Otherwise, the overflow control layers are normal children.
1004 if (!layerBacking->hasClippingLayer()) {
1005 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) {
1006 overflowControlLayer->removeFromParent();
1007 layerChildren.append(overflowControlLayer);
1010 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) {
1011 overflowControlLayer->removeFromParent();
1012 layerChildren.append(overflowControlLayer);
1015 if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) {
1016 overflowControlLayer->removeFromParent();
1017 layerChildren.append(overflowControlLayer);
1022 layerBacking->parentForSublayers()->setChildren(layerChildren);
1024 #if ENABLE(FULLSCREEN_API)
1025 // For the sake of clients of the full screen renderer, don't reparent
1026 // the full screen layer out from under them if they're in the middle of
1028 if (layer->renderer()->isRenderFullScreen() && toRenderFullScreen(layer->renderer())->isAnimating())
1031 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
1035 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
1037 if (m_overflowControlsHostLayer)
1038 m_overflowControlsHostLayer->setPosition(contentsOffset);
1041 void RenderLayerCompositor::frameViewDidChangeSize()
1044 FrameView* frameView = m_renderView->frameView();
1045 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1047 IntPoint scrollPosition = frameView->scrollPosition();
1048 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
1049 updateOverflowControlsLayers();
1053 void RenderLayerCompositor::frameViewDidScroll(const IntPoint& scrollPosition)
1056 m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
1059 String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo)
1061 if (compositingLayerUpdatePending())
1062 updateCompositingLayers();
1064 if (!m_rootPlatformLayer)
1067 // We skip dumping the scroll and clip layers to keep layerTreeAsText output
1068 // similar between platforms.
1069 return m_rootPlatformLayer->layerTreeAsText(showDebugInfo ? LayerTreeAsTextDebug : LayerTreeAsTextBehaviorNormal);
1072 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
1074 if (!renderer->node()->isFrameOwnerElement())
1077 HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(renderer->node());
1078 if (Document* contentDocument = element->contentDocument()) {
1079 if (RenderView* view = contentDocument->renderView())
1080 return view->compositor();
1085 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
1087 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
1088 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
1091 RenderLayer* layer = renderer->layer();
1092 if (!layer->isComposited())
1095 RenderLayerBacking* backing = layer->backing();
1096 GraphicsLayer* hostingLayer = backing->parentForSublayers();
1097 GraphicsLayer* rootLayer = innerCompositor->rootPlatformLayer();
1098 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
1099 hostingLayer->removeAllChildren();
1100 hostingLayer->addChild(rootLayer);
1105 // This just updates layer geometry without changing the hierarchy.
1106 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
1108 if (RenderLayerBacking* layerBacking = layer->backing()) {
1109 // The compositing state of all our children has been updated already, so now
1110 // we can compute and cache the composited bounds for this layer.
1111 layerBacking->updateCompositedBounds();
1113 if (RenderLayer* reflection = layer->reflectionLayer()) {
1114 if (reflection->backing())
1115 reflection->backing()->updateCompositedBounds();
1118 layerBacking->updateGraphicsLayerConfiguration();
1119 layerBacking->updateGraphicsLayerGeometry();
1121 if (!layer->parent())
1122 updateRootLayerPosition();
1125 if (layer->isStackingContext()) {
1126 ASSERT(!layer->m_zOrderListsDirty);
1128 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1129 size_t listSize = negZOrderList->size();
1130 for (size_t i = 0; i < listSize; ++i)
1131 updateLayerTreeGeometry(negZOrderList->at(i));
1135 ASSERT(!layer->m_normalFlowListDirty);
1136 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1137 size_t listSize = normalFlowList->size();
1138 for (size_t i = 0; i < listSize; ++i)
1139 updateLayerTreeGeometry(normalFlowList->at(i));
1142 if (layer->isStackingContext()) {
1143 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1144 size_t listSize = posZOrderList->size();
1145 for (size_t i = 0; i < listSize; ++i)
1146 updateLayerTreeGeometry(posZOrderList->at(i));
1151 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
1152 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth)
1154 if (layer != compositingAncestor) {
1155 if (RenderLayerBacking* layerBacking = layer->backing()) {
1156 layerBacking->updateCompositedBounds();
1158 if (RenderLayer* reflection = layer->reflectionLayer()) {
1159 if (reflection->backing())
1160 reflection->backing()->updateCompositedBounds();
1163 layerBacking->updateGraphicsLayerGeometry();
1164 if (updateDepth == RenderLayerBacking::CompositingChildren)
1169 if (layer->reflectionLayer())
1170 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth);
1172 if (!layer->hasCompositingDescendant())
1175 if (layer->isStackingContext()) {
1176 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1177 size_t listSize = negZOrderList->size();
1178 for (size_t i = 0; i < listSize; ++i)
1179 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth);
1183 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1184 size_t listSize = normalFlowList->size();
1185 for (size_t i = 0; i < listSize; ++i)
1186 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth);
1189 if (layer->isStackingContext()) {
1190 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1191 size_t listSize = posZOrderList->size();
1192 for (size_t i = 0; i < listSize; ++i)
1193 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth);
1199 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect)
1201 recursiveRepaintLayerRect(rootRenderLayer(), absRect);
1204 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
1206 // FIXME: This method does not work correctly with transforms.
1207 if (layer->isComposited())
1208 layer->setBackingNeedsRepaintInRect(rect);
1210 if (layer->hasCompositingDescendant()) {
1211 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1212 size_t listSize = negZOrderList->size();
1213 for (size_t i = 0; i < listSize; ++i) {
1214 RenderLayer* curLayer = negZOrderList->at(i);
1217 curLayer->convertToLayerCoords(layer, x, y);
1218 IntRect childRect(rect);
1219 childRect.move(-x, -y);
1220 recursiveRepaintLayerRect(curLayer, childRect);
1224 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1225 size_t listSize = posZOrderList->size();
1226 for (size_t i = 0; i < listSize; ++i) {
1227 RenderLayer* curLayer = posZOrderList->at(i);
1230 curLayer->convertToLayerCoords(layer, x, y);
1231 IntRect childRect(rect);
1232 childRect.move(-x, -y);
1233 recursiveRepaintLayerRect(curLayer, childRect);
1237 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1238 size_t listSize = normalFlowList->size();
1239 for (size_t i = 0; i < listSize; ++i) {
1240 RenderLayer* curLayer = normalFlowList->at(i);
1243 curLayer->convertToLayerCoords(layer, x, y);
1244 IntRect childRect(rect);
1245 childRect.move(-x, -y);
1246 recursiveRepaintLayerRect(curLayer, childRect);
1251 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
1253 return m_renderView->layer();
1256 GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const
1258 if (m_overflowControlsHostLayer)
1259 return m_overflowControlsHostLayer.get();
1260 return m_rootPlatformLayer.get();
1263 void RenderLayerCompositor::didMoveOnscreen()
1265 if (!inCompositingMode() || m_rootLayerAttachment != RootLayerUnattached)
1268 RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1269 attachRootPlatformLayer(attachment);
1272 void RenderLayerCompositor::willMoveOffscreen()
1274 if (!inCompositingMode() || m_rootLayerAttachment == RootLayerUnattached)
1277 detachRootPlatformLayer();
1280 void RenderLayerCompositor::updateRootLayerPosition()
1282 if (m_rootPlatformLayer) {
1283 m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight()));
1284 m_rootPlatformLayer->setPosition(FloatPoint(m_renderView->docLeft(), m_renderView->docTop()));
1287 FrameView* frameView = m_renderView->frameView();
1288 m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1292 void RenderLayerCompositor::didStartAcceleratedAnimation(CSSPropertyID property)
1294 // If an accelerated animation or transition runs, we have to turn off overlap checking because
1295 // we don't do layout for every frame, but we have to ensure that the layering is
1296 // correct between the animating object and other objects on the page.
1297 if (property == CSSPropertyWebkitTransform)
1298 setCompositingConsultsOverlap(false);
1301 bool RenderLayerCompositor::has3DContent() const
1303 return layerHas3DContent(rootRenderLayer());
1306 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)
1309 // frames are only independently composited in Mac pre-WebKit2.
1310 return view->platformWidget();
1315 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const
1317 #if PLATFORM(ANDROID)
1318 if (enclosingFrameElement() && !allowsIndependentlyCompositedFrames(m_renderView->frameView()))
1321 // Parent document content needs to be able to render on top of a composited frame, so correct behavior
1322 // is to have the parent document become composited too. However, this can cause problems on platforms that
1323 // use native views for frames (like Mac), so disable that behavior on those platforms for now.
1324 HTMLFrameOwnerElement* ownerElement = enclosingFrameElement();
1325 RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0;
1327 // If we are the top-level frame, don't propagate.
1331 if (!allowsIndependentlyCompositedFrames(m_renderView->frameView()))
1334 if (!renderer || !renderer->isRenderPart())
1337 // On Mac, only propagate compositing if the frame is overlapped in the parent
1338 // document, or the parent is already compositing, or the main frame is scaled.
1339 Frame* frame = m_renderView->frameView()->frame();
1340 Page* page = frame ? frame->page() : 0;
1341 if (page->mainFrame()->pageScaleFactor() != 1)
1344 RenderPart* frameRenderer = toRenderPart(renderer);
1345 if (frameRenderer->widget()) {
1346 ASSERT(frameRenderer->widget()->isFrameView());
1347 FrameView* view = static_cast<FrameView*>(frameRenderer->widget());
1348 if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor())
1355 HTMLFrameOwnerElement* RenderLayerCompositor::enclosingFrameElement() const
1357 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
1358 return (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(objectTag)) ? ownerElement : 0;
1363 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
1365 if (!canBeComposited(layer))
1368 // The root layer always has a compositing layer, but it may not have backing.
1369 #if PLATFORM(ANDROID)
1370 // If we do not have a root platform layer, don't use the
1371 // mustOverlapCompositedLayers() as a cue that this layer needs to be
1372 // composited -- the layers tree has been detached.
1373 // Otherwise we can end up in a cycle where updateBacking() switches composited
1374 // mode on because a layer has mustOverlapCompositedLayers() (by calling
1375 // enableCompositingMode()), while computeCompositingRequirements() will
1376 // (correctly) say that we do not need to be in composited mode and turns it
1377 // off, rince and repeat...
1378 return requiresCompositingLayer(layer)
1379 || (m_rootPlatformLayer && layer->mustOverlapCompositedLayers())
1380 || (inCompositingMode() && layer->isRootLayer());
1382 return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
1386 #if PLATFORM(ANDROID)
1387 bool RenderLayerCompositor::requiresCompositingForAndroidLayers(const RenderLayer* layer) const
1389 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
1390 if (layer->hasOverflowScroll())
1392 if (layer->isRootLayer() && m_renderView->frameView()->hasOverflowScroll())
1395 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
1397 // Enable composited layers (for fixed elements)
1398 if (layer->isFixed())
1405 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
1406 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
1408 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
1410 RenderObject* renderer = layer->renderer();
1411 // The compositing state of a reflection should match that of its reflected layer.
1412 if (layer->isReflection()) {
1413 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
1414 layer = toRenderBoxModelObject(renderer)->layer();
1416 return requiresCompositingForTransform(renderer)
1417 #if PLATFORM(ANDROID)
1418 || requiresCompositingForAndroidLayers(layer)
1420 || requiresCompositingForVideo(renderer)
1421 || requiresCompositingForCanvas(renderer)
1422 || requiresCompositingForPlugin(renderer)
1423 || requiresCompositingForFrame(renderer)
1424 || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1425 || clipsCompositingDescendants(layer)
1426 || requiresCompositingForAnimation(renderer)
1427 || requiresCompositingForFullScreen(renderer);
1430 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
1432 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer();
1435 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1436 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1437 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1438 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1439 // but a sibling in the z-order hierarchy.
1440 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
1442 if (!layer->isComposited() || !layer->parent())
1445 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1446 if (!compositingAncestor)
1449 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
1450 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
1452 RenderLayer* computeClipRoot = 0;
1453 RenderLayer* curr = layer;
1455 RenderLayer* next = curr->parent();
1456 if (next == compositingAncestor) {
1457 computeClipRoot = curr;
1463 if (!computeClipRoot || computeClipRoot == layer)
1466 IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true);
1467 return backgroundRect != PaintInfo::infiniteRect();
1470 // Return true if the given layer is a stacking context and has compositing child
1471 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1472 // into the hierarchy between this layer and its children in the z-order hierarchy.
1473 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1475 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
1476 if (layer->hasOverflowScroll())
1479 return layer->hasCompositingDescendant() &&
1480 (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip());
1483 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
1485 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
1488 RenderStyle* style = renderer->style();
1489 // Note that we ask the renderer if it has a transform, because the style may have transforms,
1490 // but the renderer may be an inline that doesn't suppport them.
1491 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
1494 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
1496 if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
1499 if (renderer->isVideo()) {
1500 RenderVideo* video = toRenderVideo(renderer);
1501 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
1503 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1504 else if (renderer->isRenderPart()) {
1505 if (!m_hasAcceleratedCompositing)
1508 Node* node = renderer->node();
1509 if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag)))
1512 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node);
1513 return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false;
1515 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1517 UNUSED_PARAM(renderer);
1522 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
1524 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
1527 if (renderer->isCanvas()) {
1528 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
1529 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
1534 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
1536 if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
1539 bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
1540 || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing());
1544 m_compositingDependsOnGeometry = true;
1546 RenderWidget* pluginRenderer = toRenderWidget(renderer);
1547 // If we can't reliably know the size of the plugin yet, don't change compositing state.
1548 if (pluginRenderer->needsLayout())
1549 return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited();
1551 // Don't go into compositing mode if height or width are zero, or size is 1x1.
1552 IntRect contentBox = pluginRenderer->contentBoxRect();
1553 #if PLATFORM(ANDROID)
1554 // allow all plugins including 1x1 to be composited, so that they are drawn,
1555 // and acquire an ANativeWindow on the UI thread
1556 return contentBox.height() * contentBox.width() > 0;
1558 return contentBox.height() * contentBox.width() > 1;
1562 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
1564 if (!renderer->isRenderPart())
1567 RenderPart* frameRenderer = toRenderPart(renderer);
1569 if (!frameRenderer->requiresAcceleratedCompositing())
1572 m_compositingDependsOnGeometry = true;
1574 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
1575 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())
1578 // If we can't reliably know the size of the iframe yet, don't change compositing state.
1579 if (renderer->needsLayout())
1580 return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited();
1582 // Don't go into compositing mode if height or width are zero.
1583 IntRect contentBox = frameRenderer->contentBoxRect();
1584 return contentBox.height() * contentBox.width() > 0;
1587 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
1589 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1592 if (AnimationController* animController = renderer->animation()) {
1593 #if PLATFORM(ANDROID)
1594 // android renders an opacity animation much faster if it's composited
1595 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity))
1597 return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
1599 || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1604 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
1606 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection();
1609 bool RenderLayerCompositor::requiresCompositingForFullScreen(RenderObject* renderer) const
1611 #if ENABLE(FULLSCREEN_API)
1612 return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating();
1614 UNUSED_PARAM(renderer);
1619 // If an element has negative z-index children, those children render in front of the
1620 // layer background, so we need an extra 'contents' layer for the foreground of the layer
1622 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
1624 return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0);
1627 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
1629 // We need to handle our own scrolling if we're:
1630 return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
1631 || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
1634 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1640 const IntRect& scrollbarRect = scrollbar->frameRect();
1641 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1642 IntRect transformedClip = clip;
1643 transformedClip.move(scrollbarRect.x(), scrollbarRect.y());
1644 scrollbar->paint(&context, transformedClip);
1648 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
1650 if (graphicsLayer == layerForHorizontalScrollbar())
1651 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
1652 else if (graphicsLayer == layerForVerticalScrollbar())
1653 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
1654 else if (graphicsLayer == layerForScrollCorner()) {
1655 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
1657 context.translate(-scrollCorner.x(), -scrollCorner.y());
1658 IntRect transformedClip = clip;
1659 transformedClip.move(scrollCorner.x(), scrollCorner.y());
1660 m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
1665 static bool shouldCompositeOverflowControls(ScrollView* view)
1667 if (view->platformWidget())
1669 #if !PLATFORM(CHROMIUM)
1670 if (!view->hasOverlayScrollbars())
1676 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
1678 ScrollView* view = m_renderView->frameView();
1679 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
1682 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
1684 ScrollView* view = m_renderView->frameView();
1685 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
1688 bool RenderLayerCompositor::requiresScrollCornerLayer() const
1690 ScrollView* view = m_renderView->frameView();
1691 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
1694 void RenderLayerCompositor::updateOverflowControlsLayers()
1696 bool layersChanged = false;
1698 if (requiresHorizontalScrollbarLayer()) {
1699 m_layerForHorizontalScrollbar = GraphicsLayer::create(this);
1701 m_layerForHorizontalScrollbar->setName("horizontal scrollbar");
1703 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
1704 layersChanged = true;
1705 } else if (m_layerForHorizontalScrollbar) {
1706 m_layerForHorizontalScrollbar->removeFromParent();
1707 m_layerForHorizontalScrollbar = 0;
1708 layersChanged = true;
1711 if (requiresVerticalScrollbarLayer()) {
1712 m_layerForVerticalScrollbar = GraphicsLayer::create(this);
1714 m_layerForVerticalScrollbar->setName("vertical scrollbar");
1716 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
1717 layersChanged = true;
1718 } else if (m_layerForVerticalScrollbar) {
1719 m_layerForVerticalScrollbar->removeFromParent();
1720 m_layerForVerticalScrollbar = 0;
1721 layersChanged = true;
1724 if (requiresScrollCornerLayer()) {
1725 m_layerForScrollCorner = GraphicsLayer::create(this);
1727 m_layerForScrollCorner->setName("scroll corner");
1729 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
1730 layersChanged = true;
1731 } else if (m_layerForScrollCorner) {
1732 m_layerForScrollCorner->removeFromParent();
1733 m_layerForScrollCorner = 0;
1734 layersChanged = true;
1738 m_renderView->frameView()->positionScrollbarLayers();
1741 void RenderLayerCompositor::ensureRootPlatformLayer()
1743 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1744 if (expectedAttachment == m_rootLayerAttachment)
1747 if (!m_rootPlatformLayer) {
1748 m_rootPlatformLayer = GraphicsLayer::create(0);
1750 m_rootPlatformLayer->setName("Root platform");
1752 m_rootPlatformLayer->setSize(FloatSize(m_renderView->maxXLayoutOverflow(), m_renderView->maxYLayoutOverflow()));
1753 m_rootPlatformLayer->setPosition(FloatPoint());
1755 // Need to clip to prevent transformed content showing outside this frame
1756 m_rootPlatformLayer->setMasksToBounds(true);
1759 if (requiresScrollLayer(expectedAttachment)) {
1760 if (!m_overflowControlsHostLayer) {
1761 ASSERT(!m_scrollLayer);
1762 ASSERT(!m_clipLayer);
1764 // Create a layer to host the clipping layer and the overflow controls layers.
1765 m_overflowControlsHostLayer = GraphicsLayer::create(0);
1767 m_overflowControlsHostLayer->setName("overflow controls host");
1770 // Create a clipping layer if this is an iframe
1771 m_clipLayer = GraphicsLayer::create(this);
1773 m_clipLayer->setName("iframe Clipping");
1775 m_clipLayer->setMasksToBounds(true);
1777 m_scrollLayer = GraphicsLayer::create(this);
1779 m_scrollLayer->setName("iframe scrolling");
1783 m_overflowControlsHostLayer->addChild(m_clipLayer.get());
1784 m_clipLayer->addChild(m_scrollLayer.get());
1785 m_scrollLayer->addChild(m_rootPlatformLayer.get());
1787 frameViewDidChangeSize();
1788 frameViewDidScroll(m_renderView->frameView()->scrollPosition());
1791 if (m_overflowControlsHostLayer) {
1792 m_overflowControlsHostLayer = 0;
1798 // Check to see if we have to change the attachment
1799 if (m_rootLayerAttachment != RootLayerUnattached)
1800 detachRootPlatformLayer();
1802 attachRootPlatformLayer(expectedAttachment);
1805 void RenderLayerCompositor::destroyRootPlatformLayer()
1807 if (!m_rootPlatformLayer)
1810 detachRootPlatformLayer();
1812 if (m_layerForHorizontalScrollbar) {
1813 m_layerForHorizontalScrollbar->removeFromParent();
1814 m_layerForHorizontalScrollbar = 0;
1815 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
1816 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
1819 if (m_layerForVerticalScrollbar) {
1820 m_layerForVerticalScrollbar->removeFromParent();
1821 m_layerForVerticalScrollbar = 0;
1822 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
1823 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
1826 if (m_layerForScrollCorner) {
1827 m_layerForScrollCorner = 0;
1828 m_renderView->frameView()->invalidateScrollCorner();
1831 if (m_overflowControlsHostLayer) {
1832 m_overflowControlsHostLayer = 0;
1836 ASSERT(!m_scrollLayer);
1837 m_rootPlatformLayer = 0;
1840 void RenderLayerCompositor::attachRootPlatformLayer(RootLayerAttachment attachment)
1842 if (!m_rootPlatformLayer)
1845 switch (attachment) {
1846 case RootLayerUnattached:
1847 ASSERT_NOT_REACHED();
1849 case RootLayerAttachedViaChromeClient: {
1850 Frame* frame = m_renderView->frameView()->frame();
1851 Page* page = frame ? frame->page() : 0;
1855 page->chrome()->client()->attachRootGraphicsLayer(frame, rootPlatformLayer());
1858 case RootLayerAttachedViaEnclosingFrame: {
1859 // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
1860 // for the frame's renderer in the parent document.
1861 scheduleNeedsStyleRecalc(m_renderView->document()->ownerElement());
1866 m_rootLayerAttachment = attachment;
1867 rootLayerAttachmentChanged();
1870 void RenderLayerCompositor::detachRootPlatformLayer()
1872 if (!m_rootPlatformLayer || m_rootLayerAttachment == RootLayerUnattached)
1875 switch (m_rootLayerAttachment) {
1876 case RootLayerAttachedViaEnclosingFrame: {
1877 // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
1878 // for the frame's renderer in the parent document.
1879 if (m_overflowControlsHostLayer)
1880 m_overflowControlsHostLayer->removeFromParent();
1882 m_rootPlatformLayer->removeFromParent();
1884 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
1885 scheduleNeedsStyleRecalc(ownerElement);
1888 case RootLayerAttachedViaChromeClient: {
1889 Frame* frame = m_renderView->frameView()->frame();
1890 Page* page = frame ? frame->page() : 0;
1894 page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
1897 case RootLayerUnattached:
1901 m_rootLayerAttachment = RootLayerUnattached;
1902 rootLayerAttachmentChanged();
1905 void RenderLayerCompositor::updateRootLayerAttachment()
1907 ensureRootPlatformLayer();
1910 void RenderLayerCompositor::rootLayerAttachmentChanged()
1912 // The attachment can affect whether the RenderView layer's paintingGoesToWindow() behavior,
1913 // so call updateGraphicsLayerGeometry() to udpate that.
1914 RenderLayer* layer = m_renderView->layer();
1915 if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
1916 backing->updateDrawsContent();
1919 static void needsStyleRecalcCallback(Node* node)
1921 node->setNeedsStyleRecalc(SyntheticStyleChange);
1924 void RenderLayerCompositor::scheduleNeedsStyleRecalc(Element* element)
1926 if (ContainerNode::postAttachCallbacksAreSuspended())
1927 ContainerNode::queuePostAttachCallback(needsStyleRecalcCallback, element);
1929 element->setNeedsStyleRecalc(SyntheticStyleChange);
1932 // IFrames are special, because we hook compositing layers together across iframe boundaries
1933 // when both parent and iframe content are composited. So when this frame becomes composited, we have
1934 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
1935 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
1937 Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0;
1941 for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) {
1942 if (child->document() && child->document()->ownerElement())
1943 scheduleNeedsStyleRecalc(child->document()->ownerElement());
1946 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
1947 // we need to schedule a style recalc in our parent document.
1948 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
1949 scheduleNeedsStyleRecalc(ownerElement);
1952 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
1954 const RenderStyle* style = layer->renderer()->style();
1957 (style->transformStyle3D() == TransformStyle3DPreserve3D ||
1958 style->hasPerspective() ||
1959 style->transform().has3DOperation()))
1962 if (layer->isStackingContext()) {
1963 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1964 size_t listSize = negZOrderList->size();
1965 for (size_t i = 0; i < listSize; ++i) {
1966 RenderLayer* curLayer = negZOrderList->at(i);
1967 if (layerHas3DContent(curLayer))
1972 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1973 size_t listSize = posZOrderList->size();
1974 for (size_t i = 0; i < listSize; ++i) {
1975 RenderLayer* curLayer = posZOrderList->at(i);
1976 if (layerHas3DContent(curLayer))
1982 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1983 size_t listSize = normalFlowList->size();
1984 for (size_t i = 0; i < listSize; ++i) {
1985 RenderLayer* curLayer = normalFlowList->at(i);
1986 if (layerHas3DContent(curLayer))
1993 void RenderLayerCompositor::updateContentsScale(float scale, RenderLayer* layer)
1996 layer = rootRenderLayer();
1998 layer->updateContentsScale(scale);
2000 if (layer->isStackingContext()) {
2001 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
2002 size_t listSize = negZOrderList->size();
2003 for (size_t i = 0; i < listSize; ++i)
2004 updateContentsScale(scale, negZOrderList->at(i));
2007 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
2008 size_t listSize = posZOrderList->size();
2009 for (size_t i = 0; i < listSize; ++i)
2010 updateContentsScale(scale, posZOrderList->at(i));
2014 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
2015 size_t listSize = normalFlowList->size();
2016 for (size_t i = 0; i < listSize; ++i)
2017 updateContentsScale(scale, normalFlowList->at(i));
2021 } // namespace WebCore
2023 #endif // USE(ACCELERATED_COMPOSITING)