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