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

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: Created 4 years, 11 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 ae0385bc3e257924da6719ff2fe449ecf36bc649..8e907b7b6e0e01bdf42e667f94ce7161892d94fd 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -98,15 +98,13 @@ static_assert(sizeof(LayoutBlock) == sizeof(SameSizeAsLayoutBlock), "LayoutBlock
// 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;
+static TrackedContainerMap* gPositionedContainerMap = 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;
@@ -135,34 +133,31 @@ LayoutBlock::LayoutBlock(ContainerNode* node)
, m_hasOnlySelfCollapsingChildren(false)
, m_descendantsWithFloatsMarkedForLayout(false)
, m_needsRecalcLogicalWidthAfterLayoutChildren(false)
+ , m_hasPositionedObjects(false)
+ , m_hasPercentHeightDescendants(false)
{
// LayoutBlockFlow calls setChildrenInline(true).
// By default, subclasses do not have inline children.
}
-static void removeBlockFromDescendantAndContainerMaps(LayoutBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
+void LayoutBlock::removeFromGlobalMaps()
{
- 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 (hasPositionedObjects()) {
+ OwnPtr<TrackedLayoutBoxListHashSet> descendants = gPositionedDescendantsMap->take(this);
+ ASSERT(!descendants->isEmpty());
+ for (LayoutBox* descendant : *descendants) {
+ ASSERT(gPositionedContainerMap->get(descendant) == this);
+ gPositionedContainerMap->remove(descendant);
+ }
+ }
+ if (hasPercentHeightDescendants()) {
+ OwnPtr<TrackedLayoutBoxListHashSet> descendants = gPercentHeightDescendantsMap->take(this);
+ ASSERT(!descendants->isEmpty());
+ 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()
@@ -1397,79 +1392,60 @@ void LayoutBlock::setSelectionState(SelectionState state)
inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone);
}
-void LayoutBlock::insertIntoTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
+TrackedLayoutBoxListHashSet* LayoutBlock::positionedObjectsInternal() const
+{
+ return gPositionedDescendantsMap ? gPositionedDescendantsMap->get(this) : nullptr;
+}
+
+void LayoutBlock::insertPositionedObject(LayoutBox* o)
{
- if (!descendantsMap) {
- descendantsMap = new TrackedDescendantsMap;
- containerMap = new TrackedContainerMap;
+ ASSERT(!isAnonymousBlock());
+ ASSERT(o->containingBlock() == this);
+
+ if (gPositionedContainerMap) {
+ auto containerMapIt = gPositionedContainerMap->find(o);
+ if (containerMapIt != gPositionedContainerMap->end()) {
+ if (containerMapIt->value == this) {
+ ASSERT(hasPositionedObjects() && positionedObjects()->contains(o));
+ return;
+ }
+ removePositionedObject(o);
+ }
+ } else {
+ gPositionedContainerMap = new TrackedContainerMap;
}
+ gPositionedContainerMap->set(o, this);
- TrackedLayoutBoxListHashSet* descendantSet = descendantsMap->get(this);
+ if (!gPositionedDescendantsMap)
+ gPositionedDescendantsMap = new TrackedDescendantsMap;
+ TrackedLayoutBoxListHashSet* descendantSet = gPositionedDescendantsMap->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;
+ gPositionedDescendantsMap->set(this, adoptPtr(descendantSet));
}
+ descendantSet->add(o);
- HashSet<LayoutBlock*>* containerSet = containerMap->get(descendant);
- if (!containerSet) {
- containerSet = new HashSet<LayoutBlock*>;
- containerMap->set(descendant, adoptPtr(containerSet));
- }
- ASSERT(!containerSet->contains(this));
- containerSet->add(this);
+ m_hasPositionedObjects = true;
}
-void LayoutBlock::removeFromTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
+void LayoutBlock::removePositionedObject(LayoutBox* o)
{
- if (!descendantsMap)
+ if (!gPositionedContainerMap)
return;
- OwnPtr<HashSet<LayoutBlock*>> containerSet = containerMap->take(descendant);
- if (!containerSet)
+ LayoutBlock* container = gPositionedContainerMap->take(o);
+ if (!container)
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* positionedDescendants = gPositionedDescendantsMap->get(container);
+ ASSERT(positionedDescendants && positionedDescendants->contains(o));
+ positionedDescendants->remove(o);
+ if (positionedDescendants->isEmpty()) {
+ gPositionedDescendantsMap->remove(container);
+ container->m_hasPositionedObjects = false;
}
}
-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);
-}
-
void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState containingBlockState)
{
TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects();
@@ -1506,45 +1482,60 @@ void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState c
}
}
- for (unsigned i = 0; i < deadObjects.size(); i++)
- removePositionedObject(deadObjects.at(i));
+ for (auto object : deadObjects) {
+ ASSERT(gPositionedContainerMap->get(object) == this);
+ positionedDescendants->remove(object);
+ gPositionedContainerMap->remove(object);
+ }
+ if (positionedDescendants->isEmpty()) {
+ gPositionedDescendantsMap->remove(this);
+ m_hasPositionedObjects = false;
+ }
}
void LayoutBlock::addPercentHeightDescendant(LayoutBox* descendant)
{
- insertIntoTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
-}
+ if (descendant->percentHeightContainer()) {
+ if (descendant->percentHeightContainer() == this) {
+ ASSERT(hasPercentHeightDescendant(descendant));
+ return;
+ }
+ descendant->removeFromPercentHeightContainer();
+ }
+ descendant->setPercentHeightContainer(this);
-void LayoutBlock::removePercentHeightDescendant(LayoutBox* descendant)
-{
- removeFromTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
-}
+ if (!gPercentHeightDescendantsMap)
+ gPercentHeightDescendantsMap = new TrackedDescendantsMap;
+ TrackedLayoutBoxListHashSet* descendantSet = gPercentHeightDescendantsMap->get(this);
+ if (!descendantSet) {
+ descendantSet = new TrackedLayoutBoxListHashSet;
+ gPercentHeightDescendantsMap->set(this, adoptPtr(descendantSet));
+ }
+ descendantSet->add(descendant);
-TrackedLayoutBoxListHashSet* LayoutBlock::percentHeightDescendants() const
-{
- return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
+ m_hasPercentHeightDescendants = true;
}
-bool LayoutBlock::hasPercentHeightContainerMap()
+void LayoutBlock::removePercentHeightDescendant(LayoutBox* descendant)
{
- return gPercentHeightContainerMap;
+ if (TrackedLayoutBoxListHashSet* descendants = percentHeightDescendants()) {
+ descendants->remove(descendant);
+ descendant->setPercentHeightContainer(nullptr);
+ if (descendants->isEmpty()) {
+ gPercentHeightDescendantsMap->remove(this);
+ m_hasPercentHeightDescendants = false;
+ }
+ }
}
-bool LayoutBlock::hasPercentHeightDescendant(LayoutBox* descendant)
+TrackedLayoutBoxListHashSet* LayoutBlock::percentHeightDescendantsInternal() const
{
- // 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 gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : nullptr;
}
void LayoutBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutScope& layoutScope)
{
- if (!gPercentHeightDescendantsMap)
- return;
-
- TrackedLayoutBoxListHashSet* descendants = gPercentHeightDescendantsMap->get(this);
+ TrackedLayoutBoxListHashSet* descendants = percentHeightDescendants();
if (!descendants)
return;
@@ -1562,35 +1553,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;
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlock.h ('k') | third_party/WebKit/Source/core/layout/LayoutBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698