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

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_canBePromotedToStackingContainer(false)
149 , m_descendantsAreContiguousInStackingOrderDirty(true) 151 , m_canBePromotedToStackingContainerDirty(true)
150 , m_isRootLayer(renderer->isRenderView()) 152 , m_isRootLayer(renderer->isRenderView())
151 , m_usedTransparency(false) 153 , m_usedTransparency(false)
152 , m_paintingInsideReflection(false) 154 , m_paintingInsideReflection(false)
153 , m_inOverflowRelayout(false) 155 , m_inOverflowRelayout(false)
154 , m_repaintStatus(NeedsNormalRepaint) 156 , m_repaintStatus(NeedsNormalRepaint)
155 , m_visibleContentStatusDirty(true) 157 , m_visibleContentStatusDirty(true)
156 , m_hasVisibleContent(false) 158 , m_hasVisibleContent(false)
157 , m_visibleDescendantStatusDirty(false) 159 , m_visibleDescendantStatusDirty(false)
158 , m_hasVisibleDescendant(false) 160 , m_hasVisibleDescendant(false)
159 , m_isPaginated(false) 161 , m_isPaginated(false)
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 } 477 }
476 } 478 }
477 479
478 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const 480 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const
479 { 481 {
480 return renderer()->frame() 482 return renderer()->frame()
481 && renderer()->frame()->page() 483 && renderer()->frame()->page()
482 && renderer()->frame()->page()->settings()->acceleratedCompositingForOve rflowScrollEnabled(); 484 && renderer()->frame()->page()->settings()->acceleratedCompositingForOve rflowScrollEnabled();
483 } 485 }
484 486
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) 487 static inline bool isPositionedContainer(const RenderLayer* layer)
641 { 488 {
642 // FIXME: This is not in sync with containingBlock. 489 // FIXME: This is not in sync with containingBlock.
643 // RenderObject::canContainFixedPositionedObject() should probably be used 490 // RenderObject::canContainFixedPositionedObject() should probably be used
644 // instead. 491 // instead.
645 RenderLayerModelObject* layerRenderer = layer->renderer(); 492 RenderLayerModelObject* layerRenderer = layer->renderer();
646 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform(); 493 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform();
647 } 494 }
648 495
496 enum StackingOrderDirection { FromBackground, FromForeground };
497
498 // We'd like to be able to iterate through a single paint order list, but for
499 // efficiency's sake, we hang onto two lists instead (namely, the pos and neg
500 // z-order lists produced by CollectLayers). This function allows us to index
501 // into these two lists as if they were one. It also allows us to index into
502 // this virtual list either from the start or from the end (i.e., in either
503 // stacking order direction).
504 static const RenderLayer* getStackingOrderElementAt(const Vector<RenderLayer*>* posZOrderList, const Vector<RenderLayer*>* negZOrderList, const StackingOrderDir ection direction, const size_t index)
505 {
506 size_t negZOrderListSize = negZOrderList ? negZOrderList->size() : 0;
507
508 if (direction == FromBackground) {
509 if (index < negZOrderListSize)
510 return negZOrderList->at(index);
511
512 return posZOrderList->at(index - negZOrderListSize);
513 }
514
515 size_t posZOrderListSize = posZOrderList ? posZOrderList->size() : 0;
516
517 if (index < posZOrderListSize)
518 return posZOrderList->at(posZOrderListSize - index - 1);
519
520 return negZOrderList->at(negZOrderListSize - (index - posZOrderListSize) - 1 );
521 }
522
523 // After promotion, the paint order consists of
524 // a) the non-descendants which precede the promoted layer,
525 // b) the promoted layer, and
526 // c) the non-descendants which succeed the promoted layer.
527 //
528 // If the current layer's descendants form a contiguous block in paint order
529 // before promotion, the paint order will consist of
530 // a) the non-descendants which precede the current layer and its descendants,
531 // b) the current layer and its descendants
532 // c) The non-descendants which succeed the current layer and its descendants.
533 //
534 // Sub-lists (a) and (c) should be identical in both paint order lists if
535 // and only if the descendants form a contiguous block. In fact, this is the
536 // only check we need to perform since the order of the descendants with
537 // respect to each other cannot be affected by promotion (i.e., we don't
538 // need to worry about sub-list (b)).
539 //
540 // Some examples:
541 // C = currentLayer
542 // - = negative z-order child of currentLayer
543 // + = positive z-order child of currentLayer
544 // A = positioned ancestor of currentLayer
545 // x = any other RenderLayer in the list
546 //
547 // original | zOrderListBeforePromote | zOrderLi stAfterPromote
548 // zOrderListBeforePromote | after inserting C as above |
549 // ------------------------------------------------------------------------- --------------
550 // (1) x---+++x | x---C+++x | xCx
551 // (2) x---+A++x | x---+AC++x | xACx
552 // (3) x-x--+++x | x-x--C+++x | xxCx
553 // (4) xxA++x | xxAC++x | xxACx
554 //
555 // In example (1), we compare sub-list (a) by marching from the left of both
556 // lists (zOrderListBeforePromote after inserting C and
557 // zOrderListAfterPromote). The first mismatch is at index 1 when we hit '-'
558 // and 'C'. That means we have neg z-order descendants. This is a problem if
559 // we have a background. Before promotion, this bg would get painted with
560 // the current layer (i.e., after the neg z-order descendants), but after
561 // promotion the bg would get painted before them. This is a stacking order
562 // violation and we can't promote. However, if we don't have a background,
563 // we would continue on to the second pass. When comparing from the right,
564 // we mismatch on '+' and 'C'. Since we hit 'C' on zOrderListAfterPromote,
565 // we know that the children are contiguous, and we will promote.
566 //
567 // In example (2), when marching from the left, we'll hit a mismatch again
568 // on the second element we look at. This time, since this element is an 'A'
569 // in zOrderListAfterPromote, this indicates that there is an extra layer
570 // (the 'A') mixed in with the children. This could cause a change in paint
571 // order if we promote, so we decide not to and break out of the loop. Note
572 // that if the current layer has a background, this would provide a second
573 // reason not to opt in, since again we have negative z-order children who
574 // would change paint order with respect to our background if we promoted.
575 //
576 // In example (3), the discontiguity of the negative z-order children causes
577 // us to fail early in our "FromBackground" pass when we try to compare '-'
578 // from zOrderListBeforePromote with 'x' in zOrderListAfterPromote.
579 //
580 // Finally in example (4), we would match 'xxAC' from the left, then stop
581 // since we hit 'C'. Then we would match 'x' from the right, and mismatch
582 // on '+' and 'C'. Since we're at 'C' on the zOrderListAfterPromote, we
583 // conclude that all the children are contiguous. Since there are no
584 // negative z-order children, a background layer is irrelevant in this case.
585 // We will opt in, keeping paint order constant.
586 static bool compareLayerListsBeforeAndAfterPromote(const RenderLayer* currentLay er,
587 const Vector<RenderLayer*>* posZOrderListBeforePromote,
588 const Vector<RenderLayer*>* negZOrderListBeforePromote,
589 const Vector<RenderLayer*>* posZOrderListAfterPromote,
590 const Vector<RenderLayer*>* negZOrderListAfterPromote,
591 const size_t sizeBeforePromote,
592 const size_t sizeAfterPromote,
593 const StackingOrderDirection direction)
594 {
595 for (size_t index = 0; index < sizeBeforePromote && index < sizeAfterPromote ; index++) {
596 const RenderLayer* layerBeforePromote = getStackingOrderElementAt(posZOr derListBeforePromote, negZOrderListBeforePromote, direction, index);
597 const RenderLayer* layerAfterPromote = getStackingOrderElementAt(posZOrd erListAfterPromote, negZOrderListAfterPromote, direction, index);
598
599 if (layerBeforePromote != layerAfterPromote) {
600 // If we find a mismatch, the only situation where we haven't
601 // necessarily changed paint order yet is if layerAfterPromote
602 // is currentLayer.
603 if (layerAfterPromote != currentLayer)
604 return false;
605
606 // Also, if the current layer has a background, then any
607 // negative z-order children will get between the background
608 // and the rest of the layer.
609 if (direction == FromBackground && currentLayer->renderer()->hasBack ground())
610 return false;
611 }
612
613 // To compare the sub-lists (a) and (c) from the comment above, we only
614 // need to march until we hit the currentLayer in the
615 // zOrderListAfterPromote from each direction.
616 if (layerAfterPromote == currentLayer)
617 break;
618 }
619
620 return true;
621 }
622
623 // Determine whether the current layer can be promoted to a stacking container,
624 // given its closest stacking context ancestor. We do this by computing what
625 // positive and negative z-order lists would look like before and after
626 // promotion, and ensuring that proper stacking order is preserved between the
627 // two sets of lists.
628 //
629 // For more details on how the lists will be compared, see the comment and
630 // examples for compareLayerListsBeforeAndAfterPromote().
631 void RenderLayer::updateCanBeStackingContainer(RenderLayer* ancestorStackingCont ext)
632 {
633 TRACE_EVENT0("blink", "RenderLayer::updateCanBeStackingContainer");
hartmanng 2013/05/02 14:04:01 should this be "blink" or "blink-rendering"?
634
635 ASSERT(!isStackingContext());
636
637 if (!m_canBePromotedToStackingContainerDirty || !acceleratedCompositingForOv erflowScrollEnabled())
638 return;
639
640 FrameView* frameView = renderer()->view()->frameView();
641 if (!frameView || !frameView->containsScrollableArea(this))
642 return;
643
644 OwnPtr<Vector<RenderLayer*> > posZOrderListBeforePromote;
645 OwnPtr<Vector<RenderLayer*> > negZOrderListBeforePromote;
646 OwnPtr<Vector<RenderLayer*> > posZOrderListAfterPromote;
647 OwnPtr<Vector<RenderLayer*> > negZOrderListAfterPromote;
648 size_t posZOrderListSizeBeforePromote, negZOrderListSizeBeforePromote, posZO rderListSizeAfterPromote, negZOrderListSizeAfterPromote;
649
650 collectBeforePromotionZOrderList(ancestorStackingContext, posZOrderListBefor ePromote, negZOrderListBeforePromote);
651 collectAfterPromotionZOrderList(ancestorStackingContext, posZOrderListAfterP romote, negZOrderListAfterPromote);
652
653 size_t sizeBeforePromote = 0;
654 if (posZOrderListBeforePromote)
655 sizeBeforePromote += posZOrderListBeforePromote->size();
656 if (negZOrderListBeforePromote)
657 sizeBeforePromote += negZOrderListBeforePromote->size();
658
659 size_t sizeAfterPromote = 0;
660 if (posZOrderListAfterPromote)
661 sizeAfterPromote += posZOrderListAfterPromote->size();
662 if (negZOrderListAfterPromote)
663 sizeAfterPromote += negZOrderListAfterPromote->size();
664
665 bool canPromote = compareLayerListsBeforeAndAfterPromote(this, posZOrderList BeforePromote.get(), negZOrderListBeforePromote.get(),
666 posZOrderListAfterPromote.get(), negZOrderListAfterPromote.get(),
667 sizeBeforePromote, sizeAfterPromote, FromBackground)
668 && compareLayerListsBeforeAndAfterPromote(this, posZOrderListBeforePromo te.get(), negZOrderListBeforePromote.get(),
669 posZOrderListAfterPromote.get(), negZOrderListAfterPromote.get(),
670 sizeBeforePromote, sizeAfterPromote, FromForeground);
671
672 bool didUpdate = (canPromote != m_canBePromotedToStackingContainer);
673
674 m_canBePromotedToStackingContainer = canPromote;
675 m_canBePromotedToStackingContainerDirty = false;
676 }
677
678 // Compute what positive and negative z-order lists would look like before and
679 // after promotion, so we can later ensure that proper stacking order is
680 // preserved between the two sets of lists.
681 //
682 // A few examples:
683 // c = currentLayer
684 // - = negative z-order child of currentLayer
685 // + = positive z-order child of currentLayer
686 // a = positioned ancestor of currentLayer
687 // x = any other RenderLayer in the list
688 //
689 // (a) xxxxx-----++a+++x
690 // (b) xxx-----c++++++xx
691 //
692 //
693 // Normally the current layer would be painted in the normal flow list if it
694 // doesn't already appear in the positive z-order list. However, in the case
695 // that the layer has a positioned ancestor, it will paint directly after the
696 // positioned ancestor. In example (a), the current layer would be painted in
697 // the middle of its own positive z-order children, so promoting would cause a
698 // change in paint order (since a promoted layer will paint all of its positive
699 // z-order children strictly after it paints itself).
700 //
701 // In example (b), it is ok to promote the current layer only if it does not
702 // have a background. If it has a background, the background gets painted before
703 // the layer's negative z-order children, so again, a promotion would cause a
704 // change in paint order (causing the background to get painted after the
705 // negative z-order children instead of before).
649 void RenderLayer::collectBeforePromotionZOrderList(RenderLayer* ancestorStacking Context, OwnPtr<Vector<RenderLayer*> >& posZOrderListBeforePromote, OwnPtr<Vecto r<RenderLayer*> >& negZOrderListBeforePromote) 706 void RenderLayer::collectBeforePromotionZOrderList(RenderLayer* ancestorStacking Context, OwnPtr<Vector<RenderLayer*> >& posZOrderListBeforePromote, OwnPtr<Vecto r<RenderLayer*> >& negZOrderListBeforePromote)
650 { 707 {
651 // FIXME: TemporaryChange should support bit fields. 708 // We can't use TemporaryChange<> here since m_needsCompositedScrolling and
709 // m_isNormalFlowOnly are both bitfields, so we have to do it the
710 // old-fashioned way.
652 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling; 711 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling;
653 bool oldIsNormalFlowOnly = m_isNormalFlowOnly; 712 bool oldIsNormalFlowOnly = m_isNormalFlowOnly;
654 713
655 m_needsCompositedScrolling = false; 714 m_needsCompositedScrolling = false;
656 m_isNormalFlowOnly = shouldBeNormalFlowOnly(); 715 m_isNormalFlowOnly = shouldBeNormalFlowOnly();
657 716
658 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde rListBeforePromote, negZOrderListBeforePromote, 0); 717 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde rListBeforePromote, negZOrderListBeforePromote, 0);
659 718
660 m_needsCompositedScrolling = oldNeedsCompositedScrolling; 719 m_needsCompositedScrolling = oldNeedsCompositedScrolling;
661 m_isNormalFlowOnly = oldIsNormalFlowOnly; 720 m_isNormalFlowOnly = oldIsNormalFlowOnly;
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 if (curr == ancestorStackingContainer) 1114 if (curr == ancestorStackingContainer)
1056 return; 1115 return;
1057 } 1116 }
1058 } 1117 }
1059 1118
1060 bool RenderLayer::canBeStackingContainer() const 1119 bool RenderLayer::canBeStackingContainer() const
1061 { 1120 {
1062 if (isStackingContext() || !ancestorStackingContainer()) 1121 if (isStackingContext() || !ancestorStackingContainer())
1063 return true; 1122 return true;
1064 1123
1065 return m_descendantsAreContiguousInStackingOrder; 1124 return m_canBePromotedToStackingContainer;
1066 } 1125 }
1067 1126
1068 void RenderLayer::setHasVisibleContent() 1127 void RenderLayer::setHasVisibleContent()
1069 { 1128 {
1070 if (m_hasVisibleContent && !m_visibleContentStatusDirty) { 1129 if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
1071 ASSERT(!parent() || parent()->hasVisibleDescendant()); 1130 ASSERT(!parent() || parent()->hasVisibleDescendant());
1072 return; 1131 return;
1073 } 1132 }
1074 1133
1075 m_visibleContentStatusDirty = false; 1134 m_visibleContentStatusDirty = false;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 { 1170 {
1112 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 1171 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1113 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendan t()) 1172 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendan t())
1114 break; 1173 break;
1115 1174
1116 layer->m_hasVisibleDescendant = true; 1175 layer->m_hasVisibleDescendant = true;
1117 layer->m_visibleDescendantStatusDirty = false; 1176 layer->m_visibleDescendantStatusDirty = false;
1118 } 1177 }
1119 } 1178 }
1120 1179
1121 void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* o utOfFlowDescendantContainingBlocks) 1180 void RenderLayer::updateHasOutOfFlowPositionedDescendant(HashSet<const RenderObj ect*>* containingBlocks)
1122 { 1181 {
1123 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) { 1182 const bool hadOutOfFlowPositionedDescendant = hasOutOfFlowPositionedDescenda nt();
1124 const bool hadVisibleDescendant = m_hasVisibleDescendant; 1183 m_hasOutOfFlowPositionedDescendant = false;
1125 const bool hadOutOfFlowPositionedDescendant = m_hasOutOfFlowPositionedDe scendant;
1126 1184
1185 HashSet<const RenderObject*> childContainingBlocks;
1186 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1187 childContainingBlocks.clear();
1188 child->updateHasOutOfFlowPositionedDescendant(&childContainingBlocks);
1189
1190 const bool childIsOutOfFlowPositioned = child->renderer()
1191 && child->renderer()->isOutOfFlowPositioned()
1192 && (child->hasVisibleDescendant() || child->hasVisibleContent());
1193
1194 if (childIsOutOfFlowPositioned)
1195 childContainingBlocks.add(child->renderer()->containingBlock());
1196
1197 size_t numContainingBlocks = childContainingBlocks.size();
1198 childContainingBlocks.remove(renderer());
hartmanng 2013/05/02 14:04:01 this might deserve a comment
1199
1200 if (containingBlocks && !childContainingBlocks.isEmpty()) {
1201 HashSet<const RenderObject*>::const_iterator it = childContainingBlo cks.begin();
1202 for (; it != childContainingBlocks.end(); ++it)
1203 containingBlocks->add(*it);
1204 }
1205
1206 m_hasOutOfFlowPositionedDescendant |= !childContainingBlocks.isEmpty();
1207 }
1208
1209 if (m_hasOutOfFlowPositionedDescendant != hadOutOfFlowPositionedDescendant)
1210 compositor()->setNeedsUpdateCompositingRequirementsState();
1211 }
1212
1213 void RenderLayer::updateDescendantDependentFlags()
1214 {
1215 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty) {
1127 m_hasVisibleDescendant = false; 1216 m_hasVisibleDescendant = false;
1128 m_hasSelfPaintingLayerDescendant = false; 1217 m_hasSelfPaintingLayerDescendant = false;
1129 m_hasOutOfFlowPositionedDescendant = false;
1130 1218
1131 HashSet<const RenderObject*> childOutOfFlowDescendantContainingBlocks;
1132 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { 1219 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) {
1133 childOutOfFlowDescendantContainingBlocks.clear(); 1220 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 1221
1146 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_h asVisibleDescendant; 1222 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_h asVisibleDescendant;
1147 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() | | child->hasSelfPaintingLayerDescendant(); 1223 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() | | child->hasSelfPaintingLayerDescendant();
1148 bool hasOutOfFlowPositionedDescendant = hasVisibleDescendant && (!ch ildOutOfFlowDescendantContainingBlocks.isEmpty() || child->hasOutOfFlowPositione dDescendant());
1149 1224
1150 m_hasVisibleDescendant |= hasVisibleDescendant; 1225 m_hasVisibleDescendant |= hasVisibleDescendant;
1151 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant; 1226 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
1152 m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescenda nt;
1153 1227
1154 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && m_ hasOutOfFlowPositionedDescendant) 1228 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant)
1155 break; 1229 break;
1156 } 1230 }
1157 1231
1158 if (outOfFlowDescendantContainingBlocks && renderer())
1159 outOfFlowDescendantContainingBlocks->remove(renderer());
1160
1161 m_visibleDescendantStatusDirty = false; 1232 m_visibleDescendantStatusDirty = false;
1162 m_hasSelfPaintingLayerDescendantDirty = false; 1233 m_hasSelfPaintingLayerDescendantDirty = false;
1163 m_hasOutOfFlowPositionedDescendantDirty = false;
1164
1165 if (m_hasVisibleDescendant != hadVisibleDescendant || m_hasOutOfFlowPosi tionedDescendant != hadOutOfFlowPositionedDescendant)
1166 updateNeedsCompositedScrolling();
1167 } 1234 }
1168 1235
1169 if (m_visibleContentStatusDirty) { 1236 if (m_visibleContentStatusDirty) {
1170 const bool hadVisibleContent = m_hasVisibleContent;
1171 if (renderer()->style()->visibility() == VISIBLE) 1237 if (renderer()->style()->visibility() == VISIBLE)
1172 m_hasVisibleContent = true; 1238 m_hasVisibleContent = true;
1173 else { 1239 else {
1174 // layer may be hidden but still have some visible content, check fo r this 1240 // layer may be hidden but still have some visible content, check fo r this
1175 m_hasVisibleContent = false; 1241 m_hasVisibleContent = false;
1176 RenderObject* r = renderer()->firstChild(); 1242 RenderObject* r = renderer()->firstChild();
1177 while (r) { 1243 while (r) {
1178 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { 1244 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
1179 m_hasVisibleContent = true; 1245 m_hasVisibleContent = true;
1180 break; 1246 break;
1181 } 1247 }
1182 if (r->firstChild() && !r->hasLayer()) 1248 if (r->firstChild() && !r->hasLayer())
1183 r = r->firstChild(); 1249 r = r->firstChild();
1184 else if (r->nextSibling()) 1250 else if (r->nextSibling())
1185 r = r->nextSibling(); 1251 r = r->nextSibling();
1186 else { 1252 else {
1187 do { 1253 do {
1188 r = r->parent(); 1254 r = r->parent();
1189 if (r == renderer()) 1255 if (r == renderer())
1190 r = 0; 1256 r = 0;
1191 } while (r && !r->nextSibling()); 1257 } while (r && !r->nextSibling());
1192 if (r) 1258 if (r)
1193 r = r->nextSibling(); 1259 r = r->nextSibling();
1194 } 1260 }
1195 } 1261 }
1196 } 1262 }
1197 m_visibleContentStatusDirty = false; 1263 m_visibleContentStatusDirty = false;
1198 if (hadVisibleContent != m_hasVisibleContent)
1199 updateNeedsCompositedScrolling();
1200 } 1264 }
1201 } 1265 }
1202 1266
1203 void RenderLayer::dirty3DTransformedDescendantStatus() 1267 void RenderLayer::dirty3DTransformedDescendantStatus()
1204 { 1268 {
1205 RenderLayer* curr = ancestorStackingContainer(); 1269 RenderLayer* curr = ancestorStackingContainer();
1206 if (curr) 1270 if (curr)
1207 curr->m_3DTransformedDescendantStatusDirty = true; 1271 curr->m_3DTransformedDescendantStatusDirty = true;
1208 1272
1209 // This propagates up through preserve-3d hierarchies to the enclosing flatt ening layer. 1273 // 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); 1824 child->setParent(this);
1761 1825
1762 if (child->isNormalFlowOnly()) 1826 if (child->isNormalFlowOnly())
1763 dirtyNormalFlowList(); 1827 dirtyNormalFlowList();
1764 1828
1765 if (!child->isNormalFlowOnly() || child->firstChild()) { 1829 if (!child->isNormalFlowOnly() || child->firstChild()) {
1766 // Dirty the z-order list in which we are contained. The ancestorStackin gContainer() can be null in the 1830 // 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 1831 // 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. 1832 // off dirty in that case anyway.
1769 child->dirtyStackingContainerZOrderLists(); 1833 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 } 1834 }
1781 1835
1782 child->updateDescendantDependentFlags(); 1836 child->updateDescendantDependentFlags();
1783 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) 1837 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
1784 setAncestorChainHasVisibleDescendant(); 1838 setAncestorChainHasVisibleDescendant();
1785 1839
1786 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) 1840 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
1787 setAncestorChainHasSelfPaintingLayerDescendant(); 1841 setAncestorChainHasSelfPaintingLayerDescendant();
1788 1842
1789 if (child->renderer() && (child->renderer()->isOutOfFlowPositioned() || chil d->hasOutOfFlowPositionedDescendant())) 1843 if (child->renderer() && (child->renderer()->isOutOfFlowPositioned() || chil d->hasOutOfFlowPositionedDescendant()))
1790 setAncestorChainHasOutOfFlowPositionedDescendant(child->renderer()->cont ainingBlock()); 1844 compositor()->setNeedsUpdateCompositingRequirementsState();
1791 1845
1792 compositor()->layerWasAdded(this, child); 1846 compositor()->layerWasAdded(this, child);
1793 } 1847 }
1794 1848
1795 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) 1849 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1796 { 1850 {
1797 if (!renderer()->documentBeingDestroyed()) 1851 if (!renderer()->documentBeingDestroyed())
1798 compositor()->layerWillBeRemoved(this, oldChild); 1852 compositor()->layerWillBeRemoved(this, oldChild);
1799 1853
1800 // remove the child 1854 // remove the child
1801 if (oldChild->previousSibling()) 1855 if (oldChild->previousSibling())
1802 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); 1856 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1803 if (oldChild->nextSibling()) 1857 if (oldChild->nextSibling())
1804 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()) ; 1858 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()) ;
1805 1859
1806 if (m_first == oldChild) 1860 if (m_first == oldChild)
1807 m_first = oldChild->nextSibling(); 1861 m_first = oldChild->nextSibling();
1808 if (m_last == oldChild) 1862 if (m_last == oldChild)
1809 m_last = oldChild->previousSibling(); 1863 m_last = oldChild->previousSibling();
1810 1864
1811 if (oldChild->isNormalFlowOnly()) 1865 if (oldChild->isNormalFlowOnly())
1812 dirtyNormalFlowList(); 1866 dirtyNormalFlowList();
1813 if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) { 1867 if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) {
1814 // Dirty the z-order list in which we are contained. When called via th e 1868 // 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 1869 // 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. 1870 // from the main layer tree, so we need to null-check the |stackingConta iner| value.
1817 oldChild->dirtyStackingContainerZOrderLists(); 1871 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 } 1872 }
1831 1873
1832 if ((oldChild->renderer() && oldChild->renderer()->isOutOfFlowPositioned()) || oldChild->hasOutOfFlowPositionedDescendant())
1833 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
1834
1835 oldChild->setPreviousSibling(0); 1874 oldChild->setPreviousSibling(0);
1836 oldChild->setNextSibling(0); 1875 oldChild->setNextSibling(0);
1837 oldChild->setParent(0); 1876 oldChild->setParent(0);
1838 1877
1839 oldChild->updateDescendantDependentFlags(); 1878 oldChild->updateDescendantDependentFlags();
1879 if ((oldChild->renderer() && oldChild->renderer()->isOutOfFlowPositioned()) || oldChild->hasOutOfFlowPositionedDescendant())
1880 compositor()->setNeedsUpdateCompositingRequirementsState();
1881
1840 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) 1882 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1841 dirtyAncestorChainVisibleDescendantStatus(); 1883 dirtyAncestorChainVisibleDescendantStatus();
1842 1884
1843 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescend ant()) 1885 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescend ant())
1844 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 1886 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1845 1887
1846 return oldChild; 1888 return oldChild;
1847 } 1889 }
1848 1890
1849 void RenderLayer::removeOnlyThisLayer() 1891 void RenderLayer::removeOnlyThisLayer()
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2044 rect.move(-delta.x(), -delta.y()); 2086 rect.move(-delta.x(), -delta.y());
2045 } 2087 }
2046 2088
2047 bool RenderLayer::usesCompositedScrolling() const 2089 bool RenderLayer::usesCompositedScrolling() const
2048 { 2090 {
2049 return isComposited() && backing()->scrollingLayer(); 2091 return isComposited() && backing()->scrollingLayer();
2050 } 2092 }
2051 2093
2052 bool RenderLayer::needsCompositedScrolling() const 2094 bool RenderLayer::needsCompositedScrolling() const
2053 { 2095 {
2096 switch (m_forceNeedsCompositedScrolling) {
2097 case DoNotForceCompositedScrolling:
2098 return m_needsCompositedScrolling;
2099 case ForceCompositedScrollingOn:
2100 return true;
2101 case ForceCompositedScrollingOff:
2102 return false;
2103 }
2104
2054 return m_needsCompositedScrolling; 2105 return m_needsCompositedScrolling;
2055 } 2106 }
2056 2107
2057 void RenderLayer::updateNeedsCompositedScrolling() 2108 void RenderLayer::updateNeedsCompositedScrolling()
2058 { 2109 {
2059 bool needsCompositedScrolling = false; 2110 bool needsCompositedScrolling = false;
2060 2111
2061 FrameView* frameView = renderer()->view()->frameView(); 2112 FrameView* frameView = renderer()->view()->frameView();
2062 if (frameView && frameView->containsScrollableArea(this)) { 2113 if (frameView && frameView->containsScrollableArea(this) && acceleratedCompo sitingForOverflowScrollEnabled()) {
2063 updateDescendantDependentFlags(); 2114 if (isStackingContext()) {
2115 needsCompositedScrolling = true;
2116 } else {
2117 RenderLayer* stackingContext = ancestorStackingContext();
2118 updateCanBeStackingContainer(stackingContext);
2064 2119
2065 bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScro llEnabled() 2120 bool forceUseCompositedScrolling = canBeStackingContainer() && !hasO utOfFlowPositionedDescendant();
2066 && canBeStackingContainer()
2067 && !hasOutOfFlowPositionedDescendant();
2068 2121
2069 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) 2122 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
hartmanng 2013/05/02 14:04:01 is this macro required anymore?
2070 needsCompositedScrolling = forceUseCompositedScrolling || renderer()->st yle()->useTouchOverflowScrolling(); 2123 needsCompositedScrolling = forceUseCompositedScrolling || renderer() ->style()->useTouchOverflowScrolling();
2071 #else 2124 #else
2072 needsCompositedScrolling = forceUseCompositedScrolling; 2125 needsCompositedScrolling = forceUseCompositedScrolling;
2073 #endif 2126 #endif
2127 }
2128
2074 // We gather a boolean value for use with Google UMA histograms to 2129 // We gather a boolean value for use with Google UMA histograms to
2075 // quantify the actual effects of a set of patches attempting to 2130 // quantify the actual effects of a set of patches attempting to
2076 // relax composited scrolling requirements, thereby increasing the 2131 // relax composited scrolling requirements, thereby increasing the
2077 // number of composited overflow divs. 2132 // number of composited overflow divs.
2078 if (acceleratedCompositingForOverflowScrollEnabled()) 2133 if (acceleratedCompositingForOverflowScrollEnabled())
2079 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScro lling", needsCompositedScrolling, 2); 2134 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScro lling", needsCompositedScrolling, 2);
2080 } 2135 }
2081 2136
2082 if (m_needsCompositedScrolling == needsCompositedScrolling) 2137 if (m_needsCompositedScrolling == needsCompositedScrolling)
2083 return; 2138 return;
2084 2139
2085 m_needsCompositedScrolling = needsCompositedScrolling; 2140 m_needsCompositedScrolling = needsCompositedScrolling;
2086 2141
2142 // Note, the z-order lists may need to be rebuilt, but our code guarantees
2143 // that we have not affected stacking, so we will not dirty
2144 // m_canBePromotedToStackingContainer for either us or our stacking context
2145 // or container.
2146 didUpdateNeedsCompositedScrolling();
2147 }
2148
2149 void RenderLayer::setForceNeedsCompositedScrolling(RenderLayer::ForceNeedsCompos itedScrollingMode mode)
2150 {
2151 m_forceNeedsCompositedScrolling = mode;
2152 didUpdateNeedsCompositedScrolling();
2153 }
2154
2155 void RenderLayer::didUpdateNeedsCompositedScrolling()
2156 {
2087 updateIsNormalFlowOnly(); 2157 updateIsNormalFlowOnly();
2088 updateSelfPaintingLayer(); 2158 updateSelfPaintingLayer();
2089 2159
2090 if (isStackingContainer()) 2160 if (isStackingContainer())
2091 dirtyZOrderLists(); 2161 dirtyZOrderLists();
2092 else 2162 else
2093 clearZOrderLists(); 2163 clearZOrderLists();
2094 2164
2095 dirtyStackingContainerZOrderLists(); 2165 dirtyStackingContainerZOrderLists();
2096 2166
(...skipping 3503 matching lines...) Expand 10 before | Expand all | Expand 10 after
5600 { 5670 {
5601 ASSERT(m_layerListMutationAllowed); 5671 ASSERT(m_layerListMutationAllowed);
5602 ASSERT(isStackingContainer()); 5672 ASSERT(isStackingContainer());
5603 5673
5604 if (m_posZOrderList) 5674 if (m_posZOrderList)
5605 m_posZOrderList->clear(); 5675 m_posZOrderList->clear();
5606 if (m_negZOrderList) 5676 if (m_negZOrderList)
5607 m_negZOrderList->clear(); 5677 m_negZOrderList->clear();
5608 m_zOrderListsDirty = true; 5678 m_zOrderListsDirty = true;
5609 5679
5610 m_descendantsAreContiguousInStackingOrderDirty = true; 5680 m_canBePromotedToStackingContainerDirty = true;
5681 compositor()->setNeedsUpdateCompositingRequirementsState();
5611 5682
5612 if (!renderer()->documentBeingDestroyed()) { 5683 if (!renderer()->documentBeingDestroyed()) {
5613 compositor()->setCompositingLayersNeedRebuild(); 5684 compositor()->setCompositingLayersNeedRebuild();
5614 if (acceleratedCompositingForOverflowScrollEnabled()) 5685 if (acceleratedCompositingForOverflowScrollEnabled())
5615 compositor()->setShouldReevaluateCompositingAfterLayout(); 5686 compositor()->setShouldReevaluateCompositingAfterLayout();
5616 } 5687 }
5617 } 5688 }
5618 5689
5619 void RenderLayer::dirtyStackingContainerZOrderLists() 5690 void RenderLayer::dirtyStackingContainerZOrderLists()
5620 { 5691 {
(...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) 5776 void RenderLayer::collectLayers(bool includeHiddenLayers, CollectLayersBehavior behavior, OwnPtr<Vector<RenderLayer*> >& posBuffer, OwnPtr<Vector<RenderLayer*> >& negBuffer, const RenderLayer* layerToForceAsStackingContainer)
5706 { 5777 {
5707 if (isInTopLayer()) 5778 if (isInTopLayer())
5708 return; 5779 return;
5709 5780
5710 updateDescendantDependentFlags(); 5781 updateDescendantDependentFlags();
5711 5782
5712 bool isStacking = false; 5783 bool isStacking = false;
5713 5784
5714 switch (behavior) { 5785 switch (behavior) {
5715 case StopAtStackingContexts: 5786 case StopAtStackingContexts:
5716 isStacking = (this == layerToForceAsStackingContainer) || isStacking Context(); 5787 isStacking = (this == layerToForceAsStackingContainer) || isStackingCont ext();
5717 break; 5788 break;
5718 5789
5719 case StopAtStackingContainers: 5790 case StopAtStackingContainers:
5720 isStacking = (this == layerToForceAsStackingContainer) || isStacking Container(); 5791 isStacking = (this == layerToForceAsStackingContainer) || isStackingCon tainer();
5721 break; 5792 break;
5793 }
5794
5795 // This value could be affected by opt in. What we really need to know is
5796 // are you normal flow only, regardless of your opt in status. This is very
5797 // similar to asking if a layer is a stacking context rather than a
5798 // stacking container.
5799 bool isNormalFlowWithoutCompositedScrolling = isNormalFlowOnly();
5800 if (this != layerToForceAsStackingContainer && behavior == StopAtStackingCon texts) {
5801 TemporaryChange<ForceNeedsCompositedScrollingMode> forceOff(m_forceNeeds CompositedScrolling, ForceCompositedScrollingOff);
5802 isNormalFlowWithoutCompositedScrolling = shouldBeNormalFlowOnly();
5722 } 5803 }
5723 5804
5724 // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists. 5805 // 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)); 5806 bool includeHiddenLayer = includeHiddenLayers || (m_hasVisibleContent || (m_ hasVisibleDescendant && isStacking));
5726 if (includeHiddenLayer && !isNormalFlowOnly() && !isOutOfFlowRenderFlowThrea d()) { 5807 if (includeHiddenLayer && !isNormalFlowWithoutCompositedScrolling && !isOutO fFlowRenderFlowThread()) {
5727 // Determine which buffer the child should be in. 5808 // Determine which buffer the child should be in.
5728 OwnPtr<Vector<RenderLayer*> >& buffer = (zIndex() >= 0) ? posBuffer : ne gBuffer; 5809 OwnPtr<Vector<RenderLayer*> >& buffer = (zIndex() >= 0) ? posBuffer : ne gBuffer;
5729 5810
5730 // Create the buffer if it doesn't exist yet. 5811 // Create the buffer if it doesn't exist yet.
5731 if (!buffer) 5812 if (!buffer)
5732 buffer = adoptPtr(new Vector<RenderLayer*>); 5813 buffer = adoptPtr(new Vector<RenderLayer*>);
5733 5814
5734 // Append ourselves at the end of the appropriate buffer. 5815 // Append ourselves at the end of the appropriate buffer.
5735 buffer->append(this); 5816 buffer->append(this);
5736 } 5817 }
5737 5818
5738 // Recur into our children to collect more layers, but only if we don't esta blish 5819 // Recur into our children to collect more layers, but only if we don't esta blish
5739 // a stacking context/container. 5820 // a stacking context/container.
5740 if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) { 5821 if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) {
5741 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { 5822 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) {
5742 // Ignore reflections. 5823 // Ignore reflections.
5743 if (!m_reflection || reflectionLayer() != child) 5824 if (!m_reflection || reflectionLayer() != child)
5744 child->collectLayers(includeHiddenLayers, behavior, posBuffer, n egBuffer, layerToForceAsStackingContainer); 5825 child->collectLayers(includeHiddenLayers, behavior, posBuffer, n egBuffer, layerToForceAsStackingContainer);
5745 } 5826 }
5746 } 5827 }
5747 } 5828 }
5748 5829
5749 void RenderLayer::updateLayerListsIfNeeded() 5830 void RenderLayer::updateLayerListsIfNeeded()
5750 { 5831 {
5751 bool shouldUpdateDescendantsAreContiguousInStackingOrder = acceleratedCompos itingForOverflowScrollEnabled() && isStackingContext() && (m_zOrderListsDirty || m_normalFlowListDirty) && m_descendantsAreContiguousInStackingOrderDirty;
5752 updateZOrderLists(); 5832 updateZOrderLists();
5753 updateNormalFlowList(); 5833 updateNormalFlowList();
5754 5834
5755 if (RenderLayer* reflectionLayer = this->reflectionLayer()) { 5835 if (RenderLayer* reflectionLayer = this->reflectionLayer()) {
5756 reflectionLayer->updateZOrderLists(); 5836 reflectionLayer->updateZOrderLists();
5757 reflectionLayer->updateNormalFlowList(); 5837 reflectionLayer->updateNormalFlowList();
5758 } 5838 }
5759
5760 if (shouldUpdateDescendantsAreContiguousInStackingOrder) {
5761 updateDescendantsAreContiguousInStackingOrder();
5762 // The above function can cause us to update m_needsCompositedScrolling
5763 // and dirty our layer lists. Refresh them if necessary.
5764 updateZOrderLists();
5765 updateNormalFlowList();
5766 }
5767 } 5839 }
5768 5840
5769 void RenderLayer::repaintIncludingDescendants() 5841 void RenderLayer::repaintIncludingDescendants()
5770 { 5842 {
5771 renderer()->repaint(); 5843 renderer()->repaint();
5772 for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling()) 5844 for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
5773 curr->repaintIncludingDescendants(); 5845 curr->repaintIncludingDescendants();
5774 } 5846 }
5775 5847
5776 void RenderLayer::setBackingNeedsRepaint() 5848 void RenderLayer::setBackingNeedsRepaint()
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
5936 return false; 6008 return false;
5937 } 6009 }
5938 6010
5939 void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle) 6011 void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle)
5940 { 6012 {
5941 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE; 6013 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
5942 if (oldVisibility == renderer()->style()->visibility() || !renderer()->isOut OfFlowPositioned()) 6014 if (oldVisibility == renderer()->style()->visibility() || !renderer()->isOut OfFlowPositioned())
5943 return; 6015 return;
5944 6016
5945 if (renderer()->style()->visibility() == VISIBLE) 6017 if (renderer()->style()->visibility() == VISIBLE)
5946 setAncestorChainHasOutOfFlowPositionedDescendant(renderer()->containingB lock()); 6018 compositor()->setNeedsUpdateCompositingRequirementsState();
5947 else
5948 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
5949 } 6019 }
5950 6020
5951 void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldS tyle) 6021 void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldS tyle)
5952 { 6022 {
5953 bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false; 6023 bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false;
5954 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE; 6024 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
5955 int oldZIndex = oldStyle ? oldStyle->zIndex() : 0; 6025 int oldZIndex = oldStyle ? oldStyle->zIndex() : 0;
5956 6026
5957 // FIXME: RenderLayer already handles visibility changes through our visibli ty dirty bits. This logic could 6027 // FIXME: RenderLayer already handles visibility changes through our visibli ty dirty bits. This logic could
5958 // likely be folded along with the rest. 6028 // likely be folded along with the rest.
5959 bool isStackingContext = this->isStackingContext(); 6029 bool isStackingContext = this->isStackingContext();
5960 if (isStackingContext == wasStackingContext && oldVisibility == renderer()-> style()->visibility() && oldZIndex == renderer()->style()->zIndex()) 6030 if (isStackingContext == wasStackingContext && oldVisibility == renderer()-> style()->visibility() && oldZIndex == renderer()->style()->zIndex())
5961 return; 6031 return;
5962 6032
5963 dirtyStackingContainerZOrderLists(); 6033 dirtyStackingContainerZOrderLists();
5964 6034
5965 if (isStackingContainer()) 6035 if (isStackingContainer())
5966 dirtyZOrderLists(); 6036 dirtyZOrderLists();
5967 else 6037 else
5968 clearZOrderLists(); 6038 clearZOrderLists();
5969 6039
5970 updateNeedsCompositedScrolling(); 6040 // FIXME: This should be done via a function so that we can flip a bit on
6041 // the renderview allowing us to skip updates in frames where no comp-scroll
6042 // state actually changed.
6043 compositor()->setNeedsUpdateCompositingRequirementsState();
5971 } 6044 }
5972 6045
5973 static bool overflowRequiresScrollbar(EOverflow overflow) 6046 static bool overflowRequiresScrollbar(EOverflow overflow)
5974 { 6047 {
5975 return overflow == OSCROLL; 6048 return overflow == OSCROLL;
5976 } 6049 }
5977 6050
5978 static bool overflowDefinesAutomaticScrollbar(EOverflow overflow) 6051 static bool overflowDefinesAutomaticScrollbar(EOverflow overflow)
5979 { 6052 {
5980 return overflow == OAUTO || overflow == OOVERLAY; 6053 return overflow == OAUTO || overflow == OOVERLAY;
(...skipping 28 matching lines...) Expand all
6009 6082
6010 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) { 6083 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) {
6011 ASSERT(hasVerticalScrollbar()); 6084 ASSERT(hasVerticalScrollbar());
6012 m_vBar->setEnabled(true); 6085 m_vBar->setEnabled(true);
6013 } 6086 }
6014 6087
6015 if (!m_scrollDimensionsDirty) 6088 if (!m_scrollDimensionsDirty)
6016 updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollab leVerticalOverflow()); 6089 updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollab leVerticalOverflow());
6017 } 6090 }
6018 6091
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) 6092 void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle)
6050 { 6093 {
6051 bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsoluteP osition || oldStyle->position() == FixedPosition); 6094 if (!oldStyle || (renderer()->style()->position() != oldStyle->position()))
6052 bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned(); 6095 compositor()->setNeedsUpdateCompositingRequirementsState();
6053 if (parent() && isOutOfFlowPositioned != wasOutOfFlowPositioned) {
6054 if (isOutOfFlowPositioned)
6055 parent()->setAncestorChainHasOutOfFlowPositionedDescendant(renderer( )->containingBlock());
6056 else
6057 parent()->dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus() ;
6058 }
6059 } 6096 }
6060 6097
6061 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newS tyle) 6098 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newS tyle)
6062 { 6099 {
6063 ASSERT(newStyle); 6100 ASSERT(newStyle);
6064 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter(); 6101 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter();
6065 } 6102 }
6066 6103
6067 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const 6104 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
6068 { 6105 {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
6206 if (HTMLFrameOwnerElement* owner = frame->ownerElement()) 6243 if (HTMLFrameOwnerElement* owner = frame->ownerElement())
6207 isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToH itTesting(); 6244 isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToH itTesting();
6208 6245
6209 bool updatedScrollableAreaSet = false; 6246 bool updatedScrollableAreaSet = false;
6210 if (hasOverflow && isVisibleToHitTest) 6247 if (hasOverflow && isVisibleToHitTest)
6211 updatedScrollableAreaSet = frameView->addScrollableArea(this); 6248 updatedScrollableAreaSet = frameView->addScrollableArea(this);
6212 else 6249 else
6213 updatedScrollableAreaSet = frameView->removeScrollableArea(this); 6250 updatedScrollableAreaSet = frameView->removeScrollableArea(this);
6214 6251
6215 if (updatedScrollableAreaSet) 6252 if (updatedScrollableAreaSet)
6216 updateNeedsCompositedScrolling(); 6253 compositor()->setNeedsUpdateCompositingRequirementsState();
6217 } 6254 }
6218 6255
6219 void RenderLayer::updateScrollCornerStyle() 6256 void RenderLayer::updateScrollCornerStyle()
6220 { 6257 {
6221 RenderObject* actualRenderer = rendererForScrollbar(renderer()); 6258 RenderObject* actualRenderer = rendererForScrollbar(renderer());
6222 RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer- >getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->st yle()) : PassRefPtr<RenderStyle>(0); 6259 RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer- >getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->st yle()) : PassRefPtr<RenderStyle>(0);
6223 if (corner) { 6260 if (corner) {
6224 if (!m_scrollCorner) { 6261 if (!m_scrollCorner) {
6225 m_scrollCorner = RenderScrollbarPart::createAnonymous(renderer()->do cument()); 6262 m_scrollCorner = RenderScrollbarPart::createAnonymous(renderer()->do cument());
6226 m_scrollCorner->setParent(renderer()); 6263 m_scrollCorner->setParent(renderer());
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
6457 } 6494 }
6458 } 6495 }
6459 6496
6460 void showLayerTree(const WebCore::RenderObject* renderer) 6497 void showLayerTree(const WebCore::RenderObject* renderer)
6461 { 6498 {
6462 if (!renderer) 6499 if (!renderer)
6463 return; 6500 return;
6464 showLayerTree(renderer->enclosingLayer()); 6501 showLayerTree(renderer->enclosingLayer());
6465 } 6502 }
6466 #endif 6503 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698