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

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: Added annotations describing how this patch will be split. 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
« no previous file with comments | « Source/core/rendering/RenderLayer.h ('k') | Source/core/rendering/RenderLayerCompositor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * 3 *
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5 * 5 *
6 * Other contributors: 6 * Other contributors:
7 * Robert O'Callahan <roc+@cs.cmu.edu> 7 * Robert O'Callahan <roc+@cs.cmu.edu>
8 * David Baron <dbaron@fas.harvard.edu> 8 * David Baron <dbaron@fas.harvard.edu>
9 * Christian Biesinger <cbiesinger@web.de> 9 * Christian Biesinger <cbiesinger@web.de>
10 * Randall Jesup <rjesup@wgate.com> 10 * Randall Jesup <rjesup@wgate.com>
(...skipping 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 // PATCH 2
73 #include "core/platform/chromium/TraceEvent.h"
72 #include "core/platform/FloatConversion.h" 74 #include "core/platform/FloatConversion.h"
73 #include "core/platform/HistogramSupport.h" 75 #include "core/platform/HistogramSupport.h"
74 #include "core/platform/PlatformMouseEvent.h" 76 #include "core/platform/PlatformMouseEvent.h"
75 #include "core/platform/ScrollAnimator.h" 77 #include "core/platform/ScrollAnimator.h"
76 #include "core/platform/Scrollbar.h" 78 #include "core/platform/Scrollbar.h"
77 #include "core/platform/ScrollbarTheme.h" 79 #include "core/platform/ScrollbarTheme.h"
78 #include "core/platform/graphics/FloatPoint3D.h" 80 #include "core/platform/graphics/FloatPoint3D.h"
79 #include "core/platform/graphics/FloatRect.h" 81 #include "core/platform/graphics/FloatRect.h"
80 #include "core/platform/graphics/Gradient.h" 82 #include "core/platform/graphics/Gradient.h"
81 #include "core/platform/graphics/GraphicsContext.h" 83 #include "core/platform/graphics/GraphicsContext.h"
(...skipping 24 matching lines...) Expand all
106 #include "core/rendering/RenderMarquee.h" 108 #include "core/rendering/RenderMarquee.h"
107 #include "core/rendering/RenderReplica.h" 109 #include "core/rendering/RenderReplica.h"
108 #include "core/rendering/RenderScrollbar.h" 110 #include "core/rendering/RenderScrollbar.h"
109 #include "core/rendering/RenderScrollbarPart.h" 111 #include "core/rendering/RenderScrollbarPart.h"
110 #include "core/rendering/RenderTheme.h" 112 #include "core/rendering/RenderTheme.h"
111 #include "core/rendering/RenderTreeAsText.h" 113 #include "core/rendering/RenderTreeAsText.h"
112 #include "core/rendering/RenderView.h" 114 #include "core/rendering/RenderView.h"
113 #include "core/rendering/svg/RenderSVGResourceClipper.h" 115 #include "core/rendering/svg/RenderSVGResourceClipper.h"
114 #include <wtf/MemoryInstrumentationVector.h> 116 #include <wtf/MemoryInstrumentationVector.h>
115 #include <wtf/StdLibExtras.h> 117 #include <wtf/StdLibExtras.h>
118 // PATCH 2
119 #include <wtf/TemporaryChange.h>
116 #include <wtf/text/CString.h> 120 #include <wtf/text/CString.h>
117 #include <wtf/UnusedParam.h> 121 #include <wtf/UnusedParam.h>
118 122
119 #if ENABLE(SVG) 123 #if ENABLE(SVG)
120 #include "SVGNames.h" 124 #include "SVGNames.h"
121 #endif 125 #endif
122 126
123 #define MIN_INTERSECT_FOR_REVEAL 32 127 #define MIN_INTERSECT_FOR_REVEAL 32
124 128
125 using namespace std; 129 using namespace std;
(...skipping 10 matching lines...) Expand all
136 return hitTestLocation.intersects(m_rect); 140 return hitTestLocation.intersects(m_rect);
137 } 141 }
138 142
139 RenderLayer::RenderLayer(RenderLayerModelObject* renderer) 143 RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
140 : m_inResizeMode(false) 144 : m_inResizeMode(false)
141 , m_scrollDimensionsDirty(true) 145 , m_scrollDimensionsDirty(true)
142 , m_normalFlowListDirty(true) 146 , m_normalFlowListDirty(true)
143 , m_hasSelfPaintingLayerDescendant(false) 147 , m_hasSelfPaintingLayerDescendant(false)
144 , m_hasSelfPaintingLayerDescendantDirty(false) 148 , m_hasSelfPaintingLayerDescendantDirty(false)
145 , m_hasOutOfFlowPositionedDescendant(false) 149 , m_hasOutOfFlowPositionedDescendant(false)
146 , m_hasOutOfFlowPositionedDescendantDirty(true) 150 // PATCH 1
151 , m_forceNeedsCompositedScrolling(DoNotForceCompositedScrolling)
147 , m_needsCompositedScrolling(false) 152 , m_needsCompositedScrolling(false)
148 , m_descendantsAreContiguousInStackingOrder(false) 153 // PATCH 3
149 , m_descendantsAreContiguousInStackingOrderDirty(true) 154 , m_canBePromotedToStackingContainer(false)
155 , m_canBePromotedToStackingContainerDirty(true)
150 , m_isRootLayer(renderer->isRenderView()) 156 , m_isRootLayer(renderer->isRenderView())
151 , m_usedTransparency(false) 157 , m_usedTransparency(false)
152 , m_paintingInsideReflection(false) 158 , m_paintingInsideReflection(false)
153 , m_inOverflowRelayout(false) 159 , m_inOverflowRelayout(false)
154 , m_repaintStatus(NeedsNormalRepaint) 160 , m_repaintStatus(NeedsNormalRepaint)
155 , m_visibleContentStatusDirty(true) 161 , m_visibleContentStatusDirty(true)
156 , m_hasVisibleContent(false) 162 , m_hasVisibleContent(false)
157 , m_visibleDescendantStatusDirty(false) 163 , m_visibleDescendantStatusDirty(false)
158 , m_hasVisibleDescendant(false) 164 , m_hasVisibleDescendant(false)
159 , m_isPaginated(false) 165 , m_isPaginated(false)
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 } 481 }
476 } 482 }
477 483
478 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const 484 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const
479 { 485 {
480 return renderer()->frame() 486 return renderer()->frame()
481 && renderer()->frame()->page() 487 && renderer()->frame()->page()
482 && renderer()->frame()->page()->settings()->acceleratedCompositingForOve rflowScrollEnabled(); 488 && renderer()->frame()->page()->settings()->acceleratedCompositingForOve rflowScrollEnabled();
483 } 489 }
484 490
485 // If we are a stacking container, then this function will determine if our 491 // PATCH 3
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) 492 static inline bool isPositionedContainer(const RenderLayer* layer)
641 { 493 {
642 // FIXME: This is not in sync with containingBlock. 494 // FIXME: This is not in sync with containingBlock.
643 // RenderObject::canContainFixedPositionedObject() should probably be used 495 // RenderObject::canContainFixedPositionedObject() should probably be used
644 // instead. 496 // instead.
645 RenderLayerModelObject* layerRenderer = layer->renderer(); 497 RenderLayerModelObject* layerRenderer = layer->renderer();
646 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform(); 498 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform();
647 } 499 }
648 500
501 enum StackingOrderDirection { FromBackground, FromForeground };
502
503 // We'd like to be able to iterate through a single paint order list, but for
504 // efficiency's sake, we hang onto two lists instead (namely, the pos and neg
505 // z-order lists produced by CollectLayers). This function allows us to index
506 // into these two lists as if they were one. It also allows us to index into
507 // this virtual list either from the start or from the end (i.e., in either
508 // stacking order direction).
509 static const RenderLayer* getStackingOrderElementAt(const Vector<RenderLayer*>* posZOrderList, const Vector<RenderLayer*>* negZOrderList, const StackingOrderDir ection direction, const size_t index)
510 {
511 size_t negZOrderListSize = negZOrderList ? negZOrderList->size() : 0;
512
513 if (direction == FromBackground) {
514 if (index < negZOrderListSize)
515 return negZOrderList->at(index);
516
517 return posZOrderList->at(index - negZOrderListSize);
518 }
519
520 size_t posZOrderListSize = posZOrderList ? posZOrderList->size() : 0;
521
522 if (index < posZOrderListSize)
523 return posZOrderList->at(posZOrderListSize - index - 1);
524
525 return negZOrderList->at(negZOrderListSize - (index - posZOrderListSize) - 1 );
526 }
527
528 // After promotion, the paint order consists of
529 // a) the non-descendants which precede the promoted layer,
530 // b) the promoted layer, and
531 // c) the non-descendants which succeed the promoted layer.
532 //
533 // If the current layer's descendants form a contiguous block in paint order
534 // before promotion, the paint order will consist of
535 // a) the non-descendants which precede the current layer and its descendants,
536 // b) the current layer and its descendants
537 // c) The non-descendants which succeed the current layer and its descendants.
538 //
539 // Sub-lists (a) and (c) should be identical in both paint order lists if
540 // and only if the descendants form a contiguous block. In fact, this is the
541 // only check we need to perform since the order of the descendants with
542 // respect to each other cannot be affected by promotion (i.e., we don't
543 // need to worry about sub-list (b)).
544 //
545 // Some examples:
546 // C = currentLayer
547 // - = negative z-order child of currentLayer
548 // + = positive z-order child of currentLayer
549 // A = positioned ancestor of currentLayer
550 // x = any other RenderLayer in the list
551 //
552 // original | zOrderListBeforePromote | zOrderLi stAfterPromote
553 // zOrderListBeforePromote | after inserting C as above |
554 // ------------------------------------------------------------------------- --------------
555 // (1) x---+++x | x---C+++x | xCx
556 // (2) x---+A++x | x---+AC++x | xACx
557 // (3) x-x--+++x | x-x--C+++x | xxCx
558 // (4) xxA++x | xxAC++x | xxACx
559 //
560 // In example (1), we compare sub-list (a) by marching from the left of both
561 // lists (zOrderListBeforePromote after inserting C and
562 // zOrderListAfterPromote). The first mismatch is at index 1 when we hit '-'
563 // and 'C'. That means we have neg z-order descendants. This is a problem if
564 // we have a background. Before promotion, this bg would get painted with
565 // the current layer (i.e., after the neg z-order descendants), but after
566 // promotion the bg would get painted before them. This is a stacking order
567 // violation and we can't promote. However, if we don't have a background,
568 // we would continue on to the second pass. When comparing from the right,
569 // we mismatch on '+' and 'C'. Since we hit 'C' on zOrderListAfterPromote,
570 // we know that the children are contiguous, and we will promote.
571 //
572 // In example (2), when marching from the left, we'll hit a mismatch again
573 // on the second element we look at. This time, since this element is an 'A'
574 // in zOrderListAfterPromote, this indicates that there is an extra layer
575 // (the 'A') mixed in with the children. This could cause a change in paint
576 // order if we promote, so we decide not to and break out of the loop. Note
577 // that if the current layer has a background, this would provide a second
578 // reason not to opt in, since again we have negative z-order children who
579 // would change paint order with respect to our background if we promoted.
580 //
581 // In example (3), the discontiguity of the negative z-order children causes
582 // us to fail early in our "FromBackground" pass when we try to compare '-'
583 // from zOrderListBeforePromote with 'x' in zOrderListAfterPromote.
584 //
585 // Finally in example (4), we would match 'xxAC' from the left, then stop
586 // since we hit 'C'. Then we would match 'x' from the right, and mismatch
587 // on '+' and 'C'. Since we're at 'C' on the zOrderListAfterPromote, we
588 // conclude that all the children are contiguous. Since there are no
589 // negative z-order children, a background layer is irrelevant in this case.
590 // We will opt in, keeping paint order constant.
591 static bool compareLayerListsBeforeAndAfterPromote(const RenderLayer* currentLay er,
592 const Vector<RenderLayer*>* posZOrderListBeforePromote,
593 const Vector<RenderLayer*>* negZOrderListBeforePromote,
594 const Vector<RenderLayer*>* posZOrderListAfterPromote,
595 const Vector<RenderLayer*>* negZOrderListAfterPromote,
596 const size_t sizeBeforePromote,
597 const size_t sizeAfterPromote,
598 const StackingOrderDirection direction)
599 {
600 for (size_t index = 0; index < sizeBeforePromote && index < sizeAfterPromote ; index++) {
601 const RenderLayer* layerBeforePromote = getStackingOrderElementAt(posZOr derListBeforePromote, negZOrderListBeforePromote, direction, index);
602 const RenderLayer* layerAfterPromote = getStackingOrderElementAt(posZOrd erListAfterPromote, negZOrderListAfterPromote, direction, index);
603
604 if (layerBeforePromote != layerAfterPromote) {
605 // If we find a mismatch, the only situation where we haven't
606 // necessarily changed paint order yet is if layerAfterPromote
607 // is currentLayer.
608 if (layerAfterPromote != currentLayer)
609 return false;
610
611 // Also, if the current layer has a background, then any
612 // negative z-order children will get between the background
613 // and the rest of the layer.
614 if (direction == FromBackground && currentLayer->renderer()->hasBack ground())
615 return false;
616 }
617
618 // To compare the sub-lists (a) and (c) from the comment above, we only
619 // need to march until we hit the currentLayer in the
620 // zOrderListAfterPromote from each direction.
621 if (layerAfterPromote == currentLayer)
622 break;
623 }
624
625 return true;
626 }
627
628 // Determine whether the current layer can be promoted to a stacking container,
629 // given its closest stacking context ancestor. We do this by computing what
630 // positive and negative z-order lists would look like before and after
631 // promotion, and ensuring that proper stacking order is preserved between the
632 // two sets of lists.
633 //
634 // For more details on how the lists will be compared, see the comment and
635 // examples for compareLayerListsBeforeAndAfterPromote().
636 void RenderLayer::updateCanBeStackingContainer(RenderLayer* ancestorStackingCont ext)
637 {
638 TRACE_EVENT0("blink", "RenderLayer::updateCanBeStackingContainer");
639
640 ASSERT(!isStackingContext());
641
642 if (!m_canBePromotedToStackingContainerDirty || !acceleratedCompositingForOv erflowScrollEnabled())
643 return;
644
645 FrameView* frameView = renderer()->view()->frameView();
646 if (!frameView || !frameView->containsScrollableArea(this))
647 return;
648
649 OwnPtr<Vector<RenderLayer*> > posZOrderListBeforePromote;
650 OwnPtr<Vector<RenderLayer*> > negZOrderListBeforePromote;
651 OwnPtr<Vector<RenderLayer*> > posZOrderListAfterPromote;
652 OwnPtr<Vector<RenderLayer*> > negZOrderListAfterPromote;
653 size_t posZOrderListSizeBeforePromote, negZOrderListSizeBeforePromote, posZO rderListSizeAfterPromote, negZOrderListSizeAfterPromote;
654
655 collectBeforePromotionZOrderList(ancestorStackingContext, posZOrderListBefor ePromote, negZOrderListBeforePromote);
656 collectAfterPromotionZOrderList(ancestorStackingContext, posZOrderListAfterP romote, negZOrderListAfterPromote);
657
658 size_t sizeBeforePromote = 0;
659 if (posZOrderListBeforePromote)
660 sizeBeforePromote += posZOrderListBeforePromote->size();
661 if (negZOrderListBeforePromote)
662 sizeBeforePromote += negZOrderListBeforePromote->size();
663
664 size_t sizeAfterPromote = 0;
665 if (posZOrderListAfterPromote)
666 sizeAfterPromote += posZOrderListAfterPromote->size();
667 if (negZOrderListAfterPromote)
668 sizeAfterPromote += negZOrderListAfterPromote->size();
669
670 bool canPromote = compareLayerListsBeforeAndAfterPromote(this, posZOrderList BeforePromote.get(), negZOrderListBeforePromote.get(),
671 posZOrderListAfterPromote.get(), negZOrderListAfterPromote.get(),
672 sizeBeforePromote, sizeAfterPromote, FromBackground)
673 && compareLayerListsBeforeAndAfterPromote(this, posZOrderListBeforePromo te.get(), negZOrderListBeforePromote.get(),
674 posZOrderListAfterPromote.get(), negZOrderListAfterPromote.get(),
675 sizeBeforePromote, sizeAfterPromote, FromForeground);
676
677 bool didUpdate = (canPromote != m_canBePromotedToStackingContainer);
678
679 m_canBePromotedToStackingContainer = canPromote;
680 m_canBePromotedToStackingContainerDirty = false;
681 }
682
649 void RenderLayer::collectBeforePromotionZOrderList(RenderLayer* ancestorStacking Context, OwnPtr<Vector<RenderLayer*> >& posZOrderListBeforePromote, OwnPtr<Vecto r<RenderLayer*> >& negZOrderListBeforePromote) 683 void RenderLayer::collectBeforePromotionZOrderList(RenderLayer* ancestorStacking Context, OwnPtr<Vector<RenderLayer*> >& posZOrderListBeforePromote, OwnPtr<Vecto r<RenderLayer*> >& negZOrderListBeforePromote)
650 { 684 {
651 // FIXME: TemporaryChange should support bit fields. 685 // FIXME: TemporaryChange should support bit fields.
652 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling; 686 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling;
653 bool oldIsNormalFlowOnly = m_isNormalFlowOnly; 687 bool oldIsNormalFlowOnly = m_isNormalFlowOnly;
654 688
655 m_needsCompositedScrolling = false; 689 m_needsCompositedScrolling = false;
656 m_isNormalFlowOnly = shouldBeNormalFlowOnly(); 690 m_isNormalFlowOnly = shouldBeNormalFlowOnly();
657 691
658 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde rListBeforePromote, negZOrderListBeforePromote, 0); 692 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde rListBeforePromote, negZOrderListBeforePromote, 0);
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 if (curr == ancestorStackingContainer) 1089 if (curr == ancestorStackingContainer)
1056 return; 1090 return;
1057 } 1091 }
1058 } 1092 }
1059 1093
1060 bool RenderLayer::canBeStackingContainer() const 1094 bool RenderLayer::canBeStackingContainer() const
1061 { 1095 {
1062 if (isStackingContext() || !ancestorStackingContainer()) 1096 if (isStackingContext() || !ancestorStackingContainer())
1063 return true; 1097 return true;
1064 1098
1065 return m_descendantsAreContiguousInStackingOrder; 1099 // PATCH 3
hartmanng 2013/05/02 14:04:01 There should be an assert in here, right?
1100 return m_canBePromotedToStackingContainer;
1066 } 1101 }
1067 1102
1068 void RenderLayer::setHasVisibleContent() 1103 void RenderLayer::setHasVisibleContent()
1069 { 1104 {
1070 if (m_hasVisibleContent && !m_visibleContentStatusDirty) { 1105 if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
1071 ASSERT(!parent() || parent()->hasVisibleDescendant()); 1106 ASSERT(!parent() || parent()->hasVisibleDescendant());
1072 return; 1107 return;
1073 } 1108 }
1074 1109
1075 m_visibleContentStatusDirty = false; 1110 m_visibleContentStatusDirty = false;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 { 1146 {
1112 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 1147 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1113 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendan t()) 1148 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendan t())
1114 break; 1149 break;
1115 1150
1116 layer->m_hasVisibleDescendant = true; 1151 layer->m_hasVisibleDescendant = true;
1117 layer->m_visibleDescendantStatusDirty = false; 1152 layer->m_visibleDescendantStatusDirty = false;
1118 } 1153 }
1119 } 1154 }
1120 1155
1121 void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* o utOfFlowDescendantContainingBlocks) 1156 // PATCH 2 - requires a full tree walk. We *only* want to do this once after a s tyle change,
1157 // so it must be tied to the phase work.
1158 void RenderLayer::updateHasOutOfFlowPositionedDescendant(HashSet<const RenderObj ect*>* containingBlocks)
1122 { 1159 {
1123 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) { 1160 const bool hadOutOfFlowPositionedDescendant = hasOutOfFlowPositionedDescenda nt();
1124 const bool hadVisibleDescendant = m_hasVisibleDescendant; 1161 m_hasOutOfFlowPositionedDescendant = false;
1125 const bool hadOutOfFlowPositionedDescendant = m_hasOutOfFlowPositionedDe scendant;
1126 1162
1163 HashSet<const RenderObject*> childContainingBlocks;
1164 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1165 childContainingBlocks.clear();
1166 child->updateHasOutOfFlowPositionedDescendant(&childContainingBlocks);
1167
1168 const bool childIsOutOfFlowPositioned = child->renderer()
1169 && child->renderer()->isOutOfFlowPositioned()
1170 && (child->hasVisibleDescendant() || child->hasVisibleContent());
1171
1172 if (childIsOutOfFlowPositioned)
1173 childContainingBlocks.add(child->renderer()->containingBlock());
1174
1175 size_t numContainingBlocks = childContainingBlocks.size();
1176 childContainingBlocks.remove(renderer());
1177
1178 if (containingBlocks && !childContainingBlocks.isEmpty()) {
1179 HashSet<const RenderObject*>::const_iterator it = childContainingBlo cks.begin();
1180 for (; it != childContainingBlocks.end(); ++it)
1181 containingBlocks->add(*it);
1182 }
1183
1184 m_hasOutOfFlowPositionedDescendant |= !childContainingBlocks.isEmpty();
1185 }
1186
1187 if (m_hasOutOfFlowPositionedDescendant != hadOutOfFlowPositionedDescendant)
1188 compositor()->setNeedsUpdateCompositingRequirementsState();
1189 }
1190
1191 void RenderLayer::updateDescendantDependentFlags()
1192 {
1193 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty) {
1127 m_hasVisibleDescendant = false; 1194 m_hasVisibleDescendant = false;
1128 m_hasSelfPaintingLayerDescendant = false; 1195 m_hasSelfPaintingLayerDescendant = false;
1129 m_hasOutOfFlowPositionedDescendant = false;
1130 1196
1131 HashSet<const RenderObject*> childOutOfFlowDescendantContainingBlocks;
1132 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { 1197 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) {
1133 childOutOfFlowDescendantContainingBlocks.clear(); 1198 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 1199
1146 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_h asVisibleDescendant; 1200 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_h asVisibleDescendant;
1147 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() | | child->hasSelfPaintingLayerDescendant(); 1201 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() | | child->hasSelfPaintingLayerDescendant();
1148 bool hasOutOfFlowPositionedDescendant = hasVisibleDescendant && (!ch ildOutOfFlowDescendantContainingBlocks.isEmpty() || child->hasOutOfFlowPositione dDescendant());
1149 1202
1150 m_hasVisibleDescendant |= hasVisibleDescendant; 1203 m_hasVisibleDescendant |= hasVisibleDescendant;
1151 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant; 1204 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
1152 m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescenda nt;
1153 1205
1154 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && m_ hasOutOfFlowPositionedDescendant) 1206 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant)
1155 break; 1207 break;
1156 } 1208 }
1157 1209
1158 if (outOfFlowDescendantContainingBlocks && renderer())
1159 outOfFlowDescendantContainingBlocks->remove(renderer());
1160
1161 m_visibleDescendantStatusDirty = false; 1210 m_visibleDescendantStatusDirty = false;
1162 m_hasSelfPaintingLayerDescendantDirty = false; 1211 m_hasSelfPaintingLayerDescendantDirty = false;
1163 m_hasOutOfFlowPositionedDescendantDirty = false;
1164
1165 if (m_hasVisibleDescendant != hadVisibleDescendant || m_hasOutOfFlowPosi tionedDescendant != hadOutOfFlowPositionedDescendant)
1166 updateNeedsCompositedScrolling();
1167 } 1212 }
1168 1213
1169 if (m_visibleContentStatusDirty) { 1214 if (m_visibleContentStatusDirty) {
1170 const bool hadVisibleContent = m_hasVisibleContent;
1171 if (renderer()->style()->visibility() == VISIBLE) 1215 if (renderer()->style()->visibility() == VISIBLE)
1172 m_hasVisibleContent = true; 1216 m_hasVisibleContent = true;
1173 else { 1217 else {
1174 // layer may be hidden but still have some visible content, check fo r this 1218 // layer may be hidden but still have some visible content, check fo r this
1175 m_hasVisibleContent = false; 1219 m_hasVisibleContent = false;
1176 RenderObject* r = renderer()->firstChild(); 1220 RenderObject* r = renderer()->firstChild();
1177 while (r) { 1221 while (r) {
1178 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { 1222 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
1179 m_hasVisibleContent = true; 1223 m_hasVisibleContent = true;
1180 break; 1224 break;
1181 } 1225 }
1182 if (r->firstChild() && !r->hasLayer()) 1226 if (r->firstChild() && !r->hasLayer())
1183 r = r->firstChild(); 1227 r = r->firstChild();
1184 else if (r->nextSibling()) 1228 else if (r->nextSibling())
1185 r = r->nextSibling(); 1229 r = r->nextSibling();
1186 else { 1230 else {
1187 do { 1231 do {
1188 r = r->parent(); 1232 r = r->parent();
1189 if (r == renderer()) 1233 if (r == renderer())
1190 r = 0; 1234 r = 0;
1191 } while (r && !r->nextSibling()); 1235 } while (r && !r->nextSibling());
1192 if (r) 1236 if (r)
1193 r = r->nextSibling(); 1237 r = r->nextSibling();
1194 } 1238 }
1195 } 1239 }
1196 } 1240 }
1197 m_visibleContentStatusDirty = false; 1241 m_visibleContentStatusDirty = false;
1198 if (hadVisibleContent != m_hasVisibleContent)
1199 updateNeedsCompositedScrolling();
1200 } 1242 }
1201 } 1243 }
1202 1244
1203 void RenderLayer::dirty3DTransformedDescendantStatus() 1245 void RenderLayer::dirty3DTransformedDescendantStatus()
1204 { 1246 {
1205 RenderLayer* curr = ancestorStackingContainer(); 1247 RenderLayer* curr = ancestorStackingContainer();
1206 if (curr) 1248 if (curr)
1207 curr->m_3DTransformedDescendantStatusDirty = true; 1249 curr->m_3DTransformedDescendantStatusDirty = true;
1208 1250
1209 // This propagates up through preserve-3d hierarchies to the enclosing flatt ening layer. 1251 // 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); 1802 child->setParent(this);
1761 1803
1762 if (child->isNormalFlowOnly()) 1804 if (child->isNormalFlowOnly())
1763 dirtyNormalFlowList(); 1805 dirtyNormalFlowList();
1764 1806
1765 if (!child->isNormalFlowOnly() || child->firstChild()) { 1807 if (!child->isNormalFlowOnly() || child->firstChild()) {
1766 // Dirty the z-order list in which we are contained. The ancestorStackin gContainer() can be null in the 1808 // 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 1809 // 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. 1810 // off dirty in that case anyway.
1769 child->dirtyStackingContainerZOrderLists(); 1811 child->dirtyStackingContainerZOrderLists();
1770 1812 // PATCH 2
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 } 1813 }
1781 1814
1782 child->updateDescendantDependentFlags(); 1815 child->updateDescendantDependentFlags();
1783 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) 1816 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
1784 setAncestorChainHasVisibleDescendant(); 1817 setAncestorChainHasVisibleDescendant();
1785 1818
1786 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) 1819 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
1787 setAncestorChainHasSelfPaintingLayerDescendant(); 1820 setAncestorChainHasSelfPaintingLayerDescendant();
1788 1821
1789 if (child->renderer() && (child->renderer()->isOutOfFlowPositioned() || chil d->hasOutOfFlowPositionedDescendant())) 1822 if (child->renderer() && (child->renderer()->isOutOfFlowPositioned() || chil d->hasOutOfFlowPositionedDescendant()))
1790 setAncestorChainHasOutOfFlowPositionedDescendant(child->renderer()->cont ainingBlock()); 1823 // PATCH 2
1824 compositor()->setNeedsUpdateCompositingRequirementsState();
1791 1825
1792 compositor()->layerWasAdded(this, child); 1826 compositor()->layerWasAdded(this, child);
1793 } 1827 }
1794 1828
1795 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) 1829 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1796 { 1830 {
1797 if (!renderer()->documentBeingDestroyed()) 1831 if (!renderer()->documentBeingDestroyed())
1798 compositor()->layerWillBeRemoved(this, oldChild); 1832 compositor()->layerWillBeRemoved(this, oldChild);
1799 1833
1800 // remove the child 1834 // remove the child
1801 if (oldChild->previousSibling()) 1835 if (oldChild->previousSibling())
1802 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); 1836 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1803 if (oldChild->nextSibling()) 1837 if (oldChild->nextSibling())
1804 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()) ; 1838 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()) ;
1805 1839
1806 if (m_first == oldChild) 1840 if (m_first == oldChild)
1807 m_first = oldChild->nextSibling(); 1841 m_first = oldChild->nextSibling();
1808 if (m_last == oldChild) 1842 if (m_last == oldChild)
1809 m_last = oldChild->previousSibling(); 1843 m_last = oldChild->previousSibling();
1810 1844
1811 if (oldChild->isNormalFlowOnly()) 1845 if (oldChild->isNormalFlowOnly())
1812 dirtyNormalFlowList(); 1846 dirtyNormalFlowList();
1813 if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) { 1847 if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) {
1814 // Dirty the z-order list in which we are contained. When called via th e 1848 // 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 1849 // 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. 1850 // from the main layer tree, so we need to null-check the |stackingConta iner| value.
1817 oldChild->dirtyStackingContainerZOrderLists(); 1851 oldChild->dirtyStackingContainerZOrderLists();
1818 1852 // PATCH 2
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 } 1853 }
1831 1854
1832 if ((oldChild->renderer() && oldChild->renderer()->isOutOfFlowPositioned()) || oldChild->hasOutOfFlowPositionedDescendant()) 1855 // PATCH 2
1833 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
1834
1835 oldChild->setPreviousSibling(0); 1856 oldChild->setPreviousSibling(0);
1836 oldChild->setNextSibling(0); 1857 oldChild->setNextSibling(0);
1837 oldChild->setParent(0); 1858 oldChild->setParent(0);
1838 1859
1839 oldChild->updateDescendantDependentFlags(); 1860 oldChild->updateDescendantDependentFlags();
1861 // PATCH 2
1862 if ((oldChild->renderer() && oldChild->renderer()->isOutOfFlowPositioned()) || oldChild->hasOutOfFlowPositionedDescendant())
1863 compositor()->setNeedsUpdateCompositingRequirementsState();
1864
1840 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) 1865 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1841 dirtyAncestorChainVisibleDescendantStatus(); 1866 dirtyAncestorChainVisibleDescendantStatus();
1842 1867
1843 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescend ant()) 1868 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescend ant())
1844 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 1869 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1845 1870
1846 return oldChild; 1871 return oldChild;
1847 } 1872 }
1848 1873
1849 void RenderLayer::removeOnlyThisLayer() 1874 void RenderLayer::removeOnlyThisLayer()
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2044 rect.move(-delta.x(), -delta.y()); 2069 rect.move(-delta.x(), -delta.y());
2045 } 2070 }
2046 2071
2047 bool RenderLayer::usesCompositedScrolling() const 2072 bool RenderLayer::usesCompositedScrolling() const
2048 { 2073 {
2049 return isComposited() && backing()->scrollingLayer(); 2074 return isComposited() && backing()->scrollingLayer();
2050 } 2075 }
2051 2076
2052 bool RenderLayer::needsCompositedScrolling() const 2077 bool RenderLayer::needsCompositedScrolling() const
2053 { 2078 {
2079 // PATCH 1
2080 switch (m_forceNeedsCompositedScrolling) {
2081 case DoNotForceCompositedScrolling:
2082 return m_needsCompositedScrolling;
2083 case ForceCompositedScrollingOn:
2084 return true;
2085 case ForceCompositedScrollingOff:
2086 return false;
2087 }
2088
2054 return m_needsCompositedScrolling; 2089 return m_needsCompositedScrolling;
2055 } 2090 }
2056 2091
2092 // PATCH 1
2057 void RenderLayer::updateNeedsCompositedScrolling() 2093 void RenderLayer::updateNeedsCompositedScrolling()
2058 { 2094 {
2059 bool needsCompositedScrolling = false; 2095 bool needsCompositedScrolling = false;
2060 2096
2061 FrameView* frameView = renderer()->view()->frameView(); 2097 FrameView* frameView = renderer()->view()->frameView();
2062 if (frameView && frameView->containsScrollableArea(this)) { 2098 if (frameView && frameView->containsScrollableArea(this) && acceleratedCompo sitingForOverflowScrollEnabled()) {
2063 updateDescendantDependentFlags(); 2099 if (isStackingContext()) {
2100 needsCompositedScrolling = true;
2101 } else {
2102 RenderLayer* stackingContext = ancestorStackingContext();
2103 updateCanBeStackingContainer(stackingContext);
2064 2104
2065 bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScro llEnabled() 2105 bool forceUseCompositedScrolling = canBeStackingContainer() && !hasO utOfFlowPositionedDescendant();
2066 && canBeStackingContainer()
2067 && !hasOutOfFlowPositionedDescendant();
2068 2106
2069 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) 2107 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2070 needsCompositedScrolling = forceUseCompositedScrolling || renderer()->st yle()->useTouchOverflowScrolling(); 2108 needsCompositedScrolling = forceUseCompositedScrolling || renderer() ->style()->useTouchOverflowScrolling();
2071 #else 2109 #else
2072 needsCompositedScrolling = forceUseCompositedScrolling; 2110 needsCompositedScrolling = forceUseCompositedScrolling;
2073 #endif 2111 #endif
2112 }
2113
2074 // We gather a boolean value for use with Google UMA histograms to 2114 // We gather a boolean value for use with Google UMA histograms to
2075 // quantify the actual effects of a set of patches attempting to 2115 // quantify the actual effects of a set of patches attempting to
2076 // relax composited scrolling requirements, thereby increasing the 2116 // relax composited scrolling requirements, thereby increasing the
2077 // number of composited overflow divs. 2117 // number of composited overflow divs.
2078 if (acceleratedCompositingForOverflowScrollEnabled()) 2118 if (acceleratedCompositingForOverflowScrollEnabled())
2079 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScro lling", needsCompositedScrolling, 2); 2119 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScro lling", needsCompositedScrolling, 2);
2080 } 2120 }
2081 2121
2082 if (m_needsCompositedScrolling == needsCompositedScrolling) 2122 if (m_needsCompositedScrolling == needsCompositedScrolling)
2083 return; 2123 return;
2084 2124
2085 m_needsCompositedScrolling = needsCompositedScrolling; 2125 m_needsCompositedScrolling = needsCompositedScrolling;
2086 2126
2127 // Note, the z-order lists may need to be rebuilt, but our code guarantees
2128 // that we have not affected stacking, so we will not dirty
2129 // m_canBePromotedToStackingContainer for either us or our stacking context
2130 // or container.
2131 didUpdateNeedsCompositedScrolling();
2132 }
2133
2134 // PATCH 1
2135 void RenderLayer::setForceNeedsCompositedScrolling(RenderLayer::ForceNeedsCompos itedScrollingMode mode)
2136 {
2137 m_forceNeedsCompositedScrolling = mode;
2138 didUpdateNeedsCompositedScrolling();
2139 }
2140
2141 // PATCH 1
2142 void RenderLayer::didUpdateNeedsCompositedScrolling()
2143 {
2087 updateIsNormalFlowOnly(); 2144 updateIsNormalFlowOnly();
2088 updateSelfPaintingLayer(); 2145 updateSelfPaintingLayer();
2089 2146
2090 if (isStackingContainer()) 2147 if (isStackingContainer())
2091 dirtyZOrderLists(); 2148 dirtyZOrderLists();
2092 else 2149 else
2093 clearZOrderLists(); 2150 clearZOrderLists();
2094 2151
2095 dirtyStackingContainerZOrderLists(); 2152 dirtyStackingContainerZOrderLists();
2096 2153
(...skipping 3503 matching lines...) Expand 10 before | Expand all | Expand 10 after
5600 { 5657 {
5601 ASSERT(m_layerListMutationAllowed); 5658 ASSERT(m_layerListMutationAllowed);
5602 ASSERT(isStackingContainer()); 5659 ASSERT(isStackingContainer());
5603 5660
5604 if (m_posZOrderList) 5661 if (m_posZOrderList)
5605 m_posZOrderList->clear(); 5662 m_posZOrderList->clear();
5606 if (m_negZOrderList) 5663 if (m_negZOrderList)
5607 m_negZOrderList->clear(); 5664 m_negZOrderList->clear();
5608 m_zOrderListsDirty = true; 5665 m_zOrderListsDirty = true;
5609 5666
5610 m_descendantsAreContiguousInStackingOrderDirty = true; 5667 // PATCH 3
5668 m_canBePromotedToStackingContainerDirty = true;
5669 // PATCH 2
5670 compositor()->setNeedsUpdateCompositingRequirementsState();
5611 5671
5612 if (!renderer()->documentBeingDestroyed()) { 5672 if (!renderer()->documentBeingDestroyed()) {
5613 compositor()->setCompositingLayersNeedRebuild(); 5673 compositor()->setCompositingLayersNeedRebuild();
5614 if (acceleratedCompositingForOverflowScrollEnabled()) 5674 if (acceleratedCompositingForOverflowScrollEnabled())
5615 compositor()->setShouldReevaluateCompositingAfterLayout(); 5675 compositor()->setShouldReevaluateCompositingAfterLayout();
5616 } 5676 }
5617 } 5677 }
5618 5678
5619 void RenderLayer::dirtyStackingContainerZOrderLists() 5679 void RenderLayer::dirtyStackingContainerZOrderLists()
5620 { 5680 {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
5695 if (child->isNormalFlowOnly() && (!m_reflection || reflectionLayer() != child)) { 5755 if (child->isNormalFlowOnly() && (!m_reflection || reflectionLayer() != child)) {
5696 if (!m_normalFlowList) 5756 if (!m_normalFlowList)
5697 m_normalFlowList = adoptPtr(new Vector<RenderLayer*>); 5757 m_normalFlowList = adoptPtr(new Vector<RenderLayer*>);
5698 m_normalFlowList->append(child); 5758 m_normalFlowList->append(child);
5699 } 5759 }
5700 } 5760 }
5701 5761
5702 m_normalFlowListDirty = false; 5762 m_normalFlowListDirty = false;
5703 } 5763 }
5704 5764
5765 // PATCH 2
5705 void RenderLayer::collectLayers(bool includeHiddenLayers, CollectLayersBehavior behavior, OwnPtr<Vector<RenderLayer*> >& posBuffer, OwnPtr<Vector<RenderLayer*> >& negBuffer, const RenderLayer* layerToForceAsStackingContainer) 5766 void RenderLayer::collectLayers(bool includeHiddenLayers, CollectLayersBehavior behavior, OwnPtr<Vector<RenderLayer*> >& posBuffer, OwnPtr<Vector<RenderLayer*> >& negBuffer, const RenderLayer* layerToForceAsStackingContainer)
5706 { 5767 {
5707 if (isInTopLayer()) 5768 if (isInTopLayer())
5708 return; 5769 return;
5709 5770
5710 updateDescendantDependentFlags(); 5771 updateDescendantDependentFlags();
5711 5772
5712 bool isStacking = false; 5773 bool isStacking = false;
5713 5774
5714 switch (behavior) { 5775 switch (behavior) {
5715 case StopAtStackingContexts: 5776 case StopAtStackingContexts:
5716 isStacking = (this == layerToForceAsStackingContainer) || isStacking Context(); 5777 isStacking = (this == layerToForceAsStackingContainer) || isStackingCont ext();
5717 break; 5778 break;
5718 5779
5719 case StopAtStackingContainers: 5780 case StopAtStackingContainers:
5720 isStacking = (this == layerToForceAsStackingContainer) || isStacking Container(); 5781 isStacking = (this == layerToForceAsStackingContainer) || isStackingCon tainer();
5721 break; 5782 break;
5783 }
5784
5785 // This value could be affected by opt in. What we really need to know is
5786 // are you normal flow only, regardless of your opt in status. This is very
5787 // similar to asking if a layer is a stacking context rather than a
5788 // stacking container.
5789 bool isNormalFlowWithoutCompositedScrolling = isNormalFlowOnly();
5790 if (this != layerToForceAsStackingContainer && behavior == StopAtStackingCon texts) {
5791 TemporaryChange<ForceNeedsCompositedScrollingMode> forceOff(m_forceNeeds CompositedScrolling, ForceCompositedScrollingOff);
5792 isNormalFlowWithoutCompositedScrolling = shouldBeNormalFlowOnly();
5722 } 5793 }
5723 5794
5724 // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists. 5795 // 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)); 5796 bool includeHiddenLayer = includeHiddenLayers || (m_hasVisibleContent || (m_ hasVisibleDescendant && isStacking));
5726 if (includeHiddenLayer && !isNormalFlowOnly() && !isOutOfFlowRenderFlowThrea d()) { 5797 if (includeHiddenLayer && !isNormalFlowWithoutCompositedScrolling && !isOutO fFlowRenderFlowThread()) {
5727 // Determine which buffer the child should be in. 5798 // Determine which buffer the child should be in.
5728 OwnPtr<Vector<RenderLayer*> >& buffer = (zIndex() >= 0) ? posBuffer : ne gBuffer; 5799 OwnPtr<Vector<RenderLayer*> >& buffer = (zIndex() >= 0) ? posBuffer : ne gBuffer;
5729 5800
5730 // Create the buffer if it doesn't exist yet. 5801 // Create the buffer if it doesn't exist yet.
5731 if (!buffer) 5802 if (!buffer)
5732 buffer = adoptPtr(new Vector<RenderLayer*>); 5803 buffer = adoptPtr(new Vector<RenderLayer*>);
5733 5804
5734 // Append ourselves at the end of the appropriate buffer. 5805 // Append ourselves at the end of the appropriate buffer.
5735 buffer->append(this); 5806 buffer->append(this);
5736 } 5807 }
5737 5808
5738 // Recur into our children to collect more layers, but only if we don't esta blish 5809 // Recur into our children to collect more layers, but only if we don't esta blish
5739 // a stacking context/container. 5810 // a stacking context/container.
5740 if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) { 5811 if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) {
5741 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { 5812 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) {
5742 // Ignore reflections. 5813 // Ignore reflections.
5743 if (!m_reflection || reflectionLayer() != child) 5814 if (!m_reflection || reflectionLayer() != child)
5744 child->collectLayers(includeHiddenLayers, behavior, posBuffer, n egBuffer, layerToForceAsStackingContainer); 5815 child->collectLayers(includeHiddenLayers, behavior, posBuffer, n egBuffer, layerToForceAsStackingContainer);
5745 } 5816 }
5746 } 5817 }
5747 } 5818 }
5748 5819
5820 // PATCH 2
5749 void RenderLayer::updateLayerListsIfNeeded() 5821 void RenderLayer::updateLayerListsIfNeeded()
5750 { 5822 {
5751 bool shouldUpdateDescendantsAreContiguousInStackingOrder = acceleratedCompos itingForOverflowScrollEnabled() && isStackingContext() && (m_zOrderListsDirty || m_normalFlowListDirty) && m_descendantsAreContiguousInStackingOrderDirty;
5752 updateZOrderLists(); 5823 updateZOrderLists();
5753 updateNormalFlowList(); 5824 updateNormalFlowList();
5754 5825
5755 if (RenderLayer* reflectionLayer = this->reflectionLayer()) { 5826 if (RenderLayer* reflectionLayer = this->reflectionLayer()) {
5756 reflectionLayer->updateZOrderLists(); 5827 reflectionLayer->updateZOrderLists();
5757 reflectionLayer->updateNormalFlowList(); 5828 reflectionLayer->updateNormalFlowList();
5758 } 5829 }
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 } 5830 }
5768 5831
5769 void RenderLayer::repaintIncludingDescendants() 5832 void RenderLayer::repaintIncludingDescendants()
5770 { 5833 {
5771 renderer()->repaint(); 5834 renderer()->repaint();
5772 for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling()) 5835 for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
5773 curr->repaintIncludingDescendants(); 5836 curr->repaintIncludingDescendants();
5774 } 5837 }
5775 5838
5776 void RenderLayer::setBackingNeedsRepaint() 5839 void RenderLayer::setBackingNeedsRepaint()
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
5936 return false; 5999 return false;
5937 } 6000 }
5938 6001
5939 void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle) 6002 void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle)
5940 { 6003 {
5941 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE; 6004 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
5942 if (oldVisibility == renderer()->style()->visibility() || !renderer()->isOut OfFlowPositioned()) 6005 if (oldVisibility == renderer()->style()->visibility() || !renderer()->isOut OfFlowPositioned())
5943 return; 6006 return;
5944 6007
5945 if (renderer()->style()->visibility() == VISIBLE) 6008 if (renderer()->style()->visibility() == VISIBLE)
5946 setAncestorChainHasOutOfFlowPositionedDescendant(renderer()->containingB lock()); 6009 // PATCH 2
5947 else 6010 compositor()->setNeedsUpdateCompositingRequirementsState();
5948 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
5949 } 6011 }
5950 6012
5951 void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldS tyle) 6013 void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldS tyle)
5952 { 6014 {
5953 bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false; 6015 bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false;
5954 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE; 6016 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
5955 int oldZIndex = oldStyle ? oldStyle->zIndex() : 0; 6017 int oldZIndex = oldStyle ? oldStyle->zIndex() : 0;
5956 6018
5957 // FIXME: RenderLayer already handles visibility changes through our visibli ty dirty bits. This logic could 6019 // FIXME: RenderLayer already handles visibility changes through our visibli ty dirty bits. This logic could
5958 // likely be folded along with the rest. 6020 // likely be folded along with the rest.
5959 bool isStackingContext = this->isStackingContext(); 6021 bool isStackingContext = this->isStackingContext();
5960 if (isStackingContext == wasStackingContext && oldVisibility == renderer()-> style()->visibility() && oldZIndex == renderer()->style()->zIndex()) 6022 if (isStackingContext == wasStackingContext && oldVisibility == renderer()-> style()->visibility() && oldZIndex == renderer()->style()->zIndex())
5961 return; 6023 return;
5962 6024
5963 dirtyStackingContainerZOrderLists(); 6025 dirtyStackingContainerZOrderLists();
5964 6026
5965 if (isStackingContainer()) 6027 if (isStackingContainer())
5966 dirtyZOrderLists(); 6028 dirtyZOrderLists();
5967 else 6029 else
5968 clearZOrderLists(); 6030 clearZOrderLists();
5969 6031
5970 updateNeedsCompositedScrolling(); 6032 // PATCH 2
6033 compositor()->setNeedsUpdateCompositingRequirementsState();
5971 } 6034 }
5972 6035
5973 static bool overflowRequiresScrollbar(EOverflow overflow) 6036 static bool overflowRequiresScrollbar(EOverflow overflow)
5974 { 6037 {
5975 return overflow == OSCROLL; 6038 return overflow == OSCROLL;
5976 } 6039 }
5977 6040
5978 static bool overflowDefinesAutomaticScrollbar(EOverflow overflow) 6041 static bool overflowDefinesAutomaticScrollbar(EOverflow overflow)
5979 { 6042 {
5980 return overflow == OAUTO || overflow == OOVERLAY; 6043 return overflow == OAUTO || overflow == OOVERLAY;
(...skipping 28 matching lines...) Expand all
6009 6072
6010 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) { 6073 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) {
6011 ASSERT(hasVerticalScrollbar()); 6074 ASSERT(hasVerticalScrollbar());
6012 m_vBar->setEnabled(true); 6075 m_vBar->setEnabled(true);
6013 } 6076 }
6014 6077
6015 if (!m_scrollDimensionsDirty) 6078 if (!m_scrollDimensionsDirty)
6016 updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollab leVerticalOverflow()); 6079 updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollab leVerticalOverflow());
6017 } 6080 }
6018 6081
6019 void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant(RenderObject* containingBlock) 6082 // PATCH 2
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) 6083 void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle)
6050 { 6084 {
6051 bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsoluteP osition || oldStyle->position() == FixedPosition); 6085 if (!oldStyle || (renderer()->style()->position() != oldStyle->position()))
6052 bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned(); 6086 compositor()->setNeedsUpdateCompositingRequirementsState();
6053 if (parent() && isOutOfFlowPositioned != wasOutOfFlowPositioned) {
6054 if (isOutOfFlowPositioned)
6055 parent()->setAncestorChainHasOutOfFlowPositionedDescendant(renderer( )->containingBlock());
6056 else
6057 parent()->dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus() ;
6058 }
6059 } 6087 }
6060 6088
6061 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newS tyle) 6089 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newS tyle)
6062 { 6090 {
6063 ASSERT(newStyle); 6091 ASSERT(newStyle);
6064 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter(); 6092 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter();
6065 } 6093 }
6066 6094
6067 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const 6095 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
6068 { 6096 {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
6206 if (HTMLFrameOwnerElement* owner = frame->ownerElement()) 6234 if (HTMLFrameOwnerElement* owner = frame->ownerElement())
6207 isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToH itTesting(); 6235 isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToH itTesting();
6208 6236
6209 bool updatedScrollableAreaSet = false; 6237 bool updatedScrollableAreaSet = false;
6210 if (hasOverflow && isVisibleToHitTest) 6238 if (hasOverflow && isVisibleToHitTest)
6211 updatedScrollableAreaSet = frameView->addScrollableArea(this); 6239 updatedScrollableAreaSet = frameView->addScrollableArea(this);
6212 else 6240 else
6213 updatedScrollableAreaSet = frameView->removeScrollableArea(this); 6241 updatedScrollableAreaSet = frameView->removeScrollableArea(this);
6214 6242
6215 if (updatedScrollableAreaSet) 6243 if (updatedScrollableAreaSet)
6216 updateNeedsCompositedScrolling(); 6244 // PATCH 2
6245 compositor()->setNeedsUpdateCompositingRequirementsState();
6217 } 6246 }
6218 6247
6219 void RenderLayer::updateScrollCornerStyle() 6248 void RenderLayer::updateScrollCornerStyle()
6220 { 6249 {
6221 RenderObject* actualRenderer = rendererForScrollbar(renderer()); 6250 RenderObject* actualRenderer = rendererForScrollbar(renderer());
6222 RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer- >getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->st yle()) : PassRefPtr<RenderStyle>(0); 6251 RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer- >getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->st yle()) : PassRefPtr<RenderStyle>(0);
6223 if (corner) { 6252 if (corner) {
6224 if (!m_scrollCorner) { 6253 if (!m_scrollCorner) {
6225 m_scrollCorner = RenderScrollbarPart::createAnonymous(renderer()->do cument()); 6254 m_scrollCorner = RenderScrollbarPart::createAnonymous(renderer()->do cument());
6226 m_scrollCorner->setParent(renderer()); 6255 m_scrollCorner->setParent(renderer());
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
6457 } 6486 }
6458 } 6487 }
6459 6488
6460 void showLayerTree(const WebCore::RenderObject* renderer) 6489 void showLayerTree(const WebCore::RenderObject* renderer)
6461 { 6490 {
6462 if (!renderer) 6491 if (!renderer)
6463 return; 6492 return;
6464 showLayerTree(renderer->enclosingLayer()); 6493 showLayerTree(renderer->enclosingLayer());
6465 } 6494 }
6466 #endif 6495 #endif
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderLayer.h ('k') | Source/core/rendering/RenderLayerCompositor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698