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