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