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