Bug 1945944: Add flag to dump frame tree with only deterministic information for diffing. r=layout-reviewers,emilio

Differential Revision: https://phabricator.services.mozilla.com/D236797
This commit is contained in:
David Shin
2025-02-06 15:34:27 +00:00
parent 094417d2bf
commit 61d5b05704
11 changed files with 94 additions and 49 deletions

View File

@@ -3068,7 +3068,8 @@ void nsContainerFrame::List(FILE* out, const char* aPrefix,
ListFlags aFlags) const {
nsCString str;
ListGeneric(str, aPrefix, aFlags);
ExtraContainerFrameInfo(str);
ExtraContainerFrameInfo(str,
aFlags.contains(ListFlag::OnlyListDeterministicInfo));
// Output the frame name and various fields.
fprintf_stderr(out, "%s <\n", str.get());
@@ -3120,8 +3121,9 @@ void nsContainerFrame::ListChildLists(FILE* aOut, const char* aPrefix,
// Use nsPrintfCString so that %p don't output prefix "0x". This is
// consistent with nsIFrame::ListTag().
const nsPrintfCString str("%s%s@%p <\n", aPrefix, ChildListName(listID),
&GetChildList(listID));
nsCString str{nsPrintfCString("%s%s", aPrefix, ChildListName(listID))};
ListPtr(str, aFlags, &GetChildList(listID), "@");
str += " <\n";
fprintf_stderr(aOut, "%s", str.get());
for (nsIFrame* kid : list) {
@@ -3133,8 +3135,6 @@ void nsContainerFrame::ListChildLists(FILE* aOut, const char* aPrefix,
}
}
void nsContainerFrame::ExtraContainerFrameInfo(nsACString& aTo) const {
(void)aTo;
}
void nsContainerFrame::ExtraContainerFrameInfo(nsACString&, bool) const {}
#endif

View File

@@ -70,7 +70,7 @@ class nsContainerFrame : public nsSplittableFrame {
const char* aPrefix = "") const override;
void ListChildLists(FILE* aOut, const char* aPrefix, ListFlags aFlags,
ChildListIDs aSkippedListIDs) const;
virtual void ExtraContainerFrameInfo(nsACString& aTo) const;
virtual void ExtraContainerFrameInfo(nsACString& aTo, bool aListOnlyDeterministic) const;
#endif
// nsContainerFrame methods

View File

@@ -10043,9 +10043,12 @@ nsresult nsGridContainerFrame::GetFrameName(nsAString& aResult) const {
return MakeFrameName(u"GridContainer"_ns, aResult);
}
void nsGridContainerFrame::ExtraContainerFrameInfo(nsACString& aTo) const {
void nsGridContainerFrame::ExtraContainerFrameInfo(
nsACString& aTo, bool aListOnlyDeterministic) const {
if (const void* const subgrid = GetProperty(Subgrid::Prop())) {
aTo += nsPrintfCString(" [subgrid=%p]", subgrid);
aTo += "[subgrid";
ListPtr(aTo, aListOnlyDeterministic, subgrid);
aTo += "]";
}
}

View File

@@ -140,7 +140,8 @@ class nsGridContainerFrame final : public nsContainerFrame,
#ifdef DEBUG_FRAME_DUMP
nsresult GetFrameName(nsAString& aResult) const override;
void ExtraContainerFrameInfo(nsACString& aTo) const override;
void ExtraContainerFrameInfo(nsACString& aTo,
bool aListOnlyDeterministic) const override;
#endif
// nsContainerFrame overrides

View File

@@ -8540,13 +8540,13 @@ Maybe<uint32_t> nsIFrame::ContentIndexInContainer(const nsIFrame* aFrame) {
return Nothing();
}
nsAutoCString nsIFrame::ListTag() const {
nsAutoCString nsIFrame::ListTag(bool aListOnlyDeterministic) const {
nsAutoString tmp;
GetFrameName(tmp);
nsAutoCString tag;
tag += NS_ConvertUTF16toUTF8(tmp);
tag += nsPrintfCString("@%p", static_cast<const void*>(this));
ListPtr(tag, aListOnlyDeterministic, this, "@");
return tag;
}
@@ -8576,25 +8576,31 @@ std::string nsIFrame::ConvertToString(const LogicalSize& aSize,
void nsIFrame::ListGeneric(nsACString& aTo, const char* aPrefix,
ListFlags aFlags) const {
aTo += aPrefix;
aTo += ListTag();
const bool onlyDeterministic = aFlags.contains(ListFlag::OnlyListDeterministicInfo);
aTo += ListTag(onlyDeterministic);
if (HasView()) {
aTo += nsPrintfCString(" [view=%p]", static_cast<void*>(GetView()));
aTo += " [view";
ListPtr(aTo, aFlags, GetView());
aTo += "]";
}
if (GetParent()) {
aTo += nsPrintfCString(" parent=%p", static_cast<void*>(GetParent()));
}
if (GetNextSibling()) {
aTo += nsPrintfCString(" next=%p", static_cast<void*>(GetNextSibling()));
if (!onlyDeterministic) {
if (GetParent()) {
aTo += nsPrintfCString(" parent=%p", static_cast<void*>(GetParent()));
}
if (GetNextSibling()) {
aTo +=
nsPrintfCString(" next=%p", static_cast<void*>(GetNextSibling()));
}
}
if (GetPrevContinuation()) {
bool fluid = GetPrevInFlow() == GetPrevContinuation();
aTo += nsPrintfCString(" prev-%s=%p", fluid ? "in-flow" : "continuation",
static_cast<void*>(GetPrevContinuation()));
aTo += nsPrintfCString(" prev-%s", fluid ? "in-flow" : "continuation");
ListPtr(aTo, aFlags, GetPrevContinuation());
}
if (GetNextContinuation()) {
bool fluid = GetNextInFlow() == GetNextContinuation();
aTo += nsPrintfCString(" next-%s=%p", fluid ? "in-flow" : "continuation",
static_cast<void*>(GetNextContinuation()));
aTo += nsPrintfCString(" next-%s", fluid ? "in-flow" : "continuation");
ListPtr(aTo, aFlags, GetNextContinuation());
}
if (const nsAtom* const autoPageValue =
GetProperty(AutoPageValueProperty())) {
@@ -8619,11 +8625,13 @@ void nsIFrame::ListGeneric(nsACString& aTo, const char* aPrefix,
}
void* IBsibling = GetProperty(IBSplitSibling());
if (IBsibling) {
aTo += nsPrintfCString(" IBSplitSibling=%p", IBsibling);
aTo += nsPrintfCString(" IBSplitSibling");
ListPtr(aTo, aFlags, IBsibling);
}
void* IBprevsibling = GetProperty(IBSplitPrevSibling());
if (IBprevsibling) {
aTo += nsPrintfCString(" IBSplitPrevSibling=%p", IBprevsibling);
aTo += nsPrintfCString(" IBSplitPrevSibling");
ListPtr(aTo, aFlags, IBprevsibling);
}
if (nsLayoutUtils::FontSizeInflationEnabled(PresContext())) {
if (HasAnyStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT)) {
@@ -8715,20 +8723,25 @@ void nsIFrame::ListGeneric(nsACString& aTo, const char* aPrefix,
aTo += nsPrintfCString(" combines-3d-transform-with-ancestors");
}
if (mContent) {
aTo += nsPrintfCString(" [content=%p", static_cast<void*>(mContent));
if (!onlyDeterministic) {
aTo += nsPrintfCString(" [content=%p]", static_cast<void*>(mContent));
}
if (IsPrimaryFrame() && DisplayPortUtils::HasDisplayPort(mContent)) {
// Anon boxes and continuations point to the same content - Just print on
// primary frame.
aTo += ",displayport"_ns;
aTo += "[displayport]"_ns;
}
aTo += "]"_ns;
}
aTo += nsPrintfCString(" [cs=%p", static_cast<void*>(mComputedStyle));
if (!onlyDeterministic) {
aTo += nsPrintfCString("[cs=%p]", static_cast<void*>(mComputedStyle));
}
if (mComputedStyle) {
auto pseudoType = mComputedStyle->GetPseudoType();
aTo += ToString(pseudoType).c_str();
const auto pseudoType = mComputedStyle->GetPseudoType();
const auto pseudoTypeStr = ToString(pseudoType);
if (!pseudoTypeStr.empty()) {
aTo += nsPrintfCString("[%s]", pseudoTypeStr.c_str());
}
}
aTo += "]";
auto contentVisibility = StyleDisplay()->ContentVisibility(*this);
if (contentVisibility != StyleContentVisibility::Visible) {
@@ -8829,12 +8842,20 @@ nsresult nsIFrame::MakeFrameName(const nsAString& aType,
return NS_OK;
}
void nsIFrame::DumpFrameTree() const {
PresShell()->GetRootFrame()->List(stderr);
void nsIFrame::DumpFrameTree(bool aListOnlyDeterministic) const {
ListFlags flags;
if (aListOnlyDeterministic) {
flags += ListFlag::OnlyListDeterministicInfo;
}
PresShell()->GetRootFrame()->List(stderr, "", flags);
}
void nsIFrame::DumpFrameTreeInCSSPixels() const {
PresShell()->GetRootFrame()->List(stderr, "", ListFlag::DisplayInCSSPixels);
void nsIFrame::DumpFrameTreeInCSSPixels(bool aListOnlyDeterministic) const {
ListFlags flags{ListFlag::DisplayInCSSPixels};
if (aListOnlyDeterministic) {
flags += ListFlag::OnlyListDeterministicInfo;
}
PresShell()->GetRootFrame()->List(stderr, "", flags);
}
void nsIFrame::DumpFrameTreeLimited() const { List(stderr); }

View File

@@ -5562,9 +5562,9 @@ class nsIFrame : public nsQueryFrame {
}
}
void ListTag(FILE* out) const { fputs(ListTag().get(), out); }
nsAutoCString ListTag() const;
nsAutoCString ListTag(bool aListOnlyDeterministic = false) const;
enum class ListFlag{TraverseSubdocumentFrames, DisplayInCSSPixels};
enum class ListFlag{TraverseSubdocumentFrames, DisplayInCSSPixels, OnlyListDeterministicInfo};
using ListFlags = mozilla::EnumSet<ListFlag>;
template <typename T>
@@ -5581,6 +5581,19 @@ class nsIFrame : public nsQueryFrame {
const mozilla::WritingMode aWM,
ListFlags aFlags);
template <typename T>
static void ListPtr(nsACString& aTo, const ListFlags& aFlags, const T* aPtr, const char* aPrefix = "=") {
ListPtr(aTo, aFlags.contains(ListFlag::OnlyListDeterministicInfo), aPtr, aPrefix);
}
template <typename T>
static void ListPtr(nsACString& aTo, bool aSkip, const T* aPtr, const char* aPrefix = "=") {
if (aSkip) {
return;
}
aTo += nsPrintfCString("%s%p", aPrefix, static_cast<const void*>(aPtr));
}
void ListGeneric(nsACString& aTo, const char* aPrefix = "",
ListFlags aFlags = ListFlags()) const;
virtual void List(FILE* out = stderr, const char* aPrefix = "",
@@ -5596,8 +5609,8 @@ class nsIFrame : public nsQueryFrame {
/**
* Dump the frame tree beginning from the root frame.
*/
void DumpFrameTree() const;
void DumpFrameTreeInCSSPixels() const;
void DumpFrameTree(bool aListOnlyDeterministic = false) const;
void DumpFrameTreeInCSSPixels(bool aListOnlyDeterministic = false) const;
/**
* Dump the frame tree beginning from ourselves.

View File

@@ -173,10 +173,12 @@ void nsLineBox::Cleanup() {
#ifdef DEBUG_FRAME_DUMP
static void ListFloats(FILE* out, const char* aPrefix,
const nsTArray<nsIFrame*>& aFloats) {
const nsTArray<nsIFrame*>& aFloats,
bool aListOnlyDeterministic) {
for (nsIFrame* f : aFloats) {
nsCString str(aPrefix);
str += nsPrintfCString("floatframe@%p ", static_cast<void*>(f));
str += "floatframe";
nsIFrame::ListPtr(str, aListOnlyDeterministic, f, "@");
nsAutoString frameName;
f->GetFrameName(frameName);
str += NS_ConvertUTF16toUTF8(frameName).get();
@@ -210,9 +212,11 @@ void nsLineBox::List(FILE* out, int32_t aIndent,
void nsLineBox::List(FILE* out, const char* aPrefix,
nsIFrame::ListFlags aFlags) const {
nsCString str(aPrefix);
str += "line";
nsIFrame::ListPtr(str, aFlags, this, "@");
str += nsPrintfCString(
"line@%p count=%d state=%s,%s,%s,%s,%s,%s,clear-before:%s,clear-after:%s",
this, GetChildCount(), IsBlock() ? "block" : "inline",
" count=%d state=%s,%s,%s,%s,%s,%s,clear-before:%s,clear-after:%s",
GetChildCount(), IsBlock() ? "block" : "inline",
IsDirty() ? "dirty" : "clean",
IsPreviousMarginDirty() ? "prevmargindirty" : "prevmarginclean",
IsImpactedByFloat() ? "impacted" : "not-impacted",
@@ -263,7 +267,7 @@ void nsLineBox::List(FILE* out, const char* aPrefix,
if (HasFloats()) {
fprintf_stderr(out, "%s> floats <\n", aPrefix);
ListFloats(out, pfx.get(), mInlineData->mFloats);
ListFloats(out, pfx.get(), mInlineData->mFloats, aFlags.contains(nsIFrame::ListFlag::OnlyListDeterministicInfo));
}
fprintf_stderr(out, "%s>\n", aPrefix);
}

View File

@@ -428,7 +428,7 @@ void nsPageContentFrame::EnsurePageName() {
nsresult nsPageContentFrame::GetFrameName(nsAString& aResult) const {
return MakeFrameName(u"PageContent"_ns, aResult);
}
void nsPageContentFrame::ExtraContainerFrameInfo(nsACString& aTo) const {
void nsPageContentFrame::ExtraContainerFrameInfo(nsACString& aTo, bool) const {
if (mPageName) {
aTo += " [page=";
aTo += nsAtomCString(mPageName);

View File

@@ -49,7 +49,7 @@ class nsPageContentFrame final : public mozilla::ViewportFrame {
#ifdef DEBUG_FRAME_DUMP
// Debugging
nsresult GetFrameName(nsAString& aResult) const override;
void ExtraContainerFrameInfo(nsACString& aTo) const override;
void ExtraContainerFrameInfo(nsACString& aTo, bool aListOnlyDeterministic) const override;
#endif
protected:

View File

@@ -223,7 +223,8 @@ void nsPlaceholderFrame::List(FILE* out, const char* aPrefix,
if (mOutOfFlowFrame) {
str += " outOfFlowFrame=";
str += mOutOfFlowFrame->ListTag();
str += mOutOfFlowFrame->ListTag(
aFlags.contains(ListFlag::OnlyListDeterministicInfo));
}
fprintf_stderr(out, "%s\n", str.get());
}

View File

@@ -10647,7 +10647,9 @@ void nsTextFrame::List(FILE* out, const char* aPrefix, ListFlags aFlags) const {
nsCString str;
ListGeneric(str, aPrefix, aFlags);
str += nsPrintfCString(" [run=%p]", static_cast<void*>(mTextRun));
if (!aFlags.contains(ListFlag::OnlyListDeterministicInfo)) {
str += nsPrintfCString(" [run=%p]", static_cast<void*>(mTextRun));
}
// Output the first/last content offset and prev/next in flow info
bool isComplete = uint32_t(GetContentEnd()) == GetContent()->TextLength();