Bug 1893067 - Add actions key to glean urlbar metrics. r=mak,urlbar-reviewers
[gecko.git] / layout / base / nsLayoutDebugger.cpp
blob1cca582ec533350180b05f4ee0292439f6877c00
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* some layout debugging functions that ought to live in nsFrame.cpp */
9 #include "nsAttrValue.h"
10 #include "nsIFrame.h"
11 #include "nsDisplayList.h"
12 #include "nsPrintfCString.h"
14 #include <stdio.h>
16 using namespace mozilla;
17 using namespace mozilla::layers;
19 static std::ostream& operator<<(std::ostream& os, const nsPrintfCString& rhs) {
20 os << rhs.get();
21 return os;
24 static void PrintDisplayListTo(nsDisplayListBuilder* aBuilder,
25 const nsDisplayList& aList,
26 std::stringstream& aStream, uint32_t aIndent,
27 bool aDumpHtml);
29 static void PrintDisplayItemTo(nsDisplayListBuilder* aBuilder,
30 nsDisplayItem* aItem, std::stringstream& aStream,
31 uint32_t aIndent, bool aDumpSublist,
32 bool aDumpHtml) {
33 std::stringstream ss;
35 if (!aDumpHtml) {
36 for (uint32_t indent = 0; indent < aIndent; indent++) {
37 aStream << " ";
40 nsAutoString contentData;
41 nsIFrame* f = aItem->Frame();
42 #ifdef DEBUG_FRAME_DUMP
43 f->GetFrameName(contentData);
44 #endif
45 nsIContent* content = f->GetContent();
46 if (content) {
47 nsString tmp;
48 if (content->GetID()) {
49 content->GetID()->ToString(tmp);
50 contentData.AppendLiteral(" id:");
51 contentData.Append(tmp);
53 const nsAttrValue* classes =
54 content->IsElement() ? content->AsElement()->GetClasses() : nullptr;
55 if (classes) {
56 classes->ToString(tmp);
57 contentData.AppendLiteral(" class:");
58 contentData.Append(tmp);
61 bool snap;
62 nsRect rect = aBuilder ? aItem->GetBounds(aBuilder, &snap) : nsRect();
63 nsRect component =
64 aBuilder ? aItem->GetComponentAlphaBounds(aBuilder) : nsRect();
65 nsDisplayList* list = aItem->GetChildren();
66 const DisplayItemClip& clip = aItem->GetClip();
67 nsRegion opaque =
68 aBuilder ? aItem->GetOpaqueRegion(aBuilder, &snap) : nsRect();
70 #ifdef MOZ_DUMP_PAINTING
71 if (aDumpHtml && aItem->Painted()) {
72 nsCString string(aItem->Name());
73 string.Append('-');
74 string.AppendInt((uint64_t)aItem);
75 aStream << nsPrintfCString("<a href=\"javascript:ViewImage('%s')\">",
76 string.BeginReading());
78 #endif
80 aStream << nsPrintfCString(
81 "%s p=0x%p f=0x%p(%s) key=%d %sbounds(%d,%d,%d,%d) "
82 "componentAlpha(%d,%d,%d,%d) clip(%s) asr(%s) clipChain(%s)%s ",
83 aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(contentData).get(),
84 aItem->GetPerFrameKey(),
85 (aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""),
86 rect.x, rect.y, rect.width, rect.height, component.x, component.y,
87 component.width, component.height, clip.ToString().get(),
88 ActiveScrolledRoot::ToString(aItem->GetActiveScrolledRoot()).get(),
89 DisplayItemClipChain::ToString(aItem->GetClipChain()).get(),
90 (aBuilder && aItem->IsUniform(aBuilder)) ? " uniform" : "");
92 for (auto iter = opaque.RectIter(); !iter.Done(); iter.Next()) {
93 const nsRect& r = iter.Get();
94 aStream << nsPrintfCString(" (opaque %d,%d,%d,%d)", r.x, r.y, r.width,
95 r.height);
98 const auto& willChange = aItem->Frame()->StyleDisplay()->mWillChange;
99 if (!willChange.features.IsEmpty()) {
100 aStream << " (will-change=";
101 for (size_t i = 0; i < willChange.features.Length(); i++) {
102 if (i > 0) {
103 aStream << ",";
105 nsDependentAtomString buffer(willChange.features.AsSpan()[i].AsAtom());
106 aStream << NS_LossyConvertUTF16toASCII(buffer).get();
108 aStream << ")";
111 if (aItem->HasHitTestInfo()) {
112 const auto& hitTestInfo = aItem->GetHitTestInfo();
113 aStream << nsPrintfCString(" hitTestInfo(0x%x)",
114 hitTestInfo.Info().serialize());
116 nsRect area = hitTestInfo.Area();
117 aStream << nsPrintfCString(" hitTestArea(%d,%d,%d,%d)", area.x, area.y,
118 area.width, area.height);
121 auto ReuseStateToString = [](nsDisplayItem::ReuseState aState) {
122 switch (aState) {
123 case nsDisplayItem::ReuseState::None:
124 return "None";
125 case nsDisplayItem::ReuseState::Reusable:
126 return "Reusable";
127 case nsDisplayItem::ReuseState::PreProcessed:
128 return "PreProcessed";
129 case nsDisplayItem::ReuseState::Reused:
130 return "Reused";
133 MOZ_ASSERT_UNREACHABLE();
134 return "";
137 aStream << nsPrintfCString(" reuse-state(%s)",
138 ReuseStateToString(aItem->GetReuseState()));
140 // Display item specific debug info
141 aItem->WriteDebugInfo(aStream);
143 #ifdef MOZ_DUMP_PAINTING
144 if (aDumpHtml && aItem->Painted()) {
145 aStream << "</a>";
147 #endif
148 #ifdef MOZ_DUMP_PAINTING
149 if (aItem->GetType() == DisplayItemType::TYPE_MASK) {
150 nsCString str;
151 (static_cast<nsDisplayMasksAndClipPaths*>(aItem))->PrintEffects(str);
152 aStream << str.get();
155 if (aItem->GetType() == DisplayItemType::TYPE_FILTER) {
156 nsCString str;
157 (static_cast<nsDisplayFilters*>(aItem))->PrintEffects(str);
158 aStream << str.get();
160 #endif
161 aStream << "\n";
162 #ifdef MOZ_DUMP_PAINTING
163 if (aDumpHtml && aItem->Painted()) {
164 nsCString string(aItem->Name());
165 string.Append('-');
166 string.AppendInt((uint64_t)aItem);
167 aStream << nsPrintfCString("<br><img id=\"%s\">\n", string.BeginReading());
169 #endif
171 if (aDumpSublist && list) {
172 PrintDisplayListTo(aBuilder, *list, aStream, aIndent + 1, aDumpHtml);
176 static void PrintDisplayListTo(nsDisplayListBuilder* aBuilder,
177 const nsDisplayList& aList,
178 std::stringstream& aStream, uint32_t aIndent,
179 bool aDumpHtml) {
180 if (aDumpHtml) {
181 aStream << "<ul>";
184 for (nsDisplayItem* i : aList) {
185 if (aDumpHtml) {
186 aStream << "<li>";
188 PrintDisplayItemTo(aBuilder, i, aStream, aIndent, true, aDumpHtml);
189 if (aDumpHtml) {
190 aStream << "</li>";
194 if (aDumpHtml) {
195 aStream << "</ul>";
199 void nsIFrame::PrintDisplayList(nsDisplayListBuilder* aBuilder,
200 const nsDisplayList& aList, bool aDumpHtml) {
201 std::stringstream ss;
202 PrintDisplayList(aBuilder, aList, ss, aDumpHtml);
203 fprintf_stderr(stderr, "%s", ss.str().c_str());
206 void nsIFrame::PrintDisplayList(nsDisplayListBuilder* aBuilder,
207 const nsDisplayList& aList,
208 std::stringstream& aStream, bool aDumpHtml) {
209 PrintDisplayListTo(aBuilder, aList, aStream, 0, aDumpHtml);
212 void nsIFrame::PrintDisplayItem(nsDisplayListBuilder* aBuilder,
213 nsDisplayItem* aItem,
214 std::stringstream& aStream, uint32_t aIndent,
215 bool aDumpSublist, bool aDumpHtml) {
216 PrintDisplayItemTo(aBuilder, aItem, aStream, aIndent, aDumpSublist,
217 aDumpHtml);
221 * The two functions below are intended to be called from a debugger.
223 void PrintDisplayItemToStdout(nsDisplayListBuilder* aBuilder,
224 nsDisplayItem* aItem) {
225 std::stringstream stream;
226 PrintDisplayItemTo(aBuilder, aItem, stream, 0, true, false);
227 puts(stream.str().c_str());
230 void PrintDisplayListToStdout(nsDisplayListBuilder* aBuilder,
231 const nsDisplayList& aList) {
232 std::stringstream stream;
233 PrintDisplayListTo(aBuilder, aList, stream, 0, false);
234 puts(stream.str().c_str());
237 #ifdef MOZ_DUMP_PAINTING
238 static void PrintDisplayListSetItem(nsDisplayListBuilder* aBuilder,
239 const char* aItemName,
240 const nsDisplayList& aList,
241 std::stringstream& aStream,
242 bool aDumpHtml) {
243 if (aDumpHtml) {
244 aStream << "<li>";
246 aStream << aItemName << "\n";
247 PrintDisplayListTo(aBuilder, aList, aStream, 0, aDumpHtml);
248 if (aDumpHtml) {
249 aStream << "</li>";
253 void nsIFrame::PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
254 const nsDisplayListSet& aSet,
255 std::stringstream& aStream, bool aDumpHtml) {
256 if (aDumpHtml) {
257 aStream << "<ul>";
259 PrintDisplayListSetItem(aBuilder, "[BorderBackground]",
260 *(aSet.BorderBackground()), aStream, aDumpHtml);
261 PrintDisplayListSetItem(aBuilder, "[BlockBorderBackgrounds]",
262 *(aSet.BlockBorderBackgrounds()), aStream, aDumpHtml);
263 PrintDisplayListSetItem(aBuilder, "[Floats]", *(aSet.Floats()), aStream,
264 aDumpHtml);
265 PrintDisplayListSetItem(aBuilder, "[PositionedDescendants]",
266 *(aSet.PositionedDescendants()), aStream, aDumpHtml);
267 PrintDisplayListSetItem(aBuilder, "[Outlines]", *(aSet.Outlines()), aStream,
268 aDumpHtml);
269 PrintDisplayListSetItem(aBuilder, "[Content]", *(aSet.Content()), aStream,
270 aDumpHtml);
271 if (aDumpHtml) {
272 aStream << "</ul>";
276 #endif