• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25 
26 #include "config.h"
27 
28 #if USE(ACCELERATED_COMPOSITING)
29 #include "RenderLayerCompositor.h"
30 
31 #include "AnimationController.h"
32 #include "CanvasRenderingContext.h"
33 #include "CSSPropertyNames.h"
34 #include "Chrome.h"
35 #include "ChromeClient.h"
36 #include "Frame.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"
43 #include "NodeList.h"
44 #include "Page.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"
53 #include "Settings.h"
54 
55 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
56 #include "HTMLMediaElement.h"
57 #endif
58 
59 #if PROFILE_LAYER_REBUILD
60 #include <wtf/CurrentTime.h>
61 #endif
62 
63 #ifndef NDEBUG
64 #include "RenderTreeAsText.h"
65 #endif
66 
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;
70 #endif
71 
72 namespace WebCore {
73 
74 using namespace HTMLNames;
75 
76 struct CompositingState {
CompositingStateWebCore::CompositingState77     CompositingState(RenderLayer* compAncestor)
78         : m_compositingAncestor(compAncestor)
79         , m_subtreeIsCompositing(false)
80 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
81         , m_positionedSibling(false)
82         , m_hasFixedElement(false)
83 #endif
84 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
85         , m_hasScrollableElement(false)
86 #endif
87 #ifndef NDEBUG
88         , m_depth(0)
89 #endif
90     {
91     }
92 
93     RenderLayer* m_compositingAncestor;
94     bool m_subtreeIsCompositing;
95     // m_compositingBounds is only used in computeCompositingRequirements. It can be either the
96     // ancestor bounds or the bounds for the sibling layers which are above the composited layer.
97     // It is used to reject creating unnecesary layers.
98     IntRect m_compositingBounds;
99 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
100     bool m_positionedSibling;
101     bool m_hasFixedElement;
102 #endif
103 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
104     bool m_hasScrollableElement;
105 #endif
106 #ifndef NDEBUG
107     int m_depth;
108 #endif
109 };
110 
RenderLayerCompositor(RenderView * renderView)111 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
112     : m_renderView(renderView)
113     , m_rootPlatformLayer(0)
114     , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
115     , m_hasAcceleratedCompositing(true)
116     , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
117     , m_showDebugBorders(false)
118     , m_showRepaintCounter(false)
119     , m_compositingConsultsOverlap(true)
120     , m_compositingDependsOnGeometry(false)
121     , m_compositing(false)
122     , m_compositingLayersNeedRebuild(false)
123     , m_flushingLayers(false)
124     , m_forceCompositingMode(false)
125     , m_rootLayerAttachment(RootLayerUnattached)
126 #if PROFILE_LAYER_REBUILD
127     , m_rootLayerUpdateCount(0)
128 #endif // PROFILE_LAYER_REBUILD
129 {
130     Settings* settings = m_renderView->document()->settings();
131 
132     // Even when forcing compositing mode, ignore child frames, or this will trigger
133     // layer creation from the enclosing RenderIFrame.
134     ASSERT(m_renderView->document()->frame());
135     if (settings && settings->forceCompositingMode() && settings->acceleratedCompositingEnabled()
136         && !m_renderView->document()->frame()->tree()->parent()) {
137         m_forceCompositingMode = true;
138         enableCompositingMode();
139     }
140 }
141 
~RenderLayerCompositor()142 RenderLayerCompositor::~RenderLayerCompositor()
143 {
144     ASSERT(m_rootLayerAttachment == RootLayerUnattached);
145 }
146 
enableCompositingMode(bool enable)147 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
148 {
149     if (enable != m_compositing) {
150         m_compositing = enable;
151 
152         if (m_compositing) {
153             ensureRootPlatformLayer();
154             notifyIFramesOfCompositingChange();
155         } else
156             destroyRootPlatformLayer();
157     }
158 }
159 
cacheAcceleratedCompositingFlags()160 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
161 {
162     bool hasAcceleratedCompositing = false;
163     bool showDebugBorders = false;
164     bool showRepaintCounter = false;
165 
166     if (Settings* settings = m_renderView->document()->settings()) {
167         hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
168         showDebugBorders = settings->showDebugBorders();
169         showRepaintCounter = settings->showRepaintCounter();
170     }
171 
172     // We allow the chrome to override the settings, in case the page is rendered
173     // on a chrome that doesn't allow accelerated compositing.
174     if (hasAcceleratedCompositing) {
175         Frame* frame = m_renderView->frameView()->frame();
176         Page* page = frame ? frame->page() : 0;
177         if (page) {
178             ChromeClient* chromeClient = page->chrome()->client();
179             m_compositingTriggers = chromeClient->allowedCompositingTriggers();
180             hasAcceleratedCompositing = m_compositingTriggers;
181         }
182     }
183 
184     if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter)
185         setCompositingLayersNeedRebuild();
186 
187     m_hasAcceleratedCompositing = hasAcceleratedCompositing;
188     m_showDebugBorders = showDebugBorders;
189     m_showRepaintCounter = showRepaintCounter;
190 }
191 
canRender3DTransforms() const192 bool RenderLayerCompositor::canRender3DTransforms() const
193 {
194     return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
195 }
196 
setCompositingLayersNeedRebuild(bool needRebuild)197 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
198 {
199     if (inCompositingMode())
200         m_compositingLayersNeedRebuild = needRebuild;
201 }
202 
scheduleLayerFlush()203 void RenderLayerCompositor::scheduleLayerFlush()
204 {
205     Frame* frame = m_renderView->frameView()->frame();
206     Page* page = frame ? frame->page() : 0;
207     if (!page)
208         return;
209 
210     page->chrome()->client()->scheduleCompositingLayerSync();
211 }
212 
flushPendingLayerChanges()213 void RenderLayerCompositor::flushPendingLayerChanges()
214 {
215     ASSERT(!m_flushingLayers);
216     m_flushingLayers = true;
217 
218     // FIXME: FrameView::syncCompositingStateRecursive() calls this for each
219     // frame, so when compositing layers are connected between frames, we'll
220     // end up syncing subframe's layers multiple times.
221     // https://bugs.webkit.org/show_bug.cgi?id=52489
222     if (GraphicsLayer* rootLayer = rootPlatformLayer())
223         rootLayer->syncCompositingState();
224 
225     ASSERT(m_flushingLayers);
226     m_flushingLayers = false;
227 }
228 
enclosingCompositorFlushingLayers() const229 RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const
230 {
231     if (!m_renderView->frameView())
232         return 0;
233 
234     for (Frame* frame = m_renderView->frameView()->frame(); frame; frame = frame->tree()->parent()) {
235         RenderLayerCompositor* compositor = frame->contentRenderer() ? frame->contentRenderer()->compositor() : 0;
236         if (compositor->isFlushingLayers())
237             return compositor;
238     }
239 
240     return 0;
241 }
242 
scheduleCompositingLayerUpdate()243 void RenderLayerCompositor::scheduleCompositingLayerUpdate()
244 {
245     if (!m_updateCompositingLayersTimer.isActive())
246         m_updateCompositingLayersTimer.startOneShot(0);
247 }
248 
compositingLayerUpdatePending() const249 bool RenderLayerCompositor::compositingLayerUpdatePending() const
250 {
251     return m_updateCompositingLayersTimer.isActive();
252 }
253 
updateCompositingLayersTimerFired(Timer<RenderLayerCompositor> *)254 void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*)
255 {
256     updateCompositingLayers();
257 }
258 
updateCompositingLayers(CompositingUpdateType updateType,RenderLayer * updateRoot)259 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
260 {
261     m_updateCompositingLayersTimer.stop();
262 
263     if (!m_compositingDependsOnGeometry && !m_compositing)
264         return;
265 
266     bool checkForHierarchyUpdate = m_compositingDependsOnGeometry;
267     bool needGeometryUpdate = false;
268 
269     switch (updateType) {
270     case CompositingUpdateAfterLayoutOrStyleChange:
271     case CompositingUpdateOnPaitingOrHitTest:
272         checkForHierarchyUpdate = true;
273         break;
274     case CompositingUpdateOnScroll:
275         if (m_compositingConsultsOverlap)
276             checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
277 
278         needGeometryUpdate = true;
279         break;
280     }
281 
282     if (!checkForHierarchyUpdate && !needGeometryUpdate)
283         return;
284 
285     bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
286     if (!updateRoot || m_compositingConsultsOverlap) {
287         // Only clear the flag if we're updating the entire hierarchy.
288         m_compositingLayersNeedRebuild = false;
289         updateRoot = rootRenderLayer();
290     }
291 
292 #if PROFILE_LAYER_REBUILD
293     ++m_rootLayerUpdateCount;
294 
295     double startTime = WTF::currentTime();
296 #endif
297 
298     if (checkForHierarchyUpdate) {
299         // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
300         // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
301         CompositingState compState(updateRoot);
302         bool layersChanged = false;
303 
304 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
305         compState.m_positionedSibling = false;
306         compState.m_hasFixedElement = false;
307 #endif
308 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
309         compState.m_hasScrollableElement = false;
310 #endif
311         if (m_compositingConsultsOverlap) {
312             OverlapMap overlapTestRequestMap;
313             computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged);
314         } else
315             computeCompositingRequirements(updateRoot, 0, compState, layersChanged);
316 
317         needHierarchyUpdate |= layersChanged;
318     }
319 
320     if (needHierarchyUpdate) {
321         // Update the hierarchy of the compositing layers.
322         CompositingState compState(updateRoot);
323         Vector<GraphicsLayer*> childList;
324         rebuildCompositingLayerTree(updateRoot, compState, childList);
325 
326         // Host the document layer in the RenderView's root layer.
327         if (updateRoot == rootRenderLayer()) {
328             if (childList.isEmpty())
329                 destroyRootPlatformLayer();
330             else
331                 m_rootPlatformLayer->setChildren(childList);
332         }
333     } else if (needGeometryUpdate) {
334         // We just need to do a geometry update. This is only used for position:fixed scrolling;
335         // most of the time, geometry is updated via RenderLayer::styleChanged().
336         updateLayerTreeGeometry(updateRoot);
337     }
338 
339 #if PROFILE_LAYER_REBUILD
340     double endTime = WTF::currentTime();
341     if (updateRoot == rootRenderLayer())
342         fprintf(stderr, "Update %d: computeCompositingRequirements for the world took %fms\n",
343                     m_rootLayerUpdateCount, 1000.0 * (endTime - startTime));
344 #endif
345     ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
346 
347     if (!hasAcceleratedCompositing())
348         enableCompositingMode(false);
349 }
350 
updateBacking(RenderLayer * layer,CompositingChangeRepaint shouldRepaint)351 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
352 {
353     bool layerChanged = false;
354 
355 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
356     if (needsToBeComposited(layer) || layer->shouldComposite()) {
357 #else
358     if (needsToBeComposited(layer)) {
359 #endif
360         enableCompositingMode();
361 
362         // 3D transforms turn off the testing of overlap.
363         if (requiresCompositingForTransform(layer->renderer()))
364             setCompositingConsultsOverlap(false);
365 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
366         // If we are a child of a scrollable layer, ignore the overlap from the
367         // scrollable layer as it can cause child layers to become composited
368         // siblings and will not scroll with the main content layer.
369         if (layer->hasOverflowParent())
370             setCompositingConsultsOverlap(false);
371 #endif
372 
373         if (!layer->backing()) {
374 
375             // If we need to repaint, do so before making backing
376             if (shouldRepaint == CompositingChangeRepaintNow)
377                 repaintOnCompositingChange(layer);
378 
379             layer->ensureBacking();
380 
381 #if PLATFORM(MAC) && USE(CA)
382             if (m_renderView->document()->settings()->acceleratedDrawingEnabled())
383                 layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
384             else if (layer->renderer()->isCanvas()) {
385                 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(layer->renderer()->node());
386                 if (canvas->renderingContext() && canvas->renderingContext()->isAccelerated())
387                     layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
388             }
389 #endif
390             layerChanged = true;
391         }
392     } else {
393         if (layer->backing()) {
394             // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
395             // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
396             // are both either composited, or not composited.
397             if (layer->isReflection()) {
398                 RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer();
399                 if (RenderLayerBacking* backing = sourceLayer->backing()) {
400                     ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer());
401                     backing->graphicsLayer()->setReplicatedByLayer(0);
402                 }
403             }
404 
405             layer->clearBacking();
406             layerChanged = true;
407 
408             // The layer's cached repaints rects are relative to the repaint container, so change when
409             // compositing changes; we need to update them here.
410             layer->computeRepaintRects();
411 
412             // If we need to repaint, do so now that we've removed the backing
413             if (shouldRepaint == CompositingChangeRepaintNow)
414                 repaintOnCompositingChange(layer);
415         }
416     }
417 
418 #if ENABLE(VIDEO)
419     if (layerChanged && layer->renderer()->isVideo()) {
420         // If it's a video, give the media player a chance to hook up to the layer.
421         RenderVideo* video = toRenderVideo(layer->renderer());
422         video->acceleratedRenderingStateChanged();
423     }
424 #endif
425 
426     if (layerChanged && layer->renderer()->isRenderPart()) {
427         RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
428         if (innerCompositor && innerCompositor->inCompositingMode())
429             innerCompositor->updateRootLayerAttachment();
430     }
431 
432     return layerChanged;
433 }
434 
435 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
436 {
437     bool layerChanged = updateBacking(layer, shouldRepaint);
438 
439     // See if we need content or clipping layers. Methods called here should assume
440     // that the compositing state of descendant layers has not been updated yet.
441     if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration())
442         layerChanged = true;
443 
444     return layerChanged;
445 }
446 
447 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
448 {
449     // If the renderer is not attached yet, no need to repaint.
450     if (layer->renderer() != m_renderView && !layer->renderer()->parent())
451         return;
452 
453     RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint();
454     if (!repaintContainer)
455         repaintContainer = m_renderView;
456 
457     layer->repaintIncludingNonCompositingDescendants(repaintContainer);
458     if (repaintContainer == m_renderView) {
459         // The contents of this layer may be moving between the window
460         // and a GraphicsLayer, so we need to make sure the window system
461         // synchronizes those changes on the screen.
462         m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
463     }
464 }
465 
466 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
467 // RenderLayers that are rendered by the composited RenderLayer.
468 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
469 {
470     if (!canBeComposited(layer))
471         return IntRect();
472 
473     IntRect boundingBoxRect = layer->localBoundingBox();
474     if (layer->renderer()->isRoot()) {
475         // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited),
476         // then it has to be big enough to cover the viewport in order to display the background. This is akin
477         // to the code in RenderBox::paintRootBoxFillLayers().
478         if (m_renderView->frameView()) {
479             int rw = m_renderView->frameView()->contentsWidth();
480             int rh = m_renderView->frameView()->contentsHeight();
481 
482             boundingBoxRect.setWidth(max(boundingBoxRect.width(), rw - boundingBoxRect.x()));
483             boundingBoxRect.setHeight(max(boundingBoxRect.height(), rh - boundingBoxRect.y()));
484         }
485     }
486 
487     IntRect unionBounds = boundingBoxRect;
488 
489     if (layer->renderer()->hasOverflowClip() || layer->renderer()->hasMask()) {
490         int ancestorRelX = 0, ancestorRelY = 0;
491         layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
492         boundingBoxRect.move(ancestorRelX, ancestorRelY);
493         return boundingBoxRect;
494     }
495 
496     if (RenderLayer* reflection = layer->reflectionLayer()) {
497         if (!reflection->isComposited()) {
498             IntRect childUnionBounds = calculateCompositedBounds(reflection, layer);
499             unionBounds.unite(childUnionBounds);
500         }
501     }
502 
503     ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0));
504 
505     if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
506         size_t listSize = negZOrderList->size();
507         for (size_t i = 0; i < listSize; ++i) {
508             RenderLayer* curLayer = negZOrderList->at(i);
509             if (!curLayer->isComposited()) {
510                 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
511                 unionBounds.unite(childUnionBounds);
512             }
513         }
514     }
515 
516     if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
517         size_t listSize = posZOrderList->size();
518         for (size_t i = 0; i < listSize; ++i) {
519             RenderLayer* curLayer = posZOrderList->at(i);
520             if (!curLayer->isComposited()) {
521                 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
522                 unionBounds.unite(childUnionBounds);
523             }
524         }
525     }
526 
527     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
528         size_t listSize = normalFlowList->size();
529         for (size_t i = 0; i < listSize; ++i) {
530             RenderLayer* curLayer = normalFlowList->at(i);
531             if (!curLayer->isComposited()) {
532                 IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer);
533                 unionBounds.unite(curAbsBounds);
534             }
535         }
536     }
537 
538     if (layer->paintsWithTransform(PaintBehaviorNormal)) {
539         TransformationMatrix* affineTrans = layer->transform();
540         boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
541         unionBounds = affineTrans->mapRect(unionBounds);
542     }
543 
544     int ancestorRelX = 0, ancestorRelY = 0;
545     layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
546     unionBounds.move(ancestorRelX, ancestorRelY);
547 
548     return unionBounds;
549 }
550 
551 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
552 {
553     setCompositingLayersNeedRebuild();
554 }
555 
556 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
557 {
558     if (!child->isComposited() || parent->renderer()->documentBeingDestroyed())
559         return;
560 
561     setCompositingParent(child, 0);
562 
563     RenderLayer* compLayer = parent->enclosingCompositingLayer();
564     if (compLayer) {
565         ASSERT(compLayer->backing());
566         IntRect compBounds = child->backing()->compositedBounds();
567 
568         int offsetX = 0, offsetY = 0;
569         child->convertToLayerCoords(compLayer, offsetX, offsetY);
570         compBounds.move(offsetX, offsetY);
571 
572         compLayer->setBackingNeedsRepaintInRect(compBounds);
573 
574         // The contents of this layer may be moving from a GraphicsLayer to the window,
575         // so we need to make sure the window system synchronizes those changes on the screen.
576         m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
577     }
578 
579     setCompositingLayersNeedRebuild();
580 }
581 
582 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
583 {
584     for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
585         if (curr->isStackingContext())
586             return 0;
587 
588         if (curr->renderer()->hasOverflowClip() || curr->renderer()->hasClip())
589             return curr;
590     }
591     return 0;
592 }
593 
594 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
595 {
596     if (layer->isRootLayer())
597         return;
598 
599     if (!boundsComputed) {
600         layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
601         // Empty rects never intersect, but we need them to for the purposes of overlap testing.
602         if (layerBounds.isEmpty())
603             layerBounds.setSize(IntSize(1, 1));
604         boundsComputed = true;
605     }
606 
607     overlapMap.add(layer, layerBounds);
608 }
609 
610 bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds)
611 {
612     RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end();
613     for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {
614         const IntRect& bounds = it->second;
615         if (layerBounds.intersects(bounds)) {
616             return true;
617         }
618     }
619 
620     return false;
621 }
622 
623 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
624 
625 bool RenderLayerCompositor::checkForPositionedElements(Vector<RenderLayer*>* list)
626 {
627     int listSize = list->size();
628     int haveFixedLayer = -1;
629     bool fixedSibling = false;
630     bool positionedSibling = false;
631 
632 #if 0
633     // For absolute positioned elements, we need to check if they are followed
634     // by a composited element; if so, they also need to be composited, as the
635     // layer display rendering might be incorrect (absolute elements being
636     // removed from the flow).
637     for (int i = 0; i < listSize; ++i) {
638         RenderLayer* currentLayer = list->at(i);
639         if (!needsToBeComposited(currentLayer)
640             && !currentLayer->shouldComposite()
641             && currentLayer->renderer()->isPositioned()) {
642             positionedSibling = true;
643             // check if there is a composited layer later, if so we should be
644             // composited.
645             for (int j = i + 1; j < listSize; ++j) {
646                 RenderLayer* layer = list->at(j);
647                 if (needsToBeComposited(layer)) {
648                     currentLayer->setShouldComposite(true);
649                     break;
650                 }
651             }
652             break;
653         }
654     }
655 #endif
656 
657     // If we find a fixed layer, let's mark all the following layers as being
658     // composited. The layers' surfaces will be merged if needed UI-side.
659     for (int j = 0; j < listSize; ++j) {
660         RenderLayer* currentLayer = list->at(j);
661 
662         // clear the composited flag first
663         currentLayer->setShouldComposite(false);
664 
665         if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) {
666             // Ignore fixed layers with a width or height or 1 or less...
667             IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad(
668                 FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox();
669             if (currentLayerBounds.width() > 1 && currentLayerBounds.height() > 1) {
670                 haveFixedLayer = j;
671                 fixedSibling = true;
672             }
673             continue;
674         }
675 
676         if (haveFixedLayer != -1)
677             currentLayer->setShouldComposite(true);
678     }
679 
680     return positionedSibling || fixedSibling;
681 }
682 
683 #endif
684 
685 //  Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
686 //  For the z-order children of a compositing layer:
687 //      If a child layers has a compositing layer, then all subsequent layers must
688 //      be compositing in order to render above that layer.
689 //
690 //      If a child in the negative z-order list is compositing, then the layer itself
691 //      must be compositing so that its contents render over that child.
692 //      This implies that its positive z-index children must also be compositing.
693 //
694 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, OverlapMap* overlapMap, struct CompositingState& compositingState, bool& layersChanged)
695 {
696     layer->updateLayerPosition();
697     layer->updateZOrderLists();
698     layer->updateNormalFlowList();
699 #if PLATFORM(ANDROID)
700     RenderObject* renderer = layer->renderer();
701     bool intCom = requiresCompositingLayer(layer);
702     layer->setIntrinsicallyComposited(intCom);
703 #endif
704 
705     // Clear the flag
706     layer->setHasCompositingDescendant(false);
707 
708     bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing;
709 
710     bool haveComputedBounds = false;
711     IntRect absBounds;
712     if (overlapMap && !overlapMap->isEmpty()) {
713         // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
714         absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
715         // Empty rects never intersect, but we need them to for the purposes of overlap testing.
716         if (absBounds.isEmpty())
717             absBounds.setSize(IntSize(1, 1));
718         haveComputedBounds = true;
719         // If the current subtree is not compositing, and the layer is fully inside the current compositing bounnds,
720         // there is no need to do the overlap test. This reduces the total number of the composited layers.
721         if (compositingState.m_subtreeIsCompositing || !compositingState.m_compositingBounds.contains(absBounds))
722             mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
723     }
724 
725     layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
726 
727     // The children of this layer don't need to composite, unless there is
728     // a compositing layer among them, so start by inheriting the compositing
729     // ancestor with m_subtreeIsCompositing set to false.
730     CompositingState childState(compositingState.m_compositingAncestor);
731     if (compositingState.m_subtreeIsCompositing)
732         childState.m_compositingBounds = absBounds;
733     else
734         childState.m_compositingBounds = compositingState.m_compositingBounds;
735 #ifndef NDEBUG
736     ++childState.m_depth;
737 #endif
738 
739     bool willBeComposited = needsToBeComposited(layer);
740 
741 #if 0 && ENABLE(COMPOSITED_FIXED_ELEMENTS)
742     willBeComposited |= layer->shouldComposite();
743     layer->setMustOverlapCompositedLayers(layer->shouldComposite());
744 #endif
745 
746 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
747     // tell the parent it has scrollable descendants.
748     if (layer->hasOverflowScroll())
749         compositingState.m_hasScrollableElement = true;
750 #endif
751 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
752     if (layer->isFixed())
753         compositingState.m_hasFixedElement = true;
754 #endif
755     if (willBeComposited) {
756         // Tell the parent it has compositing descendants.
757         compositingState.m_subtreeIsCompositing = true;
758         // This layer now acts as the ancestor for kids.
759         childState.m_compositingAncestor = layer;
760         childState.m_compositingBounds = absBounds;
761         if (overlapMap)
762             addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
763     }
764 
765 #if ENABLE(VIDEO)
766     // Video is special. It's a replaced element with a content layer, but has shadow content
767     // for the controller that must render in front. Without this, the controls fail to show
768     // when the video element is a stacking context (e.g. due to opacity or transform).
769     if (willBeComposited && layer->renderer()->isVideo())
770         childState.m_subtreeIsCompositing = true;
771 #endif
772 
773     if (layer->isStackingContext()) {
774         ASSERT(!layer->m_zOrderListsDirty);
775         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
776             size_t listSize = negZOrderList->size();
777 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
778             childState.m_positionedSibling = compositingState.m_positionedSibling;
779             if (checkForPositionedElements(negZOrderList))
780                 childState.m_positionedSibling = true;
781 #endif
782             for (size_t i = 0; i < listSize; ++i) {
783                 RenderLayer* curLayer = negZOrderList->at(i);
784                 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
785 
786                 // If we have to make a layer for this child, make one now so we can have a contents layer
787                 // (since we need to ensure that the -ve z-order child renders underneath our contents).
788 #ifdef ANDROID
789                 // Normally we try to reduce the number of layers by not promoting all fixed
790                 // or scrollable elements to their own compositing layer. But in the case that
791                 // we have such an element in the negative z-order, we must make it a layer
792                 // otherwise the content will be painted at a higher z-index. This breaks pages
793                 // that set a large image with a z-index of -1 to implement a background image,
794                 // for example.
795                 bool childRequiresCompositing = childState.m_hasFixedElement || childState.m_hasScrollableElement;
796                 if (!willBeComposited && (childState.m_subtreeIsCompositing || childRequiresCompositing)) {
797 #else
798                 if (!willBeComposited && childState.m_subtreeIsCompositing) {
799 #endif
800                     // make layer compositing
801                     layer->setMustOverlapCompositedLayers(true);
802                     childState.m_compositingAncestor = layer;
803                     if (overlapMap)
804                         addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
805                     willBeComposited = true;
806                 }
807             }
808         }
809     }
810 
811     ASSERT(!layer->m_normalFlowListDirty);
812     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
813         size_t listSize = normalFlowList->size();
814 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
815         childState.m_positionedSibling = compositingState.m_positionedSibling;
816         if (checkForPositionedElements(normalFlowList))
817             childState.m_positionedSibling = true;
818 #endif
819         for (size_t i = 0; i < listSize; ++i) {
820             RenderLayer* curLayer = normalFlowList->at(i);
821             computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
822         }
823     }
824 
825     if (layer->isStackingContext()) {
826         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
827             size_t listSize = posZOrderList->size();
828 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
829             childState.m_positionedSibling = compositingState.m_positionedSibling;
830             if (checkForPositionedElements(posZOrderList))
831                 childState.m_positionedSibling = true;
832 #endif
833             for (size_t i = 0; i < listSize; ++i) {
834                 RenderLayer* curLayer = posZOrderList->at(i);
835                 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
836             }
837         }
838     }
839 
840     // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
841     if (layer->isRootLayer()) {
842         if (inCompositingMode() && m_hasAcceleratedCompositing)
843             willBeComposited = true;
844     }
845 
846     ASSERT(willBeComposited == needsToBeComposited(layer));
847 
848     // If we have a software transform, and we have layers under us, we need to also
849     // be composited. Also, if we have opacity < 1, then we need to be a layer so that
850     // the child layers are opaque, then rendered with opacity on this layer.
851     if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
852         layer->setMustOverlapCompositedLayers(true);
853         if (overlapMap)
854             addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
855         willBeComposited = true;
856     }
857 
858     ASSERT(willBeComposited == needsToBeComposited(layer));
859     if (layer->reflectionLayer())
860         layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
861 
862     // Subsequent layers in the parent stacking context also need to composite.
863     if (childState.m_subtreeIsCompositing)
864         compositingState.m_subtreeIsCompositing = true;
865 
866 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
867     if (childState.m_hasFixedElement)
868         compositingState.m_hasFixedElement = true;
869     if (childState.m_positionedSibling)
870         compositingState.m_positionedSibling = true;
871 #endif
872 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
873     if (childState.m_hasScrollableElement)
874         compositingState.m_hasScrollableElement = true;
875 #endif
876 
877     // Set the flag to say that this SC has compositing children.
878     layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
879 
880     // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
881     // so test that again.
882     if (!willBeComposited && canBeComposited(layer) && clipsCompositingDescendants(layer)) {
883         if (overlapMap)
884             addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
885         willBeComposited = true;
886     }
887 
888     // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
889     // to be composited, then we can drop out of compositing mode altogether.
890 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
891     // We also need to check that we don't have a scrollable layer, as this
892     // would not have set the m_subtreeIsCompositing flag
893     if (layer->isRootLayer() && !childState.m_subtreeIsCompositing
894         && !childState.m_hasScrollableElement && !childState.m_positionedSibling && !childState.m_hasFixedElement
895         && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
896 #else
897     if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
898 #endif
899         enableCompositingMode(false);
900         willBeComposited = false;
901     }
902 
903     // If the layer is going into compositing mode, repaint its old location.
904     ASSERT(willBeComposited == needsToBeComposited(layer));
905     if (!layer->isComposited() && willBeComposited)
906         repaintOnCompositingChange(layer);
907 
908     // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
909     if (updateBacking(layer, CompositingChangeRepaintNow))
910         layersChanged = true;
911 
912     if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
913         layersChanged = true;
914 }
915 
916 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
917 {
918     ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
919     ASSERT(childLayer->isComposited());
920 
921     // It's possible to be called with a parent that isn't yet composited when we're doing
922     // partial updates as required by painting or hit testing. Just bail in that case;
923     // we'll do a full layer update soon.
924     if (!parentLayer || !parentLayer->isComposited())
925         return;
926 
927     if (parentLayer) {
928         GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
929         GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers();
930 
931         hostingLayer->addChild(hostedLayer);
932     } else
933         childLayer->backing()->childForSuperlayers()->removeFromParent();
934 }
935 
936 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
937 {
938     ASSERT(layer->isComposited());
939 
940     GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers();
941     hostingLayer->removeAllChildren();
942 }
943 
944 #if ENABLE(VIDEO)
945 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
946 {
947     if (!m_hasAcceleratedCompositing)
948         return false;
949 
950     return o->supportsAcceleratedRendering();
951 }
952 #endif
953 
954 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer)
955 {
956     // Make the layer compositing if necessary, and set up clipping and content layers.
957     // Note that we can only do work here that is independent of whether the descendant layers
958     // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
959 
960     RenderLayerBacking* layerBacking = layer->backing();
961     if (layerBacking) {
962         // The compositing state of all our children has been updated already, so now
963         // we can compute and cache the composited bounds for this layer.
964         layerBacking->updateCompositedBounds();
965 
966         if (RenderLayer* reflection = layer->reflectionLayer()) {
967             if (reflection->backing())
968                 reflection->backing()->updateCompositedBounds();
969         }
970 
971         layerBacking->updateGraphicsLayerConfiguration();
972         layerBacking->updateGraphicsLayerGeometry();
973 
974         if (!layer->parent())
975             updateRootLayerPosition();
976     }
977 
978     // If this layer has backing, then we are collecting its children, otherwise appending
979     // to the compositing child list of an enclosing layer.
980     Vector<GraphicsLayer*> layerChildren;
981     Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
982 
983     CompositingState childState = compositingState;
984     if (layer->isComposited())
985         childState.m_compositingAncestor = layer;
986 
987 #ifndef NDEBUG
988     ++childState.m_depth;
989 #endif
990 
991     // The children of this stacking context don't need to composite, unless there is
992     // a compositing layer among them, so start by assuming false.
993     childState.m_subtreeIsCompositing = false;
994 
995     if (layer->isStackingContext()) {
996         ASSERT(!layer->m_zOrderListsDirty);
997 
998         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
999             size_t listSize = negZOrderList->size();
1000             for (size_t i = 0; i < listSize; ++i) {
1001                 RenderLayer* curLayer = negZOrderList->at(i);
1002                 rebuildCompositingLayerTree(curLayer, childState, childList);
1003             }
1004         }
1005 
1006         // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
1007         if (layerBacking && layerBacking->foregroundLayer())
1008             childList.append(layerBacking->foregroundLayer());
1009     }
1010 
1011     ASSERT(!layer->m_normalFlowListDirty);
1012     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1013         size_t listSize = normalFlowList->size();
1014         for (size_t i = 0; i < listSize; ++i) {
1015             RenderLayer* curLayer = normalFlowList->at(i);
1016             rebuildCompositingLayerTree(curLayer, childState, childList);
1017         }
1018     }
1019 
1020     if (layer->isStackingContext()) {
1021         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1022             size_t listSize = posZOrderList->size();
1023             for (size_t i = 0; i < listSize; ++i) {
1024                 RenderLayer* curLayer = posZOrderList->at(i);
1025                 rebuildCompositingLayerTree(curLayer, childState, childList);
1026             }
1027         }
1028     }
1029 
1030     if (layerBacking) {
1031         bool parented = false;
1032         if (layer->renderer()->isRenderPart())
1033             parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
1034 
1035         // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
1036         // Otherwise, the overflow control layers are normal children.
1037         if (!layerBacking->hasClippingLayer()) {
1038             if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) {
1039                 overflowControlLayer->removeFromParent();
1040                 layerChildren.append(overflowControlLayer);
1041             }
1042 
1043             if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) {
1044                 overflowControlLayer->removeFromParent();
1045                 layerChildren.append(overflowControlLayer);
1046             }
1047 
1048             if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) {
1049                 overflowControlLayer->removeFromParent();
1050                 layerChildren.append(overflowControlLayer);
1051             }
1052         }
1053 
1054         if (!parented)
1055             layerBacking->parentForSublayers()->setChildren(layerChildren);
1056 
1057 #if ENABLE(FULLSCREEN_API)
1058         // For the sake of clients of the full screen renderer, don't reparent
1059         // the full screen layer out from under them if they're in the middle of
1060         // animating.
1061         if (layer->renderer()->isRenderFullScreen() && toRenderFullScreen(layer->renderer())->isAnimating())
1062             return;
1063 #endif
1064         childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
1065     }
1066 }
1067 
1068 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
1069 {
1070     if (m_overflowControlsHostLayer)
1071         m_overflowControlsHostLayer->setPosition(contentsOffset);
1072 }
1073 
1074 void RenderLayerCompositor::frameViewDidChangeSize()
1075 {
1076     if (m_clipLayer) {
1077         FrameView* frameView = m_renderView->frameView();
1078         m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1079 
1080         IntPoint scrollPosition = frameView->scrollPosition();
1081         m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
1082         updateOverflowControlsLayers();
1083     }
1084 }
1085 
1086 void RenderLayerCompositor::frameViewDidScroll(const IntPoint& scrollPosition)
1087 {
1088     if (m_scrollLayer)
1089         m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
1090 }
1091 
1092 String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo)
1093 {
1094     if (compositingLayerUpdatePending())
1095         updateCompositingLayers();
1096 
1097     if (!m_rootPlatformLayer)
1098         return String();
1099 
1100     // We skip dumping the scroll and clip layers to keep layerTreeAsText output
1101     // similar between platforms.
1102     return m_rootPlatformLayer->layerTreeAsText(showDebugInfo ? LayerTreeAsTextDebug : LayerTreeAsTextBehaviorNormal);
1103 }
1104 
1105 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
1106 {
1107     if (!renderer->node()->isFrameOwnerElement())
1108         return 0;
1109 
1110     HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(renderer->node());
1111     if (Document* contentDocument = element->contentDocument()) {
1112         if (RenderView* view = contentDocument->renderView())
1113             return view->compositor();
1114     }
1115     return 0;
1116 }
1117 
1118 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
1119 {
1120     RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
1121     if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
1122         return false;
1123 
1124     RenderLayer* layer = renderer->layer();
1125     if (!layer->isComposited())
1126         return false;
1127 
1128     RenderLayerBacking* backing = layer->backing();
1129     GraphicsLayer* hostingLayer = backing->parentForSublayers();
1130     GraphicsLayer* rootLayer = innerCompositor->rootPlatformLayer();
1131     if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
1132         hostingLayer->removeAllChildren();
1133         hostingLayer->addChild(rootLayer);
1134     }
1135     return true;
1136 }
1137 
1138 // This just updates layer geometry without changing the hierarchy.
1139 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
1140 {
1141     if (RenderLayerBacking* layerBacking = layer->backing()) {
1142         // The compositing state of all our children has been updated already, so now
1143         // we can compute and cache the composited bounds for this layer.
1144         layerBacking->updateCompositedBounds();
1145 
1146         if (RenderLayer* reflection = layer->reflectionLayer()) {
1147             if (reflection->backing())
1148                 reflection->backing()->updateCompositedBounds();
1149         }
1150 
1151         layerBacking->updateGraphicsLayerConfiguration();
1152         layerBacking->updateGraphicsLayerGeometry();
1153 
1154         if (!layer->parent())
1155             updateRootLayerPosition();
1156     }
1157 
1158     if (layer->isStackingContext()) {
1159         ASSERT(!layer->m_zOrderListsDirty);
1160 
1161         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1162             size_t listSize = negZOrderList->size();
1163             for (size_t i = 0; i < listSize; ++i)
1164                 updateLayerTreeGeometry(negZOrderList->at(i));
1165         }
1166     }
1167 
1168     ASSERT(!layer->m_normalFlowListDirty);
1169     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1170         size_t listSize = normalFlowList->size();
1171         for (size_t i = 0; i < listSize; ++i)
1172             updateLayerTreeGeometry(normalFlowList->at(i));
1173     }
1174 
1175     if (layer->isStackingContext()) {
1176         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1177             size_t listSize = posZOrderList->size();
1178             for (size_t i = 0; i < listSize; ++i)
1179                 updateLayerTreeGeometry(posZOrderList->at(i));
1180         }
1181     }
1182 }
1183 
1184 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
1185 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth)
1186 {
1187     if (layer != compositingAncestor) {
1188         if (RenderLayerBacking* layerBacking = layer->backing()) {
1189             layerBacking->updateCompositedBounds();
1190 
1191             if (RenderLayer* reflection = layer->reflectionLayer()) {
1192                 if (reflection->backing())
1193                     reflection->backing()->updateCompositedBounds();
1194             }
1195 
1196             layerBacking->updateGraphicsLayerGeometry();
1197             if (updateDepth == RenderLayerBacking::CompositingChildren)
1198                 return;
1199         }
1200     }
1201 
1202     if (layer->reflectionLayer())
1203         updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth);
1204 
1205     if (!layer->hasCompositingDescendant())
1206         return;
1207 
1208     if (layer->isStackingContext()) {
1209         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1210             size_t listSize = negZOrderList->size();
1211             for (size_t i = 0; i < listSize; ++i)
1212                 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth);
1213         }
1214     }
1215 
1216     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1217         size_t listSize = normalFlowList->size();
1218         for (size_t i = 0; i < listSize; ++i)
1219             updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth);
1220     }
1221 
1222     if (layer->isStackingContext()) {
1223         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1224             size_t listSize = posZOrderList->size();
1225             for (size_t i = 0; i < listSize; ++i)
1226                 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth);
1227         }
1228     }
1229 }
1230 
1231 
1232 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect)
1233 {
1234     recursiveRepaintLayerRect(rootRenderLayer(), absRect);
1235 }
1236 
1237 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
1238 {
1239     // FIXME: This method does not work correctly with transforms.
1240     if (layer->isComposited())
1241         layer->setBackingNeedsRepaintInRect(rect);
1242 
1243     if (layer->hasCompositingDescendant()) {
1244         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1245             size_t listSize = negZOrderList->size();
1246             for (size_t i = 0; i < listSize; ++i) {
1247                 RenderLayer* curLayer = negZOrderList->at(i);
1248                 int x = 0;
1249                 int y = 0;
1250                 curLayer->convertToLayerCoords(layer, x, y);
1251                 IntRect childRect(rect);
1252                 childRect.move(-x, -y);
1253                 recursiveRepaintLayerRect(curLayer, childRect);
1254             }
1255         }
1256 
1257         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1258             size_t listSize = posZOrderList->size();
1259             for (size_t i = 0; i < listSize; ++i) {
1260                 RenderLayer* curLayer = posZOrderList->at(i);
1261                 int x = 0;
1262                 int y = 0;
1263                 curLayer->convertToLayerCoords(layer, x, y);
1264                 IntRect childRect(rect);
1265                 childRect.move(-x, -y);
1266                 recursiveRepaintLayerRect(curLayer, childRect);
1267             }
1268         }
1269     }
1270     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1271         size_t listSize = normalFlowList->size();
1272         for (size_t i = 0; i < listSize; ++i) {
1273             RenderLayer* curLayer = normalFlowList->at(i);
1274             int x = 0;
1275             int y = 0;
1276             curLayer->convertToLayerCoords(layer, x, y);
1277             IntRect childRect(rect);
1278             childRect.move(-x, -y);
1279             recursiveRepaintLayerRect(curLayer, childRect);
1280         }
1281     }
1282 }
1283 
1284 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
1285 {
1286     return m_renderView->layer();
1287 }
1288 
1289 GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const
1290 {
1291     if (m_overflowControlsHostLayer)
1292         return m_overflowControlsHostLayer.get();
1293     return m_rootPlatformLayer.get();
1294 }
1295 
1296 void RenderLayerCompositor::didMoveOnscreen()
1297 {
1298     if (!inCompositingMode() || m_rootLayerAttachment != RootLayerUnattached)
1299         return;
1300 
1301     RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1302     attachRootPlatformLayer(attachment);
1303 }
1304 
1305 void RenderLayerCompositor::willMoveOffscreen()
1306 {
1307     if (!inCompositingMode() || m_rootLayerAttachment == RootLayerUnattached)
1308         return;
1309 
1310     detachRootPlatformLayer();
1311 }
1312 
1313 void RenderLayerCompositor::updateRootLayerPosition()
1314 {
1315     if (m_rootPlatformLayer) {
1316         m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight()));
1317         m_rootPlatformLayer->setPosition(FloatPoint(m_renderView->docLeft(), m_renderView->docTop()));
1318     }
1319     if (m_clipLayer) {
1320         FrameView* frameView = m_renderView->frameView();
1321         m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
1322     }
1323 }
1324 
1325 void RenderLayerCompositor::didStartAcceleratedAnimation(CSSPropertyID property)
1326 {
1327     // If an accelerated animation or transition runs, we have to turn off overlap checking because
1328     // we don't do layout for every frame, but we have to ensure that the layering is
1329     // correct between the animating object and other objects on the page.
1330     if (property == CSSPropertyWebkitTransform)
1331         setCompositingConsultsOverlap(false);
1332 }
1333 
1334 bool RenderLayerCompositor::has3DContent() const
1335 {
1336     return layerHas3DContent(rootRenderLayer());
1337 }
1338 
1339 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)
1340 {
1341 #if PLATFORM(MAC)
1342     // frames are only independently composited in Mac pre-WebKit2.
1343     return view->platformWidget();
1344 #endif
1345     return false;
1346 }
1347 
1348 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const
1349 {
1350 #if PLATFORM(ANDROID)
1351     if (enclosingFrameElement() && !allowsIndependentlyCompositedFrames(m_renderView->frameView()))
1352         return true;
1353 #endif
1354     // Parent document content needs to be able to render on top of a composited frame, so correct behavior
1355     // is to have the parent document become composited too. However, this can cause problems on platforms that
1356     // use native views for frames (like Mac), so disable that behavior on those platforms for now.
1357     HTMLFrameOwnerElement* ownerElement = enclosingFrameElement();
1358     RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0;
1359 
1360     // If we are the top-level frame, don't propagate.
1361     if (!ownerElement)
1362         return false;
1363 
1364     if (!allowsIndependentlyCompositedFrames(m_renderView->frameView()))
1365         return true;
1366 
1367     if (!renderer || !renderer->isRenderPart())
1368         return false;
1369 
1370     // On Mac, only propagate compositing if the frame is overlapped in the parent
1371     // document, or the parent is already compositing, or the main frame is scaled.
1372     Frame* frame = m_renderView->frameView()->frame();
1373     Page* page = frame ? frame->page() : 0;
1374     if (page->mainFrame()->pageScaleFactor() != 1)
1375         return true;
1376 
1377     RenderPart* frameRenderer = toRenderPart(renderer);
1378     if (frameRenderer->widget()) {
1379         ASSERT(frameRenderer->widget()->isFrameView());
1380         FrameView* view = static_cast<FrameView*>(frameRenderer->widget());
1381         if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor())
1382             return true;
1383     }
1384 
1385     return false;
1386 }
1387 
1388 HTMLFrameOwnerElement* RenderLayerCompositor::enclosingFrameElement() const
1389 {
1390     if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
1391         return (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(objectTag)) ? ownerElement : 0;
1392 
1393     return 0;
1394 }
1395 
1396 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
1397 {
1398     if (!canBeComposited(layer))
1399         return false;
1400 
1401     // The root layer always has a compositing layer, but it may not have backing.
1402 #if PLATFORM(ANDROID)
1403     // If we do not have a root platform layer, don't use the
1404     // mustOverlapCompositedLayers() as a cue that this layer needs to be
1405     // composited -- the layers tree has been detached.
1406     // Otherwise we can end up in a cycle where updateBacking() switches composited
1407     // mode on because a layer has mustOverlapCompositedLayers() (by calling
1408     // enableCompositingMode()), while computeCompositingRequirements() will
1409     // (correctly) say that we do not need to be in composited mode and turns it
1410     // off, rince and repeat...
1411     return requiresCompositingLayer(layer)
1412         || (m_rootPlatformLayer && layer->mustOverlapCompositedLayers())
1413         || (inCompositingMode() && layer->isRootLayer());
1414 #else
1415     return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
1416 #endif
1417 }
1418 
1419 #if PLATFORM(ANDROID)
1420 bool RenderLayerCompositor::requiresCompositingForAndroidLayers(const RenderLayer* layer) const
1421 {
1422 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
1423     if (layer->hasOverflowScroll())
1424         return true;
1425     if (layer->isRootLayer() && m_renderView->frameView()->hasOverflowScroll())
1426         return true;
1427 #endif
1428 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
1429 
1430     // Enable composited layers (for fixed elements)
1431     if (layer->isFixed())
1432         return true;
1433 #endif
1434 
1435     if (layer->renderer()->isCanvas())
1436         return true;
1437 
1438     if (layer->renderer()->style()->hasFixedBackgroundImage())
1439         return true;
1440 
1441     return false;
1442 }
1443 #endif
1444 
1445 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
1446 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
1447 // static
1448 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
1449 {
1450     RenderObject* renderer = layer->renderer();
1451     // The compositing state of a reflection should match that of its reflected layer.
1452     if (layer->isReflection()) {
1453         renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
1454         layer = toRenderBoxModelObject(renderer)->layer();
1455     }
1456     return requiresCompositingForTransform(renderer)
1457 #if PLATFORM(ANDROID)
1458              || requiresCompositingForAndroidLayers(layer)
1459 #endif
1460              || requiresCompositingForVideo(renderer)
1461              || requiresCompositingForCanvas(renderer)
1462              || requiresCompositingForPlugin(renderer)
1463              || requiresCompositingForFrame(renderer)
1464              || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
1465              || clipsCompositingDescendants(layer)
1466              || requiresCompositingForAnimation(renderer)
1467              || requiresCompositingForFullScreen(renderer);
1468 }
1469 
1470 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
1471 {
1472     return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer();
1473 }
1474 
1475 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1476 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1477 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1478 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1479 // but a sibling in the z-order hierarchy.
1480 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
1481 {
1482     if (!layer->isComposited() || !layer->parent())
1483         return false;
1484 
1485     RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1486     if (!compositingAncestor)
1487         return false;
1488 
1489     // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
1490     // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
1491     // and layer.
1492     RenderLayer* computeClipRoot = 0;
1493     RenderLayer* curr = layer;
1494     while (curr) {
1495         RenderLayer* next = curr->parent();
1496         if (next == compositingAncestor) {
1497             computeClipRoot = curr;
1498             break;
1499         }
1500         curr = next;
1501     }
1502 
1503     if (!computeClipRoot || computeClipRoot == layer)
1504         return false;
1505 
1506     IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true);
1507     return backgroundRect != PaintInfo::infiniteRect();
1508 }
1509 
1510 // Return true if the given layer is a stacking context and has compositing child
1511 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1512 // into the hierarchy between this layer and its children in the z-order hierarchy.
1513 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1514 {
1515 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
1516     if (layer->hasOverflowScroll())
1517         return false;
1518 #endif
1519     return layer->hasCompositingDescendant() &&
1520            (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip());
1521 }
1522 
1523 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
1524 {
1525     if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
1526         return false;
1527 
1528     RenderStyle* style = renderer->style();
1529     // Note that we ask the renderer if it has a transform, because the style may have transforms,
1530     // but the renderer may be an inline that doesn't suppport them.
1531     return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
1532 }
1533 
1534 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
1535 {
1536     if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
1537         return false;
1538 #if ENABLE(VIDEO)
1539     if (renderer->isVideo()) {
1540         RenderVideo* video = toRenderVideo(renderer);
1541         return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
1542     }
1543 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1544     else if (renderer->isRenderPart()) {
1545         if (!m_hasAcceleratedCompositing)
1546             return false;
1547 
1548         Node* node = renderer->node();
1549         if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag)))
1550             return false;
1551 
1552         HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node);
1553         return mediaElement->player() ? mediaElement->player()->supportsAcceleratedRendering() : false;
1554     }
1555 #endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1556 #else
1557     UNUSED_PARAM(renderer);
1558 #endif
1559     return false;
1560 }
1561 
1562 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
1563 {
1564     if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
1565         return false;
1566 
1567     if (renderer->isCanvas()) {
1568         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
1569         return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
1570     }
1571     return false;
1572 }
1573 
1574 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
1575 {
1576     if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
1577         return false;
1578 
1579     bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
1580                   || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing());
1581     if (!composite)
1582         return false;
1583 
1584     m_compositingDependsOnGeometry = true;
1585 
1586     RenderWidget* pluginRenderer = toRenderWidget(renderer);
1587     // If we can't reliably know the size of the plugin yet, don't change compositing state.
1588     if (pluginRenderer->needsLayout())
1589         return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited();
1590 
1591     // Don't go into compositing mode if height or width are zero, or size is 1x1.
1592     IntRect contentBox = pluginRenderer->contentBoxRect();
1593 #if PLATFORM(ANDROID)
1594     // allow all plugins including 1x1 to be composited, so that they are drawn,
1595     // and acquire an ANativeWindow on the UI thread
1596     return contentBox.height() * contentBox.width() > 0;
1597 #else
1598     return contentBox.height() * contentBox.width() > 1;
1599 #endif
1600 }
1601 
1602 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
1603 {
1604     if (!renderer->isRenderPart())
1605         return false;
1606 
1607     RenderPart* frameRenderer = toRenderPart(renderer);
1608 
1609     if (!frameRenderer->requiresAcceleratedCompositing())
1610         return false;
1611 
1612     m_compositingDependsOnGeometry = true;
1613 
1614     RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
1615     if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())
1616         return false;
1617 
1618     // If we can't reliably know the size of the iframe yet, don't change compositing state.
1619     if (renderer->needsLayout())
1620         return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited();
1621 
1622     // Don't go into compositing mode if height or width are zero.
1623     IntRect contentBox = frameRenderer->contentBoxRect();
1624     return contentBox.height() * contentBox.width() > 0;
1625 }
1626 
1627 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
1628 {
1629     if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
1630         return false;
1631 
1632     if (AnimationController* animController = renderer->animation()) {
1633 #if PLATFORM(ANDROID)
1634         // android renders an opacity animation much faster if it's composited
1635         return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity))
1636 #else
1637         return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
1638 #endif
1639             || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
1640     }
1641     return false;
1642 }
1643 
1644 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
1645 {
1646     return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection();
1647 }
1648 
1649 bool RenderLayerCompositor::requiresCompositingForFullScreen(RenderObject* renderer) const
1650 {
1651 #if ENABLE(FULLSCREEN_API)
1652     return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating();
1653 #else
1654     UNUSED_PARAM(renderer);
1655     return false;
1656 #endif
1657 }
1658 
1659 // If an element has negative z-index children, those children render in front of the
1660 // layer background, so we need an extra 'contents' layer for the foreground of the layer
1661 // object.
1662 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
1663 {
1664     return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0);
1665 }
1666 
1667 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
1668 {
1669     // We need to handle our own scrolling if we're:
1670     return !m_renderView->frameView()->platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
1671         || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
1672 }
1673 
1674 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1675 {
1676     if (!scrollbar)
1677         return;
1678 
1679     context.save();
1680     const IntRect& scrollbarRect = scrollbar->frameRect();
1681     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1682     IntRect transformedClip = clip;
1683     transformedClip.move(scrollbarRect.x(), scrollbarRect.y());
1684     scrollbar->paint(&context, transformedClip);
1685     context.restore();
1686 }
1687 
1688 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
1689 {
1690     if (graphicsLayer == layerForHorizontalScrollbar())
1691         paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
1692     else if (graphicsLayer == layerForVerticalScrollbar())
1693         paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
1694     else if (graphicsLayer == layerForScrollCorner()) {
1695         const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
1696         context.save();
1697         context.translate(-scrollCorner.x(), -scrollCorner.y());
1698         IntRect transformedClip = clip;
1699         transformedClip.move(scrollCorner.x(), scrollCorner.y());
1700         m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
1701         context.restore();
1702     }
1703 }
1704 
1705 static bool shouldCompositeOverflowControls(ScrollView* view)
1706 {
1707     if (view->platformWidget())
1708         return false;
1709 #if !PLATFORM(CHROMIUM)
1710     if (!view->hasOverlayScrollbars())
1711         return false;
1712 #endif
1713     return true;
1714 }
1715 
1716 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
1717 {
1718     ScrollView* view = m_renderView->frameView();
1719     return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
1720 }
1721 
1722 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
1723 {
1724     ScrollView* view = m_renderView->frameView();
1725     return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
1726 }
1727 
1728 bool RenderLayerCompositor::requiresScrollCornerLayer() const
1729 {
1730     ScrollView* view = m_renderView->frameView();
1731     return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
1732 }
1733 
1734 void RenderLayerCompositor::updateOverflowControlsLayers()
1735 {
1736     bool layersChanged = false;
1737 
1738     if (requiresHorizontalScrollbarLayer()) {
1739         m_layerForHorizontalScrollbar = GraphicsLayer::create(this);
1740 #ifndef NDEBUG
1741         m_layerForHorizontalScrollbar->setName("horizontal scrollbar");
1742 #endif
1743         m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
1744         layersChanged = true;
1745     } else if (m_layerForHorizontalScrollbar) {
1746         m_layerForHorizontalScrollbar->removeFromParent();
1747         m_layerForHorizontalScrollbar = 0;
1748         layersChanged = true;
1749     }
1750 
1751     if (requiresVerticalScrollbarLayer()) {
1752         m_layerForVerticalScrollbar = GraphicsLayer::create(this);
1753 #ifndef NDEBUG
1754         m_layerForVerticalScrollbar->setName("vertical scrollbar");
1755 #endif
1756         m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
1757         layersChanged = true;
1758     } else if (m_layerForVerticalScrollbar) {
1759         m_layerForVerticalScrollbar->removeFromParent();
1760         m_layerForVerticalScrollbar = 0;
1761         layersChanged = true;
1762     }
1763 
1764     if (requiresScrollCornerLayer()) {
1765         m_layerForScrollCorner = GraphicsLayer::create(this);
1766 #ifndef NDEBUG
1767         m_layerForScrollCorner->setName("scroll corner");
1768 #endif
1769         m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
1770         layersChanged = true;
1771     } else if (m_layerForScrollCorner) {
1772         m_layerForScrollCorner->removeFromParent();
1773         m_layerForScrollCorner = 0;
1774         layersChanged = true;
1775     }
1776 
1777     if (layersChanged)
1778         m_renderView->frameView()->positionScrollbarLayers();
1779 }
1780 
1781 void RenderLayerCompositor::ensureRootPlatformLayer()
1782 {
1783     RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1784     if (expectedAttachment == m_rootLayerAttachment)
1785          return;
1786 
1787     if (!m_rootPlatformLayer) {
1788         m_rootPlatformLayer = GraphicsLayer::create(0);
1789 #ifndef NDEBUG
1790         m_rootPlatformLayer->setName("Root platform");
1791 #endif
1792         m_rootPlatformLayer->setSize(FloatSize(m_renderView->maxXLayoutOverflow(), m_renderView->maxYLayoutOverflow()));
1793         m_rootPlatformLayer->setPosition(FloatPoint());
1794 
1795         // Need to clip to prevent transformed content showing outside this frame
1796         m_rootPlatformLayer->setMasksToBounds(true);
1797     }
1798 
1799     if (requiresScrollLayer(expectedAttachment)) {
1800         if (!m_overflowControlsHostLayer) {
1801             ASSERT(!m_scrollLayer);
1802             ASSERT(!m_clipLayer);
1803 
1804             // Create a layer to host the clipping layer and the overflow controls layers.
1805             m_overflowControlsHostLayer = GraphicsLayer::create(0);
1806 #ifndef NDEBUG
1807             m_overflowControlsHostLayer->setName("overflow controls host");
1808 #endif
1809 
1810             // Create a clipping layer if this is an iframe
1811             m_clipLayer = GraphicsLayer::create(this);
1812 #ifndef NDEBUG
1813             m_clipLayer->setName("iframe Clipping");
1814 #endif
1815             m_clipLayer->setMasksToBounds(true);
1816 
1817             m_scrollLayer = GraphicsLayer::create(this);
1818 #ifndef NDEBUG
1819             m_scrollLayer->setName("iframe scrolling");
1820 #endif
1821 
1822             // Hook them up
1823             m_overflowControlsHostLayer->addChild(m_clipLayer.get());
1824             m_clipLayer->addChild(m_scrollLayer.get());
1825             m_scrollLayer->addChild(m_rootPlatformLayer.get());
1826 
1827             frameViewDidChangeSize();
1828             frameViewDidScroll(m_renderView->frameView()->scrollPosition());
1829         }
1830     } else {
1831         if (m_overflowControlsHostLayer) {
1832             m_overflowControlsHostLayer = 0;
1833             m_clipLayer = 0;
1834             m_scrollLayer = 0;
1835         }
1836     }
1837 
1838     // Check to see if we have to change the attachment
1839     if (m_rootLayerAttachment != RootLayerUnattached)
1840         detachRootPlatformLayer();
1841 
1842     attachRootPlatformLayer(expectedAttachment);
1843 }
1844 
1845 void RenderLayerCompositor::destroyRootPlatformLayer()
1846 {
1847     if (!m_rootPlatformLayer)
1848         return;
1849 
1850     detachRootPlatformLayer();
1851 
1852     if (m_layerForHorizontalScrollbar) {
1853         m_layerForHorizontalScrollbar->removeFromParent();
1854         m_layerForHorizontalScrollbar = 0;
1855         if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
1856             m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
1857     }
1858 
1859     if (m_layerForVerticalScrollbar) {
1860         m_layerForVerticalScrollbar->removeFromParent();
1861         m_layerForVerticalScrollbar = 0;
1862         if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
1863             m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
1864     }
1865 
1866     if (m_layerForScrollCorner) {
1867         m_layerForScrollCorner = 0;
1868         m_renderView->frameView()->invalidateScrollCorner();
1869     }
1870 
1871     if (m_overflowControlsHostLayer) {
1872         m_overflowControlsHostLayer = 0;
1873         m_clipLayer = 0;
1874         m_scrollLayer = 0;
1875     }
1876     ASSERT(!m_scrollLayer);
1877     m_rootPlatformLayer = 0;
1878 }
1879 
1880 void RenderLayerCompositor::attachRootPlatformLayer(RootLayerAttachment attachment)
1881 {
1882     if (!m_rootPlatformLayer)
1883         return;
1884 
1885     switch (attachment) {
1886         case RootLayerUnattached:
1887             ASSERT_NOT_REACHED();
1888             break;
1889         case RootLayerAttachedViaChromeClient: {
1890             Frame* frame = m_renderView->frameView()->frame();
1891             Page* page = frame ? frame->page() : 0;
1892             if (!page)
1893                 return;
1894 
1895             page->chrome()->client()->attachRootGraphicsLayer(frame, rootPlatformLayer());
1896             break;
1897         }
1898         case RootLayerAttachedViaEnclosingFrame: {
1899             // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
1900             // for the frame's renderer in the parent document.
1901             scheduleNeedsStyleRecalc(m_renderView->document()->ownerElement());
1902             break;
1903         }
1904     }
1905 
1906     m_rootLayerAttachment = attachment;
1907     rootLayerAttachmentChanged();
1908 }
1909 
1910 void RenderLayerCompositor::detachRootPlatformLayer()
1911 {
1912     if (!m_rootPlatformLayer || m_rootLayerAttachment == RootLayerUnattached)
1913         return;
1914 
1915     switch (m_rootLayerAttachment) {
1916     case RootLayerAttachedViaEnclosingFrame: {
1917         // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
1918         // for the frame's renderer in the parent document.
1919         if (m_overflowControlsHostLayer)
1920             m_overflowControlsHostLayer->removeFromParent();
1921         else
1922             m_rootPlatformLayer->removeFromParent();
1923 
1924         if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
1925             scheduleNeedsStyleRecalc(ownerElement);
1926         break;
1927     }
1928     case RootLayerAttachedViaChromeClient: {
1929         Frame* frame = m_renderView->frameView()->frame();
1930         Page* page = frame ? frame->page() : 0;
1931         if (!page)
1932             return;
1933 
1934         page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
1935     }
1936     break;
1937     case RootLayerUnattached:
1938         break;
1939     }
1940 
1941     m_rootLayerAttachment = RootLayerUnattached;
1942     rootLayerAttachmentChanged();
1943 }
1944 
1945 void RenderLayerCompositor::updateRootLayerAttachment()
1946 {
1947     ensureRootPlatformLayer();
1948 }
1949 
1950 void RenderLayerCompositor::rootLayerAttachmentChanged()
1951 {
1952     // The attachment can affect whether the RenderView layer's paintingGoesToWindow() behavior,
1953     // so call updateGraphicsLayerGeometry() to udpate that.
1954     RenderLayer* layer = m_renderView->layer();
1955     if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
1956         backing->updateDrawsContent();
1957 }
1958 
1959 static void needsStyleRecalcCallback(Node* node)
1960 {
1961     node->setNeedsStyleRecalc(SyntheticStyleChange);
1962 }
1963 
1964 void RenderLayerCompositor::scheduleNeedsStyleRecalc(Element* element)
1965 {
1966     if (ContainerNode::postAttachCallbacksAreSuspended())
1967         ContainerNode::queuePostAttachCallback(needsStyleRecalcCallback, element);
1968     else
1969         element->setNeedsStyleRecalc(SyntheticStyleChange);
1970 }
1971 
1972 // IFrames are special, because we hook compositing layers together across iframe boundaries
1973 // when both parent and iframe content are composited. So when this frame becomes composited, we have
1974 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
1975 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
1976 {
1977     Frame* frame = m_renderView->frameView() ? m_renderView->frameView()->frame() : 0;
1978     if (!frame)
1979         return;
1980 
1981     for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) {
1982         if (child->document() && child->document()->ownerElement())
1983             scheduleNeedsStyleRecalc(child->document()->ownerElement());
1984     }
1985 
1986     // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
1987     // we need to schedule a style recalc in our parent document.
1988     if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
1989         scheduleNeedsStyleRecalc(ownerElement);
1990 }
1991 
1992 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
1993 {
1994     const RenderStyle* style = layer->renderer()->style();
1995 
1996     if (style &&
1997         (style->transformStyle3D() == TransformStyle3DPreserve3D ||
1998          style->hasPerspective() ||
1999          style->transform().has3DOperation()))
2000         return true;
2001 
2002     if (layer->isStackingContext()) {
2003         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
2004             size_t listSize = negZOrderList->size();
2005             for (size_t i = 0; i < listSize; ++i) {
2006                 RenderLayer* curLayer = negZOrderList->at(i);
2007                 if (layerHas3DContent(curLayer))
2008                     return true;
2009             }
2010         }
2011 
2012         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
2013             size_t listSize = posZOrderList->size();
2014             for (size_t i = 0; i < listSize; ++i) {
2015                 RenderLayer* curLayer = posZOrderList->at(i);
2016                 if (layerHas3DContent(curLayer))
2017                     return true;
2018             }
2019         }
2020     }
2021 
2022     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
2023         size_t listSize = normalFlowList->size();
2024         for (size_t i = 0; i < listSize; ++i) {
2025             RenderLayer* curLayer = normalFlowList->at(i);
2026             if (layerHas3DContent(curLayer))
2027                 return true;
2028         }
2029     }
2030     return false;
2031 }
2032 
2033 void RenderLayerCompositor::updateContentsScale(float scale, RenderLayer* layer)
2034 {
2035     if (!layer)
2036         layer = rootRenderLayer();
2037 
2038     layer->updateContentsScale(scale);
2039 
2040     if (layer->isStackingContext()) {
2041         if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
2042             size_t listSize = negZOrderList->size();
2043             for (size_t i = 0; i < listSize; ++i)
2044                 updateContentsScale(scale, negZOrderList->at(i));
2045         }
2046 
2047         if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
2048             size_t listSize = posZOrderList->size();
2049             for (size_t i = 0; i < listSize; ++i)
2050                 updateContentsScale(scale, posZOrderList->at(i));
2051         }
2052     }
2053 
2054     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
2055         size_t listSize = normalFlowList->size();
2056         for (size_t i = 0; i < listSize; ++i)
2057             updateContentsScale(scale, normalFlowList->at(i));
2058     }
2059 }
2060 
2061 } // namespace WebCore
2062 
2063 #endif // USE(ACCELERATED_COMPOSITING)
2064