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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 } | 137 } |
138 | 138 |
139 RenderLayer::RenderLayer(RenderLayerModelObject* renderer) | 139 RenderLayer::RenderLayer(RenderLayerModelObject* renderer) |
140 : m_inResizeMode(false) | 140 : m_inResizeMode(false) |
141 , m_scrollDimensionsDirty(true) | 141 , m_scrollDimensionsDirty(true) |
142 , m_normalFlowListDirty(true) | 142 , m_normalFlowListDirty(true) |
143 , m_hasSelfPaintingLayerDescendant(false) | 143 , m_hasSelfPaintingLayerDescendant(false) |
144 , m_hasSelfPaintingLayerDescendantDirty(false) | 144 , m_hasSelfPaintingLayerDescendantDirty(false) |
145 , m_hasOutOfFlowPositionedDescendant(false) | 145 , m_hasOutOfFlowPositionedDescendant(false) |
146 , m_hasOutOfFlowPositionedDescendantDirty(true) | 146 , m_hasOutOfFlowPositionedDescendantDirty(true) |
147 , m_hasUnclippedDescendant(false) | |
147 , m_forceNeedsCompositedScrolling(DoNotForceCompositedScrolling) | 148 , m_forceNeedsCompositedScrolling(DoNotForceCompositedScrolling) |
148 , m_needsCompositedScrolling(false) | 149 , m_needsCompositedScrolling(false) |
149 , m_descendantsAreContiguousInStackingOrder(false) | 150 , m_descendantsAreContiguousInStackingOrder(false) |
150 , m_descendantsAreContiguousInStackingOrderDirty(true) | 151 , m_descendantsAreContiguousInStackingOrderDirty(true) |
151 , m_isRootLayer(renderer->isRenderView()) | 152 , m_isRootLayer(renderer->isRenderView()) |
152 , m_usedTransparency(false) | 153 , m_usedTransparency(false) |
153 , m_paintingInsideReflection(false) | 154 , m_paintingInsideReflection(false) |
154 , m_inOverflowRelayout(false) | 155 , m_inOverflowRelayout(false) |
155 , m_repaintStatus(NeedsNormalRepaint) | 156 , m_repaintStatus(NeedsNormalRepaint) |
156 , m_visibleContentStatusDirty(true) | 157 , m_visibleContentStatusDirty(true) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 if (FrameView* frameView = frame->view()) | 220 if (FrameView* frameView = frame->view()) |
220 frameView->removeScrollableArea(this); | 221 frameView->removeScrollableArea(this); |
221 } | 222 } |
222 | 223 |
223 if (!m_renderer->documentBeingDestroyed()) { | 224 if (!m_renderer->documentBeingDestroyed()) { |
224 Node* node = m_renderer->node(); | 225 Node* node = m_renderer->node(); |
225 if (node && node->isElementNode()) | 226 if (node && node->isElementNode()) |
226 toElement(node)->setSavedLayerScrollOffset(m_scrollOffset); | 227 toElement(node)->setSavedLayerScrollOffset(m_scrollOffset); |
227 } | 228 } |
228 | 229 |
230 if (!m_renderer->documentBeingDestroyed()) | |
231 compositor()->removeOutOfFlowPositionedLayer(this); | |
Julien - ping for review
2013/05/03 21:15:13
It's weird that you try to remove |this| even if i
Ian Vollick
2013/05/04 03:33:00
The layer can get destructed when we cease to be o
| |
232 | |
229 destroyScrollbar(HorizontalScrollbar); | 233 destroyScrollbar(HorizontalScrollbar); |
230 destroyScrollbar(VerticalScrollbar); | 234 destroyScrollbar(VerticalScrollbar); |
231 | 235 |
232 if (renderer()->frame() && renderer()->frame()->page()) { | 236 if (renderer()->frame() && renderer()->frame()->page()) { |
233 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->pa ge()->scrollingCoordinator()) | 237 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->pa ge()->scrollingCoordinator()) |
234 scrollingCoordinator->willDestroyScrollableArea(this); | 238 scrollingCoordinator->willDestroyScrollableArea(this); |
235 } | 239 } |
236 | 240 |
237 if (m_reflection) | 241 if (m_reflection) |
238 removeReflection(); | 242 removeReflection(); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
469 layer->m_hasSelfPaintingLayerDescendantDirty = true; | 473 layer->m_hasSelfPaintingLayerDescendantDirty = true; |
470 // If we have reached a self-painting layer, we know our parent should h ave a self-painting descendant | 474 // If we have reached a self-painting layer, we know our parent should h ave a self-painting descendant |
471 // in this case, there is no need to dirty our ancestors further. | 475 // in this case, there is no need to dirty our ancestors further. |
472 if (layer->isSelfPaintingLayer()) { | 476 if (layer->isSelfPaintingLayer()) { |
473 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant()); | 477 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant()); |
474 break; | 478 break; |
475 } | 479 } |
476 } | 480 } |
477 } | 481 } |
478 | 482 |
483 void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant() | |
484 { | |
485 for (RenderLayer* layer = this; layer; layer = layer->parent()) { | |
486 if (!layer->m_hasOutOfFlowPositionedDescendantDirty && layer->hasOutOfFl owPositionedDescendant()) | |
487 break; | |
488 | |
489 layer->m_hasOutOfFlowPositionedDescendantDirty = false; | |
490 layer->m_hasOutOfFlowPositionedDescendant = true; | |
491 } | |
492 } | |
493 | |
494 void RenderLayer::dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus() | |
495 { | |
496 for (RenderLayer* layer = this; layer; layer = layer->parent()) { | |
497 layer->m_hasOutOfFlowPositionedDescendantDirty = true; | |
498 | |
499 // We may or may not have an unclipped descendant. If we do, we'll reset | |
500 // this to true the next time composited scrolling state is updated. | |
501 layer->m_hasUnclippedDescendant = false; | |
502 | |
503 // If we have reached an out of flow positioned layer, we know our paren t should have an out-of-flow positioned descendant. | |
504 // In this case, there is no need to dirty our ancestors further. | |
505 if (layer->renderer()->isOutOfFlowPositioned()) { | |
506 ASSERT(!parent() || parent()->m_hasOutOfFlowPositionedDescendantDirt y || parent()->hasOutOfFlowPositionedDescendant()); | |
507 break; | |
508 } | |
509 } | |
510 } | |
511 | |
479 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const | 512 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const |
480 { | 513 { |
481 return renderer()->frame() | 514 return renderer()->frame() |
482 && renderer()->frame()->page() | 515 && renderer()->frame()->page() |
483 && renderer()->frame()->page()->settings()->acceleratedCompositingForOve rflowScrollEnabled(); | 516 && renderer()->frame()->page()->settings()->acceleratedCompositingForOve rflowScrollEnabled(); |
484 } | 517 } |
485 | 518 |
486 // If we are a stacking container, then this function will determine if our | 519 // If we are a stacking container, then this function will determine if our |
487 // descendants for a contiguous block in stacking order. This is required in | 520 // descendants for a contiguous block in stacking order. This is required in |
488 // order for an element to be safely promoted to a stacking container. It is saf e | 521 // order for an element to be safely promoted to a stacking container. It is saf e |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
558 // maxStackIndex - minStackIndex == numSCDescendants | 591 // maxStackIndex - minStackIndex == numSCDescendants |
559 // ===> 3 - 0 == 3 | 592 // ===> 3 - 0 == 3 |
560 // ===> 3 == 3 | 593 // ===> 3 == 3 |
561 // | 594 // |
562 // And we would conclude that C could be promoted. | 595 // And we would conclude that C could be promoted. |
563 void RenderLayer::updateDescendantsAreContiguousInStackingOrder() | 596 void RenderLayer::updateDescendantsAreContiguousInStackingOrder() |
564 { | 597 { |
565 if (!m_descendantsAreContiguousInStackingOrderDirty || !isStackingContext() || !acceleratedCompositingForOverflowScrollEnabled()) | 598 if (!m_descendantsAreContiguousInStackingOrderDirty || !isStackingContext() || !acceleratedCompositingForOverflowScrollEnabled()) |
566 return; | 599 return; |
567 | 600 |
568 ASSERT(!m_normalFlowListDirty); | |
569 ASSERT(!m_zOrderListsDirty); | |
Julien - ping for review
2013/05/03 21:15:13
It's the second time I see this ASSERT removed. Co
Ian Vollick
2013/05/04 03:33:00
I don't think these ASSERTS were ever useful. This
| |
570 | |
571 OwnPtr<Vector<RenderLayer*> > posZOrderList; | 601 OwnPtr<Vector<RenderLayer*> > posZOrderList; |
572 OwnPtr<Vector<RenderLayer*> > negZOrderList; | 602 OwnPtr<Vector<RenderLayer*> > negZOrderList; |
573 rebuildZOrderLists(StopAtStackingContexts, posZOrderList, negZOrderList); | 603 rebuildZOrderLists(StopAtStackingContexts, posZOrderList, negZOrderList); |
574 | 604 |
575 // Create a reverse lookup. | 605 // Create a reverse lookup. |
576 HashMap<const RenderLayer*, int> lookup; | 606 HashMap<const RenderLayer*, int> lookup; |
577 | 607 |
578 if (negZOrderList) { | 608 if (negZOrderList) { |
579 int stackingOrderIndex = -1; | 609 int stackingOrderIndex = -1; |
580 size_t listSize = negZOrderList->size(); | 610 size_t listSize = negZOrderList->size(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
622 int childMaxIndex = 0; | 652 int childMaxIndex = 0; |
623 int childCount = 0; | 653 int childCount = 0; |
624 child->updateDescendantsAreContiguousInStackingOrderRecursive(lookup, ch ildMinIndex, childMaxIndex, childCount, false); | 654 child->updateDescendantsAreContiguousInStackingOrderRecursive(lookup, ch ildMinIndex, childMaxIndex, childCount, false); |
625 if (childCount) { | 655 if (childCount) { |
626 count += childCount; | 656 count += childCount; |
627 minIndex = std::min(minIndex, childMinIndex); | 657 minIndex = std::min(minIndex, childMinIndex); |
628 maxIndex = std::max(maxIndex, childMaxIndex); | 658 maxIndex = std::max(maxIndex, childMaxIndex); |
629 } | 659 } |
630 } | 660 } |
631 | 661 |
632 if (!isStackingContext()) { | 662 if (!isStackingContext()) |
633 bool newValue = maxIndex - minIndex == count; | 663 m_descendantsAreContiguousInStackingOrder = maxIndex - minIndex == count ; |
Julien - ping for review
2013/05/03 21:15:13
As you touch this line, I would put some parenthes
Ian Vollick
2013/05/04 03:33:00
Done.
| |
634 bool didUpdate = newValue != m_descendantsAreContiguousInStackingOrder; | |
635 m_descendantsAreContiguousInStackingOrder = newValue; | |
636 if (didUpdate) | |
637 updateNeedsCompositedScrolling(); | |
638 } | |
639 } | 664 } |
640 | 665 |
641 static inline bool isPositionedContainer(const RenderLayer* layer) | 666 static inline bool isPositionedContainer(const RenderLayer* layer) |
642 { | 667 { |
643 // FIXME: This is not in sync with containingBlock. | 668 // FIXME: This is not in sync with containingBlock. |
644 // RenderObject::canContainFixedPositionedObject() should probably be used | 669 // RenderObject::canContainFixedPositionedObject() should probably be used |
645 // instead. | 670 // instead. |
646 RenderLayerModelObject* layerRenderer = layer->renderer(); | 671 RenderLayerModelObject* layerRenderer = layer->renderer(); |
647 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform(); | 672 return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTr ansform(); |
648 } | 673 } |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1056 if (curr == ancestorStackingContainer) | 1081 if (curr == ancestorStackingContainer) |
1057 return; | 1082 return; |
1058 } | 1083 } |
1059 } | 1084 } |
1060 | 1085 |
1061 bool RenderLayer::canBeStackingContainer() const | 1086 bool RenderLayer::canBeStackingContainer() const |
1062 { | 1087 { |
1063 if (isStackingContext() || !ancestorStackingContainer()) | 1088 if (isStackingContext() || !ancestorStackingContainer()) |
1064 return true; | 1089 return true; |
1065 | 1090 |
1091 ASSERT(m_descendantsAreContiguousInStackingOrderDirty); | |
Julien - ping for review
2013/05/03 21:15:13
Isn't the ASSERT backwards? (I don't see a good ar
Ian Vollick
2013/05/04 03:33:00
Whoa! Yeah, it's backwards. The typo'd ASSERT was
| |
1066 return m_descendantsAreContiguousInStackingOrder; | 1092 return m_descendantsAreContiguousInStackingOrder; |
1067 } | 1093 } |
1068 | 1094 |
1069 void RenderLayer::setHasVisibleContent() | 1095 void RenderLayer::setHasVisibleContent() |
1070 { | 1096 { |
1071 if (m_hasVisibleContent && !m_visibleContentStatusDirty) { | 1097 if (m_hasVisibleContent && !m_visibleContentStatusDirty) { |
1072 ASSERT(!parent() || parent()->hasVisibleDescendant()); | 1098 ASSERT(!parent() || parent()->hasVisibleDescendant()); |
1073 return; | 1099 return; |
1074 } | 1100 } |
1075 | 1101 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1112 { | 1138 { |
1113 for (RenderLayer* layer = this; layer; layer = layer->parent()) { | 1139 for (RenderLayer* layer = this; layer; layer = layer->parent()) { |
1114 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendan t()) | 1140 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendan t()) |
1115 break; | 1141 break; |
1116 | 1142 |
1117 layer->m_hasVisibleDescendant = true; | 1143 layer->m_hasVisibleDescendant = true; |
1118 layer->m_visibleDescendantStatusDirty = false; | 1144 layer->m_visibleDescendantStatusDirty = false; |
1119 } | 1145 } |
1120 } | 1146 } |
1121 | 1147 |
1122 void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* o utOfFlowDescendantContainingBlocks) | 1148 // This method is called on all out of flow positioned layers. It simply walks |
1149 // up to its containing block marking every layer it passes as having an | |
1150 // 'unclipped' descendant. The map is used to prevent wasted walking. If we | |
1151 // have already passed layer A heading towards containing block B, there's no | |
1152 // need to do it again; we can early out. | |
1153 void RenderLayer::updateHasUnclippedDescendant(RenderLayer::AncestorContainingBl ockMap& map) | |
1154 { | |
1155 ASSERT(renderer()->isOutOfFlowPositioned()); | |
1156 if (!m_hasVisibleContent && !m_hasVisibleDescendant) | |
1157 return; | |
1158 | |
1159 const RenderObject* containingBlock = renderer()->containingBlock(); | |
1160 for (RenderLayer* ancestor = parent(); ancestor && ancestor->renderer() != c ontainingBlock; ancestor = ancestor->parent()) { | |
1161 if (!map.contains(ancestor)) { | |
Julien - ping for review
2013/05/03 21:15:13
Ninja trick that avoids 3 hash lookups per call:
Ian Vollick
2013/05/04 03:33:00
Done.
Ian Vollick
2013/05/04 03:33:00
Done.
| |
1162 OwnPtr<HashSet<const RenderObject*> > containingBlocks = adoptPtr(ne w HashSet<const RenderObject*>); | |
1163 containingBlocks->add(containingBlock); | |
1164 map.add(ancestor, containingBlocks.release()); | |
1165 } else if (!map.get(ancestor)->contains(containingBlock)) { | |
1166 map.get(ancestor)->add(containingBlock); | |
1167 } else { | |
1168 break; | |
1169 } | |
1170 | |
1171 ancestor->m_hasUnclippedDescendant = true; | |
1172 } | |
1173 } | |
1174 | |
1175 void RenderLayer::updateDescendantDependentFlags() | |
1123 { | 1176 { |
1124 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) { | 1177 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) { |
1125 const bool hadVisibleDescendant = m_hasVisibleDescendant; | |
1126 const bool hadOutOfFlowPositionedDescendant = m_hasOutOfFlowPositionedDe scendant; | |
1127 | |
1128 m_hasVisibleDescendant = false; | 1178 m_hasVisibleDescendant = false; |
1129 m_hasSelfPaintingLayerDescendant = false; | 1179 m_hasSelfPaintingLayerDescendant = false; |
1130 m_hasOutOfFlowPositionedDescendant = false; | 1180 m_hasOutOfFlowPositionedDescendant = false; |
1131 | 1181 |
1132 HashSet<const RenderObject*> childOutOfFlowDescendantContainingBlocks; | |
1133 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { | 1182 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { |
1134 childOutOfFlowDescendantContainingBlocks.clear(); | 1183 child->updateDescendantDependentFlags(); |
1135 child->updateDescendantDependentFlags(&childOutOfFlowDescendantConta iningBlocks); | |
1136 | |
1137 bool childIsOutOfFlowPositioned = child->renderer() && child->render er()->isOutOfFlowPositioned(); | |
1138 if (childIsOutOfFlowPositioned) | |
1139 childOutOfFlowDescendantContainingBlocks.add(child->renderer()-> containingBlock()); | |
1140 | |
1141 if (outOfFlowDescendantContainingBlocks) { | |
1142 HashSet<const RenderObject*>::const_iterator it = childOutOfFlow DescendantContainingBlocks.begin(); | |
1143 for (; it != childOutOfFlowDescendantContainingBlocks.end(); ++i t) | |
1144 outOfFlowDescendantContainingBlocks->add(*it); | |
1145 } | |
1146 | 1184 |
1147 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_h asVisibleDescendant; | 1185 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_h asVisibleDescendant; |
1148 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() | | child->hasSelfPaintingLayerDescendant(); | 1186 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() | | child->hasSelfPaintingLayerDescendant(); |
1149 bool hasOutOfFlowPositionedDescendant = hasVisibleDescendant && (!ch ildOutOfFlowDescendantContainingBlocks.isEmpty() || child->hasOutOfFlowPositione dDescendant()); | 1187 bool hasOutOfFlowPositionedDescendant = child->renderer()->isOutOfFl owPositioned() || child->hasOutOfFlowPositionedDescendant(); |
1150 | 1188 |
1151 m_hasVisibleDescendant |= hasVisibleDescendant; | 1189 m_hasVisibleDescendant |= hasVisibleDescendant; |
1152 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant; | 1190 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant; |
1153 m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescenda nt; | 1191 m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescenda nt; |
1154 | 1192 |
1155 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && m_ hasOutOfFlowPositionedDescendant) | 1193 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && ha sOutOfFlowPositionedDescendant) |
1156 break; | 1194 break; |
1157 } | 1195 } |
1158 | 1196 |
1159 if (outOfFlowDescendantContainingBlocks && renderer()) | |
1160 outOfFlowDescendantContainingBlocks->remove(renderer()); | |
1161 | |
1162 m_visibleDescendantStatusDirty = false; | 1197 m_visibleDescendantStatusDirty = false; |
1163 m_hasSelfPaintingLayerDescendantDirty = false; | 1198 m_hasSelfPaintingLayerDescendantDirty = false; |
1164 m_hasOutOfFlowPositionedDescendantDirty = false; | 1199 m_hasOutOfFlowPositionedDescendantDirty = false; |
1165 | |
1166 if (m_hasVisibleDescendant != hadVisibleDescendant || m_hasOutOfFlowPosi tionedDescendant != hadOutOfFlowPositionedDescendant) | |
1167 updateNeedsCompositedScrolling(); | |
1168 } | 1200 } |
1169 | 1201 |
1170 if (m_visibleContentStatusDirty) { | 1202 if (m_visibleContentStatusDirty) { |
1171 const bool hadVisibleContent = m_hasVisibleContent; | |
1172 if (renderer()->style()->visibility() == VISIBLE) | 1203 if (renderer()->style()->visibility() == VISIBLE) |
1173 m_hasVisibleContent = true; | 1204 m_hasVisibleContent = true; |
1174 else { | 1205 else { |
1175 // layer may be hidden but still have some visible content, check fo r this | 1206 // layer may be hidden but still have some visible content, check fo r this |
1176 m_hasVisibleContent = false; | 1207 m_hasVisibleContent = false; |
1177 RenderObject* r = renderer()->firstChild(); | 1208 RenderObject* r = renderer()->firstChild(); |
1178 while (r) { | 1209 while (r) { |
1179 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { | 1210 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { |
1180 m_hasVisibleContent = true; | 1211 m_hasVisibleContent = true; |
1181 break; | 1212 break; |
1182 } | 1213 } |
1183 if (r->firstChild() && !r->hasLayer()) | 1214 if (r->firstChild() && !r->hasLayer()) |
1184 r = r->firstChild(); | 1215 r = r->firstChild(); |
1185 else if (r->nextSibling()) | 1216 else if (r->nextSibling()) |
1186 r = r->nextSibling(); | 1217 r = r->nextSibling(); |
1187 else { | 1218 else { |
1188 do { | 1219 do { |
1189 r = r->parent(); | 1220 r = r->parent(); |
1190 if (r == renderer()) | 1221 if (r == renderer()) |
1191 r = 0; | 1222 r = 0; |
1192 } while (r && !r->nextSibling()); | 1223 } while (r && !r->nextSibling()); |
1193 if (r) | 1224 if (r) |
1194 r = r->nextSibling(); | 1225 r = r->nextSibling(); |
1195 } | 1226 } |
1196 } | 1227 } |
1197 } | 1228 } |
1198 m_visibleContentStatusDirty = false; | 1229 m_visibleContentStatusDirty = false; |
1199 if (hadVisibleContent != m_hasVisibleContent) | |
1200 updateNeedsCompositedScrolling(); | |
1201 } | 1230 } |
1202 } | 1231 } |
1203 | 1232 |
1204 void RenderLayer::dirty3DTransformedDescendantStatus() | 1233 void RenderLayer::dirty3DTransformedDescendantStatus() |
1205 { | 1234 { |
1206 RenderLayer* curr = ancestorStackingContainer(); | 1235 RenderLayer* curr = ancestorStackingContainer(); |
1207 if (curr) | 1236 if (curr) |
1208 curr->m_3DTransformedDescendantStatusDirty = true; | 1237 curr->m_3DTransformedDescendantStatusDirty = true; |
1209 | 1238 |
1210 // This propagates up through preserve-3d hierarchies to the enclosing flatt ening layer. | 1239 // 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... | |
1761 child->setParent(this); | 1790 child->setParent(this); |
1762 | 1791 |
1763 if (child->isNormalFlowOnly()) | 1792 if (child->isNormalFlowOnly()) |
1764 dirtyNormalFlowList(); | 1793 dirtyNormalFlowList(); |
1765 | 1794 |
1766 if (!child->isNormalFlowOnly() || child->firstChild()) { | 1795 if (!child->isNormalFlowOnly() || child->firstChild()) { |
1767 // Dirty the z-order list in which we are contained. The ancestorStackin gContainer() can be null in the | 1796 // Dirty the z-order list in which we are contained. The ancestorStackin gContainer() can be null in the |
1768 // case where we're building up generated content layers. This is ok, si nce the lists will start | 1797 // case where we're building up generated content layers. This is ok, si nce the lists will start |
1769 // off dirty in that case anyway. | 1798 // off dirty in that case anyway. |
1770 child->dirtyStackingContainerZOrderLists(); | 1799 child->dirtyStackingContainerZOrderLists(); |
1771 | |
1772 // Adding an out of flow positioned descendant can only affect | |
1773 // the opt-in decision for layers beneath and including our | |
1774 // containing block. | |
1775 RenderObject* containingBlock = child->renderer()->containingBlock(); | |
1776 for (RenderLayer* layer = child; layer; layer = layer->parent()) { | |
1777 layer->updateNeedsCompositedScrolling(); | |
1778 if (layer->renderer() == containingBlock) | |
1779 break; | |
1780 } | |
1781 } | 1800 } |
1782 | 1801 |
1783 child->updateDescendantDependentFlags(); | 1802 child->updateDescendantDependentFlags(); |
1784 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) | 1803 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) |
1785 setAncestorChainHasVisibleDescendant(); | 1804 setAncestorChainHasVisibleDescendant(); |
1786 | 1805 |
1787 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) | 1806 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) |
1788 setAncestorChainHasSelfPaintingLayerDescendant(); | 1807 setAncestorChainHasSelfPaintingLayerDescendant(); |
1789 | 1808 |
1790 if (child->renderer() && (child->renderer()->isOutOfFlowPositioned() || chil d->hasOutOfFlowPositionedDescendant())) | 1809 if (child->renderer() && (child->renderer()->isOutOfFlowPositioned() || chil d->hasOutOfFlowPositionedDescendant())) { |
1791 setAncestorChainHasOutOfFlowPositionedDescendant(child->renderer()->cont ainingBlock()); | 1810 // Now that the out of flow positioned descendant is in the tree, we |
1811 // need to tell the compositor to reevaluate the compositing | |
1812 // requirements since we may be able to mark more layers as having | |
1813 // an 'unclipped' descendant. | |
1814 compositor()->setNeedsUpdateCompositingRequirementsState(); | |
1815 setAncestorChainHasOutOfFlowPositionedDescendant(); | |
1816 } | |
1792 | 1817 |
1793 compositor()->layerWasAdded(this, child); | 1818 compositor()->layerWasAdded(this, child); |
1794 } | 1819 } |
1795 | 1820 |
1796 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) | 1821 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) |
1797 { | 1822 { |
1798 if (!renderer()->documentBeingDestroyed()) | 1823 if (!renderer()->documentBeingDestroyed()) |
1799 compositor()->layerWillBeRemoved(this, oldChild); | 1824 compositor()->layerWillBeRemoved(this, oldChild); |
1800 | 1825 |
1801 // remove the child | 1826 // remove the child |
1802 if (oldChild->previousSibling()) | 1827 if (oldChild->previousSibling()) |
1803 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); | 1828 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); |
1804 if (oldChild->nextSibling()) | 1829 if (oldChild->nextSibling()) |
1805 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()) ; | 1830 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()) ; |
1806 | 1831 |
1807 if (m_first == oldChild) | 1832 if (m_first == oldChild) |
1808 m_first = oldChild->nextSibling(); | 1833 m_first = oldChild->nextSibling(); |
1809 if (m_last == oldChild) | 1834 if (m_last == oldChild) |
1810 m_last = oldChild->previousSibling(); | 1835 m_last = oldChild->previousSibling(); |
1811 | 1836 |
1812 if (oldChild->isNormalFlowOnly()) | 1837 if (oldChild->isNormalFlowOnly()) |
1813 dirtyNormalFlowList(); | 1838 dirtyNormalFlowList(); |
1814 if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) { | 1839 if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) { |
1815 // Dirty the z-order list in which we are contained. When called via th e | 1840 // Dirty the z-order list in which we are contained. When called via th e |
1816 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected | 1841 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected |
1817 // from the main layer tree, so we need to null-check the |stackingConta iner| value. | 1842 // from the main layer tree, so we need to null-check the |stackingConta iner| value. |
1818 oldChild->dirtyStackingContainerZOrderLists(); | 1843 oldChild->dirtyStackingContainerZOrderLists(); |
1819 | |
1820 // This could affect whether or not a layer has an out of flow | |
1821 // positioned descendant so we need to schedule some updates. | |
1822 // Removing an out of flow positioned descendant can only affect | |
1823 // the opt-in decision for layers beneath and including the old child's | |
1824 // containing block. | |
1825 RenderObject* containingBlock = oldChild->renderer()->containingBlock(); | |
1826 for (RenderLayer* layer = this; layer; layer = layer->parent()) { | |
1827 layer->updateNeedsCompositedScrolling(); | |
1828 if (layer->renderer() == containingBlock) | |
1829 break; | |
1830 } | |
1831 } | 1844 } |
1832 | 1845 |
1833 if ((oldChild->renderer() && oldChild->renderer()->isOutOfFlowPositioned()) || oldChild->hasOutOfFlowPositionedDescendant()) | |
1834 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus(); | |
1835 | |
1836 oldChild->setPreviousSibling(0); | 1846 oldChild->setPreviousSibling(0); |
1837 oldChild->setNextSibling(0); | 1847 oldChild->setNextSibling(0); |
1838 oldChild->setParent(0); | 1848 oldChild->setParent(0); |
1839 | 1849 |
1840 oldChild->updateDescendantDependentFlags(); | 1850 oldChild->updateDescendantDependentFlags(); |
1851 if ((oldChild->renderer() && oldChild->renderer()->isOutOfFlowPositioned()) || oldChild->hasOutOfFlowPositionedDescendant()) { | |
1852 // It may now be the case that a layer no longer has an unclipped | |
1853 // descendant. Let the compositor know that it needs to reevaluate | |
1854 // its compositing requirements to check this. | |
1855 compositor()->setNeedsUpdateCompositingRequirementsState(); | |
1856 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus(); | |
1857 } | |
1858 | |
1841 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) | 1859 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) |
1842 dirtyAncestorChainVisibleDescendantStatus(); | 1860 dirtyAncestorChainVisibleDescendantStatus(); |
1843 | 1861 |
1844 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescend ant()) | 1862 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescend ant()) |
1845 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); | 1863 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); |
1846 | 1864 |
1847 return oldChild; | 1865 return oldChild; |
1848 } | 1866 } |
1849 | 1867 |
1850 void RenderLayer::removeOnlyThisLayer() | 1868 void RenderLayer::removeOnlyThisLayer() |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2059 return true; | 2077 return true; |
2060 case ForceCompositedScrollingOff: | 2078 case ForceCompositedScrollingOff: |
2061 return false; | 2079 return false; |
2062 } | 2080 } |
2063 | 2081 |
2064 return m_needsCompositedScrolling; | 2082 return m_needsCompositedScrolling; |
2065 } | 2083 } |
2066 | 2084 |
2067 void RenderLayer::updateNeedsCompositedScrolling() | 2085 void RenderLayer::updateNeedsCompositedScrolling() |
2068 { | 2086 { |
2087 if (RenderLayer* ancestor = ancestorStackingContext()) | |
2088 ancestor->updateDescendantsAreContiguousInStackingOrder(); | |
2089 | |
2069 bool needsCompositedScrolling = false; | 2090 bool needsCompositedScrolling = false; |
2070 | 2091 |
2071 FrameView* frameView = renderer()->view()->frameView(); | 2092 FrameView* frameView = renderer()->view()->frameView(); |
2072 if (frameView && frameView->containsScrollableArea(this)) { | 2093 if (frameView && frameView->containsScrollableArea(this)) { |
2073 updateDescendantDependentFlags(); | 2094 updateDescendantDependentFlags(); |
2074 | 2095 |
2075 bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScro llEnabled() | 2096 bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScro llEnabled() |
2076 && canBeStackingContainer() | 2097 && canBeStackingContainer() |
2077 && !hasOutOfFlowPositionedDescendant(); | 2098 && !hasUnclippedDescendant(); |
2078 | 2099 |
2079 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) | 2100 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) |
2080 needsCompositedScrolling = forceUseCompositedScrolling || renderer()->st yle()->useTouchOverflowScrolling(); | 2101 needsCompositedScrolling = forceUseCompositedScrolling || renderer()->st yle()->useTouchOverflowScrolling(); |
2081 #else | 2102 #else |
2082 needsCompositedScrolling = forceUseCompositedScrolling; | 2103 needsCompositedScrolling = forceUseCompositedScrolling; |
2083 #endif | 2104 #endif |
2084 // We gather a boolean value for use with Google UMA histograms to | 2105 // We gather a boolean value for use with Google UMA histograms to |
2085 // quantify the actual effects of a set of patches attempting to | 2106 // quantify the actual effects of a set of patches attempting to |
2086 // relax composited scrolling requirements, thereby increasing the | 2107 // relax composited scrolling requirements, thereby increasing the |
2087 // number of composited overflow divs. | 2108 // number of composited overflow divs. |
2088 if (acceleratedCompositingForOverflowScrollEnabled()) | 2109 if (acceleratedCompositingForOverflowScrollEnabled()) |
2089 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScro lling", needsCompositedScrolling, 2); | 2110 HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScro lling", needsCompositedScrolling, 2); |
2090 } | 2111 } |
2091 | 2112 |
2113 setNeedsCompositedScrolling(needsCompositedScrolling); | |
2114 } | |
2115 | |
2116 void RenderLayer::setNeedsCompositedScrolling(bool needsCompositedScrolling) | |
2117 { | |
2092 if (m_needsCompositedScrolling == needsCompositedScrolling) | 2118 if (m_needsCompositedScrolling == needsCompositedScrolling) |
2093 return; | 2119 return; |
2094 | 2120 |
2095 m_needsCompositedScrolling = needsCompositedScrolling; | 2121 m_needsCompositedScrolling = needsCompositedScrolling; |
2096 | 2122 |
2097 // Note, the z-order lists may need to be rebuilt, but our code guarantees | 2123 // Note, the z-order lists may need to be rebuilt, but our code guarantees |
2098 // that we have not affected stacking, so we will not dirty | 2124 // that we have not affected stacking, so we will not dirty |
2099 // m_canBePromotedToStackingContainer for either us or our stacking context | 2125 // m_canBePromotedToStackingContainer for either us or our stacking context |
2100 // or container. | 2126 // or container. |
2101 didUpdateNeedsCompositedScrolling(); | 2127 didUpdateNeedsCompositedScrolling(); |
(...skipping 3507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5609 | 5635 |
5610 if (m_posZOrderList) | 5636 if (m_posZOrderList) |
5611 m_posZOrderList->clear(); | 5637 m_posZOrderList->clear(); |
5612 if (m_negZOrderList) | 5638 if (m_negZOrderList) |
5613 m_negZOrderList->clear(); | 5639 m_negZOrderList->clear(); |
5614 m_zOrderListsDirty = true; | 5640 m_zOrderListsDirty = true; |
5615 | 5641 |
5616 m_descendantsAreContiguousInStackingOrderDirty = true; | 5642 m_descendantsAreContiguousInStackingOrderDirty = true; |
5617 | 5643 |
5618 if (!renderer()->documentBeingDestroyed()) { | 5644 if (!renderer()->documentBeingDestroyed()) { |
5645 compositor()->setNeedsUpdateCompositingRequirementsState(); | |
5619 compositor()->setCompositingLayersNeedRebuild(); | 5646 compositor()->setCompositingLayersNeedRebuild(); |
5620 if (acceleratedCompositingForOverflowScrollEnabled()) | 5647 if (acceleratedCompositingForOverflowScrollEnabled()) |
5621 compositor()->setShouldReevaluateCompositingAfterLayout(); | 5648 compositor()->setShouldReevaluateCompositingAfterLayout(); |
5622 } | 5649 } |
5623 } | 5650 } |
5624 | 5651 |
5625 void RenderLayer::dirtyStackingContainerZOrderLists() | 5652 void RenderLayer::dirtyStackingContainerZOrderLists() |
5626 { | 5653 { |
5627 RenderLayer* stackingContainer = this->ancestorStackingContainer(); | 5654 RenderLayer* stackingContainer = this->ancestorStackingContainer(); |
5628 if (stackingContainer) | 5655 if (stackingContainer) |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5747 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { | 5774 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin g()) { |
5748 // Ignore reflections. | 5775 // Ignore reflections. |
5749 if (!m_reflection || reflectionLayer() != child) | 5776 if (!m_reflection || reflectionLayer() != child) |
5750 child->collectLayers(includeHiddenLayers, behavior, posBuffer, n egBuffer, layerToForceAsStackingContainer); | 5777 child->collectLayers(includeHiddenLayers, behavior, posBuffer, n egBuffer, layerToForceAsStackingContainer); |
5751 } | 5778 } |
5752 } | 5779 } |
5753 } | 5780 } |
5754 | 5781 |
5755 void RenderLayer::updateLayerListsIfNeeded() | 5782 void RenderLayer::updateLayerListsIfNeeded() |
5756 { | 5783 { |
5757 bool shouldUpdateDescendantsAreContiguousInStackingOrder = acceleratedCompos itingForOverflowScrollEnabled() && isStackingContext() && (m_zOrderListsDirty || m_normalFlowListDirty) && m_descendantsAreContiguousInStackingOrderDirty; | |
5758 updateZOrderLists(); | 5784 updateZOrderLists(); |
5759 updateNormalFlowList(); | 5785 updateNormalFlowList(); |
5760 | 5786 |
5761 if (RenderLayer* reflectionLayer = this->reflectionLayer()) { | 5787 if (RenderLayer* reflectionLayer = this->reflectionLayer()) { |
5762 reflectionLayer->updateZOrderLists(); | 5788 reflectionLayer->updateZOrderLists(); |
5763 reflectionLayer->updateNormalFlowList(); | 5789 reflectionLayer->updateNormalFlowList(); |
5764 } | 5790 } |
5765 | |
5766 if (shouldUpdateDescendantsAreContiguousInStackingOrder) { | |
5767 updateDescendantsAreContiguousInStackingOrder(); | |
5768 // The above function can cause us to update m_needsCompositedScrolling | |
5769 // and dirty our layer lists. Refresh them if necessary. | |
5770 updateZOrderLists(); | |
5771 updateNormalFlowList(); | |
5772 } | |
5773 } | 5791 } |
5774 | 5792 |
5775 void RenderLayer::repaintIncludingDescendants() | 5793 void RenderLayer::repaintIncludingDescendants() |
5776 { | 5794 { |
5777 renderer()->repaint(); | 5795 renderer()->repaint(); |
5778 for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling()) | 5796 for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling()) |
5779 curr->repaintIncludingDescendants(); | 5797 curr->repaintIncludingDescendants(); |
5780 } | 5798 } |
5781 | 5799 |
5782 void RenderLayer::setBackingNeedsRepaint() | 5800 void RenderLayer::setBackingNeedsRepaint() |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5935 return true; | 5953 return true; |
5936 | 5954 |
5937 if (hasVisibleBoxDecorations()) | 5955 if (hasVisibleBoxDecorations()) |
5938 return true; | 5956 return true; |
5939 | 5957 |
5940 return false; | 5958 return false; |
5941 } | 5959 } |
5942 | 5960 |
5943 void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle) | 5961 void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle) |
5944 { | 5962 { |
5945 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE; | 5963 if (!oldStyle || (oldStyle->visibility() != renderer()->style()->visibility( ))) |
5946 if (oldVisibility == renderer()->style()->visibility() || !renderer()->isOut OfFlowPositioned()) | 5964 compositor()->setNeedsUpdateCompositingRequirementsState(); |
5947 return; | |
5948 | |
5949 if (renderer()->style()->visibility() == VISIBLE) | |
5950 setAncestorChainHasOutOfFlowPositionedDescendant(renderer()->containingB lock()); | |
5951 else | |
5952 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus(); | |
5953 } | 5965 } |
5954 | 5966 |
5955 void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldS tyle) | 5967 void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldS tyle) |
5956 { | 5968 { |
5957 bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false; | 5969 bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false; |
5958 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE; | 5970 EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE; |
5959 int oldZIndex = oldStyle ? oldStyle->zIndex() : 0; | 5971 int oldZIndex = oldStyle ? oldStyle->zIndex() : 0; |
5960 | 5972 |
5961 // FIXME: RenderLayer already handles visibility changes through our visibli ty dirty bits. This logic could | 5973 // FIXME: RenderLayer already handles visibility changes through our visibli ty dirty bits. This logic could |
5962 // likely be folded along with the rest. | 5974 // likely be folded along with the rest. |
5963 bool isStackingContext = this->isStackingContext(); | 5975 bool isStackingContext = this->isStackingContext(); |
5964 if (isStackingContext == wasStackingContext && oldVisibility == renderer()-> style()->visibility() && oldZIndex == renderer()->style()->zIndex()) | 5976 if (isStackingContext == wasStackingContext && oldVisibility == renderer()-> style()->visibility() && oldZIndex == renderer()->style()->zIndex()) |
5965 return; | 5977 return; |
5966 | 5978 |
5967 dirtyStackingContainerZOrderLists(); | 5979 dirtyStackingContainerZOrderLists(); |
5968 | 5980 |
5969 if (isStackingContainer()) | 5981 if (isStackingContainer()) |
5970 dirtyZOrderLists(); | 5982 dirtyZOrderLists(); |
5971 else | 5983 else |
5972 clearZOrderLists(); | 5984 clearZOrderLists(); |
5973 | 5985 |
5974 updateNeedsCompositedScrolling(); | 5986 compositor()->setNeedsUpdateCompositingRequirementsState(); |
5975 } | 5987 } |
5976 | 5988 |
5977 static bool overflowRequiresScrollbar(EOverflow overflow) | 5989 static bool overflowRequiresScrollbar(EOverflow overflow) |
5978 { | 5990 { |
5979 return overflow == OSCROLL; | 5991 return overflow == OSCROLL; |
5980 } | 5992 } |
5981 | 5993 |
5982 static bool overflowDefinesAutomaticScrollbar(EOverflow overflow) | 5994 static bool overflowDefinesAutomaticScrollbar(EOverflow overflow) |
5983 { | 5995 { |
5984 return overflow == OAUTO || overflow == OOVERLAY; | 5996 return overflow == OAUTO || overflow == OOVERLAY; |
(...skipping 28 matching lines...) Expand all Loading... | |
6013 | 6025 |
6014 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) { | 6026 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) { |
6015 ASSERT(hasVerticalScrollbar()); | 6027 ASSERT(hasVerticalScrollbar()); |
6016 m_vBar->setEnabled(true); | 6028 m_vBar->setEnabled(true); |
6017 } | 6029 } |
6018 | 6030 |
6019 if (!m_scrollDimensionsDirty) | 6031 if (!m_scrollDimensionsDirty) |
6020 updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollab leVerticalOverflow()); | 6032 updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollab leVerticalOverflow()); |
6021 } | 6033 } |
6022 | 6034 |
6023 void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant(RenderObject* containingBlock) | |
6024 { | |
6025 for (RenderLayer* layer = this; layer; layer = layer->parent()) { | |
6026 if (!layer->m_hasOutOfFlowPositionedDescendantDirty && layer->hasOutOfFl owPositionedDescendant()) | |
6027 break; | |
6028 | |
6029 layer->m_hasOutOfFlowPositionedDescendantDirty = false; | |
6030 layer->m_hasOutOfFlowPositionedDescendant = true; | |
6031 layer->updateNeedsCompositedScrolling(); | |
6032 | |
6033 if (layer->renderer() && layer->renderer() == containingBlock) | |
6034 break; | |
6035 } | |
6036 } | |
6037 | |
6038 void RenderLayer::dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus() | |
6039 { | |
6040 if (m_hasOutOfFlowPositionedDescendant) { | |
6041 m_hasOutOfFlowPositionedDescendantDirty = true; | |
6042 // FIXME It would be nice to avoid this when we clean up render layer | |
6043 // updating. We shouldn't have to update the composited scrolling state | |
6044 // nearly as frequently if all the updates happen in a single, well | |
6045 // defined phase. | |
6046 updateNeedsCompositedScrolling(); | |
6047 } | |
6048 | |
6049 if (parent()) | |
6050 parent()->dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus(); | |
6051 } | |
6052 | |
6053 void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle) | 6035 void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle) |
6054 { | 6036 { |
6037 if (oldStyle && (renderer()->style()->position() == oldStyle->position())) | |
6038 return; | |
6039 | |
6055 bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsoluteP osition || oldStyle->position() == FixedPosition); | 6040 bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsoluteP osition || oldStyle->position() == FixedPosition); |
6056 bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned(); | 6041 bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned(); |
6057 if (parent() && isOutOfFlowPositioned != wasOutOfFlowPositioned) { | 6042 if (!wasOutOfFlowPositioned && !isOutOfFlowPositioned) |
6058 if (isOutOfFlowPositioned) | 6043 return; |
6059 parent()->setAncestorChainHasOutOfFlowPositionedDescendant(renderer( )->containingBlock()); | 6044 |
6060 else | 6045 // Even if the layer remains out-of-flow, a change to this property |
6061 parent()->dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus() ; | 6046 // will likely change its containing block. We must clear these bits |
6047 // so that they can be set properly by the RenderLayerCompositor. | |
6048 for (RenderLayer* ancestor = parent(); ancestor; ancestor = ancestor->parent ()) | |
6049 ancestor->m_hasUnclippedDescendant = false; | |
6050 | |
6051 // Ensures that we reset the above bits correctly. | |
6052 compositor()->setNeedsUpdateCompositingRequirementsState(); | |
6053 | |
6054 if (wasOutOfFlowPositioned && isOutOfFlowPositioned) | |
6055 return; | |
6056 | |
6057 if (isOutOfFlowPositioned) { | |
6058 setAncestorChainHasOutOfFlowPositionedDescendant(); | |
6059 compositor()->addOutOfFlowPositionedLayer(this); | |
6060 } else { | |
6061 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); | |
6062 compositor()->removeOutOfFlowPositionedLayer(this); | |
6062 } | 6063 } |
6063 } | 6064 } |
6064 | 6065 |
6065 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newS tyle) | 6066 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newS tyle) |
6066 { | 6067 { |
6067 ASSERT(newStyle); | 6068 ASSERT(newStyle); |
6068 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter(); | 6069 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter(); |
6069 } | 6070 } |
6070 | 6071 |
6071 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const | 6072 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6204 | 6205 |
6205 FrameView* frameView = frame->view(); | 6206 FrameView* frameView = frame->view(); |
6206 if (!frameView) | 6207 if (!frameView) |
6207 return; | 6208 return; |
6208 | 6209 |
6209 bool isVisibleToHitTest = renderer()->visibleToHitTesting(); | 6210 bool isVisibleToHitTest = renderer()->visibleToHitTesting(); |
6210 if (HTMLFrameOwnerElement* owner = frame->ownerElement()) | 6211 if (HTMLFrameOwnerElement* owner = frame->ownerElement()) |
6211 isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToH itTesting(); | 6212 isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToH itTesting(); |
6212 | 6213 |
6213 bool updatedScrollableAreaSet = false; | 6214 bool updatedScrollableAreaSet = false; |
6214 if (hasOverflow && isVisibleToHitTest) | 6215 if (hasOverflow && isVisibleToHitTest) { |
6215 updatedScrollableAreaSet = frameView->addScrollableArea(this); | 6216 updatedScrollableAreaSet = frameView->addScrollableArea(this); |
6216 else | 6217 compositor()->setNeedsUpdateCompositingRequirementsState(); |
6218 } else { | |
6217 updatedScrollableAreaSet = frameView->removeScrollableArea(this); | 6219 updatedScrollableAreaSet = frameView->removeScrollableArea(this); |
6218 | 6220 setNeedsCompositedScrolling(false); |
6219 if (updatedScrollableAreaSet) | 6221 } |
6220 updateNeedsCompositedScrolling(); | |
6221 } | 6222 } |
6222 | 6223 |
6223 void RenderLayer::updateScrollCornerStyle() | 6224 void RenderLayer::updateScrollCornerStyle() |
6224 { | 6225 { |
6225 RenderObject* actualRenderer = rendererForScrollbar(renderer()); | 6226 RenderObject* actualRenderer = rendererForScrollbar(renderer()); |
6226 RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer- >getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->st yle()) : PassRefPtr<RenderStyle>(0); | 6227 RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer- >getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->st yle()) : PassRefPtr<RenderStyle>(0); |
6227 if (corner) { | 6228 if (corner) { |
6228 if (!m_scrollCorner) { | 6229 if (!m_scrollCorner) { |
6229 m_scrollCorner = RenderScrollbarPart::createAnonymous(renderer()->do cument()); | 6230 m_scrollCorner = RenderScrollbarPart::createAnonymous(renderer()->do cument()); |
6230 m_scrollCorner->setParent(renderer()); | 6231 m_scrollCorner->setParent(renderer()); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6461 } | 6462 } |
6462 } | 6463 } |
6463 | 6464 |
6464 void showLayerTree(const WebCore::RenderObject* renderer) | 6465 void showLayerTree(const WebCore::RenderObject* renderer) |
6465 { | 6466 { |
6466 if (!renderer) | 6467 if (!renderer) |
6467 return; | 6468 return; |
6468 showLayerTree(renderer->enclosingLayer()); | 6469 showLayerTree(renderer->enclosingLayer()); |
6469 } | 6470 } |
6470 #endif | 6471 #endif |
OLD | NEW |