Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(706)

Side by Side Diff: Source/core/rendering/RenderLayer.cpp

Issue 13427009: Replace the current contiguity check for composited scrolling (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: one more test update... Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderLayer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * 3 *
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5 * 5 *
6 * Other contributors: 6 * Other contributors:
7 * Robert O'Callahan <roc+@cs.cmu.edu> 7 * Robert O'Callahan <roc+@cs.cmu.edu>
8 * David Baron <dbaron@fas.harvard.edu> 8 * David Baron <dbaron@fas.harvard.edu>
9 * Christian Biesinger <cbiesinger@web.de> 9 * Christian Biesinger <cbiesinger@web.de>
10 * Randall Jesup <rjesup@wgate.com> 10 * Randall Jesup <rjesup@wgate.com>
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 RenderLayer::RenderLayer(RenderLayerModelObject* renderer) 127 RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
128 : m_inResizeMode(false) 128 : m_inResizeMode(false)
129 , m_scrollDimensionsDirty(true) 129 , m_scrollDimensionsDirty(true)
130 , m_normalFlowListDirty(true) 130 , m_normalFlowListDirty(true)
131 , m_hasSelfPaintingLayerDescendant(false) 131 , m_hasSelfPaintingLayerDescendant(false)
132 , m_hasSelfPaintingLayerDescendantDirty(false) 132 , m_hasSelfPaintingLayerDescendantDirty(false)
133 , m_hasOutOfFlowPositionedDescendant(false) 133 , m_hasOutOfFlowPositionedDescendant(false)
134 , m_hasOutOfFlowPositionedDescendantDirty(true) 134 , m_hasOutOfFlowPositionedDescendantDirty(true)
135 , m_hasUnclippedDescendant(false) 135 , m_hasUnclippedDescendant(false)
136 , m_needsCompositedScrolling(false) 136 , m_needsCompositedScrolling(false)
137 , m_descendantsAreContiguousInStackingOrder(false) 137 , m_canBePromotedToStackingContainer(false)
138 , m_descendantsAreContiguousInStackingOrderDirty(true) 138 , m_canBePromotedToStackingContainerDirty(true)
139 , m_isRootLayer(renderer->isRenderView()) 139 , m_isRootLayer(renderer->isRenderView())
140 , m_usedTransparency(false) 140 , m_usedTransparency(false)
141 , m_paintingInsideReflection(false) 141 , m_paintingInsideReflection(false)
142 , m_inOverflowRelayout(false) 142 , m_inOverflowRelayout(false)
143 , m_repaintStatus(NeedsNormalRepaint) 143 , m_repaintStatus(NeedsNormalRepaint)
144 , m_visibleContentStatusDirty(true) 144 , m_visibleContentStatusDirty(true)
145 , m_hasVisibleContent(false) 145 , m_hasVisibleContent(false)
146 , m_visibleDescendantStatusDirty(false) 146 , m_visibleDescendantStatusDirty(false)
147 , m_hasVisibleDescendant(false) 147 , m_hasVisibleDescendant(false)
148 , m_isPaginated(false) 148 , m_isPaginated(false)
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 } 498 }
499 } 499 }
500 } 500 }
501 501
502 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const 502 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const
503 { 503 {
504 const Settings* settings = renderer()->document()->settings(); 504 const Settings* settings = renderer()->document()->settings();
505 return settings && settings->acceleratedCompositingForOverflowScrollEnabled( ); 505 return settings && settings->acceleratedCompositingForOverflowScrollEnabled( );
506 } 506 }
507 507
508 // If we are a stacking container, then this function will determine if our 508 // Determine whether the current layer can be promoted to a stacking container.
509 // descendants for a contiguous block in stacking order. This is required in 509 // We do this by computing what positive and negative z-order lists would look
510 // order for an element to be safely promoted to a stacking container. It is saf e 510 // like before and after promotion, and ensuring that proper stacking order is
511 // to become a stacking container if this change would not alter the stacking 511 // preserved between the two sets of lists.
512 // order of layers on the page. That can only happen if a non-descendant appear 512 void RenderLayer::updateCanBeStackingContainer()
513 // between us and our descendants in stacking order. Here's an example:
514 //
515 // this
516 // / | \.
517 // A B C
518 // /\ | /\.
519 // 0 -8 D 2 7
520 // |
521 // 5
522 //
523 // I've labeled our normal flow descendants A, B, C, and D, our stacking
524 // container descendants with their z indices, and us with 'this' (we're a
525 // stacking container and our zIndex doesn't matter here). These nodes appear in
526 // three lists: posZOrder, negZOrder, and normal flow (keep in mind that normal
527 // flow layers don't overlap). So if we arrange these lists in order we get our
528 // stacking order:
529 //
530 // [-8], [A-D], [0, 2, 5, 7]--> pos z-order.
531 // | |
532 // Neg z-order. <-+ +--> Normal flow descendants.
533 //
534 // We can then assign new, 'stacking' order indices to these elements as follows :
535 //
536 // [-8], [A-D], [0, 2, 5, 7]
537 // 'Stacking' indices: -1 0 1 2 3 4
538 //
539 // Note that the normal flow descendants can share an index because they don't
540 // stack/overlap. Now our problem becomes very simple: a layer can safely become
541 // a stacking container if the stacking-order indices of it and its descendants
542 // appear in a contiguous block in the list of stacking indices. This problem
543 // can be solved very efficiently by calculating the min/max stacking indices in
544 // the subtree, and the number stacking container descendants. Once we have this
545 // information, we know that the subtree's indices form a contiguous block if:
546 //
547 // maxStackIndex - minStackIndex == numSCDescendants
548 //
549 // So for node A in the example above we would have:
550 // maxStackIndex = 1
551 // minStackIndex = -1
552 // numSCDecendants = 2
553 //
554 // and so,
555 // maxStackIndex - minStackIndex == numSCDescendants
556 // ===> 1 - (-1) == 2
557 // ===> 2 == 2
558 //
559 // Since this is true, A can safely become a stacking container.
560 // Now, for node C we have:
561 //
562 // maxStackIndex = 4
563 // minStackIndex = 0 <-- because C has stacking index 0.
564 // numSCDecendants = 2
565 //
566 // and so,
567 // maxStackIndex - minStackIndex == numSCDescendants
568 // ===> 4 - 0 == 2
569 // ===> 4 == 2
570 //
571 // Since this is false, C cannot be safely promoted to a stacking container. Thi s
572 // happened because of the elements with z-index 5 and 0. Now if 5 had been a
573 // child of C rather than D, and A had no child with Z index 0, we would have ha d:
574 //
575 // maxStackIndex = 3
576 // minStackIndex = 0 <-- because C has stacking index 0.
577 // numSCDecendants = 3
578 //
579 // and so,
580 // maxStackIndex - minStackIndex == numSCDescendants
581 // ===> 3 - 0 == 3
582 // ===> 3 == 3
583 //
584 // And we would conclude that C could be promoted.
585 void RenderLayer::updateDescendantsAreContiguousInStackingOrder()
586 { 513 {
587 if (!m_descendantsAreContiguousInStackingOrderDirty || !isStackingContext() || !acceleratedCompositingForOverflowScrollEnabled()) 514 TRACE_EVENT0("blink_rendering", "RenderLayer::updateCanBeStackingContainer") ;
515
516 if (isStackingContext() || !m_canBePromotedToStackingContainerDirty || !acce leratedCompositingForOverflowScrollEnabled())
588 return; 517 return;
589 518
590 OwnPtr<Vector<RenderLayer*> > posZOrderList; 519 FrameView* frameView = renderer()->view()->frameView();
591 OwnPtr<Vector<RenderLayer*> > negZOrderList; 520 if (!frameView || !frameView->containsScrollableArea(this))
592 rebuildZOrderLists(StopAtStackingContexts, posZOrderList, negZOrderList); 521 return;
593 522
594 // Create a reverse lookup. 523 RenderLayer* ancestorStackingContext = this->ancestorStackingContext();
595 HashMap<const RenderLayer*, int> lookup; 524 if (!ancestorStackingContext)
525 return;
596 526
597 if (negZOrderList) { 527 OwnPtr<Vector<RenderLayer*> > posZOrderListBeforePromote = adoptPtr(new Vect or<RenderLayer*>);
598 int stackingOrderIndex = -1; 528 OwnPtr<Vector<RenderLayer*> > negZOrderListBeforePromote = adoptPtr(new Vect or<RenderLayer*>);
599 size_t listSize = negZOrderList->size(); 529 OwnPtr<Vector<RenderLayer*> > posZOrderListAfterPromote = adoptPtr(new Vecto r<RenderLayer*>);
600 for (size_t i = 0; i < listSize; ++i) { 530 OwnPtr<Vector<RenderLayer*> > negZOrderListAfterPromote = adoptPtr(new Vecto r<RenderLayer*>);
601 RenderLayer* currentLayer = negZOrderList->at(listSize - i - 1); 531
602 if (!currentLayer->isStackingContext()) 532 collectBeforePromotionZOrderList(ancestorStackingContext, posZOrderListBefor ePromote, negZOrderListBeforePromote);
603 continue; 533 collectAfterPromotionZOrderList(ancestorStackingContext, posZOrderListAfterP romote, negZOrderListAfterPromote);
604 lookup.set(currentLayer, stackingOrderIndex--); 534
605 } 535 size_t maxIndex = std::min(posZOrderListAfterPromote->size() + negZOrderList AfterPromote->size(), posZOrderListBeforePromote->size() + negZOrderListBeforePr omote->size());
536
537 m_canBePromotedToStackingContainerDirty = false;
538 m_canBePromotedToStackingContainer = false;
539
540 const RenderLayer* layerAfterPromote = 0;
541 for (size_t i = 0; i < maxIndex && layerAfterPromote != this; ++i) {
542 const RenderLayer* layerBeforePromote = i < negZOrderListBeforePromote-> size()
543 ? negZOrderListBeforePromote->at(i)
544 : posZOrderListBeforePromote->at(i - negZOrderListBeforePromote->siz e());
545 layerAfterPromote = i < negZOrderListAfterPromote->size()
546 ? negZOrderListAfterPromote->at(i)
547 : posZOrderListAfterPromote->at(i - negZOrderListAfterPromote->size( ));
548
549 if (layerBeforePromote != layerAfterPromote && (layerAfterPromote != thi s || renderer()->hasBackground()))
550 return;
606 } 551 }
607 552
608 if (posZOrderList) { 553 layerAfterPromote = 0;
609 size_t listSize = posZOrderList->size(); 554 for (size_t i = 0; i < maxIndex && layerAfterPromote != this; ++i) {
610 int stackingOrderIndex = 1; 555 const RenderLayer* layerBeforePromote = i < posZOrderListBeforePromote-> size()
611 for (size_t i = 0; i < listSize; ++i) { 556 ? posZOrderListBeforePromote->at(posZOrderListBeforePromote->size() - i - 1)
612 RenderLayer* currentLayer = posZOrderList->at(i); 557 : negZOrderListBeforePromote->at(negZOrderListBeforePromote->size() + posZOrderListBeforePromote->size() - i - 1);
613 if (!currentLayer->isStackingContext()) 558 layerAfterPromote = i < posZOrderListAfterPromote->size()
614 continue; 559 ? posZOrderListAfterPromote->at(posZOrderListAfterPromote->size() - i - 1)
615 lookup.set(currentLayer, stackingOrderIndex++); 560 : negZOrderListAfterPromote->at(negZOrderListAfterPromote->size() + posZOrderListAfterPromote->size() - i - 1);
616 } 561
562 if (layerBeforePromote != layerAfterPromote && layerAfterPromote != this )
563 return;
617 } 564 }
618 565
619 int minIndex = 0; 566 m_canBePromotedToStackingContainer = true;
620 int maxIndex = 0;
621 int count = 0;
622 bool firstIteration = true;
623 updateDescendantsAreContiguousInStackingOrderRecursive(lookup, minIndex, max Index, count, firstIteration);
624
625 m_descendantsAreContiguousInStackingOrderDirty = false;
626 }
627
628 void RenderLayer::updateDescendantsAreContiguousInStackingOrderRecursive(const H ashMap<const RenderLayer*, int>& lookup, int& minIndex, int& maxIndex, int& coun t, bool firstIteration)
629 {
630 if (isStackingContext() && !firstIteration) {
631 if (lookup.contains(this)) {
632 minIndex = std::min(minIndex, lookup.get(this));
633 maxIndex = std::max(maxIndex, lookup.get(this));
634 count++;
635 }
636 return;
637 }
638
639 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
640 int childMinIndex = 0;
641 int childMaxIndex = 0;
642 int childCount = 0;
643 child->updateDescendantsAreContiguousInStackingOrderRecursive(lookup, ch ildMinIndex, childMaxIndex, childCount, false);
644 if (childCount) {
645 count += childCount;
646 minIndex = std::min(minIndex, childMinIndex);
647 maxIndex = std::max(maxIndex, childMaxIndex);
648 }
649 }
650
651 if (!isStackingContext()) {
652 m_descendantsAreContiguousInStackingOrder = (maxIndex - minIndex) == cou nt;
653 m_descendantsAreContiguousInStackingOrderDirty = false;
654 }
655 } 567 }
656 568
657 static inline bool isPositionedContainer(const RenderLayer* layer) 569 static inline bool isPositionedContainer(const RenderLayer* layer)
658 { 570 {
659 // FIXME: This is not in sync with containingBlock. 571 // FIXME: This is not in sync with containingBlock.
660 // RenderObject::canContainFixedPositionedObject() should probably be used 572 // RenderObject::canContainFixedPositionedObject() should probably be used
661 // instead. 573 // instead.
662 RenderLayerModelObject* layerRenderer = layer->renderer(); 574 RenderLayerModelObject* layerRenderer = layer->renderer();
663 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform(); 575 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform();
664 } 576 }
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 if (curr == ancestorStackingContainer) 990 if (curr == ancestorStackingContainer)
1079 return; 991 return;
1080 } 992 }
1081 } 993 }
1082 994
1083 bool RenderLayer::canBeStackingContainer() const 995 bool RenderLayer::canBeStackingContainer() const
1084 { 996 {
1085 if (isStackingContext() || !ancestorStackingContainer()) 997 if (isStackingContext() || !ancestorStackingContainer())
1086 return true; 998 return true;
1087 999
1088 ASSERT(!m_descendantsAreContiguousInStackingOrderDirty); 1000 ASSERT(!m_canBePromotedToStackingContainerDirty);
1089 return m_descendantsAreContiguousInStackingOrder; 1001 return m_canBePromotedToStackingContainer;
1090 } 1002 }
1091 1003
1092 void RenderLayer::setHasVisibleContent() 1004 void RenderLayer::setHasVisibleContent()
1093 { 1005 {
1094 if (m_hasVisibleContent && !m_visibleContentStatusDirty) { 1006 if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
1095 ASSERT(!parent() || parent()->hasVisibleDescendant()); 1007 ASSERT(!parent() || parent()->hasVisibleDescendant());
1096 return; 1008 return;
1097 } 1009 }
1098 1010
1099 m_visibleContentStatusDirty = false; 1011 m_visibleContentStatusDirty = false;
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 case CompositedScrollingAlwaysOff: 1972 case CompositedScrollingAlwaysOff:
2061 return false; 1973 return false;
2062 } 1974 }
2063 1975
2064 ASSERT_NOT_REACHED(); 1976 ASSERT_NOT_REACHED();
2065 return m_needsCompositedScrolling; 1977 return m_needsCompositedScrolling;
2066 } 1978 }
2067 1979
2068 void RenderLayer::updateNeedsCompositedScrolling() 1980 void RenderLayer::updateNeedsCompositedScrolling()
2069 { 1981 {
2070 if (RenderLayer* ancestor = ancestorStackingContext()) 1982 updateCanBeStackingContainer();
2071 ancestor->updateDescendantsAreContiguousInStackingOrder();
2072 1983
2073 bool needsCompositedScrolling = false; 1984 bool needsCompositedScrolling = false;
1985 updateDescendantDependentFlags();
2074 1986
2075 FrameView* frameView = renderer()->view()->frameView(); 1987 ASSERT(renderer()->view()->frameView() && renderer()->view()->frameView()->c ontainsScrollableArea(this));
2076 if (frameView && frameView->containsScrollableArea(this)) { 1988 bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScrollEn abled()
2077 updateDescendantDependentFlags(); 1989 && canBeStackingContainer()
2078 1990 && !hasUnclippedDescendant();
2079 bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScro llEnabled()
2080 && canBeStackingContainer()
2081 && !hasUnclippedDescendant();
2082 1991
2083 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) 1992 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2084 needsCompositedScrolling = forceUseCompositedScrolling || renderer()->st yle()->useTouchOverflowScrolling(); 1993 needsCompositedScrolling = forceUseCompositedScrolling || renderer()->style( )->useTouchOverflowScrolling();
2085 #else 1994 #else
2086 needsCompositedScrolling = forceUseCompositedScrolling; 1995 needsCompositedScrolling = forceUseCompositedScrolling;
2087 #endif 1996 #endif
2088 // We gather a boolean value for use with Google UMA histograms to 1997 // We gather a boolean value for use with Google UMA histograms to
2089 // quantify the actual effects of a set of patches attempting to 1998 // quantify the actual effects of a set of patches attempting to
2090 // relax composited scrolling requirements, thereby increasing the 1999 // relax composited scrolling requirements, thereby increasing the
2091 // number of composited overflow divs. 2000 // number of composited overflow divs.
2092 if (acceleratedCompositingForOverflowScrollEnabled()) 2001 if (acceleratedCompositingForOverflowScrollEnabled())
2093 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScro lling", needsCompositedScrolling, 2); 2002 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScrollin g", needsCompositedScrolling, 2);
2094 }
2095 2003
2096 setNeedsCompositedScrolling(needsCompositedScrolling); 2004 setNeedsCompositedScrolling(needsCompositedScrolling);
2097 } 2005 }
2098 2006
2099 void RenderLayer::setNeedsCompositedScrolling(bool needsCompositedScrolling) 2007 void RenderLayer::setNeedsCompositedScrolling(bool needsCompositedScrolling)
2100 { 2008 {
2101 if (m_needsCompositedScrolling == needsCompositedScrolling) 2009 if (m_needsCompositedScrolling == needsCompositedScrolling)
2102 return; 2010 return;
2103 2011
2104 m_needsCompositedScrolling = needsCompositedScrolling; 2012 m_needsCompositedScrolling = needsCompositedScrolling;
(...skipping 3514 matching lines...) Expand 10 before | Expand all | Expand 10 after
5619 { 5527 {
5620 ASSERT(m_layerListMutationAllowed); 5528 ASSERT(m_layerListMutationAllowed);
5621 ASSERT(isStackingContainer()); 5529 ASSERT(isStackingContainer());
5622 5530
5623 if (m_posZOrderList) 5531 if (m_posZOrderList)
5624 m_posZOrderList->clear(); 5532 m_posZOrderList->clear();
5625 if (m_negZOrderList) 5533 if (m_negZOrderList)
5626 m_negZOrderList->clear(); 5534 m_negZOrderList->clear();
5627 m_zOrderListsDirty = true; 5535 m_zOrderListsDirty = true;
5628 5536
5629 m_descendantsAreContiguousInStackingOrderDirty = true; 5537 m_canBePromotedToStackingContainerDirty = true;
5630 5538
5631 if (!renderer()->documentBeingDestroyed()) { 5539 if (!renderer()->documentBeingDestroyed()) {
5632 compositor()->setNeedsUpdateCompositingRequirementsState(); 5540 compositor()->setNeedsUpdateCompositingRequirementsState();
5633 compositor()->setCompositingLayersNeedRebuild(); 5541 compositor()->setCompositingLayersNeedRebuild();
5634 if (acceleratedCompositingForOverflowScrollEnabled()) 5542 if (acceleratedCompositingForOverflowScrollEnabled())
5635 compositor()->setShouldReevaluateCompositingAfterLayout(); 5543 compositor()->setShouldReevaluateCompositingAfterLayout();
5636 } 5544 }
5637 } 5545 }
5638 5546
5639 void RenderLayer::dirtyStackingContainerZOrderLists() 5547 void RenderLayer::dirtyStackingContainerZOrderLists()
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
6452 } 6360 }
6453 } 6361 }
6454 6362
6455 void showLayerTree(const WebCore::RenderObject* renderer) 6363 void showLayerTree(const WebCore::RenderObject* renderer)
6456 { 6364 {
6457 if (!renderer) 6365 if (!renderer)
6458 return; 6366 return;
6459 showLayerTree(renderer->enclosingLayer()); 6367 showLayerTree(renderer->enclosingLayer());
6460 } 6368 }
6461 #endif 6369 #endif
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderLayer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698