From abf84fd28259ff2ea9858e94f40ad135b8ce850b Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 2 Apr 2024 19:03:06 +0000 Subject: [PATCH] Bug 1888535 Part 6 - Unhook display reflow debugging from nsLayoutStatics, and remove display reflow debugging. r=layout-reviewers,emilio This final patch completely removes display reflow debugging mechanism. Differential Revision: https://phabricator.services.mozilla.com/D206318 --- layout/build/nsLayoutStatics.cpp | 6 - layout/generic/nsIFrame.cpp | 571 ------------------------------- layout/generic/nsIFrame.h | 4 - 3 files changed, 581 deletions(-) diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index 1738098ed2ef..ecc84ad28684 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -183,9 +183,6 @@ nsresult nsLayoutStatics::Initialize() { nsMathMLOperators::AddRefTable(); -#ifdef DEBUG - nsIFrame::DisplayReflowStartup(); -#endif Attr::Initialize(); PopupBlocker::Initialize(); @@ -320,9 +317,6 @@ void nsLayoutStatics::Shutdown() { HTMLDNSPrefetch::Shutdown(); nsCSSRendering::Shutdown(); StaticPresData::Shutdown(); -#ifdef DEBUG - nsIFrame::DisplayReflowShutdown(); -#endif nsCellMap::Shutdown(); ActiveLayerTracker::Shutdown(); diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp index 2bda17733e68..7dd1e7c13066 100644 --- a/layout/generic/nsIFrame.cpp +++ b/layout/generic/nsIFrame.cpp @@ -11673,577 +11673,6 @@ void nsIFrame::VerifyDirtyBitSet(const nsFrameList& aFrameList) { } } -// Start Display Reflow -struct DR_Rule; - -struct DR_FrameTypeInfo { - DR_FrameTypeInfo(LayoutFrameType aFrameType, const char* aFrameNameAbbrev, - const char* aFrameName); - ~DR_FrameTypeInfo(); - - LayoutFrameType mType; - char mNameAbbrev[16]; - char mName[32]; - nsTArray mRules; - - private: - DR_FrameTypeInfo& operator=(const DR_FrameTypeInfo&) = delete; -}; - -struct DR_FrameTreeNode; -struct DR_Rule; - -struct DR_State { - DR_State(); - ~DR_State(); - void Init(); - void AddFrameTypeInfo(LayoutFrameType aFrameType, - const char* aFrameNameAbbrev, const char* aFrameName); - DR_FrameTypeInfo* GetFrameTypeInfo(LayoutFrameType aFrameType); - DR_FrameTypeInfo* GetFrameTypeInfo(char* aFrameName); - void InitFrameTypeTable(); - DR_FrameTreeNode* CreateTreeNode(nsIFrame* aFrame, - const ReflowInput* aReflowInput); - void FindMatchingRule(DR_FrameTreeNode& aNode); - bool RuleMatches(DR_Rule& aRule, DR_FrameTreeNode& aNode); - bool GetToken(FILE* aFile, char* aBuf, size_t aBufSize); - DR_Rule* ParseRule(FILE* aFile); - void ParseRulesFile(); - void AddRule(nsTArray& aRules, DR_Rule& aRule); - bool IsWhiteSpace(int c); - bool GetNumber(char* aBuf, int32_t& aNumber); - void PrettyUC(nscoord aSize, char* aBuf, int aBufSize); - void PrintMargin(const char* tag, const nsMargin* aMargin); - void DisplayFrameTypeInfo(nsIFrame* aFrame, int32_t aIndent); - void DeleteTreeNode(DR_FrameTreeNode& aNode); - - bool mInited; - bool mActive; - int32_t mCount; - int32_t mAssert; - int32_t mIndent; - bool mIndentUndisplayedFrames; - bool mDisplayPixelErrors; - nsTArray mWildRules; - nsTArray mFrameTypeTable; - // reflow specific state - nsTArray mFrameTreeLeaves; -}; - -static DR_State* DR_state; // the one and only DR_State - -struct DR_RulePart { - explicit DR_RulePart(LayoutFrameType aFrameType) - : mFrameType(aFrameType), mNext(0) {} - - void Destroy(); - - LayoutFrameType mFrameType; - DR_RulePart* mNext; -}; - -void DR_RulePart::Destroy() { - if (mNext) { - mNext->Destroy(); - } - delete this; -} - -struct DR_Rule { - DR_Rule() : mLength(0), mTarget(nullptr), mDisplay(false) { - MOZ_COUNT_CTOR(DR_Rule); - } - ~DR_Rule() { - if (mTarget) mTarget->Destroy(); - MOZ_COUNT_DTOR(DR_Rule); - } - void AddPart(LayoutFrameType aFrameType); - - uint32_t mLength; - DR_RulePart* mTarget; - bool mDisplay; -}; - -void DR_Rule::AddPart(LayoutFrameType aFrameType) { - DR_RulePart* newPart = new DR_RulePart(aFrameType); - newPart->mNext = mTarget; - mTarget = newPart; - mLength++; -} - -DR_FrameTypeInfo::~DR_FrameTypeInfo() { - int32_t numElements; - numElements = mRules.Length(); - for (int32_t i = numElements - 1; i >= 0; i--) { - delete mRules.ElementAt(i); - } -} - -DR_FrameTypeInfo::DR_FrameTypeInfo(LayoutFrameType aFrameType, - const char* aFrameNameAbbrev, - const char* aFrameName) { - mType = aFrameType; - PL_strncpyz(mNameAbbrev, aFrameNameAbbrev, sizeof(mNameAbbrev)); - PL_strncpyz(mName, aFrameName, sizeof(mName)); -} - -struct DR_FrameTreeNode { - DR_FrameTreeNode(nsIFrame* aFrame, DR_FrameTreeNode* aParent) - : mFrame(aFrame), mParent(aParent), mDisplay(0), mIndent(0) { - MOZ_COUNT_CTOR(DR_FrameTreeNode); - } - - MOZ_COUNTED_DTOR(DR_FrameTreeNode) - - nsIFrame* mFrame; - DR_FrameTreeNode* mParent; - bool mDisplay; - uint32_t mIndent; -}; - -// DR_State implementation - -DR_State::DR_State() - : mInited(false), - mActive(false), - mCount(0), - mAssert(-1), - mIndent(0), - mIndentUndisplayedFrames(false), - mDisplayPixelErrors(false) { - MOZ_COUNT_CTOR(DR_State); -} - -void DR_State::Init() { - char* env = PR_GetEnv("GECKO_DISPLAY_REFLOW_ASSERT"); - int32_t num; - if (env) { - if (GetNumber(env, num)) - mAssert = num; - else - printf("GECKO_DISPLAY_REFLOW_ASSERT - invalid value = %s", env); - } - - env = PR_GetEnv("GECKO_DISPLAY_REFLOW_INDENT_START"); - if (env) { - if (GetNumber(env, num)) - mIndent = num; - else - printf("GECKO_DISPLAY_REFLOW_INDENT_START - invalid value = %s", env); - } - - env = PR_GetEnv("GECKO_DISPLAY_REFLOW_INDENT_UNDISPLAYED_FRAMES"); - if (env) { - if (GetNumber(env, num)) - mIndentUndisplayedFrames = num; - else - printf( - "GECKO_DISPLAY_REFLOW_INDENT_UNDISPLAYED_FRAMES - invalid value = %s", - env); - } - - env = PR_GetEnv("GECKO_DISPLAY_REFLOW_FLAG_PIXEL_ERRORS"); - if (env) { - if (GetNumber(env, num)) - mDisplayPixelErrors = num; - else - printf("GECKO_DISPLAY_REFLOW_FLAG_PIXEL_ERRORS - invalid value = %s", - env); - } - - InitFrameTypeTable(); - ParseRulesFile(); - mInited = true; -} - -DR_State::~DR_State() { - MOZ_COUNT_DTOR(DR_State); - int32_t numElements, i; - numElements = mWildRules.Length(); - for (i = numElements - 1; i >= 0; i--) { - delete mWildRules.ElementAt(i); - } - numElements = mFrameTreeLeaves.Length(); - for (i = numElements - 1; i >= 0; i--) { - delete mFrameTreeLeaves.ElementAt(i); - } -} - -bool DR_State::GetNumber(char* aBuf, int32_t& aNumber) { - if (sscanf(aBuf, "%d", &aNumber) > 0) - return true; - else - return false; -} - -bool DR_State::IsWhiteSpace(int c) { - return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'); -} - -bool DR_State::GetToken(FILE* aFile, char* aBuf, size_t aBufSize) { - bool haveToken = false; - aBuf[0] = 0; - // get the 1st non whitespace char - int c = -1; - for (c = getc(aFile); (c > 0) && IsWhiteSpace(c); c = getc(aFile)) { - } - - if (c > 0) { - haveToken = true; - aBuf[0] = c; - // get everything up to the next whitespace char - size_t cX; - for (cX = 1; cX + 1 < aBufSize; cX++) { - c = getc(aFile); - if (c < 0) { // EOF - ungetc(' ', aFile); - break; - } else { - if (IsWhiteSpace(c)) { - break; - } else { - aBuf[cX] = c; - } - } - } - aBuf[cX] = 0; - } - return haveToken; -} - -DR_Rule* DR_State::ParseRule(FILE* aFile) { - char buf[128]; - int32_t doDisplay; - DR_Rule* rule = nullptr; - while (GetToken(aFile, buf, sizeof(buf))) { - if (GetNumber(buf, doDisplay)) { - if (rule) { - rule->mDisplay = !!doDisplay; - break; - } else { - printf("unexpected token - %s \n", buf); - } - } else { - if (!rule) { - rule = new DR_Rule; - } - if (strcmp(buf, "*") == 0) { - rule->AddPart(LayoutFrameType::None); - } else { - DR_FrameTypeInfo* info = GetFrameTypeInfo(buf); - if (info) { - rule->AddPart(info->mType); - } else { - printf("invalid frame type - %s \n", buf); - } - } - } - } - return rule; -} - -void DR_State::AddRule(nsTArray& aRules, DR_Rule& aRule) { - int32_t numRules = aRules.Length(); - for (int32_t ruleX = 0; ruleX < numRules; ruleX++) { - DR_Rule* rule = aRules.ElementAt(ruleX); - NS_ASSERTION(rule, "program error"); - if (aRule.mLength > rule->mLength) { - aRules.InsertElementAt(ruleX, &aRule); - return; - } - } - aRules.AppendElement(&aRule); -} - -static Maybe ShouldLogReflow(const char* processes) { - switch (processes[0]) { - case 'A': - case 'a': - return Some(true); - case 'P': - case 'p': - return Some(XRE_IsParentProcess()); - case 'C': - case 'c': - return Some(XRE_IsContentProcess()); - default: - return Nothing{}; - } -} - -void DR_State::ParseRulesFile() { - char* processes = PR_GetEnv("GECKO_DISPLAY_REFLOW_PROCESSES"); - if (processes) { - Maybe enableLog = ShouldLogReflow(processes); - if (enableLog.isNothing()) { - MOZ_CRASH("GECKO_DISPLAY_REFLOW_PROCESSES: [a]ll [p]arent [c]ontent"); - } else if (enableLog.value()) { - DR_Rule* rule = new DR_Rule; - rule->AddPart(LayoutFrameType::None); - rule->mDisplay = true; - AddRule(mWildRules, *rule); - mActive = true; - } - return; - } - - char* path = PR_GetEnv("GECKO_DISPLAY_REFLOW_RULES_FILE"); - if (path) { - FILE* inFile = fopen(path, "r"); - if (!inFile) { - MOZ_CRASH( - "Failed to open the specified rules file; Try `--setpref " - "security.sandbox.content.level=2` if the sandbox is at cause"); - } - for (DR_Rule* rule = ParseRule(inFile); rule; rule = ParseRule(inFile)) { - if (rule->mTarget) { - LayoutFrameType fType = rule->mTarget->mFrameType; - if (fType != LayoutFrameType::None) { - DR_FrameTypeInfo* info = GetFrameTypeInfo(fType); - AddRule(info->mRules, *rule); - } else { - AddRule(mWildRules, *rule); - } - mActive = true; - } - } - - fclose(inFile); - } -} - -void DR_State::AddFrameTypeInfo(LayoutFrameType aFrameType, - const char* aFrameNameAbbrev, - const char* aFrameName) { - mFrameTypeTable.EmplaceBack(aFrameType, aFrameNameAbbrev, aFrameName); -} - -DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(LayoutFrameType aFrameType) { - int32_t numEntries = mFrameTypeTable.Length(); - NS_ASSERTION(numEntries != 0, "empty FrameTypeTable"); - for (int32_t i = 0; i < numEntries; i++) { - DR_FrameTypeInfo& info = mFrameTypeTable.ElementAt(i); - if (info.mType == aFrameType) { - return &info; - } - } - return &mFrameTypeTable.ElementAt(numEntries - - 1); // return unknown frame type -} - -DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(char* aFrameName) { - int32_t numEntries = mFrameTypeTable.Length(); - NS_ASSERTION(numEntries != 0, "empty FrameTypeTable"); - for (int32_t i = 0; i < numEntries; i++) { - DR_FrameTypeInfo& info = mFrameTypeTable.ElementAt(i); - if ((strcmp(aFrameName, info.mName) == 0) || - (strcmp(aFrameName, info.mNameAbbrev) == 0)) { - return &info; - } - } - return &mFrameTypeTable.ElementAt(numEntries - - 1); // return unknown frame type -} - -void DR_State::InitFrameTypeTable() { - AddFrameTypeInfo(LayoutFrameType::Block, "block", "block"); - AddFrameTypeInfo(LayoutFrameType::Br, "br", "br"); - AddFrameTypeInfo(LayoutFrameType::ColorControl, "color", "colorControl"); - AddFrameTypeInfo(LayoutFrameType::GfxButtonControl, "button", - "gfxButtonControl"); - AddFrameTypeInfo(LayoutFrameType::HTMLButtonControl, "HTMLbutton", - "HTMLButtonControl"); - AddFrameTypeInfo(LayoutFrameType::HTMLCanvas, "HTMLCanvas", "HTMLCanvas"); - AddFrameTypeInfo(LayoutFrameType::SubDocument, "subdoc", "subDocument"); - AddFrameTypeInfo(LayoutFrameType::Image, "img", "image"); - AddFrameTypeInfo(LayoutFrameType::Inline, "inline", "inline"); - AddFrameTypeInfo(LayoutFrameType::Letter, "letter", "letter"); - AddFrameTypeInfo(LayoutFrameType::Line, "line", "line"); - AddFrameTypeInfo(LayoutFrameType::ListControl, "select", "select"); - AddFrameTypeInfo(LayoutFrameType::Page, "page", "page"); - AddFrameTypeInfo(LayoutFrameType::Placeholder, "place", "placeholder"); - AddFrameTypeInfo(LayoutFrameType::Canvas, "canvas", "canvas"); - AddFrameTypeInfo(LayoutFrameType::Scroll, "scroll", "scroll"); - AddFrameTypeInfo(LayoutFrameType::TableCell, "cell", "tableCell"); - AddFrameTypeInfo(LayoutFrameType::TableCol, "col", "tableCol"); - AddFrameTypeInfo(LayoutFrameType::TableColGroup, "colG", "tableColGroup"); - AddFrameTypeInfo(LayoutFrameType::Table, "tbl", "table"); - AddFrameTypeInfo(LayoutFrameType::TableWrapper, "tblW", "tableWrapper"); - AddFrameTypeInfo(LayoutFrameType::TableRowGroup, "rowG", "tableRowGroup"); - AddFrameTypeInfo(LayoutFrameType::TableRow, "row", "tableRow"); - AddFrameTypeInfo(LayoutFrameType::TextInput, "textCtl", "textInput"); - AddFrameTypeInfo(LayoutFrameType::Text, "text", "text"); - AddFrameTypeInfo(LayoutFrameType::Viewport, "VP", "viewport"); - AddFrameTypeInfo(LayoutFrameType::Slider, "Slider", "Slider"); - AddFrameTypeInfo(LayoutFrameType::None, "unknown", "unknown"); -} - -void DR_State::DisplayFrameTypeInfo(nsIFrame* aFrame, int32_t aIndent) { - DR_FrameTypeInfo* frameTypeInfo = GetFrameTypeInfo(aFrame->Type()); - if (frameTypeInfo) { - for (int32_t i = 0; i < aIndent; i++) { - printf(" "); - } - if (!strcmp(frameTypeInfo->mNameAbbrev, "unknown")) { - if (aFrame) { - nsAutoString name; - aFrame->GetFrameName(name); - printf("%s %p ", NS_LossyConvertUTF16toASCII(name).get(), - (void*)aFrame); - } else { - printf("%s %p ", frameTypeInfo->mNameAbbrev, (void*)aFrame); - } - } else { - printf("%s %p ", frameTypeInfo->mNameAbbrev, (void*)aFrame); - } - } -} - -bool DR_State::RuleMatches(DR_Rule& aRule, DR_FrameTreeNode& aNode) { - NS_ASSERTION(aRule.mTarget, "program error"); - - DR_RulePart* rulePart; - DR_FrameTreeNode* parentNode; - for (rulePart = aRule.mTarget->mNext, parentNode = aNode.mParent; - rulePart && parentNode; - rulePart = rulePart->mNext, parentNode = parentNode->mParent) { - if (rulePart->mFrameType != LayoutFrameType::None) { - if (parentNode->mFrame) { - if (rulePart->mFrameType != parentNode->mFrame->Type()) { - return false; - } - } else - NS_ASSERTION(false, "program error"); - } - // else wild card match - } - return true; -} - -void DR_State::FindMatchingRule(DR_FrameTreeNode& aNode) { - if (!aNode.mFrame) { - NS_ASSERTION(false, "invalid DR_FrameTreeNode \n"); - return; - } - - bool matchingRule = false; - - DR_FrameTypeInfo* info = GetFrameTypeInfo(aNode.mFrame->Type()); - NS_ASSERTION(info, "program error"); - int32_t numRules = info->mRules.Length(); - for (int32_t ruleX = 0; ruleX < numRules; ruleX++) { - DR_Rule* rule = info->mRules.ElementAt(ruleX); - if (rule && RuleMatches(*rule, aNode)) { - aNode.mDisplay = rule->mDisplay; - matchingRule = true; - break; - } - } - if (!matchingRule) { - int32_t numWildRules = mWildRules.Length(); - for (int32_t ruleX = 0; ruleX < numWildRules; ruleX++) { - DR_Rule* rule = mWildRules.ElementAt(ruleX); - if (rule && RuleMatches(*rule, aNode)) { - aNode.mDisplay = rule->mDisplay; - break; - } - } - } -} - -DR_FrameTreeNode* DR_State::CreateTreeNode(nsIFrame* aFrame, - const ReflowInput* aReflowInput) { - // find the frame of the parent reflow input (usually just the parent of - // aFrame) - nsIFrame* parentFrame; - if (aReflowInput) { - const ReflowInput* parentRI = aReflowInput->mParentReflowInput; - parentFrame = (parentRI) ? parentRI->mFrame : nullptr; - } else { - parentFrame = aFrame->GetParent(); - } - - // find the parent tree node leaf - DR_FrameTreeNode* parentNode = nullptr; - - DR_FrameTreeNode* lastLeaf = nullptr; - if (mFrameTreeLeaves.Length()) - lastLeaf = mFrameTreeLeaves.ElementAt(mFrameTreeLeaves.Length() - 1); - if (lastLeaf) { - for (parentNode = lastLeaf; - parentNode && (parentNode->mFrame != parentFrame); - parentNode = parentNode->mParent) { - } - } - DR_FrameTreeNode* newNode = new DR_FrameTreeNode(aFrame, parentNode); - FindMatchingRule(*newNode); - - newNode->mIndent = mIndent; - if (newNode->mDisplay || mIndentUndisplayedFrames) { - ++mIndent; - } - - if (lastLeaf && (lastLeaf == parentNode)) { - mFrameTreeLeaves.RemoveLastElement(); - } - mFrameTreeLeaves.AppendElement(newNode); - mCount++; - - return newNode; -} - -void DR_State::PrettyUC(nscoord aSize, char* aBuf, int aBufSize) { - if (NS_UNCONSTRAINEDSIZE == aSize) { - strcpy(aBuf, "UC"); - } else { - if ((nscoord)0xdeadbeefU == aSize) { - strcpy(aBuf, "deadbeef"); - } else { - snprintf(aBuf, aBufSize, "%d", aSize); - } - } -} - -void DR_State::PrintMargin(const char* tag, const nsMargin* aMargin) { - if (aMargin) { - char t[16], r[16], b[16], l[16]; - PrettyUC(aMargin->top, t, 16); - PrettyUC(aMargin->right, r, 16); - PrettyUC(aMargin->bottom, b, 16); - PrettyUC(aMargin->left, l, 16); - printf(" %s=%s,%s,%s,%s", tag, t, r, b, l); - } else { - // use %p here for consistency with other null-pointer printouts - printf(" %s=%p", tag, (void*)aMargin); - } -} - -void DR_State::DeleteTreeNode(DR_FrameTreeNode& aNode) { - mFrameTreeLeaves.RemoveElement(&aNode); - int32_t numLeaves = mFrameTreeLeaves.Length(); - if ((0 == numLeaves) || - (aNode.mParent != mFrameTreeLeaves.ElementAt(numLeaves - 1))) { - mFrameTreeLeaves.AppendElement(aNode.mParent); - } - - if (aNode.mDisplay || mIndentUndisplayedFrames) { - --mIndent; - } - // delete the tree node - delete &aNode; -} - -/* static */ -void nsIFrame::DisplayReflowStartup() { DR_state = new DR_State(); } - -/* static */ -void nsIFrame::DisplayReflowShutdown() { - delete DR_state; - DR_state = nullptr; -} - -// End Display Reflow - // Validation of SideIsVertical. # define CASE(side, result) \ static_assert(SideIsVertical(side) == result, "SideIsVertical is wrong") diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index c837fadf2080..1e8380a127dc 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -5489,10 +5489,6 @@ class nsIFrame : public nsQueryFrame { // NS_FRAME_IS_DIRTY bit set static void VerifyDirtyBitSet(const nsFrameList& aFrameList); - // Display Reflow Debugging - static void DisplayReflowStartup(); - static void DisplayReflowShutdown(); - static mozilla::LazyLogModule sFrameLogModule; #endif };