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