Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Unified Diff: third_party/WebKit/Source/core/layout/LayoutBlock.cpp

Issue 1544423002: Improve positioned/percentHeight descendant/container tracking (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: virtual destructor Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/LayoutBlock.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index 7daa88b77c873e20b2aba1437feb64eb10f7c978..f3bababbf581770dbcbb18408331997287960a69 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -87,26 +87,6 @@ struct SameSizeAsLayoutBlock : public LayoutBox {
static_assert(sizeof(LayoutBlock) == sizeof(SameSizeAsLayoutBlock), "LayoutBlock should stay small");
-// This map keeps track of the positioned objects associated with a containing
-// block.
-//
-// This map is populated during layout. It is kept across layouts to handle
-// that we skip unchanged sub-trees during layout, in such a way that we are
-// able to lay out deeply nested out-of-flow descendants if their containing
-// block got laid out. The map could be invalidated during style change but
-// keeping track of containing blocks at that time is complicated (we are in
-// the middle of recomputing the style so we can't rely on any of its
-// information), which is why it's easier to just update it for every layout.
-static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr;
-
-// This map keeps track of the descendants whose 'height' is percentage associated
-// with a containing block. Like |gPositionedDescendantsMap|, it is also recomputed
-// for every layout (see the comment above about why).
-static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr;
-
-static TrackedContainerMap* gPositionedContainerMap = nullptr;
-static TrackedContainerMap* gPercentHeightContainerMap = nullptr;
-
struct ScrollInfo {
ScrollInfo() : autoHorizontalScrollBarChanged(false), autoVerticalScrollBarChanged(false) {}
DoubleSize scrollOffset;
@@ -140,34 +120,20 @@ LayoutBlock::LayoutBlock(ContainerNode* node)
// By default, subclasses do not have inline children.
}
-static void removeBlockFromDescendantAndContainerMaps(LayoutBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
+LayoutBlock::~LayoutBlock()
{
- if (OwnPtr<TrackedLayoutBoxListHashSet> descendantSet = descendantMap->take(block)) {
- for (auto& descendant : *descendantSet) {
- TrackedContainerMap::iterator it = containerMap->find(descendant);
- ASSERT(it != containerMap->end());
- if (it == containerMap->end())
- continue;
- HashSet<LayoutBlock*>* containerSet = it->value.get();
- ASSERT(containerSet->contains(block));
- containerSet->remove(block);
- if (containerSet->isEmpty())
- containerMap->remove(it);
+ if (TrackedLayoutBoxListHashSet* descendants = positionedObjects()) {
+ for (LayoutBox* descendant : *descendants) {
+ ASSERT(descendant->positionedContainer() == this);
+ descendant->setPositionedContainer(nullptr);
+ }
+ }
+ if (TrackedLayoutBoxListHashSet* descendants = percentHeightDescendants()) {
+ for (LayoutBox* descendant : *descendants) {
+ ASSERT(descendant->percentHeightContainer() == this);
+ descendant->setPercentHeightContainer(nullptr);
}
}
-}
-
-void LayoutBlock::removeFromGlobalMaps()
-{
- if (gPercentHeightDescendantsMap)
- removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
- if (gPositionedDescendantsMap)
- removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
-}
-
-LayoutBlock::~LayoutBlock()
-{
- removeFromGlobalMaps();
}
void LayoutBlock::willBeDestroyed()
@@ -1396,77 +1362,34 @@ void LayoutBlock::setSelectionState(SelectionState state)
inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone);
}
-void LayoutBlock::insertIntoTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
+void LayoutBlock::insertPositionedObject(LayoutBox* descendant)
{
- if (!descendantsMap) {
- descendantsMap = new TrackedDescendantsMap;
- containerMap = new TrackedContainerMap;
- }
-
- TrackedLayoutBoxListHashSet* descendantSet = descendantsMap->get(this);
- if (!descendantSet) {
- descendantSet = new TrackedLayoutBoxListHashSet;
- descendantsMap->set(this, adoptPtr(descendantSet));
- }
- bool added = descendantSet->add(descendant).isNewEntry;
- if (!added) {
- ASSERT(containerMap->get(descendant));
- ASSERT(containerMap->get(descendant)->contains(this));
- return;
- }
-
- HashSet<LayoutBlock*>* containerSet = containerMap->get(descendant);
- if (!containerSet) {
- containerSet = new HashSet<LayoutBlock*>;
- containerMap->set(descendant, adoptPtr(containerSet));
+ ASSERT(!isAnonymousBlock());
+ OwnPtr<TrackedLayoutBoxListHashSet>& positionedDescendants = ensureLayoutBlockRareData().m_positionedDescendants;
+ if (!positionedDescendants)
+ positionedDescendants = adoptPtr(new TrackedLayoutBoxListHashSet);
+ if (descendant->positionedContainer()) {
+ if (descendant->positionedContainer() == this) {
+ ASSERT(positionedDescendants->contains(descendant));
+ return;
+ }
+ descendant->removeFromPositionedContainer();
}
- ASSERT(!containerSet->contains(this));
- containerSet->add(this);
+ positionedDescendants->add(descendant);
+ descendant->setPositionedContainer(this);
}
-void LayoutBlock::removeFromTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
+void LayoutBlock::removePositionedObject(LayoutBox* descendant)
{
- if (!descendantsMap)
- return;
-
- OwnPtr<HashSet<LayoutBlock*>> containerSet = containerMap->take(descendant);
- if (!containerSet)
+ TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects();
+ if (!descendant->positionedContainer()) {
+ ASSERT(!positionedDescendants || !positionedDescendants->contains(descendant));
return;
-
- for (auto* container : *containerSet) {
- // FIXME: Disabling this assert temporarily until we fix the layout
- // bugs associated with positioned objects not properly cleared from
- // their ancestor chain before being moved. See webkit bug 93766.
- // ASSERT(descendant->isDescendantOf(container));
-
- TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap->find(container);
- ASSERT(descendantsMapIterator != descendantsMap->end());
- if (descendantsMapIterator == descendantsMap->end())
- continue;
- TrackedLayoutBoxListHashSet* descendantSet = descendantsMapIterator->value.get();
- ASSERT(descendantSet->contains(descendant));
- descendantSet->remove(descendant);
- if (descendantSet->isEmpty())
- descendantsMap->remove(descendantsMapIterator);
}
-}
-
-TrackedLayoutBoxListHashSet* LayoutBlock::positionedObjects() const
-{
- if (gPositionedDescendantsMap)
- return gPositionedDescendantsMap->get(this);
- return nullptr;
-}
-
-void LayoutBlock::insertPositionedObject(LayoutBox* o)
-{
- ASSERT(!isAnonymousBlock());
- insertIntoTrackedLayoutBoxMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
-}
-
-void LayoutBlock::removePositionedObject(LayoutBox* o)
-{
- removeFromTrackedLayoutBoxMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
+ ASSERT(descendant->positionedContainer() == this);
+ ASSERT(positionedDescendants && positionedDescendants->contains(descendant));
+ positionedDescendants->remove(descendant);
+ descendant->setPositionedContainer(nullptr);
}
void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState containingBlockState)
@@ -1505,49 +1428,51 @@ void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState c
}
}
- for (unsigned i = 0; i < deadObjects.size(); i++)
- removePositionedObject(deadObjects.at(i));
+ for (auto* deadObject : deadObjects)
+ deadObject->removeFromPositionedContainer();
}
void LayoutBlock::addPercentHeightDescendant(LayoutBox* descendant)
{
- insertIntoTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
+ OwnPtr<TrackedLayoutBoxListHashSet>& percentHeightDescendants = ensureLayoutBlockRareData().m_percentHeightDescendants;
+ if (!percentHeightDescendants)
+ percentHeightDescendants = adoptPtr(new TrackedLayoutBoxListHashSet);
+ if (descendant->percentHeightContainer()) {
+ if (descendant->percentHeightContainer() == this) {
+ ASSERT(percentHeightDescendants->contains(descendant));
+ return;
+ }
+ descendant->removeFromPercentHeightContainer();
+ }
+ percentHeightDescendants->add(descendant);
+ descendant->setPercentHeightContainer(this);
}
void LayoutBlock::removePercentHeightDescendant(LayoutBox* descendant)
{
- removeFromTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
-}
-
-TrackedLayoutBoxListHashSet* LayoutBlock::percentHeightDescendants() const
-{
- return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
-}
-
-bool LayoutBlock::hasPercentHeightContainerMap()
-{
- return gPercentHeightContainerMap;
+ TrackedLayoutBoxListHashSet* percentHeightDescendants = this->percentHeightDescendants();
+ if (!descendant->percentHeightContainer()) {
+ ASSERT(!percentHeightDescendants || !percentHeightDescendants->contains(descendant));
+ return;
+ }
+ ASSERT(descendant->percentHeightContainer() == this);
+ ASSERT(percentHeightDescendants && percentHeightDescendants->contains(descendant));
+ percentHeightDescendants->remove(descendant);
+ descendant->setPercentHeightContainer(nullptr);
}
bool LayoutBlock::hasPercentHeightDescendant(LayoutBox* descendant)
{
- // We don't null check gPercentHeightContainerMap since the caller
- // already ensures this and we need to call this function on every
- // descendant in clearPercentHeightDescendantsFrom().
- ASSERT(gPercentHeightContainerMap);
- return gPercentHeightContainerMap->contains(descendant);
+ return percentHeightDescendants() && percentHeightDescendants()->contains(descendant);
}
void LayoutBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutScope& layoutScope)
{
- if (!gPercentHeightDescendantsMap)
- return;
-
- TrackedLayoutBoxListHashSet* descendants = gPercentHeightDescendantsMap->get(this);
- if (!descendants)
+ TrackedLayoutBoxListHashSet* percentHeightDescendants = this->percentHeightDescendants();
+ if (!percentHeightDescendants)
return;
- for (auto* box : *descendants) {
+ for (auto* box : *percentHeightDescendants) {
ASSERT(box->isDescendantOf(this));
while (box != this) {
if (box->normalChildNeedsLayout())
@@ -1561,35 +1486,6 @@ void LayoutBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutSco
}
}
-void LayoutBlock::removePercentHeightDescendantIfNeeded(LayoutBox* descendant)
-{
- // We query the map directly, rather than looking at style's
- // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those
- // can change with writing mode/directional changes.
- if (!hasPercentHeightContainerMap())
- return;
-
- if (!hasPercentHeightDescendant(descendant))
- return;
-
- removePercentHeightDescendant(descendant);
-}
-
-void LayoutBlock::clearPercentHeightDescendantsFrom(LayoutBox* parent)
-{
- ASSERT(gPercentHeightContainerMap);
- for (LayoutObject* curr = parent->slowFirstChild(); curr; curr = curr->nextInPreOrder(parent)) {
- if (!curr->isBox())
- continue;
-
- LayoutBox* box = toLayoutBox(curr);
- if (!hasPercentHeightDescendant(box))
- continue;
-
- removePercentHeightDescendant(box);
- }
-}
-
LayoutUnit LayoutBlock::textIndentOffset() const
{
LayoutUnit cw = 0;
@@ -2876,15 +2772,9 @@ bool LayoutBlock::tryLayoutDoingPositionedMovementOnly()
#if ENABLE(ASSERT)
void LayoutBlock::checkPositionedObjectsNeedLayout()
{
- if (!gPositionedDescendantsMap)
- return;
-
if (TrackedLayoutBoxListHashSet* positionedDescendantSet = positionedObjects()) {
- TrackedLayoutBoxListHashSet::const_iterator end = positionedDescendantSet->end();
- for (TrackedLayoutBoxListHashSet::const_iterator it = positionedDescendantSet->begin(); it != end; ++it) {
- LayoutBox* currBox = *it;
- ASSERT(!currBox->needsLayout());
- }
+ for (LayoutBox* box : *positionedDescendantSet)
+ ASSERT(!box->needsLayout());
}
}

Powered by Google App Engine
This is Rietveld 408576698