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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 #include "CSSPropertyNames.h" | 47 #include "CSSPropertyNames.h" |
48 #include "HTMLFrameElement.h" | 48 #include "HTMLFrameElement.h" |
49 #include "HTMLFrameOwnerElement.h" | 49 #include "HTMLFrameOwnerElement.h" |
50 #include "HTMLNames.h" | 50 #include "HTMLNames.h" |
51 #include "core/css/StylePropertySet.h" | 51 #include "core/css/StylePropertySet.h" |
52 #include "core/css/StyleResolver.h" | 52 #include "core/css/StyleResolver.h" |
53 #include "core/dom/Document.h" | 53 #include "core/dom/Document.h" |
54 #include "core/dom/DocumentEventQueue.h" | 54 #include "core/dom/DocumentEventQueue.h" |
55 #include "core/dom/OverflowEvent.h" | 55 #include "core/dom/OverflowEvent.h" |
56 #include "core/dom/ShadowRoot.h" | 56 #include "core/dom/ShadowRoot.h" |
57 #include "core/dom/StaticHashSetNodeList.h" | |
58 #include "core/dom/WebCoreMemoryInstrumentation.h" | 57 #include "core/dom/WebCoreMemoryInstrumentation.h" |
59 #include "core/editing/FrameSelection.h" | 58 #include "core/editing/FrameSelection.h" |
60 #include "core/loader/FrameLoader.h" | 59 #include "core/loader/FrameLoader.h" |
61 #include "core/loader/FrameLoaderClient.h" | 60 #include "core/loader/FrameLoaderClient.h" |
62 #include "core/page/Chrome.h" | 61 #include "core/page/Chrome.h" |
63 #include "core/page/EventHandler.h" | 62 #include "core/page/EventHandler.h" |
64 #include "core/page/FocusController.h" | 63 #include "core/page/FocusController.h" |
65 #include "core/page/Frame.h" | 64 #include "core/page/Frame.h" |
66 #include "core/page/FrameTree.h" | 65 #include "core/page/FrameTree.h" |
67 #include "core/page/FrameView.h" | 66 #include "core/page/FrameView.h" |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 | 642 |
644 static inline bool isPositionedContainer(const RenderLayer* layer) | 643 static inline bool isPositionedContainer(const RenderLayer* layer) |
645 { | 644 { |
646 // FIXME: This is not in sync with containingBlock. | 645 // FIXME: This is not in sync with containingBlock. |
647 // RenderObject::canContainFixedPositionedObject() should probably be used | 646 // RenderObject::canContainFixedPositionedObject() should probably be used |
648 // instead. | 647 // instead. |
649 RenderLayerModelObject* layerRenderer = layer->renderer(); | 648 RenderLayerModelObject* layerRenderer = layer->renderer(); |
650 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr
ansform(); | 649 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr
ansform(); |
651 } | 650 } |
652 | 651 |
653 enum StackingOrderDirection { FromBackground, FromForeground }; | 652 void RenderLayer::collectBeforePromotionZOrderList(RenderLayer* ancestorStacking
Context, OwnPtr<Vector<RenderLayer*> >& posZOrderListBeforePromote, OwnPtr<Vecto
r<RenderLayer*> >& negZOrderListBeforePromote) |
| 653 { |
| 654 // FIXME: TemporaryChange should support bit fields. |
| 655 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling; |
| 656 bool oldIsNormalFlowOnly = m_isNormalFlowOnly; |
654 | 657 |
655 // We'd like to be able to iterate through a single paint order list, but for | 658 m_needsCompositedScrolling = false; |
656 // efficiency's sake, we hang onto two lists instead (namely, the pos and neg | 659 m_isNormalFlowOnly = shouldBeNormalFlowOnly(); |
657 // z-order lists produced by CollectLayers). This function allows us to index | |
658 // into these two lists as if they were one. It also allows us to index into | |
659 // this virtual list either from the start or from the end (i.e., in either | |
660 // stacking order direction). | |
661 static const RenderLayer* getStackingOrderElementAt(const Vector<RenderLayer*>*
posZOrderList, const Vector<RenderLayer*>* negZOrderList, const StackingOrderDir
ection direction, const size_t index) | |
662 { | |
663 size_t negZOrderListSize = negZOrderList ? negZOrderList->size() : 0; | |
664 | 660 |
665 if (direction == FromBackground) { | 661 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde
rListBeforePromote, negZOrderListBeforePromote, 0); |
666 if (index < negZOrderListSize) | |
667 return negZOrderList->at(index); | |
668 | 662 |
669 return posZOrderList->at(index - negZOrderListSize); | 663 m_needsCompositedScrolling = oldNeedsCompositedScrolling; |
| 664 m_isNormalFlowOnly = oldIsNormalFlowOnly; |
| 665 |
| 666 const RenderLayer* positionedAncestor = parent(); |
| 667 while (positionedAncestor && !isPositionedContainer(positionedAncestor) && !
positionedAncestor->isStackingContext()) |
| 668 positionedAncestor = positionedAncestor->parent(); |
| 669 if (positionedAncestor && (!isPositionedContainer(positionedAncestor) || pos
itionedAncestor->isStackingContext())) |
| 670 positionedAncestor = 0; |
| 671 |
| 672 if (!posZOrderListBeforePromote) |
| 673 posZOrderListBeforePromote = adoptPtr(new Vector<RenderLayer*>()); |
| 674 else if (posZOrderListBeforePromote->find(this) != notFound) |
| 675 return; |
| 676 |
| 677 // The current layer will appear in the z-order lists after promotion, so |
| 678 // for a meaningful comparison, we must insert it in the z-order lists |
| 679 // before promotion if it does not appear there already. |
| 680 if (!positionedAncestor) { |
| 681 posZOrderListBeforePromote->prepend(this); |
| 682 return; |
670 } | 683 } |
671 | 684 |
672 size_t posZOrderListSize = posZOrderList ? posZOrderList->size() : 0; | 685 for (size_t index = 0; index < posZOrderListBeforePromote->size(); index++)
{ |
| 686 if (posZOrderListBeforePromote->at(index) == positionedAncestor) { |
| 687 posZOrderListBeforePromote->insert(index + 1, this); |
| 688 return; |
| 689 } |
| 690 } |
| 691 } |
673 | 692 |
674 if (index < posZOrderListSize) | 693 void RenderLayer::collectAfterPromotionZOrderList(RenderLayer* ancestorStackingC
ontext, OwnPtr<Vector<RenderLayer*> >& posZOrderListAfterPromote, OwnPtr<Vector<
RenderLayer*> >& negZOrderListAfterPromote) |
675 return posZOrderList->at(posZOrderListSize - index - 1); | 694 { |
| 695 // FIXME: TemporaryChange should support bit fields. |
| 696 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling; |
| 697 bool oldIsNormalFlowOnly = m_isNormalFlowOnly; |
676 | 698 |
677 return negZOrderList->at(negZOrderListSize - (index - posZOrderListSize) - 1
); | 699 m_isNormalFlowOnly = false; |
| 700 m_needsCompositedScrolling = true; |
| 701 |
| 702 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde
rListAfterPromote, negZOrderListAfterPromote, this); |
| 703 |
| 704 m_needsCompositedScrolling = oldNeedsCompositedScrolling; |
| 705 m_isNormalFlowOnly = oldIsNormalFlowOnly; |
678 } | 706 } |
679 | 707 |
680 // Compute what positive and negative z-order lists would look like before and | 708 // Compute what positive and negative z-order lists would look like before and |
681 // after promotion, so we can later ensure that proper stacking order is | 709 // after promotion, so we can later ensure that proper stacking order is |
682 // preserved between the two sets of lists. | 710 // preserved between the two sets of lists. |
683 // | 711 // |
684 // A few examples: | 712 // A few examples: |
685 // c = currentLayer | 713 // c = currentLayer |
686 // - = negative z-order child of currentLayer | 714 // - = negative z-order child of currentLayer |
687 // + = positive z-order child of currentLayer | 715 // + = positive z-order child of currentLayer |
688 // a = positioned ancestor of currentLayer | 716 // a = positioned ancestor of currentLayer |
689 // x = any other RenderLayer in the list | 717 // x = any other RenderLayer in the list |
690 // | 718 // |
691 // (a) xxxxx-----++a+++x | 719 // (a) xxxxx-----++a+++x |
692 // (b) xxx-----c++++++xx | 720 // (b) xxx-----c++++++xx |
693 // | 721 // |
694 // | |
695 // Normally the current layer would be painted in the normal flow list if it | 722 // Normally the current layer would be painted in the normal flow list if it |
696 // doesn't already appear in the positive z-order list. However, in the case | 723 // doesn't already appear in the positive z-order list. However, in the case |
697 // that the layer has a positioned ancestor, it will paint directly after the | 724 // that the layer has a positioned ancestor, it will paint directly after the |
698 // positioned ancestor. In example (a), the current layer would be painted in | 725 // positioned ancestor. In example (a), the current layer would be painted in |
699 // the middle of its own positive z-order children, so promoting would cause a | 726 // the middle of its own positive z-order children, so promoting would cause a |
700 // change in paint order (since a promoted layer will paint all of its positive | 727 // change in paint order (since a promoted layer will paint all of its positive |
701 // z-order children strictly after it paints itself). | 728 // z-order children strictly after it paints itself). |
702 // | 729 // |
703 // In example (b), it is ok to promote the current layer only if it does not | 730 // In example (b), it is ok to promote the current layer only if it does not |
704 // have a background. If it has a background, the background gets painted before | 731 // have a background. If it has a background, the background gets painted before |
705 // the layer's negative z-order children, so again, a promotion would cause a | 732 // the layer's negative z-order children, so again, a promotion would cause a |
706 // change in paint order (causing the background to get painted after the | 733 // change in paint order (causing the background to get painted after the |
707 // negative z-order children instead of before). | 734 // negative z-order children instead of before). |
708 void RenderLayer::collectBeforePromotionZOrderList(RenderLayer* ancestorStacking
Context, OwnPtr<Vector<RenderLayer*> >& posZOrderListBeforePromote, OwnPtr<Vecto
r<RenderLayer*> >& negZOrderListBeforePromote, size_t& posZOrderListSizeBeforePr
omote, size_t& negZOrderListSizeBeforePromote) | 735 // |
| 736 void RenderLayer::computePaintOrderList(PaintOrderListType type, Vector<RefPtr<N
ode> >& list) |
709 { | 737 { |
710 // We can't use TemporaryChange<> here since m_needsCompositedScrolling and | 738 OwnPtr<Vector<RenderLayer*> > posZOrderList; |
711 // m_isNormalFlowOnly are both bitfields, so we have to do it the | 739 OwnPtr<Vector<RenderLayer*> > negZOrderList; |
712 // old-fashioned way. | |
713 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling; | |
714 bool oldIsNormalFlowOnly = m_isNormalFlowOnly; | |
715 | |
716 // Set the flag on the current layer, then rebuild ancestor stacking | |
717 // context's lists. This way, we can see the exact effects that promoting | |
718 // this layer would cause. | |
719 m_needsCompositedScrolling = false; | |
720 m_isNormalFlowOnly = shouldBeNormalFlowOnly(); | |
721 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde
rListBeforePromote, negZOrderListBeforePromote, 0); | |
722 | |
723 m_needsCompositedScrolling = oldNeedsCompositedScrolling; | |
724 m_isNormalFlowOnly = oldIsNormalFlowOnly; | |
725 | |
726 | |
727 posZOrderListSizeBeforePromote = posZOrderListBeforePromote ? posZOrderListB
eforePromote->size() : 0; | |
728 negZOrderListSizeBeforePromote = negZOrderListBeforePromote ? negZOrderListB
eforePromote->size() : 0; | |
729 | |
730 const RenderLayer* positionedAncestor = parent(); | |
731 while (positionedAncestor && !isPositionedContainer(positionedAncestor) && !
positionedAncestor->isStackingContext()) | |
732 positionedAncestor = positionedAncestor->parent(); | |
733 if (positionedAncestor && (!isPositionedContainer(positionedAncestor) || pos
itionedAncestor->isStackingContext())) | |
734 positionedAncestor = 0; | |
735 | |
736 bool currentLayerIsInPosZOrderListBeforePromote = false; | |
737 | |
738 for (size_t index = 0; index < posZOrderListSizeBeforePromote; index++) { | |
739 if (posZOrderListBeforePromote->at(index) == this) { | |
740 currentLayerIsInPosZOrderListBeforePromote = true; | |
741 break; | |
742 } | |
743 } | |
744 | |
745 // Insert this into the posZOrderListBeforePromote directly after the | |
746 // positioned ancestor, if there is one. Otherwise, add it to the very | |
747 // beginning. | |
748 // | |
749 // The current layer will appear in the z-order lists after promotion, so | |
750 // for a meaningful comparison, we must insert it in the z-order lists | |
751 // before promotion if it does not appear there already. | |
752 if (!currentLayerIsInPosZOrderListBeforePromote) { | |
753 if (!positionedAncestor) { | |
754 if (!posZOrderListBeforePromote) | |
755 posZOrderListBeforePromote = adoptPtr(new Vector<RenderLayer*>()
); | |
756 | |
757 posZOrderListBeforePromote->prepend(this); | |
758 posZOrderListSizeBeforePromote++; | |
759 } else { | |
760 for (size_t index = 0; index < posZOrderListSizeBeforePromote; index
++) { | |
761 if (posZOrderListBeforePromote->at(index) == positionedAncestor)
{ | |
762 posZOrderListBeforePromote->insert(index + 1, this); | |
763 posZOrderListSizeBeforePromote++; | |
764 break; | |
765 } | |
766 } | |
767 } | |
768 } | |
769 } | |
770 | |
771 void RenderLayer::collectAfterPromotionZOrderList(RenderLayer* ancestorStackingC
ontext, OwnPtr<Vector<RenderLayer*> >& posZOrderListAfterPromote, OwnPtr<Vector<
RenderLayer*> >& negZOrderListAfterPromote, size_t& posZOrderListSizeAfterPromot
e, size_t& negZOrderListSizeAfterPromote) | |
772 { | |
773 // We can't use TemporaryChange<> here since m_needsCompositedScrolling and | |
774 // m_isNormalFlowOnly are both bitfields, so we have to do it the | |
775 // old-fashioned way. | |
776 bool oldNeedsCompositedScrolling = m_needsCompositedScrolling; | |
777 bool oldIsNormalFlowOnly = m_isNormalFlowOnly; | |
778 | |
779 // Set the flag on the current layer, then rebuild ancestor stacking | |
780 // context's lists. This way, we can see the exact effects that promoting | |
781 // this layer would cause. | |
782 m_isNormalFlowOnly = false; | |
783 m_needsCompositedScrolling = true; | |
784 ancestorStackingContext->rebuildZOrderLists(StopAtStackingContexts, posZOrde
rListAfterPromote, negZOrderListAfterPromote, this); | |
785 | |
786 m_needsCompositedScrolling = oldNeedsCompositedScrolling; | |
787 m_isNormalFlowOnly = oldIsNormalFlowOnly; | |
788 | |
789 posZOrderListSizeAfterPromote = posZOrderListAfterPromote ? posZOrderListAft
erPromote->size() : 0; | |
790 negZOrderListSizeAfterPromote = negZOrderListAfterPromote ? negZOrderListAft
erPromote->size() : 0; | |
791 } | |
792 | |
793 #ifndef NDEBUG | |
794 String RenderLayer::paintOrderListsAsText() | |
795 { | |
796 OwnPtr<Vector<RenderLayer*> > posZOrderListBeforePromote; | |
797 OwnPtr<Vector<RenderLayer*> > negZOrderListBeforePromote; | |
798 OwnPtr<Vector<RenderLayer*> > posZOrderListAfterPromote; | |
799 OwnPtr<Vector<RenderLayer*> > negZOrderListAfterPromote; | |
800 size_t posZOrderListSizeBeforePromote, negZOrderListSizeBeforePromote, posZO
rderListSizeAfterPromote, negZOrderListSizeAfterPromote; | |
801 | 740 |
802 RenderLayer* stackingContext = ancestorStackingContext(); | 741 RenderLayer* stackingContext = ancestorStackingContext(); |
803 | 742 |
804 if (!stackingContext) | 743 if (!stackingContext) |
805 return String(); | 744 return; |
806 | 745 |
807 collectBeforePromotionZOrderList(stackingContext, posZOrderListBeforePromote
, negZOrderListBeforePromote, posZOrderListSizeBeforePromote, negZOrderListSizeB
eforePromote); | 746 switch (type) { |
808 collectAfterPromotionZOrderList(stackingContext, posZOrderListAfterPromote,
negZOrderListAfterPromote, posZOrderListSizeAfterPromote, negZOrderListSizeAfter
Promote); | 747 case BeforePromote: |
809 | 748 collectBeforePromotionZOrderList(stackingContext, posZOrderList, negZOrd
erList); |
810 size_t sizeBeforePromote = posZOrderListSizeBeforePromote + negZOrderListSiz
eBeforePromote; | 749 break; |
811 size_t sizeAfterPromote = posZOrderListSizeAfterPromote + negZOrderListSizeA
fterPromote; | 750 case AfterPromote: |
812 | 751 collectAfterPromotionZOrderList(stackingContext, posZOrderList, negZOrde
rList); |
813 TextStream ts; | 752 break; |
814 | |
815 ts << "Layer: " << this << " \"" << debugName() << "\", z-index: " << render
er()->style()->zIndex() << "\n"; | |
816 | |
817 ts << " stacking context's paint order list BEFORE promote:\n"; | |
818 for (size_t index = 0; index < sizeBeforePromote; index++) { | |
819 const RenderLayer* layerBeforePromote = getStackingOrderElementAt(posZOr
derListBeforePromote.get(), negZOrderListBeforePromote.get(), FromBackground, in
dex); | |
820 ts << " " << layerBeforePromote << " \"" << layerBeforePromote->debug
Name() << "\", z-index: " << layerBeforePromote->renderer()->style()->zIndex() <
< "\n"; | |
821 } | 753 } |
822 | 754 |
823 ts << " stacking context's paint order list AFTER promote:\n"; | 755 if (negZOrderList) { |
824 for (size_t index = 0; index < sizeAfterPromote; index++) { | 756 for (size_t index = 0; index < negZOrderList->size(); ++index) |
825 const RenderLayer* layerAfterPromote = getStackingOrderElementAt(posZOrd
erListAfterPromote.get(), negZOrderListAfterPromote.get(), FromBackground, index
); | 757 list.append(negZOrderList->at(index)->renderer()->node()); |
826 ts << " " << layerAfterPromote << " \"" << layerAfterPromote->debugNa
me() << "\", z-index: " << layerAfterPromote->renderer()->style()->zIndex() << "
\n"; | |
827 } | 758 } |
828 | 759 |
829 return ts.release(); | 760 if (posZOrderList) { |
830 } | 761 for (size_t index = 0; index < posZOrderList->size(); ++index) |
831 #endif | 762 list.append(posZOrderList->at(index)->renderer()->node()); |
832 | |
833 PassRefPtr<NodeList> RenderLayer::paintOrderList(PaintOrderListType type) | |
834 { | |
835 OwnPtr<Vector<RenderLayer*> > posZOrderList; | |
836 OwnPtr<Vector<RenderLayer*> > negZOrderList; | |
837 size_t posZOrderListSize, negZOrderListSize; | |
838 | |
839 RenderLayer* stackingContext = ancestorStackingContext(); | |
840 | |
841 if (!stackingContext) | |
842 return 0; | |
843 | |
844 switch(type) { | |
845 case BeforePromote: | |
846 collectBeforePromotionZOrderList(stackingContext, posZOrderList, neg
ZOrderList, posZOrderListSize, negZOrderListSize); | |
847 break; | |
848 | |
849 case AfterPromote: | |
850 collectAfterPromotionZOrderList(stackingContext, posZOrderList, negZ
OrderList, posZOrderListSize, negZOrderListSize); | |
851 break; | |
852 | |
853 default: | |
854 return 0; | |
855 } | 763 } |
856 | |
857 size_t size = posZOrderListSize + negZOrderListSize; | |
858 | |
859 ListHashSet<RefPtr<Node> > list; | |
860 for (size_t index = 0; index < size; index++) { | |
861 const RenderLayer* layer = getStackingOrderElementAt(posZOrderList.get()
, negZOrderList.get(), FromBackground, index); | |
862 list.add(layer->renderer()->node()); | |
863 } | |
864 | |
865 return StaticHashSetNodeList::adopt(list); | |
866 } | 764 } |
867 | 765 |
868 void RenderLayer::computeRepaintRects(const RenderLayerModelObject* repaintConta
iner, const RenderGeometryMap* geometryMap) | 766 void RenderLayer::computeRepaintRects(const RenderLayerModelObject* repaintConta
iner, const RenderGeometryMap* geometryMap) |
869 { | 767 { |
870 ASSERT(!m_visibleContentStatusDirty); | 768 ASSERT(!m_visibleContentStatusDirty); |
871 | 769 |
872 m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer); | 770 m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer); |
873 m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer, geometr
yMap); | 771 m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer, geometr
yMap); |
874 } | 772 } |
875 | 773 |
(...skipping 5684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6560 } | 6458 } |
6561 } | 6459 } |
6562 | 6460 |
6563 void showLayerTree(const WebCore::RenderObject* renderer) | 6461 void showLayerTree(const WebCore::RenderObject* renderer) |
6564 { | 6462 { |
6565 if (!renderer) | 6463 if (!renderer) |
6566 return; | 6464 return; |
6567 showLayerTree(renderer->enclosingLayer()); | 6465 showLayerTree(renderer->enclosingLayer()); |
6568 } | 6466 } |
6569 #endif | 6467 #endif |
OLD | NEW |