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