1 /*
2 * Copyright (C) 2009 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 "Chrome.h"
33 #include "ChromeClient.h"
34 #include "CSSPropertyNames.h"
35 #include "Frame.h"
36 #include "FrameView.h"
37 #include "GraphicsLayer.h"
38 #include "HitTestResult.h"
39 #include "HTMLCanvasElement.h"
40 #include "Page.h"
41 #include "RenderEmbeddedObject.h"
42 #include "RenderLayerBacking.h"
43 #include "RenderReplica.h"
44 #include "RenderVideo.h"
45 #include "RenderView.h"
46 #include "Settings.h"
47
48 #if PROFILE_LAYER_REBUILD
49 #include <wtf/CurrentTime.h>
50 #endif
51
52 #ifndef NDEBUG
53 #include "CString.h"
54 #include "RenderTreeAsText.h"
55 #endif
56
57 #if ENABLE(3D_RENDERING)
58 // This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm').
59 bool WebCoreHas3DRendering = true;
60 #endif
61
62 namespace WebCore {
63
64 using namespace HTMLNames;
65
66 struct CompositingState {
CompositingStateWebCore::CompositingState67 CompositingState(RenderLayer* compAncestor)
68 : m_compositingAncestor(compAncestor)
69 , m_subtreeIsCompositing(false)
70 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
71 , m_fixedSibling(false)
72 #endif
73 #ifndef NDEBUG
74 , m_depth(0)
75 #endif
76 {
77 }
78
79 RenderLayer* m_compositingAncestor;
80 bool m_subtreeIsCompositing;
81 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
82 bool m_fixedSibling;
83 #endif
84 #ifndef NDEBUG
85 int m_depth;
86 #endif
87 };
88
RenderLayerCompositor(RenderView * renderView)89 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
90 : m_renderView(renderView)
91 , m_rootPlatformLayer(0)
92 , m_hasAcceleratedCompositing(true)
93 , m_showDebugBorders(false)
94 , m_showRepaintCounter(false)
95 , m_compositingConsultsOverlap(true)
96 , m_compositing(false)
97 , m_rootLayerAttached(false)
98 , m_compositingLayersNeedRebuild(false)
99 #if PROFILE_LAYER_REBUILD
100 , m_rootLayerUpdateCount(0)
101 #endif // PROFILE_LAYER_REBUILD
102 {
103 }
104
~RenderLayerCompositor()105 RenderLayerCompositor::~RenderLayerCompositor()
106 {
107 ASSERT(!m_rootLayerAttached);
108 }
109
enableCompositingMode(bool enable)110 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
111 {
112 if (enable != m_compositing) {
113 m_compositing = enable;
114
115 // We never go out of compositing mode for a given page,
116 // but if all the layers disappear, we'll just be left with
117 // the empty root layer, which has minimal overhead.
118 if (m_compositing)
119 ensureRootPlatformLayer();
120 else
121 destroyRootPlatformLayer();
122 }
123 }
124
cacheAcceleratedCompositingFlags()125 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
126 {
127 bool hasAcceleratedCompositing = false;
128 bool showDebugBorders = false;
129 bool showRepaintCounter = false;
130
131 if (Settings* settings = m_renderView->document()->settings()) {
132 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
133 showDebugBorders = settings->showDebugBorders();
134 showRepaintCounter = settings->showRepaintCounter();
135 }
136
137 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter)
138 setCompositingLayersNeedRebuild();
139
140 m_hasAcceleratedCompositing = hasAcceleratedCompositing;
141 m_showDebugBorders = showDebugBorders;
142 m_showRepaintCounter = showRepaintCounter;
143 }
144
setCompositingLayersNeedRebuild(bool needRebuild)145 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
146 {
147 if (inCompositingMode())
148 m_compositingLayersNeedRebuild = needRebuild;
149 }
150
scheduleSync()151 void RenderLayerCompositor::scheduleSync()
152 {
153 Frame* frame = m_renderView->frameView()->frame();
154 Page* page = frame ? frame->page() : 0;
155 if (!page)
156 return;
157
158 page->chrome()->client()->scheduleCompositingLayerSync();
159 }
160
updateCompositingLayers(CompositingUpdateType updateType,RenderLayer * updateRoot)161 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
162 {
163 bool checkForHierarchyUpdate = false;
164 bool needGeometryUpdate = false;
165
166 switch (updateType) {
167 case CompositingUpdateAfterLayoutOrStyleChange:
168 case CompositingUpdateOnPaitingOrHitTest:
169 checkForHierarchyUpdate = true;
170 break;
171 case CompositingUpdateOnScroll:
172 if (m_compositingConsultsOverlap)
173 checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
174
175 needGeometryUpdate = true;
176 break;
177 }
178
179 if (!checkForHierarchyUpdate && !needGeometryUpdate)
180 return;
181
182 ASSERT(inCompositingMode());
183
184 bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
185 if (!updateRoot) {
186 // Only clear the flag if we're updating the entire hierarchy.
187 m_compositingLayersNeedRebuild = false;
188 updateRoot = rootRenderLayer();
189 }
190
191 #if PROFILE_LAYER_REBUILD
192 ++m_rootLayerUpdateCount;
193
194 double startTime = WTF::currentTime();
195 #endif
196
197 if (checkForHierarchyUpdate) {
198 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
199 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
200 CompositingState compState(updateRoot);
201 bool layersChanged = false;
202 if (m_compositingConsultsOverlap) {
203 OverlapMap overlapTestRequestMap;
204 computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged);
205 } else
206 computeCompositingRequirements(updateRoot, 0, compState, layersChanged);
207
208 needHierarchyUpdate |= layersChanged;
209 }
210
211 if (needHierarchyUpdate) {
212 // Update the hierarchy of the compositing layers.
213 CompositingState compState(updateRoot);
214 Vector<GraphicsLayer*> childList;
215 rebuildCompositingLayerTree(updateRoot, compState, childList);
216
217 // Host the document layer in the RenderView's root layer.
218 if (updateRoot == rootRenderLayer() && !childList.isEmpty())
219 m_rootPlatformLayer->setChildren(childList);
220 } else if (needGeometryUpdate) {
221 // We just need to do a geometry update. This is only used for position:fixed scrolling;
222 // most of the time, geometry is updated via RenderLayer::styleChanged().
223 updateLayerTreeGeometry(updateRoot);
224 }
225
226 #if PROFILE_LAYER_REBUILD
227 double endTime = WTF::currentTime();
228 if (updateRoot == rootRenderLayer())
229 fprintf(stderr, "Update %d: computeCompositingRequirements for the world took %fms\n",
230 m_rootLayerUpdateCount, 1000.0 * (endTime - startTime));
231 #endif
232 ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
233
234 if (!hasAcceleratedCompositing())
235 enableCompositingMode(false);
236 }
237
updateBacking(RenderLayer * layer,CompositingChangeRepaint shouldRepaint)238 bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
239 {
240 bool layerChanged = false;
241
242 if (needsToBeComposited(layer)) {
243 enableCompositingMode();
244
245 // 3D transforms turn off the testing of overlap.
246 if (requiresCompositingForTransform(layer->renderer()))
247 setCompositingConsultsOverlap(false);
248
249 if (!layer->backing()) {
250
251 // If we need to repaint, do so before making backing
252 if (shouldRepaint == CompositingChangeRepaintNow)
253 repaintOnCompositingChange(layer);
254
255 layer->ensureBacking();
256 layerChanged = true;
257 }
258 } else {
259 if (layer->backing()) {
260 // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
261 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
262 // are both either composited, or not composited.
263 if (layer->isReflection()) {
264 RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer();
265 if (RenderLayerBacking* backing = sourceLayer->backing()) {
266 ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer());
267 backing->graphicsLayer()->setReplicatedByLayer(0);
268 }
269 }
270
271 layer->clearBacking();
272 layerChanged = true;
273
274 // The layer's cached repaints rects are relative to the repaint container, so change when
275 // compositing changes; we need to update them here.
276 layer->computeRepaintRects();
277
278 // If we need to repaint, do so now that we've removed the backing
279 if (shouldRepaint == CompositingChangeRepaintNow)
280 repaintOnCompositingChange(layer);
281 }
282 }
283
284 #if ENABLE(VIDEO)
285 if (layerChanged && layer->renderer()->isVideo()) {
286 // If it's a video, give the media player a chance to hook up to the layer.
287 RenderVideo* video = toRenderVideo(layer->renderer());
288 video->acceleratedRenderingStateChanged();
289 }
290 #endif
291 return layerChanged;
292 }
293
updateLayerCompositingState(RenderLayer * layer,CompositingChangeRepaint shouldRepaint)294 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, CompositingChangeRepaint shouldRepaint)
295 {
296 bool layerChanged = updateBacking(layer, shouldRepaint);
297
298 // See if we need content or clipping layers. Methods called here should assume
299 // that the compositing state of descendant layers has not been updated yet.
300 if (layer->backing() && layer->backing()->updateGraphicsLayerConfiguration())
301 layerChanged = true;
302
303 return layerChanged;
304 }
305
repaintOnCompositingChange(RenderLayer * layer)306 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
307 {
308 // If the renderer is not attached yet, no need to repaint.
309 if (!layer->renderer()->parent())
310 return;
311
312 RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint();
313 if (!repaintContainer)
314 repaintContainer = m_renderView;
315
316 layer->repaintIncludingNonCompositingDescendants(repaintContainer);
317 if (repaintContainer == m_renderView) {
318 // The contents of this layer may be moving between the window
319 // and a GraphicsLayer, so we need to make sure the window system
320 // synchronizes those changes on the screen.
321 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
322 }
323 }
324
325 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
326 // RenderLayers that are rendered by the composited RenderLayer.
calculateCompositedBounds(const RenderLayer * layer,const RenderLayer * ancestorLayer)327 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
328 {
329 if (!layer->isSelfPaintingLayer())
330 return IntRect();
331
332 IntRect boundingBoxRect, unionBounds;
333 boundingBoxRect = unionBounds = layer->localBoundingBox();
334
335 if (layer->renderer()->hasOverflowClip() || layer->renderer()->hasMask()) {
336 int ancestorRelX = 0, ancestorRelY = 0;
337 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
338 boundingBoxRect.move(ancestorRelX, ancestorRelY);
339 return boundingBoxRect;
340 }
341
342 if (RenderLayer* reflection = layer->reflectionLayer()) {
343 if (!reflection->isComposited()) {
344 IntRect childUnionBounds = calculateCompositedBounds(reflection, layer);
345 unionBounds.unite(childUnionBounds);
346 }
347 }
348
349 ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0));
350
351 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
352 size_t listSize = negZOrderList->size();
353 for (size_t i = 0; i < listSize; ++i) {
354 RenderLayer* curLayer = negZOrderList->at(i);
355 if (!curLayer->isComposited()) {
356 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
357 unionBounds.unite(childUnionBounds);
358 }
359 }
360 }
361
362 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
363 size_t listSize = posZOrderList->size();
364 for (size_t i = 0; i < listSize; ++i) {
365 RenderLayer* curLayer = posZOrderList->at(i);
366 if (!curLayer->isComposited()) {
367 IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
368 unionBounds.unite(childUnionBounds);
369 }
370 }
371 }
372
373 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
374 size_t listSize = normalFlowList->size();
375 for (size_t i = 0; i < listSize; ++i) {
376 RenderLayer* curLayer = normalFlowList->at(i);
377 if (!curLayer->isComposited()) {
378 IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer);
379 unionBounds.unite(curAbsBounds);
380 }
381 }
382 }
383
384 if (layer->paintsWithTransform(PaintBehaviorNormal)) {
385 TransformationMatrix* affineTrans = layer->transform();
386 boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
387 unionBounds = affineTrans->mapRect(unionBounds);
388 }
389
390 int ancestorRelX = 0, ancestorRelY = 0;
391 layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
392 unionBounds.move(ancestorRelX, ancestorRelY);
393
394 return unionBounds;
395 }
396
layerWasAdded(RenderLayer *,RenderLayer *)397 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
398 {
399 setCompositingLayersNeedRebuild();
400 }
401
layerWillBeRemoved(RenderLayer * parent,RenderLayer * child)402 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
403 {
404 if (!child->isComposited() || parent->renderer()->documentBeingDestroyed())
405 return;
406
407 setCompositingParent(child, 0);
408
409 RenderLayer* compLayer = parent->enclosingCompositingLayer();
410 if (compLayer) {
411 ASSERT(compLayer->backing());
412 IntRect compBounds = child->backing()->compositedBounds();
413
414 int offsetX = 0, offsetY = 0;
415 child->convertToLayerCoords(compLayer, offsetX, offsetY);
416 compBounds.move(offsetX, offsetY);
417
418 compLayer->setBackingNeedsRepaintInRect(compBounds);
419
420 // The contents of this layer may be moving from a GraphicsLayer to the window,
421 // so we need to make sure the window system synchronizes those changes on the screen.
422 m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
423 }
424
425 setCompositingLayersNeedRebuild();
426 }
427
enclosingNonStackingClippingLayer(const RenderLayer * layer) const428 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
429 {
430 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
431 if (curr->isStackingContext())
432 return 0;
433
434 if (curr->renderer()->hasOverflowClip())
435 return curr;
436 }
437 return 0;
438 }
439
addToOverlapMap(OverlapMap & overlapMap,RenderLayer * layer,IntRect & layerBounds,bool & boundsComputed)440 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
441 {
442 if (layer->isRootLayer())
443 return;
444
445 if (!boundsComputed) {
446 layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
447 boundsComputed = true;
448 }
449
450 overlapMap.add(layer, layerBounds);
451 }
452
overlapsCompositedLayers(OverlapMap & overlapMap,const IntRect & layerBounds)453 bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds)
454 {
455 RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end();
456 for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {
457 const IntRect& bounds = it->second;
458 if (layerBounds.intersects(bounds))
459 return true;
460 }
461
462 return false;
463 }
464
465 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
466 // For the z-order children of a compositing layer:
467 // If a child layers has a compositing layer, then all subsequent layers must
468 // be compositing in order to render above that layer.
469 //
470 // If a child in the negative z-order list is compositing, then the layer itself
471 // must be compositing so that its contents render over that child.
472 // This implies that its positive z-index children must also be compositing.
473 //
computeCompositingRequirements(RenderLayer * layer,OverlapMap * overlapMap,struct CompositingState & compositingState,bool & layersChanged)474 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, OverlapMap* overlapMap, struct CompositingState& compositingState, bool& layersChanged)
475 {
476 layer->updateLayerPosition();
477 layer->updateZOrderLists();
478 layer->updateNormalFlowList();
479
480 // Clear the flag
481 layer->setHasCompositingDescendant(false);
482
483 bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing;
484
485 bool haveComputedBounds = false;
486 IntRect absBounds;
487 if (overlapMap && !overlapMap->isEmpty()) {
488 // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
489 absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
490 haveComputedBounds = true;
491 mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
492 }
493
494 layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
495
496 // The children of this layer don't need to composite, unless there is
497 // a compositing layer among them, so start by inheriting the compositing
498 // ancestor with m_subtreeIsCompositing set to false.
499 CompositingState childState(compositingState.m_compositingAncestor);
500 #ifndef NDEBUG
501 ++childState.m_depth;
502 #endif
503
504 const bool willBeComposited = needsToBeComposited(layer);
505
506 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
507 // If we are a fixed layer, signal it to our siblings
508 if (layer->isFixed())
509 compositingState.m_fixedSibling = true;
510
511 if (!willBeComposited && compositingState.m_fixedSibling)
512 layer->setMustOverlapCompositedLayers(true);
513
514 if (willBeComposited || compositingState.m_fixedSibling) {
515 #else
516 if (willBeComposited) {
517 #endif
518 // Tell the parent it has compositing descendants.
519 compositingState.m_subtreeIsCompositing = true;
520 // This layer now acts as the ancestor for kids.
521 childState.m_compositingAncestor = layer;
522 if (overlapMap)
523 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
524 }
525
526 #if ENABLE(VIDEO)
527 // Video is special. It's a replaced element with a content layer, but has shadow content
528 // for the controller that must render in front. Without this, the controls fail to show
529 // when the video element is a stacking context (e.g. due to opacity or transform).
530 if (willBeComposited && layer->renderer()->isVideo())
531 childState.m_subtreeIsCompositing = true;
532 #endif
533
534 if (layer->isStackingContext()) {
535 ASSERT(!layer->m_zOrderListsDirty);
536 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
537 size_t listSize = negZOrderList->size();
538 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
539 childState.m_fixedSibling = false;
540
541 // For the negative z-order, if we have a fixed layer
542 // we need to make all the siblings composited layers.
543 // Otherwise a negative layer (below the fixed layer) could
544 // still be drawn onto a higher z-order layer (e.g. the body)
545 // if not immediately intersecting with our fixed layer.
546 // So it's not enough here to only set m_fixedSibling for
547 // subsequent siblings as we do for the normal flow
548 // and positive z-order.
549 for (size_t j = 0; j < listSize; ++j) {
550 if ((negZOrderList->at(j))->isFixed()) {
551 childState.m_fixedSibling = true;
552 break;
553 }
554 }
555 #endif
556
557 for (size_t i = 0; i < listSize; ++i) {
558 RenderLayer* curLayer = negZOrderList->at(i);
559 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
560
561 // If we have to make a layer for this child, make one now so we can have a contents layer
562 // (since we need to ensure that the -ve z-order child renders underneath our contents).
563 if (!willBeComposited && childState.m_subtreeIsCompositing) {
564 // make layer compositing
565 layer->setMustOverlapCompositedLayers(true);
566 childState.m_compositingAncestor = layer;
567 if (overlapMap)
568 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
569 }
570 }
571 }
572 }
573
574 ASSERT(!layer->m_normalFlowListDirty);
575 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
576 size_t listSize = normalFlowList->size();
577 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
578 childState.m_fixedSibling = false;
579 #endif
580 for (size_t i = 0; i < listSize; ++i) {
581 RenderLayer* curLayer = normalFlowList->at(i);
582 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
583 }
584 }
585
586 if (layer->isStackingContext()) {
587 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
588 size_t listSize = posZOrderList->size();
589 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
590 childState.m_fixedSibling = false;
591 #endif
592 for (size_t i = 0; i < listSize; ++i) {
593 RenderLayer* curLayer = posZOrderList->at(i);
594 computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
595 }
596 }
597 }
598
599 // If we have a software transform, and we have layers under us, we need to also
600 // be composited. Also, if we have opacity < 1, then we need to be a layer so that
601 // the child layers are opaque, then rendered with opacity on this layer.
602 if (!willBeComposited && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
603 layer->setMustOverlapCompositedLayers(true);
604 if (overlapMap)
605 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
606 }
607
608 if (layer->reflectionLayer())
609 layer->reflectionLayer()->setMustOverlapCompositedLayers(needsToBeComposited(layer));
610
611 // Subsequent layers in the parent stacking context also need to composite.
612 if (childState.m_subtreeIsCompositing)
613 compositingState.m_subtreeIsCompositing = true;
614
615 // If the layer is going into compositing mode, repaint its old location.
616 if (!layer->isComposited() && needsToBeComposited(layer))
617 repaintOnCompositingChange(layer);
618
619 // Set the flag to say that this SC has compositing children.
620 // this can affect the answer to needsToBeComposited() when clipping,
621 // but that's ok here.
622 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
623
624 // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
625 if (updateBacking(layer, CompositingChangeRepaintNow))
626 layersChanged = true;
627
628 if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
629 layersChanged = true;
630 }
631
632 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
633 {
634 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
635 ASSERT(childLayer->isComposited());
636
637 // It's possible to be called with a parent that isn't yet composited when we're doing
638 // partial updates as required by painting or hit testing. Just bail in that case;
639 // we'll do a full layer update soon.
640 if (!parentLayer || !parentLayer->isComposited())
641 return;
642
643 if (parentLayer) {
644 GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
645 GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers();
646
647 hostingLayer->addChild(hostedLayer);
648 } else
649 childLayer->backing()->childForSuperlayers()->removeFromParent();
650 }
651
652 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
653 {
654 ASSERT(layer->isComposited());
655
656 GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers();
657 hostingLayer->removeAllChildren();
658 }
659
660 void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer)
661 {
662 ASSERT(layer->isComposited());
663
664 GraphicsLayer* layerAnchor = layer->backing()->childForSuperlayers();
665
666 if (layerAnchor->parent() != m_rootPlatformLayer) {
667 layerAnchor->removeFromParent();
668 if (m_rootPlatformLayer)
669 m_rootPlatformLayer->addChild(layerAnchor);
670 }
671 }
672
673 #if ENABLE(VIDEO)
674 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
675 {
676 if (!m_hasAcceleratedCompositing)
677 return false;
678
679 return o->supportsAcceleratedRendering();
680 }
681 #endif
682
683 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, const CompositingState& compositingState, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer)
684 {
685 // Make the layer compositing if necessary, and set up clipping and content layers.
686 // Note that we can only do work here that is independent of whether the descendant layers
687 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
688
689 RenderLayerBacking* layerBacking = layer->backing();
690 if (layerBacking) {
691 // The compositing state of all our children has been updated already, so now
692 // we can compute and cache the composited bounds for this layer.
693 layerBacking->updateCompositedBounds();
694
695 if (RenderLayer* reflection = layer->reflectionLayer()) {
696 if (reflection->backing())
697 reflection->backing()->updateCompositedBounds();
698 }
699
700 layerBacking->updateGraphicsLayerConfiguration();
701 layerBacking->updateGraphicsLayerGeometry();
702
703 if (!layer->parent())
704 updateRootLayerPosition();
705 }
706
707 // If this layer has backing, then we are collecting its children, otherwise appending
708 // to the compositing child list of an enclosing layer.
709 Vector<GraphicsLayer*> layerChildren;
710 Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
711
712 CompositingState childState = compositingState;
713 if (layer->isComposited())
714 childState.m_compositingAncestor = layer;
715
716 #ifndef NDEBUG
717 ++childState.m_depth;
718 #endif
719
720 // The children of this stacking context don't need to composite, unless there is
721 // a compositing layer among them, so start by assuming false.
722 childState.m_subtreeIsCompositing = false;
723
724 if (layer->isStackingContext()) {
725 ASSERT(!layer->m_zOrderListsDirty);
726
727 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
728 size_t listSize = negZOrderList->size();
729 for (size_t i = 0; i < listSize; ++i) {
730 RenderLayer* curLayer = negZOrderList->at(i);
731 rebuildCompositingLayerTree(curLayer, childState, childList);
732 }
733 }
734
735 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
736 if (layerBacking && layerBacking->foregroundLayer())
737 childList.append(layerBacking->foregroundLayer());
738 }
739
740 ASSERT(!layer->m_normalFlowListDirty);
741 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
742 size_t listSize = normalFlowList->size();
743 for (size_t i = 0; i < listSize; ++i) {
744 RenderLayer* curLayer = normalFlowList->at(i);
745 rebuildCompositingLayerTree(curLayer, childState, childList);
746 }
747 }
748
749 if (layer->isStackingContext()) {
750 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
751 size_t listSize = posZOrderList->size();
752 for (size_t i = 0; i < listSize; ++i) {
753 RenderLayer* curLayer = posZOrderList->at(i);
754 rebuildCompositingLayerTree(curLayer, childState, childList);
755 }
756 }
757 }
758
759 if (layerBacking) {
760 layerBacking->parentForSublayers()->setChildren(layerChildren);
761 childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
762 }
763 }
764
765 // This just updates layer geometry without changing the hierarchy.
766 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
767 {
768 if (RenderLayerBacking* layerBacking = layer->backing()) {
769 // The compositing state of all our children has been updated already, so now
770 // we can compute and cache the composited bounds for this layer.
771 layerBacking->updateCompositedBounds();
772
773 if (RenderLayer* reflection = layer->reflectionLayer()) {
774 if (reflection->backing())
775 reflection->backing()->updateCompositedBounds();
776 }
777
778 layerBacking->updateGraphicsLayerConfiguration();
779 layerBacking->updateGraphicsLayerGeometry();
780
781 if (!layer->parent())
782 updateRootLayerPosition();
783 }
784
785 if (layer->isStackingContext()) {
786 ASSERT(!layer->m_zOrderListsDirty);
787
788 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
789 size_t listSize = negZOrderList->size();
790 for (size_t i = 0; i < listSize; ++i)
791 updateLayerTreeGeometry(negZOrderList->at(i));
792 }
793 }
794
795 ASSERT(!layer->m_normalFlowListDirty);
796 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
797 size_t listSize = normalFlowList->size();
798 for (size_t i = 0; i < listSize; ++i)
799 updateLayerTreeGeometry(normalFlowList->at(i));
800 }
801
802 if (layer->isStackingContext()) {
803 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
804 size_t listSize = posZOrderList->size();
805 for (size_t i = 0; i < listSize; ++i)
806 updateLayerTreeGeometry(posZOrderList->at(i));
807 }
808 }
809 }
810
811 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
812 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer* layer, RenderLayerBacking::UpdateDepth updateDepth)
813 {
814 if (layer != compositingAncestor) {
815 if (RenderLayerBacking* layerBacking = layer->backing()) {
816 layerBacking->updateCompositedBounds();
817
818 if (RenderLayer* reflection = layer->reflectionLayer()) {
819 if (reflection->backing())
820 reflection->backing()->updateCompositedBounds();
821 }
822
823 layerBacking->updateGraphicsLayerGeometry();
824 if (updateDepth == RenderLayerBacking::CompositingChildren)
825 return;
826 }
827 }
828
829 if (layer->reflectionLayer())
830 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth);
831
832 if (!layer->hasCompositingDescendant())
833 return;
834
835 if (layer->isStackingContext()) {
836 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
837 size_t listSize = negZOrderList->size();
838 for (size_t i = 0; i < listSize; ++i)
839 updateCompositingDescendantGeometry(compositingAncestor, negZOrderList->at(i), updateDepth);
840 }
841 }
842
843 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
844 size_t listSize = normalFlowList->size();
845 for (size_t i = 0; i < listSize; ++i)
846 updateCompositingDescendantGeometry(compositingAncestor, normalFlowList->at(i), updateDepth);
847 }
848
849 if (layer->isStackingContext()) {
850 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
851 size_t listSize = posZOrderList->size();
852 for (size_t i = 0; i < listSize; ++i)
853 updateCompositingDescendantGeometry(compositingAncestor, posZOrderList->at(i), updateDepth);
854 }
855 }
856 }
857
858
859 void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect)
860 {
861 recursiveRepaintLayerRect(rootRenderLayer(), absRect);
862 }
863
864 void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
865 {
866 // FIXME: This method does not work correctly with transforms.
867 if (layer->isComposited())
868 layer->setBackingNeedsRepaintInRect(rect);
869
870 if (layer->hasCompositingDescendant()) {
871 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
872 size_t listSize = negZOrderList->size();
873 for (size_t i = 0; i < listSize; ++i) {
874 RenderLayer* curLayer = negZOrderList->at(i);
875 int x = 0;
876 int y = 0;
877 curLayer->convertToLayerCoords(layer, x, y);
878 IntRect childRect(rect);
879 childRect.move(-x, -y);
880 recursiveRepaintLayerRect(curLayer, childRect);
881 }
882 }
883
884 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
885 size_t listSize = posZOrderList->size();
886 for (size_t i = 0; i < listSize; ++i) {
887 RenderLayer* curLayer = posZOrderList->at(i);
888 int x = 0;
889 int y = 0;
890 curLayer->convertToLayerCoords(layer, x, y);
891 IntRect childRect(rect);
892 childRect.move(-x, -y);
893 recursiveRepaintLayerRect(curLayer, childRect);
894 }
895 }
896 }
897 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
898 size_t listSize = normalFlowList->size();
899 for (size_t i = 0; i < listSize; ++i) {
900 RenderLayer* curLayer = normalFlowList->at(i);
901 int x = 0;
902 int y = 0;
903 curLayer->convertToLayerCoords(layer, x, y);
904 IntRect childRect(rect);
905 childRect.move(-x, -y);
906 recursiveRepaintLayerRect(curLayer, childRect);
907 }
908 }
909 }
910
911 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
912 {
913 return m_renderView->layer();
914 }
915
916 GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const
917 {
918 return m_rootPlatformLayer.get();
919 }
920
921 void RenderLayerCompositor::didMoveOnscreen()
922 {
923 if (!m_rootPlatformLayer)
924 return;
925
926 Frame* frame = m_renderView->frameView()->frame();
927 Page* page = frame ? frame->page() : 0;
928 if (!page)
929 return;
930
931 page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer.get());
932 m_rootLayerAttached = true;
933 }
934
935 void RenderLayerCompositor::willMoveOffscreen()
936 {
937 if (!m_rootPlatformLayer || !m_rootLayerAttached)
938 return;
939
940 Frame* frame = m_renderView->frameView()->frame();
941 Page* page = frame ? frame->page() : 0;
942 if (!page)
943 return;
944
945 page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
946 m_rootLayerAttached = false;
947 }
948
949 void RenderLayerCompositor::updateRootLayerPosition()
950 {
951 if (m_rootPlatformLayer)
952 m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow()));
953 }
954
955 void RenderLayerCompositor::didStartAcceleratedAnimation()
956 {
957 // If an accelerated animation or transition runs, we have to turn off overlap checking because
958 // we don't do layout for every frame, but we have to ensure that the layering is
959 // correct between the animating object and other objects on the page.
960 setCompositingConsultsOverlap(false);
961 }
962
963 bool RenderLayerCompositor::has3DContent() const
964 {
965 return layerHas3DContent(rootRenderLayer());
966 }
967
968 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
969 {
970 if (!m_hasAcceleratedCompositing || !layer->isSelfPaintingLayer())
971 return false;
972
973 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
974 // if an ancestor is fixed positioned, we need to be composited...
975 const RenderLayer* currLayer = layer;
976 while ((currLayer = currLayer->parent())) {
977 if (currLayer->isComposited() && currLayer->isFixed())
978 return true;
979 }
980 #endif
981
982 return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers();
983 }
984
985 #if PLATFORM(ANDROID)
986 bool RenderLayerCompositor::requiresCompositingForMobileSites(const RenderLayer* layer) const
987 {
988 // First, check if we are in an iframe, and if so bail out
989 if (m_renderView->document()->frame()->tree()->parent())
990 return false;
991
992 RenderObject* renderer = layer->renderer();
993 // Check for transforms
994 if (requiresCompositingForTransform(renderer))
995 return true;
996
997 // Check for animations
998 if (requiresCompositingForAnimation(renderer))
999 return true;
1000
1001 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
1002 // For the moment, we want to only enable fixed composited layers on mobile websites.
1003 // We can consider a website as being a 'mobile' site if all the
1004 // following checks are true:
1005 // 1) - the viewport width is either undefined (-1) or equal to device-width (0), and
1006 // 2) - no scaling is allowed
1007 if (!layer->isFixed())
1008 return false;
1009
1010 Settings* settings = m_renderView->document()->settings();
1011 if (!settings)
1012 return false;
1013
1014 if ((settings->viewportWidth() == -1 || settings->viewportWidth() == 0) &&
1015 !settings->viewportUserScalable())
1016 return true;
1017 #endif
1018
1019 return false;
1020 }
1021 #endif
1022
1023 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
1024 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
1025 // static
1026 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
1027 {
1028 RenderObject* renderer = layer->renderer();
1029 // The compositing state of a reflection should match that of its reflected layer.
1030 if (layer->isReflection()) {
1031 renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected.
1032 layer = toRenderBoxModelObject(renderer)->layer();
1033 }
1034 // The root layer always has a compositing layer, but it may not have backing.
1035 return (inCompositingMode() && layer->isRootLayer()) ||
1036 #if PLATFORM(ANDROID)
1037 requiresCompositingForMobileSites(layer) ||
1038 #else
1039 requiresCompositingForTransform(renderer) ||
1040 requiresCompositingForVideo(renderer) ||
1041 requiresCompositingForCanvas(renderer) ||
1042 requiresCompositingForPlugin(renderer) ||
1043 requiresCompositingForAnimation(renderer) ||
1044 #endif
1045 renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden ||
1046 clipsCompositingDescendants(layer);
1047 }
1048
1049 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1050 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1051 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1052 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1053 // but a sibling in the z-order hierarchy.
1054 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
1055 {
1056 if (!layer->isComposited() || !layer->parent())
1057 return false;
1058
1059 RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1060 if (!compositingAncestor)
1061 return false;
1062
1063 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
1064 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
1065 // and layer.
1066 RenderLayer* computeClipRoot = 0;
1067 RenderLayer* curr = layer;
1068 while (curr) {
1069 RenderLayer* next = curr->parent();
1070 if (next == compositingAncestor) {
1071 computeClipRoot = curr;
1072 break;
1073 }
1074 curr = next;
1075 }
1076
1077 if (!computeClipRoot || computeClipRoot == layer)
1078 return false;
1079
1080 IntRect backgroundRect = layer->backgroundClipRect(computeClipRoot, true);
1081 return backgroundRect != ClipRects::infiniteRect();
1082 }
1083
1084 // Return true if the given layer is a stacking context and has compositing child
1085 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1086 // into the hierarchy between this layer and its children in the z-order hierarchy.
1087 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1088 {
1089 // FIXME: need to look at hasClip() too eventually
1090 return layer->hasCompositingDescendant() &&
1091 layer->renderer()->hasOverflowClip();
1092 }
1093
1094 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
1095 {
1096 RenderStyle* style = renderer->style();
1097 // Note that we ask the renderer if it has a transform, because the style may have transforms,
1098 // but the renderer may be an inline that doesn't suppport them.
1099 return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
1100 }
1101
1102 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
1103 {
1104 #if ENABLE(VIDEO)
1105 if (renderer->isVideo()) {
1106 RenderVideo* video = toRenderVideo(renderer);
1107 return canAccelerateVideoRendering(video);
1108 }
1109 #else
1110 UNUSED_PARAM(renderer);
1111 #endif
1112 return false;
1113 }
1114
1115 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
1116 {
1117 #if ENABLE(3D_CANVAS)
1118 if (renderer->isCanvas()) {
1119 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
1120 return canvas->is3D();
1121 }
1122 #else
1123 UNUSED_PARAM(renderer);
1124 #endif
1125 return false;
1126 }
1127
1128 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
1129 {
1130 return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
1131 }
1132
1133 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
1134 {
1135 if (AnimationController* animController = renderer->animation()) {
1136 return (animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
1137 || animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyWebkitTransform);
1138 }
1139 return false;
1140 }
1141
1142 bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
1143 {
1144 return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection();
1145 }
1146
1147 // If an element has negative z-index children, those children render in front of the
1148 // layer background, so we need an extra 'contents' layer for the foreground of the layer
1149 // object.
1150 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
1151 {
1152 return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0);
1153 }
1154
1155 void RenderLayerCompositor::ensureRootPlatformLayer()
1156 {
1157 if (m_rootPlatformLayer)
1158 return;
1159
1160 m_rootPlatformLayer = GraphicsLayer::create(0);
1161 m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow()));
1162 m_rootPlatformLayer->setPosition(FloatPoint(0, 0));
1163 // The root layer does flipping if we need it on this platform.
1164 m_rootPlatformLayer->setGeometryOrientation(GraphicsLayer::compositingCoordinatesOrientation());
1165
1166 // Need to clip to prevent transformed content showing outside this frame
1167 m_rootPlatformLayer->setMasksToBounds(true);
1168
1169 didMoveOnscreen();
1170 }
1171
1172 void RenderLayerCompositor::destroyRootPlatformLayer()
1173 {
1174 if (!m_rootPlatformLayer)
1175 return;
1176
1177 willMoveOffscreen();
1178 m_rootPlatformLayer = 0;
1179 }
1180
1181 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
1182 {
1183 const RenderStyle* style = layer->renderer()->style();
1184
1185 if (style &&
1186 (style->transformStyle3D() == TransformStyle3DPreserve3D ||
1187 style->hasPerspective() ||
1188 style->transform().has3DOperation()))
1189 return true;
1190
1191 if (layer->isStackingContext()) {
1192 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
1193 size_t listSize = negZOrderList->size();
1194 for (size_t i = 0; i < listSize; ++i) {
1195 RenderLayer* curLayer = negZOrderList->at(i);
1196 if (layerHas3DContent(curLayer))
1197 return true;
1198 }
1199 }
1200
1201 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
1202 size_t listSize = posZOrderList->size();
1203 for (size_t i = 0; i < listSize; ++i) {
1204 RenderLayer* curLayer = posZOrderList->at(i);
1205 if (layerHas3DContent(curLayer))
1206 return true;
1207 }
1208 }
1209 }
1210
1211 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
1212 size_t listSize = normalFlowList->size();
1213 for (size_t i = 0; i < listSize; ++i) {
1214 RenderLayer* curLayer = normalFlowList->at(i);
1215 if (layerHas3DContent(curLayer))
1216 return true;
1217 }
1218 }
1219 return false;
1220 }
1221
1222 } // namespace WebCore
1223
1224 #endif // USE(ACCELERATED_COMPOSITING)
1225