blob: 4ae8bf2a425bdd23c97c807492c1616b94be987d [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LayoutSubtreeRootList_h
#define LayoutSubtreeRootList_h
#include "wtf/HashSet.h"
#include "wtf/Vector.h"
namespace blink {
class LayoutObject;
// This class keeps track of layout objects that have identified to be
// independent layout roots meaning they won't affect other parts of the tree
// by their layout. This is an optimization to avoid doing extra work and tree
// walking during layout. See objectIsRelayoutBoundary for the criteria for
// being a root.
// These roots are sorted into a vector ordered by their depth in the tree,
// and returned one by one deepest first for layout. This is necessary in the
// case of nested subtree roots where a positioned object is added to the
// contained root but its containing block is above that root.
// It ensures we add positioned objects to their containing block's positioned
// descendant lists before laying out those objects if they're contained in
// a higher root.
// TODO(leviw): This should really be something akin to a LayoutController
// that FrameView delegates layout work to.
class LayoutSubtreeRootList {
public:
LayoutSubtreeRootList()
{ }
void addRoot(LayoutObject& object)
{
ASSERT(m_orderedRoots.isEmpty());
m_roots.add(&object);
}
void removeRoot(LayoutObject&);
void clearAndMarkContainingBlocksForLayout();
void clear() { m_roots.clear(); }
int size() { return m_roots.size(); }
bool isEmpty() const { return m_roots.isEmpty(); }
// TODO(leviw): Remove this once we stop exposing to DevTools one root
// for a layout crbug.com/460596
LayoutObject* randomRoot();
LayoutObject* takeDeepestRoot();
void countObjectsNeedingLayout(unsigned& needsLayoutObjects, unsigned& totalObjects);
static void countObjectsNeedingLayoutInRoot(const LayoutObject* root, unsigned& needsLayoutObjects, unsigned& totalObjects);
private:
struct LayoutSubtree {
LayoutSubtree(LayoutObject* inObject)
: object(inObject)
, depth(determineDepth(inObject))
{ }
LayoutSubtree()
: object(0)
, depth(0)
{ }
LayoutObject* object;
unsigned depth;
bool operator<(const LayoutSubtreeRootList::LayoutSubtree& other) const
{
return depth < other.depth;
}
private:
static unsigned determineDepth(LayoutObject*);
};
// Layout roots sorted by depth (shallowest first). This structure is only
// populated at the beginning of layout.
Vector<LayoutSubtree> m_orderedRoots;
// Outside of layout, roots can be added when marked as needing layout and
// removed when removed when destroyed. They're kept in this hashset to
// keep those operations fast.
HashSet<LayoutObject*> m_roots;
};
} // namespace blink
#endif // LayoutSubtreeRootList_h