Bug 1674766 - Remove DisplayListChecker r=mattwoodrow

Differential Revision: https://phabricator.services.mozilla.com/D95531
This commit is contained in:
Miko Mynttinen 2020-11-02 20:04:37 +00:00
parent 6b00235dd5
commit e312ab88d1
7 changed files with 5 additions and 468 deletions

View File

@ -12,7 +12,6 @@
#include "ActiveLayerTracker.h"
#include "ClientLayerManager.h"
#include "DisplayItemClip.h"
#include "DisplayListChecker.h"
#include "FrameLayerBuilder.h"
#include "GeckoProfiler.h"
#include "gfx2DGlue.h"
@ -3304,10 +3303,6 @@ nsresult nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext,
gfxPlatform::AsyncPanZoomEnabled() &&
nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell));
DisplayListChecker beforeMergeChecker;
DisplayListChecker toBeMergedChecker;
DisplayListChecker afterMergeChecker;
// If a pref is toggled that adds or removes display list items,
// we need to rebuild the display list. The pref may be toggled
// manually by the user, or during test setup.
@ -3320,18 +3315,7 @@ nsresult nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext,
// This calls BuildDisplayListForStacking context on a subset of the
// viewport.
if (shouldAttemptPartialUpdate) {
if (StaticPrefs::layout_display_list_retain_verify()) {
beforeMergeChecker.Set(list, "BM");
}
updateState = retainedBuilder->AttemptPartialUpdate(
aBackstop, beforeMergeChecker ? &toBeMergedChecker : nullptr);
if ((updateState != PartialUpdateResult::Failed) &&
beforeMergeChecker) {
afterMergeChecker.Set(list, "AM");
}
updateState = retainedBuilder->AttemptPartialUpdate(aBackstop);
metrics->EndPartialBuild(updateState);
} else {
// Partial updates are disabled.
@ -3339,10 +3323,8 @@ nsresult nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext,
metrics->mPartialUpdateFailReason = PartialUpdateFailReason::Disabled;
}
// Rebuild the full display list if the partial display list build failed,
// or if the merge checker is used.
bool doFullRebuild =
updateState == PartialUpdateResult::Failed || afterMergeChecker;
// Rebuild the full display list if the partial display list build failed.
bool doFullRebuild = updateState == PartialUpdateResult::Failed;
if (StaticPrefs::layout_display_list_build_twice()) {
// Build display list twice to compare partial and full display list
@ -3368,28 +3350,6 @@ nsresult nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext,
metrics->EndFullBuild();
updateState = PartialUpdateResult::Updated;
if (afterMergeChecker) {
DisplayListChecker nonRetainedChecker(list, "NR");
std::stringstream ss;
ss << "**** Differences between retained-after-merged (AM) and "
<< "non-retained (NR) display lists:";
if (!nonRetainedChecker.CompareList(afterMergeChecker, ss)) {
ss << "\n\n*** non-retained display items:";
nonRetainedChecker.Dump(ss);
ss << "\n\n*** before-merge retained display items:";
beforeMergeChecker.Dump(ss);
ss << "\n\n*** to-be-merged retained display items:";
toBeMergedChecker.Dump(ss);
ss << "\n\n*** after-merge retained display items:";
afterMergeChecker.Dump(ss);
fprintf(stderr, "%s\n\n", ss.str().c_str());
#ifdef DEBUG_FRAME_DUMP
fprintf(stderr, "*** Frame tree:\n");
aFrame->DumpFrameTree();
#endif
}
}
}
}

View File

@ -1,355 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DisplayListChecker.h"
#include "nsDisplayList.h"
#include "mozilla/StaticPrefs_layout.h"
namespace mozilla {
class DisplayItemBlueprint;
// Stack node used during tree visits, to store the path to a display item.
struct DisplayItemBlueprintStack {
const DisplayItemBlueprintStack* mPrevious;
const DisplayItemBlueprint* mItem;
// Output stack to aSs, with format "name#index > ... > name#index".
// Returns true if anything was output, false if empty.
bool Output(std::stringstream& aSs) const;
};
// Object representing a list of display items (either the top of the tree, or
// an item's children), with just enough information to compare with another
// tree and output useful debugging information.
class DisplayListBlueprint {
public:
DisplayListBlueprint(nsDisplayList* aList, const char* aName)
: DisplayListBlueprint(aList, 0, aName) {}
DisplayListBlueprint(nsDisplayList* aList, const char* aName,
unsigned& aIndex) {
processChildren(aList, aName, aIndex);
}
// Find a display item with the given frame and per-frame key.
// Returns empty string if not found.
std::string Find(const nsIFrame* aFrame, uint32_t aPerFrameKey) const {
const DisplayItemBlueprintStack stack{nullptr, nullptr};
return Find(aFrame, aPerFrameKey, stack);
}
std::string Find(const nsIFrame* aFrame, uint32_t aPerFrameKey,
const DisplayItemBlueprintStack& aStack) const;
// Compare this list with another one, output differences between the two
// into aDiff.
// Differences include: Display items from one tree for which a corresponding
// item (same frame and per-frame key) cannot be found under corresponding
// parent items.
// Returns true if trees are similar, false if different.
bool CompareList(const DisplayListBlueprint& aOther,
std::stringstream& aDiff) const {
const DisplayItemBlueprintStack stack{nullptr, nullptr};
const bool ab = CompareList(*this, aOther, aOther, aDiff, stack, stack);
const bool ba =
aOther.CompareList(aOther, *this, *this, aDiff, stack, stack);
return ab && ba;
}
bool CompareList(const DisplayListBlueprint& aRoot,
const DisplayListBlueprint& aOther,
const DisplayListBlueprint& aOtherRoot,
std::stringstream& aDiff,
const DisplayItemBlueprintStack& aStack,
const DisplayItemBlueprintStack& aStackOther) const;
// Output this tree to aSs.
void Dump(std::stringstream& aSs) const { Dump(aSs, 0); }
void Dump(std::stringstream& aSs, unsigned aDepth) const;
private:
// Only used by first constructor, to call the 2nd constructor with an index
// variable on the stack.
DisplayListBlueprint(nsDisplayList* aList, unsigned aIndex, const char* aName)
: DisplayListBlueprint(aList, aName, aIndex) {}
void processChildren(nsDisplayList* aList, const char* aName,
unsigned& aIndex);
std::vector<DisplayItemBlueprint> mItems;
const bool mVerifyOrder =
StaticPrefs::layout_display_list_retain_verify_order();
};
// Object representing one display item, with just enough information to
// compare with another item and output useful debugging information.
class DisplayItemBlueprint {
public:
DisplayItemBlueprint(nsDisplayItem& aItem, const char* aName,
unsigned& aIndex)
: mListName(aName),
mIndex(++aIndex),
mIndexString(WriteIndex(aName, aIndex)),
mIndexStringFW(WriteIndexFW(aName, aIndex)),
mDisplayItemPointer(WriteDisplayItemPointer(aItem)),
mDescription(WriteDescription(aName, aIndex, aItem)),
mFrame(aItem.HasDeletedFrame() ? nullptr : aItem.Frame()),
mPerFrameKey(aItem.GetPerFrameKey()),
mChildren(aItem.GetChildren(), aName, aIndex) {}
// Compare this item with another one, based on frame and per-frame key.
// Not recursive! I.e., children are not examined.
bool CompareItem(const DisplayItemBlueprint& aOther,
std::stringstream& aDiff) const {
return mFrame == aOther.mFrame && mPerFrameKey == aOther.mPerFrameKey;
}
void Dump(std::stringstream& aSs, unsigned aDepth) const;
const char* mListName;
const unsigned mIndex;
const std::string mIndexString;
const std::string mIndexStringFW;
const std::string mDisplayItemPointer;
const std::string mDescription;
// For pointer comparison only, do not dereference!
const nsIFrame* const mFrame;
const uint32_t mPerFrameKey;
const DisplayListBlueprint mChildren;
private:
static std::string WriteIndex(const char* aName, unsigned aIndex) {
return nsPrintfCString("%s#%u", aName, aIndex).get();
}
static std::string WriteIndexFW(const char* aName, unsigned aIndex) {
return nsPrintfCString("%s#%4u", aName, aIndex).get();
}
static std::string WriteDisplayItemPointer(nsDisplayItem& aItem) {
return nsPrintfCString("0x%p", &aItem).get();
}
static std::string WriteDescription(const char* aName, unsigned aIndex,
nsDisplayItem& aItem) {
if (aItem.HasDeletedFrame()) {
return nsPrintfCString("%s %s#%u 0x%p f=0x0", aItem.Name(), aName, aIndex,
&aItem)
.get();
}
const nsIFrame* f = aItem.Frame();
nsAutoString contentData;
#ifdef DEBUG_FRAME_DUMP
f->GetFrameName(contentData);
#endif
nsIContent* content = f->GetContent();
if (content) {
nsString tmp;
if (content->GetID()) {
content->GetID()->ToString(tmp);
contentData.AppendLiteral(" id:");
contentData.Append(tmp);
}
const nsAttrValue* classes =
content->IsElement() ? content->AsElement()->GetClasses() : nullptr;
if (classes) {
classes->ToString(tmp);
contentData.AppendLiteral(" class:");
contentData.Append(tmp);
}
}
return nsPrintfCString("%s %s#%u p=0x%p f=0x%p(%s) key=%" PRIu32,
aItem.Name(), aName, aIndex, &aItem, f,
NS_ConvertUTF16toUTF8(contentData).get(),
aItem.GetPerFrameKey())
.get();
}
};
void DisplayListBlueprint::processChildren(nsDisplayList* aList,
const char* aName,
unsigned& aIndex) {
if (!aList) {
return;
}
const uint32_t n = aList->Count();
if (n == 0) {
return;
}
mItems.reserve(n);
for (nsDisplayItem* item = aList->GetBottom(); item;
item = item->GetAbove()) {
mItems.emplace_back(*item, aName, aIndex);
}
MOZ_ASSERT(mItems.size() == n);
}
bool DisplayItemBlueprintStack::Output(std::stringstream& aSs) const {
const bool output = mPrevious ? mPrevious->Output(aSs) : false;
if (mItem) {
if (output) {
aSs << " > ";
}
aSs << mItem->mIndexString;
return true;
}
return output;
}
std::string DisplayListBlueprint::Find(
const nsIFrame* aFrame, uint32_t aPerFrameKey,
const DisplayItemBlueprintStack& aStack) const {
for (const DisplayItemBlueprint& item : mItems) {
if (item.mFrame == aFrame && item.mPerFrameKey == aPerFrameKey) {
std::stringstream ss;
if (aStack.Output(ss)) {
ss << " > ";
}
ss << item.mDescription;
return ss.str();
}
const DisplayItemBlueprintStack stack = {&aStack, &item};
std::string s = item.mChildren.Find(aFrame, aPerFrameKey, stack);
if (!s.empty()) {
return s;
}
}
return "";
}
bool DisplayListBlueprint::CompareList(
const DisplayListBlueprint& aRoot, const DisplayListBlueprint& aOther,
const DisplayListBlueprint& aOtherRoot, std::stringstream& aDiff,
const DisplayItemBlueprintStack& aStack,
const DisplayItemBlueprintStack& aStackOther) const {
bool same = true;
unsigned previousFoundIndex = 0;
const DisplayItemBlueprint* previousFoundItemBefore = nullptr;
const DisplayItemBlueprint* previousFoundItemAfter = nullptr;
for (const DisplayItemBlueprint& itemBefore : mItems) {
bool found = false;
unsigned foundIndex = 0;
for (const DisplayItemBlueprint& itemAfter : aOther.mItems) {
if (itemBefore.CompareItem(itemAfter, aDiff)) {
found = true;
if (mVerifyOrder) {
if (foundIndex < previousFoundIndex) {
same = false;
aDiff << "\n";
if (aStack.Output(aDiff)) {
aDiff << " > ";
}
aDiff << itemBefore.mDescription;
aDiff << "\n * Corresponding item in unexpected order: ";
if (aStackOther.Output(aDiff)) {
aDiff << " > ";
}
aDiff << itemAfter.mDescription;
aDiff << "\n * Was expected after: ";
if (aStackOther.Output(aDiff)) {
aDiff << " > ";
}
MOZ_ASSERT(previousFoundItemAfter);
aDiff << previousFoundItemAfter->mDescription;
aDiff << "\n which corresponds to: ";
if (aStack.Output(aDiff)) {
aDiff << " > ";
}
MOZ_ASSERT(previousFoundItemBefore);
aDiff << previousFoundItemBefore->mDescription;
}
previousFoundIndex = foundIndex;
previousFoundItemBefore = &itemBefore;
previousFoundItemAfter = &itemAfter;
}
const DisplayItemBlueprintStack stack = {&aStack, &itemBefore};
const DisplayItemBlueprintStack stackOther = {&aStackOther, &itemAfter};
if (!itemBefore.mChildren.CompareList(aRoot, itemAfter.mChildren,
aOtherRoot, aDiff, stack,
stackOther)) {
same = false;
}
break;
}
++foundIndex;
}
if (!found) {
same = false;
aDiff << "\n";
if (aStack.Output(aDiff)) {
aDiff << " > ";
}
aDiff << itemBefore.mDescription;
aDiff << "\n * Cannot find corresponding item under ";
if (!aStackOther.Output(aDiff)) {
if (!aOtherRoot.mItems.empty()) {
aDiff << aOtherRoot.mItems[0].mListName;
} else {
aDiff << "other root";
}
}
std::string elsewhere =
aOtherRoot.Find(itemBefore.mFrame, itemBefore.mPerFrameKey);
if (!elsewhere.empty()) {
aDiff << "\n * But found: " << elsewhere;
}
}
}
return same;
}
void DisplayListBlueprint::Dump(std::stringstream& aSs, unsigned aDepth) const {
for (const DisplayItemBlueprint& item : mItems) {
item.Dump(aSs, aDepth);
}
}
void DisplayItemBlueprint::Dump(std::stringstream& aSs, unsigned aDepth) const {
aSs << "\n" << mIndexStringFW << " ";
for (unsigned i = 0; i < aDepth; ++i) {
aSs << " ";
}
aSs << mDescription;
mChildren.Dump(aSs, aDepth + 1);
}
DisplayListChecker::DisplayListChecker() : mBlueprint(nullptr) {}
DisplayListChecker::DisplayListChecker(nsDisplayList* aList, const char* aName)
: mBlueprint(MakeUnique<DisplayListBlueprint>(aList, aName)) {}
DisplayListChecker::~DisplayListChecker() = default;
void DisplayListChecker::Set(nsDisplayList* aList, const char* aName) {
mBlueprint = MakeUnique<DisplayListBlueprint>(aList, aName);
}
// Compare this list with another one, output differences between the two
// into aDiff.
// Differences include: Display items from one tree for which a corresponding
// item (same frame and per-frame key) cannot be found under corresponding
// parent items.
// Returns true if trees are similar, false if different.
bool DisplayListChecker::CompareList(const DisplayListChecker& aOther,
std::stringstream& aDiff) const {
MOZ_ASSERT(mBlueprint);
MOZ_ASSERT(aOther.mBlueprint);
return mBlueprint->CompareList(*aOther.mBlueprint, aDiff);
}
void DisplayListChecker::Dump(std::stringstream& aSs) const {
MOZ_ASSERT(mBlueprint);
mBlueprint->Dump(aSs);
}
} // namespace mozilla

View File

@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DisplayListChecker_h__
#define DisplayListChecker_h__
#include <sstream>
#include <mozilla/UniquePtr.h>
class nsDisplayList;
namespace mozilla {
class DisplayListBlueprint;
class DisplayListChecker {
public:
DisplayListChecker();
DisplayListChecker(nsDisplayList* aList, const char* aName);
~DisplayListChecker();
void Set(nsDisplayList* aList, const char* aName);
explicit operator bool() const { return mBlueprint.get(); }
// Compare this list with another one, output differences between the two
// into aDiff.
// Differences include: Display items from one tree for which a corresponding
// item (same frame and per-frame key) cannot be found under corresponding
// parent items.
// Returns true if trees are similar, false if different.
bool CompareList(const DisplayListChecker& aOther,
std::stringstream& aDiff) const;
// Output this tree to aSs.
void Dump(std::stringstream& aSs) const;
private:
UniquePtr<DisplayListBlueprint> mBlueprint;
};
} // namespace mozilla
#endif // DisplayListChecker_h__

View File

@ -7,7 +7,6 @@
#include "RetainedDisplayListBuilder.h"
#include "DisplayListChecker.h"
#include "mozilla/StaticPrefs_layout.h"
#include "nsIFrame.h"
#include "nsIFrameInlines.h"
@ -1402,7 +1401,7 @@ void RetainedDisplayListBuilder::ClearFramesWithProps() {
}
PartialUpdateResult RetainedDisplayListBuilder::AttemptPartialUpdate(
nscolor aBackstop, mozilla::DisplayListChecker* aChecker) {
nscolor aBackstop) {
mBuilder.RemoveModifiedWindowRegions();
if (mBuilder.ShouldSyncDecodeImages()) {
@ -1478,10 +1477,6 @@ PartialUpdateResult RetainedDisplayListBuilder::AttemptPartialUpdate(
return PartialUpdateResult::Failed;
}
if (aChecker) {
aChecker->Set(&modifiedDL, "TM");
}
// printf_stderr("Painting --- Modified list (dirty %d,%d,%d,%d):\n",
// modifiedDirty.x, modifiedDirty.y, modifiedDirty.width,
// modifiedDirty.height);

View File

@ -12,9 +12,6 @@
#include "mozilla/TypedEnumBits.h"
class nsWindowSizes;
namespace mozilla {
class DisplayListChecker;
} // namespace mozilla
/**
* RetainedDisplayListData contains frame invalidation information. It is stored
@ -179,8 +176,7 @@ struct RetainedDisplayListBuilder {
RetainedDisplayListMetrics* Metrics() { return &mMetrics; }
PartialUpdateResult AttemptPartialUpdate(
nscolor aBackstop, mozilla::DisplayListChecker* aChecker);
PartialUpdateResult AttemptPartialUpdate(nscolor aBackstop);
/**
* Iterates through the display list builder reference frame document and

View File

@ -37,7 +37,6 @@ UNIFIED_SOURCES += [
"DashedCornerFinder.cpp",
"DisplayItemClip.cpp",
"DisplayItemClipChain.cpp",
"DisplayListChecker.cpp",
"DisplayListClipState.cpp",
"DottedCornerFinder.cpp",
"FrameLayerBuilder.cpp",

View File

@ -6369,16 +6369,6 @@
value: true
mirror: always
- name: layout.display-list.retain.verify
type: RelaxedAtomicBool
value: false
mirror: always
- name: layout.display-list.retain.verify.order
type: RelaxedAtomicBool
value: false
mirror: always
# Set the maximum number of modified frames allowed before doing a full
# display list rebuild.
- name: layout.display-list.rebuild-frame-limit