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

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

Issue 14741004: NOT FOR REVIEW - Update comp-scrolling state at a well defined point in the pipeline. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 7 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
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 #include "core/page/EventHandler.h" 62 #include "core/page/EventHandler.h"
63 #include "core/page/FocusController.h" 63 #include "core/page/FocusController.h"
64 #include "core/page/Frame.h" 64 #include "core/page/Frame.h"
65 #include "core/page/FrameTree.h" 65 #include "core/page/FrameTree.h"
66 #include "core/page/FrameView.h" 66 #include "core/page/FrameView.h"
67 #include "core/page/Page.h" 67 #include "core/page/Page.h"
68 #include "core/page/Settings.h" 68 #include "core/page/Settings.h"
69 #include "core/page/UseCounter.h" 69 #include "core/page/UseCounter.h"
70 #include "core/page/animation/AnimationController.h" 70 #include "core/page/animation/AnimationController.h"
71 #include "core/page/scrolling/ScrollingCoordinator.h" 71 #include "core/page/scrolling/ScrollingCoordinator.h"
72 #include "core/platform/chromium/TraceEvent.h"
72 #include "core/platform/FloatConversion.h" 73 #include "core/platform/FloatConversion.h"
73 #include "core/platform/HistogramSupport.h" 74 #include "core/platform/HistogramSupport.h"
74 #include "core/platform/PlatformMouseEvent.h" 75 #include "core/platform/PlatformMouseEvent.h"
75 #include "core/platform/ScrollAnimator.h" 76 #include "core/platform/ScrollAnimator.h"
76 #include "core/platform/Scrollbar.h" 77 #include "core/platform/Scrollbar.h"
77 #include "core/platform/ScrollbarTheme.h" 78 #include "core/platform/ScrollbarTheme.h"
78 #include "core/platform/graphics/FloatPoint3D.h" 79 #include "core/platform/graphics/FloatPoint3D.h"
79 #include "core/platform/graphics/FloatRect.h" 80 #include "core/platform/graphics/FloatRect.h"
80 #include "core/platform/graphics/Gradient.h" 81 #include "core/platform/graphics/Gradient.h"
81 #include "core/platform/graphics/GraphicsContext.h" 82 #include "core/platform/graphics/GraphicsContext.h"
(...skipping 24 matching lines...) Expand all
106 #include "core/rendering/RenderMarquee.h" 107 #include "core/rendering/RenderMarquee.h"
107 #include "core/rendering/RenderReplica.h" 108 #include "core/rendering/RenderReplica.h"
108 #include "core/rendering/RenderScrollbar.h" 109 #include "core/rendering/RenderScrollbar.h"
109 #include "core/rendering/RenderScrollbarPart.h" 110 #include "core/rendering/RenderScrollbarPart.h"
110 #include "core/rendering/RenderTheme.h" 111 #include "core/rendering/RenderTheme.h"
111 #include "core/rendering/RenderTreeAsText.h" 112 #include "core/rendering/RenderTreeAsText.h"
112 #include "core/rendering/RenderView.h" 113 #include "core/rendering/RenderView.h"
113 #include "core/rendering/svg/RenderSVGResourceClipper.h" 114 #include "core/rendering/svg/RenderSVGResourceClipper.h"
114 #include <wtf/MemoryInstrumentationVector.h> 115 #include <wtf/MemoryInstrumentationVector.h>
115 #include <wtf/StdLibExtras.h> 116 #include <wtf/StdLibExtras.h>
117 #include <wtf/TemporaryChange.h>
116 #include <wtf/text/CString.h> 118 #include <wtf/text/CString.h>
117 #include <wtf/UnusedParam.h> 119 #include <wtf/UnusedParam.h>
118 120
119 #if ENABLE(SVG) 121 #if ENABLE(SVG)
120 #include "SVGNames.h" 122 #include "SVGNames.h"
121 #endif 123 #endif
122 124
123 #define MIN_INTERSECT_FOR_REVEAL 32 125 #define MIN_INTERSECT_FOR_REVEAL 32
124 126
125 using namespace std; 127 using namespace std;
(...skipping 10 matching lines...) Expand all
136 return hitTestLocation.intersects(m_rect); 138 return hitTestLocation.intersects(m_rect);
137 } 139 }
138 140
139 RenderLayer::RenderLayer(RenderLayerModelObject* renderer) 141 RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
140 : m_inResizeMode(false) 142 : m_inResizeMode(false)
141 , m_scrollDimensionsDirty(true) 143 , m_scrollDimensionsDirty(true)
142 , m_normalFlowListDirty(true) 144 , m_normalFlowListDirty(true)
143 , m_hasSelfPaintingLayerDescendant(false) 145 , m_hasSelfPaintingLayerDescendant(false)
144 , m_hasSelfPaintingLayerDescendantDirty(false) 146 , m_hasSelfPaintingLayerDescendantDirty(false)
145 , m_hasOutOfFlowPositionedDescendant(false) 147 , m_hasOutOfFlowPositionedDescendant(false)
146 , m_hasOutOfFlowPositionedDescendantDirty(true) 148 , m_forceNeedsCompositedScrolling(DoNotForceCompositedScrolling)
147 , m_needsCompositedScrolling(false) 149 , m_needsCompositedScrolling(false)
148 , m_descendantsAreContiguousInStackingOrder(false) 150 , m_updatingNeedsCompositedScrolling(false)
149 , m_descendantsAreContiguousInStackingOrderDirty(true) 151 , m_canBePromotedToStackingContainer(false)
152 , m_updatingCanBePromotedToStackingContainer(false)
150 , m_isRootLayer(renderer->isRenderView()) 153 , m_isRootLayer(renderer->isRenderView())
151 , m_usedTransparency(false) 154 , m_usedTransparency(false)
152 , m_paintingInsideReflection(false) 155 , m_paintingInsideReflection(false)
153 , m_inOverflowRelayout(false) 156 , m_inOverflowRelayout(false)
154 , m_repaintStatus(NeedsNormalRepaint) 157 , m_repaintStatus(NeedsNormalRepaint)
155 , m_visibleContentStatusDirty(true) 158 , m_visibleContentStatusDirty(true)
156 , m_hasVisibleContent(false) 159 , m_hasVisibleContent(false)
157 , m_visibleDescendantStatusDirty(false) 160 , m_visibleDescendantStatusDirty(false)
158 , m_hasVisibleDescendant(false) 161 , m_hasVisibleDescendant(false)
159 , m_isPaginated(false) 162 , m_isPaginated(false)
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 } 478 }
476 } 479 }
477 480
478 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const 481 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const
479 { 482 {
480 return renderer()->frame() 483 return renderer()->frame()
481 && renderer()->frame()->page() 484 && renderer()->frame()->page()
482 && renderer()->frame()->page()->settings()->acceleratedCompositingForOve rflowScrollEnabled(); 485 && renderer()->frame()->page()->settings()->acceleratedCompositingForOve rflowScrollEnabled();
483 } 486 }
484 487
485 // If we are a stacking container, then this function will determine if our
486 // descendants for a contiguous block in stacking order. This is required in
487 // order for an element to be safely promoted to a stacking container. It is saf e
488 // to become a stacking container if this change would not alter the stacking
489 // order of layers on the page. That can only happen if a non-descendant appear
490 // between us and our descendants in stacking order. Here's an example:
491 //
492 // this
493 // / | \.
494 // A B C
495 // /\ | /\.
496 // 0 -8 D 2 7
497 // |
498 // 5
499 //
500 // I've labeled our normal flow descendants A, B, C, and D, our stacking
501 // container descendants with their z indices, and us with 'this' (we're a
502 // stacking container and our zIndex doesn't matter here). These nodes appear in
503 // three lists: posZOrder, negZOrder, and normal flow (keep in mind that normal
504 // flow layers don't overlap). So if we arrange these lists in order we get our
505 // stacking order:
506 //
507 // [-8], [A-D], [0, 2, 5, 7]--> pos z-order.
508 // | |
509 // Neg z-order. <-+ +--> Normal flow descendants.
510 //
511 // We can then assign new, 'stacking' order indices to these elements as follows :
512 //
513 // [-8], [A-D], [0, 2, 5, 7]
514 // 'Stacking' indices: -1 0 1 2 3 4
515 //
516 // Note that the normal flow descendants can share an index because they don't
517 // stack/overlap. Now our problem becomes very simple: a layer can safely become
518 // a stacking container if the stacking-order indices of it and its descendants
519 // appear in a contiguous block in the list of stacking indices. This problem
520 // can be solved very efficiently by calculating the min/max stacking indices in
521 // the subtree, and the number stacking container descendants. Once we have this
522 // information, we know that the subtree's indices form a contiguous block if:
523 //
524 // maxStackIndex - minStackIndex == numSCDescendants
525 //
526 // So for node A in the example above we would have:
527 // maxStackIndex = 1
528 // minStackIndex = -1
529 // numSCDecendants = 2
530 //
531 // and so,
532 // maxStackIndex - minStackIndex == numSCDescendants
533 // ===> 1 - (-1) == 2
534 // ===> 2 == 2
535 //
536 // Since this is true, A can safely become a stacking container.
537 // Now, for node C we have:
538 //
539 // maxStackIndex = 4
540 // minStackIndex = 0 <-- because C has stacking index 0.
541 // numSCDecendants = 2
542 //
543 // and so,
544 // maxStackIndex - minStackIndex == numSCDescendants
545 // ===> 4 - 0 == 2
546 // ===> 4 == 2
547 //
548 // Since this is false, C cannot be safely promoted to a stacking container. Thi s
549 // happened because of the elements with z-index 5 and 0. Now if 5 had been a
550 // child of C rather than D, and A had no child with Z index 0, we would have ha d:
551 //
552 // maxStackIndex = 3
553 // minStackIndex = 0 <-- because C has stacking index 0.
554 // numSCDecendants = 3
555 //
556 // and so,
557 // maxStackIndex - minStackIndex == numSCDescendants
558 // ===> 3 - 0 == 3
559 // ===> 3 == 3
560 //
561 // And we would conclude that C could be promoted.
562 void RenderLayer::updateDescendantsAreContiguousInStackingOrder()
563 {
564 if (!m_descendantsAreContiguousInStackingOrderDirty || !isStackingContext() || !acceleratedCompositingForOverflowScrollEnabled())
565 return;
566
567 ASSERT(!m_normalFlowListDirty);
568 ASSERT(!m_zOrderListsDirty);
569
570 OwnPtr<Vector<RenderLayer*> > posZOrderList;
571 OwnPtr<Vector<RenderLayer*> > negZOrderList;
572 rebuildZOrderLists(StopAtStackingContexts, posZOrderList, negZOrderList);
573
574 // Create a reverse lookup.
575 HashMap<const RenderLayer*, int> lookup;
576
577 if (negZOrderList) {
578 int stackingOrderIndex = -1;
579 size_t listSize = negZOrderList->size();
580 for (size_t i = 0; i < listSize; ++i) {
581 RenderLayer* currentLayer = negZOrderList->at(listSize - i - 1);
582 if (!currentLayer->isStackingContext())
583 continue;
584 lookup.set(currentLayer, stackingOrderIndex--);
585 }
586 }
587
588 if (posZOrderList) {
589 size_t listSize = posZOrderList->size();
590 int stackingOrderIndex = 1;
591 for (size_t i = 0; i < listSize; ++i) {
592 RenderLayer* currentLayer = posZOrderList->at(i);
593 if (!currentLayer->isStackingContext())
594 continue;
595 lookup.set(currentLayer, stackingOrderIndex++);
596 }
597 }
598
599 int minIndex = 0;
600 int maxIndex = 0;
601 int count = 0;
602 bool firstIteration = true;
603 updateDescendantsAreContiguousInStackingOrderRecursive(lookup, minIndex, max Index, count, firstIteration);
604
605 m_descendantsAreContiguousInStackingOrderDirty = false;
606 }
607
608 void RenderLayer::updateDescendantsAreContiguousInStackingOrderRecursive(const H ashMap<const RenderLayer*, int>& lookup, int& minIndex, int& maxIndex, int& coun t, bool firstIteration)
609 {
610 if (isStackingContext() && !firstIteration) {
611 if (lookup.contains(this)) {
612 minIndex = std::min(minIndex, lookup.get(this));
613 maxIndex = std::max(maxIndex, lookup.get(this));
614 count++;
615 }
616 return;
617 }
618
619 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
620 int childMinIndex = 0;
621 int childMaxIndex = 0;
622 int childCount = 0;
623 child->updateDescendantsAreContiguousInStackingOrderRecursive(lookup, ch ildMinIndex, childMaxIndex, childCount, false);
624 if (childCount) {
625 count += childCount;
626 minIndex = std::min(minIndex, childMinIndex);
627 maxIndex = std::max(maxIndex, childMaxIndex);
628 }
629 }
630
631 if (!isStackingContext()) {
632 bool newValue = maxIndex - minIndex == count;
633 bool didUpdate = newValue != m_descendantsAreContiguousInStackingOrder;
634 m_descendantsAreContiguousInStackingOrder = newValue;
635 if (didUpdate)
636 updateNeedsCompositedScrolling();
637 }
638 }
639
640 static inline bool isPositionedContainer(const RenderLayer* layer) 488 static inline bool isPositionedContainer(const RenderLayer* layer)
641 { 489 {
642 // FIXME: This is not in sync with containingBlock. 490 // FIXME: This is not in sync with containingBlock.
643 // RenderObject::canContainFixedPositionedObject() should probably be used 491 // RenderObject::canContainFixedPositionedObject() should probably be used
644 // instead. 492 // instead.
645 RenderLayerModelObject* layerRenderer = layer->renderer(); 493 RenderLayerModelObject* layerRenderer = layer->renderer();
646 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform(); 494 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform();
647 } 495 }
648 496
497 enum StackingOrderDirection { FromBackground, FromForeground };
498
499 // We'd like to be able to iterate through a single paint order list, but for
500 // efficiency's sake, we hang onto two lists instead (namely, the pos and neg
501 // z-order lists produced by CollectLayers). This function allows us to index
502 // into these two lists as if they were one. It also allows us to index into
503 // this virtual list either from the start or from the end (i.e., in either
504 // stacking order direction).
505 static const RenderLayer* getStackingOrderElementAt(const Vector<RenderLayer*>* posZOrderList, const Vector<RenderLayer*>* negZOrderList, const StackingOrderDir ection direction, const size_t index)
506 {
507 size_t negZOrderListSize = negZOrderList ? negZOrderList->size() : 0;
508
509 if (direction == FromBackground) {
510 if (index < negZOrderListSize)
511 return negZOrderList->at(index);
512
513 return posZOrderList->at(index - negZOrderListSize);
514 }
515
516 size_t posZOrderListSize = posZOrderList ? posZOrderList->size() : 0;
517
518 if (index < posZOrderListSize)
519 return posZOrderList->at(posZOrderListSize - index - 1);
520
521 return negZOrderList->at(negZOrderListSize - (index - posZOrderListSize) - 1 );
522 }
523
524 // After promotion, the paint order consists of
525 // a) the non-descendants which precede the promoted layer,
526 // b) the promoted layer, and
527 // c) the non-descendants which succeed the promoted layer.
528 //
529 // If the current layer's descendants form a contiguous block in paint order
530 // before promotion, the paint order will consist of
531 // a) the non-descendants which precede the current layer and its descendants,
532 // b) the current layer and its descendants
533 // c) The non-descendants which succeed the current layer and its descendants.
534 //
535 // Sub-lists (a) and (c) should be identical in both paint order lists if
536 // and only if the descendants form a contiguous block. In fact, this is the
537 // only check we need to perform since the order of the descendants with
538 // respect to each other cannot be affected by promotion (i.e., we don't
539 // need to worry about sub-list (b)).
540 //
541 // Some examples:
542 // C = currentLayer
543 // - = negative z-order child of currentLayer
544 // + = positive z-order child of currentLayer
545 // A = positioned ancestor of currentLayer
546 // x = any other RenderLayer in the list
547 //
548 // original | zOrderListBeforePromote | zOrderLi stAfterPromote
549 // zOrderListBeforePromote | after inserting C as above |
550 // ------------------------------------------------------------------------- --------------
551 // (1) x---+++x | x---C+++x | xCx
552 // (2) x---+A++x | x---+AC++x | xACx
553 // (3) x-x--+++x | x-x--C+++x | xxCx
554 // (4) xxA++x | xxAC++x | xxACx
555 //
556 // In example (1), we compare sub-list (a) by marching from the left of both
557 // lists (zOrderListBeforePromote after inserting C and
558 // zOrderListAfterPromote). The first mismatch is at index 1 when we hit '-'
559 // and 'C'. That means we have neg z-order descendants. This is a problem if
560 // we have a background. Before promotion, this bg would get painted with
561 // the current layer (i.e., after the neg z-order descendants), but after
562 // promotion the bg would get painted before them. This is a stacking order
563 // violation and we can't promote. However, if we don't have a background,
564 // we would continue on to the second pass. When comparing from the right,
565 // we mismatch on '+' and 'C'. Since we hit 'C' on zOrderListAfterPromote,
566 // we know that the children are contiguous, and we will promote.
567 //
568 // In example (2), when marching from the left, we'll hit a mismatch again
569 // on the second element we look at. This time, since this element is an 'A'
570 // in zOrderListAfterPromote, this indicates that there is an extra layer
571 // (the 'A') mixed in with the children. This could cause a change in paint
572 // order if we promote, so we decide not to and break out of the loop. Note
573 // that if the current layer has a background, this would provide a second
574 // reason not to opt in, since again we have negative z-order children who
575 // would change paint order with respect to our background if we promoted.
576 //
577 // In example (3), the discontiguity of the negative z-order children causes
578 // us to fail early in our "FromBackground" pass when we try to compare '-'
579 // from zOrderListBeforePromote with 'x' in zOrderListAfterPromote.
580 //
581 // Finally in example (4), we would match 'xxAC' from the left, then stop
582 // since we hit 'C'. Then we would match 'x' from the right, and mismatch
583 // on '+' and 'C'. Since we're at 'C' on the zOrderListAfterPromote, we
584 // conclude that all the children are contiguous. Since there are no
585 // negative z-order children, a background layer is irrelevant in this case.
586 // We will opt in, keeping paint order constant.
587 static bool compareLayerListsBeforeAndAfterPromote(const RenderLayer* currentLay er,
588 const Vector<RenderLayer*>* posZOrderListBeforePromote,
589 const Vector<RenderLayer*>* negZOrderListBeforePromote,
590 const Vector<RenderLayer*>* posZOrderListAfterPromote,
591 const Vector<RenderLayer*>* negZOrderListAfterPromote,
592 const size_t sizeBeforePromote,
593 const size_t sizeAfterPromote,
594 const StackingOrderDirection direction)
595 {
596 for (size_t index = 0; index < sizeBeforePromote && index < sizeAfterPromote ; index++) {
597 const RenderLayer* layerBeforePromote = getStackingOrderElementAt(posZOr derListBeforePromote, negZOrderListBeforePromote, direction, index);
598 const RenderLayer* layerAfterPromote = getStackingOrderElementAt(posZOrd erListAfterPromote, negZOrderListAfterPromote, direction, index);
599
600 if (layerBeforePromote != layerAfterPromote) {
601 // If we find a mismatch, the only situation where we haven't
602 // necessarily changed paint order yet is if layerAfterPromote
603 // is currentLayer.
604 if (layerAfterPromote != currentLayer)
605 return false;
606
607 // Also, if the current layer has a background, then any
608 // negative z-order children will get between the background
609 // and the rest of the layer.
610 if (direction == FromBackground && currentLayer->renderer()->hasBack ground())
611 return false;
612 }
613
614 // To compare the sub-lists (a) and (c) from the comment above, we only
615 // need to march until we hit the currentLayer in the
616 // zOrderListAfterPromote from each direction.
617 if (layerAfterPromote == currentLayer)
618 break;
619 }
620
621 return true;
622 }
623
624 // Determine whether the current layer can be promoted to a stacking container,
625 // given its closest stacking context ancestor. We do this by computing what
626 // positive and negative z-order lists would look like before and after
627 // promotion, and ensuring that proper stacking order is preserved between the
628 // two sets of lists.
629 //
630 // For more details on how the lists will be compared, see the comment and
631 // examples for compareLayerListsBeforeAndAfterPromote().
632 void RenderLayer::updateCanBeStackingContainer(RenderLayer* ancestorStackingCont ext)
633 {
634 TRACE_EVENT0("blink", "RenderLayer::updateCanBeStackingContainer");
635 ASSERT(!isStackingContext());
636
637 if (m_updatingCanBePromotedToStackingContainer || !acceleratedCompositingFor OverflowScrollEnabled())
638 return;
639
640 FrameView* frameView = renderer()->view()->frameView();
641 if (!frameView || !frameView->containsScrollableArea(this))
642 return;
643
644 m_updatingCanBePromotedToStackingContainer = true;
645
646 OwnPtr<Vector<RenderLayer*> > posZOrderListBeforePromote;
647 OwnPtr<Vector<RenderLayer*> > negZOrderListBeforePromote;
648 OwnPtr<Vector<RenderLayer*> > posZOrderListAfterPromote;
649 OwnPtr<Vector<RenderLayer*> > negZOrderListAfterPromote;
650 size_t posZOrderListSizeBeforePromote, negZOrderListSizeBeforePromote, posZO rderListSizeAfterPromote, negZOrderListSizeAfterPromote;
651
652 collectBeforePromotionZOrderList(ancestorStackingContext, posZOrderListBefor ePromote, negZOrderListBeforePromote);
653 collectAfterPromotionZOrderList(ancestorStackingContext, posZOrderListAfterP romote, negZOrderListAfterPromote);
654
655 size_t sizeBeforePromote = 0;
656 if (posZOrderListBeforePromote)
657 sizeBeforePromote += posZOrderListBeforePromote->size();
658 if (negZOrderListBeforePromote)
659 sizeBeforePromote += negZOrderListBeforePromote->size();
660
661 size_t sizeAfterPromote = 0;
662 if (posZOrderListAfterPromote)
663 sizeAfterPromote += posZOrderListAfterPromote->size();
664 if (negZOrderListAfterPromote)
665 sizeAfterPromote += negZOrderListAfterPromote->size();
666
667 bool canPromote = compareLayerListsBeforeAndAfterPromote(this, posZOrderList BeforePromote.get(), negZOrderListBeforePromote.get(),
668 posZOrderListAfterPromote.get(), negZOrderListAfterPromote.get(),
669 sizeBeforePromote, sizeAfterPromote, FromBackground)
670 && compareLayerListsBeforeAndAfterPromote(this, posZOrderListBeforePromo te.get(), negZOrderListBeforePromote.get(),
671 posZOrderListAfterPromote.get(), negZOrderListAfterPromote.get(),
672 sizeBeforePromote, sizeAfterPromote, FromForeground);
673
674 bool didUpdate = (canPromote != m_canBePromotedToStackingContainer);
675
676 m_canBePromotedToStackingContainer = canPromote;
677 m_updatingCanBePromotedToStackingContainer = false;
678 }
679
680 void RenderLayer::updateCanBeStackingContainerRecursively(RenderLayer* ancestorS tackingContext)
681 {
682 if (this != ancestorStackingContext) {
683 if (isStackingContext())
684 return;
685
686 updateCanBeStackingContainer(ancestorStackingContext);
687 }
688
689 if (m_hasVisibleDescendant) {
690 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) {
691 // Ignore reflections.
692 if (!m_reflection || reflectionLayer() != child)
693 child->updateCanBeStackingContainerRecursively(ancestorStackingC ontext);
694 }
695 }
696 }
697
698 // Compute what positive and negative z-order lists would look like before and
699 // after promotion, so we can later ensure that proper stacking order is
700 // preserved between the two sets of lists.
701 //
702 // A few examples:
703 // c = currentLayer
704 // - = negative z-order child of currentLayer
705 // + = positive z-order child of currentLayer
706 // a = positioned ancestor of currentLayer
707 // x = any other RenderLayer in the list
708 //
709 // (a) xxxxx-----++a+++x
710 // (b) xxx-----c++++++xx
711 //
712 //
713 // Normally the current layer would be painted in the normal flow list if it
714 // doesn't already appear in the positive z-order list. However, in the case
715 // that the layer has a positioned ancestor, it will paint directly after the
716 // positioned ancestor. In example (a), the current layer would be painted in
717 // the middle of its own positive z-order children, so promoting would cause a
718 // change in paint order (since a promoted layer will paint all of its positive
719 // z-order children strictly after it paints itself).
720 //
721 // In example (b), it is ok to promote the current layer only if it does not
722 // have a background. If it has a background, the background gets painted before
723 // the layer's negative z-order children, so again, a promotion would cause a
724 // change in paint order (causing the background to get painted after the
725 // negative z-order children instead of before).
649 void RenderLayer::collectBeforePromotionZOrderList(RenderLayer* ancestorStacking Context, OwnPtr<Vector<RenderLayer*> >& posZOrderListBeforePromote, OwnPtr<Vecto r<RenderLayer*> >& negZOrderListBeforePromote) 726 void RenderLayer::collectBeforePromotionZOrderList(RenderLayer* ancestorStacking Context, OwnPtr<Vector<RenderLayer*> >& posZOrderListBeforePromote, OwnPtr<Vecto r<RenderLayer*> >& negZOrderListBeforePromote)
650 { 727 {
651 // FIXME: TemporaryChange should support bit fields. 728 // We can't use TemporaryChange<> here since m_needsCompositedScrolling and
729 // m_isNormalFlowOnly are both bitfields, so we have to do it the
730 // old-fashioned way.
652 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling; 731 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling;
653 bool oldIsNormalFlowOnly = m_isNormalFlowOnly; 732 bool oldIsNormalFlowOnly = m_isNormalFlowOnly;
654 733
655 m_needsCompositedScrolling = false; 734 m_needsCompositedScrolling = false;
656 m_isNormalFlowOnly = shouldBeNormalFlowOnly(); 735 m_isNormalFlowOnly = shouldBeNormalFlowOnly();
657 736
658 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde rListBeforePromote, negZOrderListBeforePromote, 0); 737 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde rListBeforePromote, negZOrderListBeforePromote, 0);
659 738
660 m_needsCompositedScrolling = oldNeedsCompositedScrolling; 739 m_needsCompositedScrolling = oldNeedsCompositedScrolling;
661 m_isNormalFlowOnly = oldIsNormalFlowOnly; 740 m_isNormalFlowOnly = oldIsNormalFlowOnly;
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 if (curr == ancestorStackingContainer) 1134 if (curr == ancestorStackingContainer)
1056 return; 1135 return;
1057 } 1136 }
1058 } 1137 }
1059 1138
1060 bool RenderLayer::canBeStackingContainer() const 1139 bool RenderLayer::canBeStackingContainer() const
1061 { 1140 {
1062 if (isStackingContext() || !ancestorStackingContainer()) 1141 if (isStackingContext() || !ancestorStackingContainer())
1063 return true; 1142 return true;
1064 1143
1065 return m_descendantsAreContiguousInStackingOrder; 1144 return m_canBePromotedToStackingContainer;
1066 } 1145 }
1067 1146
1068 void RenderLayer::setHasVisibleContent() 1147 void RenderLayer::setHasVisibleContent()
1069 { 1148 {
1070 if (m_hasVisibleContent && !m_visibleContentStatusDirty) { 1149 if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
1071 ASSERT(!parent() || parent()->hasVisibleDescendant()); 1150 ASSERT(!parent() || parent()->hasVisibleDescendant());
1072 return; 1151 return;
1073 } 1152 }
1074 1153
1075 m_visibleContentStatusDirty = false; 1154 m_visibleContentStatusDirty = false;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 { 1190 {
1112 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 1191 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1113 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendan t()) 1192 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendan t())
1114 break; 1193 break;
1115 1194
1116 layer->m_hasVisibleDescendant = true; 1195 layer->m_hasVisibleDescendant = true;
1117 layer->m_visibleDescendantStatusDirty = false; 1196 layer->m_visibleDescendantStatusDirty = false;
1118 } 1197 }
1119 } 1198 }
1120 1199
1121 void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* o utOfFlowDescendantContainingBlocks) 1200 void RenderLayer::updateHasOutOfFlowPositionedDescendant(HashSet<const RenderObj ect*>* containingBlocks)
1122 { 1201 {
1123 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) { 1202 const bool hadOutOfFlowPositionedDescendant = hasOutOfFlowPositionedDescenda nt();
1124 const bool hadVisibleDescendant = m_hasVisibleDescendant; 1203 m_hasOutOfFlowPositionedDescendant = false;
1125 const bool hadOutOfFlowPositionedDescendant = m_hasOutOfFlowPositionedDe scendant;
1126 1204
1205 HashSet<const RenderObject*> childContainingBlocks;
1206 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1207 childContainingBlocks.clear();
1208 child->updateHasOutOfFlowPositionedDescendant(&childContainingBlocks);
1209
1210 const bool childIsOutOfFlowPositioned = child->renderer()
1211 && child->renderer()->isOutOfFlowPositioned()
1212 && (child->hasVisibleDescendant() || child->hasVisibleContent());
1213
1214 if (childIsOutOfFlowPositioned) {
1215 childContainingBlocks.add(child->renderer()->containingBlock());
1216
1217 childContainingBlocks.remove(renderer());
1218
1219 if (containingBlocks && !childContainingBlocks.isEmpty()) {
1220 HashSet<const RenderObject*>::const_iterator it = childContainingBlo cks.begin();
1221 for (; it != childContainingBlocks.end(); ++it)
1222 containingBlocks->add(*it);
1223 }
1224
1225 m_hasOutOfFlowPositionedDescendant |= !childContainingBlocks.isEmpty();
1226 }
1227
1228 if (m_hasOutOfFlowPositionedDescendant != hadOutOfFlowPositionedDescendant)
1229 compositor()->setNeedsUpdateCompositingRequirementsState();
1230 }
1231
1232 void RenderLayer::updateDescendantDependentFlags()
1233 {
1234 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty) {
1127 m_hasVisibleDescendant = false; 1235 m_hasVisibleDescendant = false;
1128 m_hasSelfPaintingLayerDescendant = false; 1236 m_hasSelfPaintingLayerDescendant = false;
1129 m_hasOutOfFlowPositionedDescendant = false;
1130 1237
1131 HashSet<const RenderObject*> childOutOfFlowDescendantContainingBlocks;
1132 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { 1238 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) {
1133 childOutOfFlowDescendantContainingBlocks.clear(); 1239 child->updateDescendantDependentFlags();
1134 child->updateDescendantDependentFlags(&childOutOfFlowDescendantConta iningBlocks);
1135
1136 bool childIsOutOfFlowPositioned = child->renderer() && child->render er()->isOutOfFlowPositioned();
1137 if (childIsOutOfFlowPositioned)
1138 childOutOfFlowDescendantContainingBlocks.add(child->renderer()-> containingBlock());
1139
1140 if (outOfFlowDescendantContainingBlocks) {
1141 HashSet<const RenderObject*>::const_iterator it = childOutOfFlow DescendantContainingBlocks.begin();
1142 for (; it != childOutOfFlowDescendantContainingBlocks.end(); ++i t)
1143 outOfFlowDescendantContainingBlocks->add(*it);
1144 }
1145 1240
1146 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_h asVisibleDescendant; 1241 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_h asVisibleDescendant;
1147 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() | | child->hasSelfPaintingLayerDescendant(); 1242 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() | | child->hasSelfPaintingLayerDescendant();
1148 bool hasOutOfFlowPositionedDescendant = hasVisibleDescendant && (!ch ildOutOfFlowDescendantContainingBlocks.isEmpty() || child->hasOutOfFlowPositione dDescendant());
1149 1243
1150 m_hasVisibleDescendant |= hasVisibleDescendant; 1244 m_hasVisibleDescendant |= hasVisibleDescendant;
1151 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant; 1245 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
1152 m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescenda nt;
1153 1246
1154 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && m_ hasOutOfFlowPositionedDescendant) 1247 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant)
1155 break; 1248 break;
1156 } 1249 }
1157 1250
1158 if (outOfFlowDescendantContainingBlocks && renderer())
1159 outOfFlowDescendantContainingBlocks->remove(renderer());
1160
1161 m_visibleDescendantStatusDirty = false; 1251 m_visibleDescendantStatusDirty = false;
1162 m_hasSelfPaintingLayerDescendantDirty = false; 1252 m_hasSelfPaintingLayerDescendantDirty = false;
1163 m_hasOutOfFlowPositionedDescendantDirty = false;
1164
1165 if (m_hasVisibleDescendant != hadVisibleDescendant || m_hasOutOfFlowPosi tionedDescendant != hadOutOfFlowPositionedDescendant)
1166 updateNeedsCompositedScrolling();
1167 } 1253 }
1168 1254
1169 if (m_visibleContentStatusDirty) { 1255 if (m_visibleContentStatusDirty) {
1170 const bool hadVisibleContent = m_hasVisibleContent;
1171 if (renderer()->style()->visibility() == VISIBLE) 1256 if (renderer()->style()->visibility() == VISIBLE)
1172 m_hasVisibleContent = true; 1257 m_hasVisibleContent = true;
1173 else { 1258 else {
1174 // layer may be hidden but still have some visible content, check fo r this 1259 // layer may be hidden but still have some visible content, check fo r this
1175 m_hasVisibleContent = false; 1260 m_hasVisibleContent = false;
1176 RenderObject* r = renderer()->firstChild(); 1261 RenderObject* r = renderer()->firstChild();
1177 while (r) { 1262 while (r) {
1178 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { 1263 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
1179 m_hasVisibleContent = true; 1264 m_hasVisibleContent = true;
1180 break; 1265 break;
1181 } 1266 }
1182 if (r->firstChild() && !r->hasLayer()) 1267 if (r->firstChild() && !r->hasLayer())
1183 r = r->firstChild(); 1268 r = r->firstChild();
1184 else if (r->nextSibling()) 1269 else if (r->nextSibling())
1185 r = r->nextSibling(); 1270 r = r->nextSibling();
1186 else { 1271 else {
1187 do { 1272 do {
1188 r = r->parent(); 1273 r = r->parent();
1189 if (r == renderer()) 1274 if (r == renderer())
1190 r = 0; 1275 r = 0;
1191 } while (r && !r->nextSibling()); 1276 } while (r && !r->nextSibling());
1192 if (r) 1277 if (r)
1193 r = r->nextSibling(); 1278 r = r->nextSibling();
1194 } 1279 }
1195 } 1280 }
1196 } 1281 }
1197 m_visibleContentStatusDirty = false; 1282 m_visibleContentStatusDirty = false;
1198 if (hadVisibleContent != m_hasVisibleContent)
1199 updateNeedsCompositedScrolling();
1200 } 1283 }
1201 } 1284 }
1202 1285
1203 void RenderLayer::dirty3DTransformedDescendantStatus() 1286 void RenderLayer::dirty3DTransformedDescendantStatus()
1204 { 1287 {
1205 RenderLayer* curr = ancestorStackingContainer(); 1288 RenderLayer* curr = ancestorStackingContainer();
1206 if (curr) 1289 if (curr)
1207 curr->m_3DTransformedDescendantStatusDirty = true; 1290 curr->m_3DTransformedDescendantStatusDirty = true;
1208 1291
1209 // This propagates up through preserve-3d hierarchies to the enclosing flatt ening layer. 1292 // This propagates up through preserve-3d hierarchies to the enclosing flatt ening layer.
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 child->setParent(this); 1843 child->setParent(this);
1761 1844
1762 if (child->isNormalFlowOnly()) 1845 if (child->isNormalFlowOnly())
1763 dirtyNormalFlowList(); 1846 dirtyNormalFlowList();
1764 1847
1765 if (!child->isNormalFlowOnly() || child->firstChild()) { 1848 if (!child->isNormalFlowOnly() || child->firstChild()) {
1766 // Dirty the z-order list in which we are contained. The ancestorStackin gContainer() can be null in the 1849 // Dirty the z-order list in which we are contained. The ancestorStackin gContainer() can be null in the
1767 // case where we're building up generated content layers. This is ok, si nce the lists will start 1850 // case where we're building up generated content layers. This is ok, si nce the lists will start
1768 // off dirty in that case anyway. 1851 // off dirty in that case anyway.
1769 child->dirtyStackingContainerZOrderLists(); 1852 child->dirtyStackingContainerZOrderLists();
1770
1771 // Adding an out of flow positioned descendant can only affect
1772 // the opt-in decision for layers beneath and including our
1773 // containing block.
1774 RenderObject* containingBlock = child->renderer()->containingBlock();
1775 for (RenderLayer* layer = child; layer; layer = layer->parent()) {
1776 layer->updateNeedsCompositedScrolling();
1777 if (layer->renderer() == containingBlock)
1778 break;
1779 }
1780 } 1853 }
1781 1854
1782 child->updateDescendantDependentFlags(); 1855 child->updateDescendantDependentFlags();
1783 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) 1856 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
1784 setAncestorChainHasVisibleDescendant(); 1857 setAncestorChainHasVisibleDescendant();
1785 1858
1786 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) 1859 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
1787 setAncestorChainHasSelfPaintingLayerDescendant(); 1860 setAncestorChainHasSelfPaintingLayerDescendant();
1788 1861
1789 if (child->renderer() && (child->renderer()->isOutOfFlowPositioned() || chil d->hasOutOfFlowPositionedDescendant())) 1862 if (child->renderer() && (child->renderer()->isOutOfFlowPositioned() || chil d->hasOutOfFlowPositionedDescendant()))
1790 setAncestorChainHasOutOfFlowPositionedDescendant(child->renderer()->cont ainingBlock()); 1863 compositor()->setNeedsUpdateCompositingRequirementsState();
1791 1864
1792 compositor()->layerWasAdded(this, child); 1865 compositor()->layerWasAdded(this, child);
1793 } 1866 }
1794 1867
1795 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) 1868 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1796 { 1869 {
1797 if (!renderer()->documentBeingDestroyed()) 1870 if (!renderer()->documentBeingDestroyed())
1798 compositor()->layerWillBeRemoved(this, oldChild); 1871 compositor()->layerWillBeRemoved(this, oldChild);
1799 1872
1800 // remove the child 1873 // remove the child
1801 if (oldChild->previousSibling()) 1874 if (oldChild->previousSibling())
1802 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); 1875 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1803 if (oldChild->nextSibling()) 1876 if (oldChild->nextSibling())
1804 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()) ; 1877 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()) ;
1805 1878
1806 if (m_first == oldChild) 1879 if (m_first == oldChild)
1807 m_first = oldChild->nextSibling(); 1880 m_first = oldChild->nextSibling();
1808 if (m_last == oldChild) 1881 if (m_last == oldChild)
1809 m_last = oldChild->previousSibling(); 1882 m_last = oldChild->previousSibling();
1810 1883
1811 if (oldChild->isNormalFlowOnly()) 1884 if (oldChild->isNormalFlowOnly())
1812 dirtyNormalFlowList(); 1885 dirtyNormalFlowList();
1813 if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) { 1886 if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) {
1814 // Dirty the z-order list in which we are contained. When called via th e 1887 // Dirty the z-order list in which we are contained. When called via th e
1815 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected 1888 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
1816 // from the main layer tree, so we need to null-check the |stackingConta iner| value. 1889 // from the main layer tree, so we need to null-check the |stackingConta iner| value.
1817 oldChild->dirtyStackingContainerZOrderLists(); 1890 oldChild->dirtyStackingContainerZOrderLists();
1818
1819 // This could affect whether or not a layer has an out of flow
1820 // positioned descendant so we need to schedule some updates.
1821 // Removing an out of flow positioned descendant can only affect
1822 // the opt-in decision for layers beneath and including the old child's
1823 // containing block.
1824 RenderObject* containingBlock = oldChild->renderer()->containingBlock();
1825 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1826 layer->updateNeedsCompositedScrolling();
1827 if (layer->renderer() == containingBlock)
1828 break;
1829 }
1830 } 1891 }
1831 1892
1832 if ((oldChild->renderer() && oldChild->renderer()->isOutOfFlowPositioned()) || oldChild->hasOutOfFlowPositionedDescendant())
1833 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
1834
1835 oldChild->setPreviousSibling(0); 1893 oldChild->setPreviousSibling(0);
1836 oldChild->setNextSibling(0); 1894 oldChild->setNextSibling(0);
1837 oldChild->setParent(0); 1895 oldChild->setParent(0);
1838 1896
1839 oldChild->updateDescendantDependentFlags(); 1897 oldChild->updateDescendantDependentFlags();
1898 if ((oldChild->renderer() && oldChild->renderer()->isOutOfFlowPositioned()) || oldChild->hasOutOfFlowPositionedDescendant())
1899 compositor()->setNeedsUpdateCompositingRequirementsState();
1900
1840 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) 1901 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1841 dirtyAncestorChainVisibleDescendantStatus(); 1902 dirtyAncestorChainVisibleDescendantStatus();
1842 1903
1843 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescend ant()) 1904 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescend ant())
1844 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 1905 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1845 1906
1846 return oldChild; 1907 return oldChild;
1847 } 1908 }
1848 1909
1849 void RenderLayer::removeOnlyThisLayer() 1910 void RenderLayer::removeOnlyThisLayer()
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2044 rect.move(-delta.x(), -delta.y()); 2105 rect.move(-delta.x(), -delta.y());
2045 } 2106 }
2046 2107
2047 bool RenderLayer::usesCompositedScrolling() const 2108 bool RenderLayer::usesCompositedScrolling() const
2048 { 2109 {
2049 return isComposited() && backing()->scrollingLayer(); 2110 return isComposited() && backing()->scrollingLayer();
2050 } 2111 }
2051 2112
2052 bool RenderLayer::needsCompositedScrolling() const 2113 bool RenderLayer::needsCompositedScrolling() const
2053 { 2114 {
2115 switch (m_forceNeedsCompositedScrolling) {
2116 case DoNotForceCompositedScrolling:
2117 return m_needsCompositedScrolling;
2118 case ForceCompositedScrollingOn:
2119 return true;
2120 case ForceCompositedScrollingOff:
2121 return false;
2122 }
2054 return m_needsCompositedScrolling; 2123 return m_needsCompositedScrolling;
2055 } 2124 }
2056 2125
2057 void RenderLayer::updateNeedsCompositedScrolling() 2126 void RenderLayer::updateNeedsCompositedScrolling()
2058 { 2127 {
2059 bool needsCompositedScrolling = false; 2128 TRACE_EVENT0("blink-rendering", "RenderLayer::updateNeedsCompositedScrolling \n");
hartmanng 2013/05/02 14:04:01 Might not be a bad idea to leave these trace event
2129 #ifndef NDEBUG
2130 fprintf(stderr, "vollick: RenderLayer::updateNeedsCompositedScrolling %s\n", debugName().ascii().data());
2131 #endif
2132 if (m_updatingNeedsCompositedScrolling || m_updatingCanBePromotedToStackingC ontainer)
2133 return;
2134
2135 bool needsCompositedScrolling = isStackingContext();
2060 2136
2061 FrameView* frameView = renderer()->view()->frameView(); 2137 FrameView* frameView = renderer()->view()->frameView();
2062 if (frameView && frameView->containsScrollableArea(this)) { 2138 if (!needsCompositedScrolling && acceleratedCompositingForOverflowScrollEnab led() && frameView && frameView->containsScrollableArea(this)) {
2139 m_updatingNeedsCompositedScrolling = true;
2063 updateDescendantDependentFlags(); 2140 updateDescendantDependentFlags();
2141 RenderLayer* stackingContext = ancestorStackingContext();
2142 updateCanBeStackingContainer(stackingContext);
2064 2143
2065 bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScro llEnabled() 2144 bool forceUseCompositedScrolling = canBeStackingContainer() && !hasOutOf FlowPositionedDescendant();
2066 && canBeStackingContainer() 2145
2067 && !hasOutOfFlowPositionedDescendant(); 2146 #ifndef NDEBUG
2147 fprintf(stderr, "vollick: RenderLayer::updateNeedsCompositedScrolling %d %d %s\n", canBeStackingContainer(), hasOutOfFlowPositionedDescendant(), debugNa me().ascii().data());
2148 #endif
2149
2150 TRACE_EVENT_INSTANT2("blink-rendering",
2151 "RenderLayer::updateNeedsCompositedScrolling",
2152 "Can be a stacking container",
2153 canBeStackingContainer(),
2154 "Has out of flow positioned descendant",
2155 hasOutOfFlowPositionedDescendant());
2068 2156
2069 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) 2157 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2070 needsCompositedScrolling = forceUseCompositedScrolling || renderer()->st yle()->useTouchOverflowScrolling(); 2158 needsCompositedScrolling = forceUseCompositedScrolling || renderer()->st yle()->useTouchOverflowScrolling();
2071 #else 2159 #else
2072 needsCompositedScrolling = forceUseCompositedScrolling; 2160 needsCompositedScrolling = forceUseCompositedScrolling;
2073 #endif 2161 #endif
2074 // We gather a boolean value for use with Google UMA histograms to 2162 // We gather a boolean value for use with Google UMA histograms to
2075 // quantify the actual effects of a set of patches attempting to 2163 // quantify the actual effects of a set of patches attempting to
2076 // relax composited scrolling requirements, thereby increasing the 2164 // relax composited scrolling requirements, thereby increasing the
2077 // number of composited overflow divs. 2165 // number of composited overflow divs.
2078 if (acceleratedCompositingForOverflowScrollEnabled()) 2166 if (acceleratedCompositingForOverflowScrollEnabled())
2079 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScro lling", needsCompositedScrolling, 2); 2167 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScro lling", needsCompositedScrolling, 2);
2168
2169 m_updatingNeedsCompositedScrolling = false;
2080 } 2170 }
2081 2171
2172 setNeedsCompositedScrolling(needsCompositedScrolling);
2173 }
2174
2175 void RenderLayer::setNeedsCompositedScrolling(bool needsCompositedScrolling)
2176 {
2082 if (m_needsCompositedScrolling == needsCompositedScrolling) 2177 if (m_needsCompositedScrolling == needsCompositedScrolling)
2083 return; 2178 return;
2084 2179
2085 m_needsCompositedScrolling = needsCompositedScrolling; 2180 m_needsCompositedScrolling = needsCompositedScrolling;
2086 2181
2182 // Note, the z-order lists may need to be rebuilt, but our code guarantees
2183 // that we have not affected stacking, so we will not dirty
2184 // m_canBePromotedToStackingContainer for either us or our stacking context
2185 // or container.
2186 didSetNeedsCompositedScrolling();
2187 }
2188
2189 void RenderLayer::setForceNeedsCompositedScrolling(RenderLayer::ForceNeedsCompos itedScrollingMode mode)
2190 {
2191 m_forceNeedsCompositedScrolling = mode;
2192 didSetNeedsCompositedScrolling();
2193 }
2194
2195 void RenderLayer::didSetNeedsCompositedScrolling()
2196 {
2087 updateIsNormalFlowOnly(); 2197 updateIsNormalFlowOnly();
2088 updateSelfPaintingLayer(); 2198 updateSelfPaintingLayer();
2089 2199
2090 if (isStackingContainer()) 2200 if (isStackingContainer())
2091 dirtyZOrderLists(); 2201 dirtyZOrderLists();
2092 else 2202 else
2093 clearZOrderLists(); 2203 clearZOrderLists();
2094 2204
2095 dirtyStackingContainerZOrderLists(); 2205 dirtyStackingContainerZOrderLists();
2096 2206
(...skipping 3503 matching lines...) Expand 10 before | Expand all | Expand 10 after
5600 { 5710 {
5601 ASSERT(m_layerListMutationAllowed); 5711 ASSERT(m_layerListMutationAllowed);
5602 ASSERT(isStackingContainer()); 5712 ASSERT(isStackingContainer());
5603 5713
5604 if (m_posZOrderList) 5714 if (m_posZOrderList)
5605 m_posZOrderList->clear(); 5715 m_posZOrderList->clear();
5606 if (m_negZOrderList) 5716 if (m_negZOrderList)
5607 m_negZOrderList->clear(); 5717 m_negZOrderList->clear();
5608 m_zOrderListsDirty = true; 5718 m_zOrderListsDirty = true;
5609 5719
5610 m_descendantsAreContiguousInStackingOrderDirty = true; 5720 compositor()->setNeedsUpdateCompositingRequirementsState();
5611 5721
5612 if (!renderer()->documentBeingDestroyed()) { 5722 if (!renderer()->documentBeingDestroyed()) {
5613 compositor()->setCompositingLayersNeedRebuild(); 5723 compositor()->setCompositingLayersNeedRebuild();
5614 if (acceleratedCompositingForOverflowScrollEnabled()) 5724 if (acceleratedCompositingForOverflowScrollEnabled())
5615 compositor()->setShouldReevaluateCompositingAfterLayout(); 5725 compositor()->setShouldReevaluateCompositingAfterLayout();
5616 } 5726 }
5617 } 5727 }
5618 5728
5619 void RenderLayer::dirtyStackingContainerZOrderLists() 5729 void RenderLayer::dirtyStackingContainerZOrderLists()
5620 { 5730 {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
5705 void RenderLayer::collectLayers(bool includeHiddenLayers, CollectLayersBehavior behavior, OwnPtr<Vector<RenderLayer*> >& posBuffer, OwnPtr<Vector<RenderLayer*> >& negBuffer, const RenderLayer* layerToForceAsStackingContainer) 5815 void RenderLayer::collectLayers(bool includeHiddenLayers, CollectLayersBehavior behavior, OwnPtr<Vector<RenderLayer*> >& posBuffer, OwnPtr<Vector<RenderLayer*> >& negBuffer, const RenderLayer* layerToForceAsStackingContainer)
5706 { 5816 {
5707 if (isInTopLayer()) 5817 if (isInTopLayer())
5708 return; 5818 return;
5709 5819
5710 updateDescendantDependentFlags(); 5820 updateDescendantDependentFlags();
5711 5821
5712 bool isStacking = false; 5822 bool isStacking = false;
5713 5823
5714 switch (behavior) { 5824 switch (behavior) {
5715 case StopAtStackingContexts: 5825 case StopAtStackingContexts:
5716 isStacking = (this == layerToForceAsStackingContainer) || isStacking Context(); 5826 isStacking = (this == layerToForceAsStackingContainer) || isStackingCont ext();
5717 break; 5827 break;
5718 5828
5719 case StopAtStackingContainers: 5829 case StopAtStackingContainers:
5720 isStacking = (this == layerToForceAsStackingContainer) || isStacking Container(); 5830 isStacking = (this == layerToForceAsStackingContainer) || isStackingCon tainer();
5721 break; 5831 break;
5832 }
5833
5834 // This value could be affected by opt in. What we really need to know is
5835 // are you normal flow only, regardless of your opt in status. This is very
5836 // similar to asking if a layer is a stacking context rather than a
5837 // stacking container.
5838 bool isNormalFlowWithoutCompositedScrolling = isNormalFlowOnly();
5839 if (this != layerToForceAsStackingContainer && behavior == StopAtStackingCon texts) {
5840 TemporaryChange<ForceNeedsCompositedScrollingMode> forceOff(m_forceNeeds CompositedScrolling, ForceCompositedScrollingOff);
5841 isNormalFlowWithoutCompositedScrolling = shouldBeNormalFlowOnly();
5722 } 5842 }
5723 5843
5724 // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists. 5844 // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
5725 bool includeHiddenLayer = includeHiddenLayers || (m_hasVisibleContent || (m_ hasVisibleDescendant && isStacking)); 5845 bool includeHiddenLayer = includeHiddenLayers || (m_hasVisibleContent || (m_ hasVisibleDescendant && isStacking));
5726 if (includeHiddenLayer && !isNormalFlowOnly() && !isOutOfFlowRenderFlowThrea d()) { 5846 if (includeHiddenLayer && !isNormalFlowWithoutCompositedScrolling && !isOutO fFlowRenderFlowThread()) {
5727 // Determine which buffer the child should be in. 5847 // Determine which buffer the child should be in.
5728 OwnPtr<Vector<RenderLayer*> >& buffer = (zIndex() >= 0) ? posBuffer : ne gBuffer; 5848 OwnPtr<Vector<RenderLayer*> >& buffer = (zIndex() >= 0) ? posBuffer : ne gBuffer;
5729 5849
5730 // Create the buffer if it doesn't exist yet. 5850 // Create the buffer if it doesn't exist yet.
5731 if (!buffer) 5851 if (!buffer)
5732 buffer = adoptPtr(new Vector<RenderLayer*>); 5852 buffer = adoptPtr(new Vector<RenderLayer*>);
5733 5853
5734 // Append ourselves at the end of the appropriate buffer. 5854 // Append ourselves at the end of the appropriate buffer.
5735 buffer->append(this); 5855 buffer->append(this);
5736 } 5856 }
5737 5857
5738 // Recur into our children to collect more layers, but only if we don't esta blish 5858 // Recur into our children to collect more layers, but only if we don't esta blish
5739 // a stacking context/container. 5859 // a stacking context/container.
5740 if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) { 5860 if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) {
5741 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { 5861 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) {
5742 // Ignore reflections. 5862 // Ignore reflections.
5743 if (!m_reflection || reflectionLayer() != child) 5863 if (!m_reflection || reflectionLayer() != child)
5744 child->collectLayers(includeHiddenLayers, behavior, posBuffer, n egBuffer, layerToForceAsStackingContainer); 5864 child->collectLayers(includeHiddenLayers, behavior, posBuffer, n egBuffer, layerToForceAsStackingContainer);
5745 } 5865 }
5746 } 5866 }
5747 } 5867 }
5748 5868
5749 void RenderLayer::updateLayerListsIfNeeded() 5869 void RenderLayer::updateLayerListsIfNeeded()
5750 { 5870 {
5751 bool shouldUpdateDescendantsAreContiguousInStackingOrder = acceleratedCompos itingForOverflowScrollEnabled() && isStackingContext() && (m_zOrderListsDirty || m_normalFlowListDirty) && m_descendantsAreContiguousInStackingOrderDirty; 5871 // bool shouldUpdateCanBeStackingContainer = acceleratedCompositingForOverflo wScrollEnabled() && isStackingContext() && (m_zOrderListsDirty || m_normalFlowLi stDirty) && m_canBePromotedToStackingContainerDirty;
5872 bool shouldUpdateCanBeStackingContainer = false;
5752 updateZOrderLists(); 5873 updateZOrderLists();
5753 updateNormalFlowList(); 5874 updateNormalFlowList();
5754 5875
5755 if (RenderLayer* reflectionLayer = this->reflectionLayer()) { 5876 if (RenderLayer* reflectionLayer = this->reflectionLayer()) {
5756 reflectionLayer->updateZOrderLists(); 5877 reflectionLayer->updateZOrderLists();
5757 reflectionLayer->updateNormalFlowList(); 5878 reflectionLayer->updateNormalFlowList();
5758 } 5879 }
5759 5880
5760 if (shouldUpdateDescendantsAreContiguousInStackingOrder) { 5881 if (shouldUpdateCanBeStackingContainer) {
5761 updateDescendantsAreContiguousInStackingOrder(); 5882 // Call UpdateCanBeStackingContainer for all descendants,
5883 // passing self in as ancestor stacking context.
5884 updateCanBeStackingContainerRecursively(this);
5885
5762 // The above function can cause us to update m_needsCompositedScrolling 5886 // The above function can cause us to update m_needsCompositedScrolling
5763 // and dirty our layer lists. Refresh them if necessary. 5887 // and dirty our layer lists. Refresh them if necessary.
5764 updateZOrderLists(); 5888 updateZOrderLists();
5765 updateNormalFlowList(); 5889 updateNormalFlowList();
5766 } 5890 }
5767 } 5891 }
5768 5892
5769 void RenderLayer::repaintIncludingDescendants() 5893 void RenderLayer::repaintIncludingDescendants()
5770 { 5894 {
5771 renderer()->repaint(); 5895 renderer()->repaint();
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
5936 return false; 6060 return false;
5937 } 6061 }
5938 6062
5939 void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle) 6063 void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle)
5940 { 6064 {
5941 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE; 6065 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
5942 if (oldVisibility == renderer()->style()->visibility() || !renderer()->isOut OfFlowPositioned()) 6066 if (oldVisibility == renderer()->style()->visibility() || !renderer()->isOut OfFlowPositioned())
5943 return; 6067 return;
5944 6068
5945 if (renderer()->style()->visibility() == VISIBLE) 6069 if (renderer()->style()->visibility() == VISIBLE)
5946 setAncestorChainHasOutOfFlowPositionedDescendant(renderer()->containingB lock()); 6070 compositor()->setNeedsUpdateCompositingRequirementsState();
5947 else
5948 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
5949 } 6071 }
5950 6072
5951 void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldS tyle) 6073 void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldS tyle)
5952 { 6074 {
5953 bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false; 6075 bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false;
5954 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE; 6076 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
5955 int oldZIndex = oldStyle ? oldStyle->zIndex() : 0; 6077 int oldZIndex = oldStyle ? oldStyle->zIndex() : 0;
5956 6078
5957 // FIXME: RenderLayer already handles visibility changes through our visibli ty dirty bits. This logic could 6079 // FIXME: RenderLayer already handles visibility changes through our visibli ty dirty bits. This logic could
5958 // likely be folded along with the rest. 6080 // likely be folded along with the rest.
5959 bool isStackingContext = this->isStackingContext(); 6081 bool isStackingContext = this->isStackingContext();
5960 if (isStackingContext == wasStackingContext && oldVisibility == renderer()-> style()->visibility() && oldZIndex == renderer()->style()->zIndex()) 6082 if (isStackingContext == wasStackingContext && oldVisibility == renderer()-> style()->visibility() && oldZIndex == renderer()->style()->zIndex())
5961 return; 6083 return;
5962 6084
5963 dirtyStackingContainerZOrderLists(); 6085 dirtyStackingContainerZOrderLists();
5964 6086
5965 if (isStackingContainer()) 6087 if (isStackingContainer())
5966 dirtyZOrderLists(); 6088 dirtyZOrderLists();
5967 else 6089 else
5968 clearZOrderLists(); 6090 clearZOrderLists();
5969 6091
5970 updateNeedsCompositedScrolling(); 6092 // FIXME: This should be done via a function so that we can flip a bit on
6093 // the renderview allowing us to skip updates in frames where no comp-scroll
6094 // state actually changed.
6095 compositor()->setNeedsUpdateCompositingRequirementsState();
5971 } 6096 }
5972 6097
5973 static bool overflowRequiresScrollbar(EOverflow overflow) 6098 static bool overflowRequiresScrollbar(EOverflow overflow)
5974 { 6099 {
5975 return overflow == OSCROLL; 6100 return overflow == OSCROLL;
5976 } 6101 }
5977 6102
5978 static bool overflowDefinesAutomaticScrollbar(EOverflow overflow) 6103 static bool overflowDefinesAutomaticScrollbar(EOverflow overflow)
5979 { 6104 {
5980 return overflow == OAUTO || overflow == OOVERLAY; 6105 return overflow == OAUTO || overflow == OOVERLAY;
(...skipping 28 matching lines...) Expand all
6009 6134
6010 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) { 6135 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) {
6011 ASSERT(hasVerticalScrollbar()); 6136 ASSERT(hasVerticalScrollbar());
6012 m_vBar->setEnabled(true); 6137 m_vBar->setEnabled(true);
6013 } 6138 }
6014 6139
6015 if (!m_scrollDimensionsDirty) 6140 if (!m_scrollDimensionsDirty)
6016 updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollab leVerticalOverflow()); 6141 updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollab leVerticalOverflow());
6017 } 6142 }
6018 6143
6019 void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant(RenderObject* containingBlock)
6020 {
6021 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
6022 if (!layer->m_hasOutOfFlowPositionedDescendantDirty && layer->hasOutOfFl owPositionedDescendant())
6023 break;
6024
6025 layer->m_hasOutOfFlowPositionedDescendantDirty = false;
6026 layer->m_hasOutOfFlowPositionedDescendant = true;
6027 layer->updateNeedsCompositedScrolling();
6028
6029 if (layer->renderer() && layer->renderer() == containingBlock)
6030 break;
6031 }
6032 }
6033
6034 void RenderLayer::dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus()
6035 {
6036 if (m_hasOutOfFlowPositionedDescendant) {
6037 m_hasOutOfFlowPositionedDescendantDirty = true;
6038 // FIXME It would be nice to avoid this when we clean up render layer
6039 // updating. We shouldn't have to update the composited scrolling state
6040 // nearly as frequently if all the updates happen in a single, well
6041 // defined phase.
6042 updateNeedsCompositedScrolling();
6043 }
6044
6045 if (parent())
6046 parent()->dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
6047 }
6048
6049 void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle) 6144 void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle)
6050 { 6145 {
6051 bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsoluteP osition || oldStyle->position() == FixedPosition); 6146 if (!oldStyle || (renderer()->style()->position() != oldStyle->position()))
6052 bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned(); 6147 compositor()->setNeedsUpdateCompositingRequirementsState();
6053 if (parent() && isOutOfFlowPositioned != wasOutOfFlowPositioned) {
6054 if (isOutOfFlowPositioned)
6055 parent()->setAncestorChainHasOutOfFlowPositionedDescendant(renderer( )->containingBlock());
6056 else
6057 parent()->dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus() ;
6058 }
6059 } 6148 }
6060 6149
6061 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newS tyle) 6150 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newS tyle)
6062 { 6151 {
6063 ASSERT(newStyle); 6152 ASSERT(newStyle);
6064 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter(); 6153 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter();
6065 } 6154 }
6066 6155
6067 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const 6156 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
6068 { 6157 {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
6206 if (HTMLFrameOwnerElement* owner = frame->ownerElement()) 6295 if (HTMLFrameOwnerElement* owner = frame->ownerElement())
6207 isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToH itTesting(); 6296 isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToH itTesting();
6208 6297
6209 bool updatedScrollableAreaSet = false; 6298 bool updatedScrollableAreaSet = false;
6210 if (hasOverflow && isVisibleToHitTest) 6299 if (hasOverflow && isVisibleToHitTest)
6211 updatedScrollableAreaSet = frameView->addScrollableArea(this); 6300 updatedScrollableAreaSet = frameView->addScrollableArea(this);
6212 else 6301 else
6213 updatedScrollableAreaSet = frameView->removeScrollableArea(this); 6302 updatedScrollableAreaSet = frameView->removeScrollableArea(this);
6214 6303
6215 if (updatedScrollableAreaSet) 6304 if (updatedScrollableAreaSet)
6216 updateNeedsCompositedScrolling(); 6305 compositor()->setNeedsUpdateCompositingRequirementsState();
6217 } 6306 }
6218 6307
6219 void RenderLayer::updateScrollCornerStyle() 6308 void RenderLayer::updateScrollCornerStyle()
6220 { 6309 {
6221 RenderObject* actualRenderer = rendererForScrollbar(renderer()); 6310 RenderObject* actualRenderer = rendererForScrollbar(renderer());
6222 RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer- >getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->st yle()) : PassRefPtr<RenderStyle>(0); 6311 RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer- >getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->st yle()) : PassRefPtr<RenderStyle>(0);
6223 if (corner) { 6312 if (corner) {
6224 if (!m_scrollCorner) { 6313 if (!m_scrollCorner) {
6225 m_scrollCorner = RenderScrollbarPart::createAnonymous(renderer()->do cument()); 6314 m_scrollCorner = RenderScrollbarPart::createAnonymous(renderer()->do cument());
6226 m_scrollCorner->setParent(renderer()); 6315 m_scrollCorner->setParent(renderer());
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
6457 } 6546 }
6458 } 6547 }
6459 6548
6460 void showLayerTree(const WebCore::RenderObject* renderer) 6549 void showLayerTree(const WebCore::RenderObject* renderer)
6461 { 6550 {
6462 if (!renderer) 6551 if (!renderer)
6463 return; 6552 return;
6464 showLayerTree(renderer->enclosingLayer()); 6553 showLayerTree(renderer->enclosingLayer());
6465 } 6554 }
6466 #endif 6555 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698