瀏覽代碼

Refactor formatting context debug tracker and profiling

Michael Ragazzon 4 月之前
父節點
當前提交
d9b741b9f4

+ 24 - 42
Source/Core/Layout/FormattingContext.cpp

@@ -43,6 +43,21 @@
 
 namespace Rml {
 
+#ifdef RMLUI_TRACY_PROFILING
+	#define RMLUI_ZONE_TEXT_CACHE_CAPTURE(element, override_initial_box, containing_block, absolute_containing_block)                              \
+		auto RmlUiZoneTextCacheMessage = [&, element, override_initial_box, containing_block, absolute_containing_block](const char* cache_info) { \
+			RMLUI_ZoneText(CreateString("%s on %x. Containing block: %g, %g. Absolute containing block: %g, %g. Box (size): %g, %g", cache_info,   \
+				element, containing_block.x, containing_block.y, absolute_containing_block.x, absolute_containing_block.y,                         \
+				override_initial_box ? override_initial_box->GetSize().x : std::numeric_limits<float>::quiet_NaN(),                                \
+				override_initial_box ? override_initial_box->GetSize().y : std::numeric_limits<float>::quiet_NaN()));                              \
+		}
+
+	#define RMLUI_ZONE_TEXT_CACHE_MESSAGE(message) RmlUiZoneTextCacheMessage(message)
+#else
+	#define RMLUI_ZONE_TEXT_CACHE_CAPTURE
+	#define RMLUI_ZONE_TEXT_CACHE_MESSAGE(message)
+#endif
+
 static bool UsesFitContentSizeForAutoWidth(Element* element)
 {
 	// Whether to apply the fit-content sizing (shrink-to-fit width) algorithm to find the width of the element.
@@ -93,15 +108,8 @@ UniquePtr<LayoutBox> FormattingContext::FormatIndependent(ContainerBox* parent_c
 	if (type == FormattingContextType::None)
 		return nullptr;
 
-#ifdef RMLUI_DEBUG
-	auto* debug_tracker = FormatIndependentDebugTracker::GetIf();
-	FormatIndependentDebugTracker::Entry* tracker_entry = nullptr;
-	if (debug_tracker)
-		tracker_entry = &debug_tracker->PushEntry(FormatIndependentDebugTracker::FormatType::FormatIndependent, parent_container, element,
-			override_initial_box, type);
-#endif
-
 	UniquePtr<LayoutBox> layout_box;
+	ScopedFormatIndependentDebugTracker debug_tracker{parent_container, element, override_initial_box, type};
 
 	const FormattingMode& formatting_mode = parent_container->GetFormattingMode();
 
@@ -109,30 +117,20 @@ UniquePtr<LayoutBox> FormattingContext::FormatIndependent(ContainerBox* parent_c
 	{
 		const Vector2f containing_block = parent_container->GetContainingBlockSize(Style::Position::Static);
 		const Vector2f absolute_containing_block = parent_container->GetContainingBlockSize(Style::Position::Absolute);
-
-#ifdef RMLUI_TRACY_PROFILING
-		auto DebugCacheTracyMessage = [&](const char* cache_info) {
-			RMLUI_ZoneText(CreateString("%s on %x. Containing block: %g, %g. Absolute containing block: %g, %g. Box (size): %g, %g", cache_info,
-				element, containing_block.x, containing_block.y, absolute_containing_block.x, absolute_containing_block.y,
-				override_initial_box ? override_initial_box->GetSize().x : std::numeric_limits<float>::quiet_NaN(),
-				override_initial_box ? override_initial_box->GetSize().y : std::numeric_limits<float>::quiet_NaN()));
-		};
-#else
-	#define DebugCacheTracyMessage(message)
-#endif
+		RMLUI_ZONE_TEXT_CACHE_CAPTURE(element, override_initial_box, containing_block, absolute_containing_block);
 
 		LayoutNode* layout_node = element->GetLayoutNode();
 		if (layout_node->CommittedLayoutMatches(containing_block, absolute_containing_block, override_initial_box,
 				formatting_mode.constraint != FormattingMode::Constraint::None))
 		{
-			DebugCacheTracyMessage("Cache match");
+			RMLUI_ZONE_TEXT_CACHE_MESSAGE("Cache match");
 			const CommittedLayout& commited_layout = layout_node->GetCommittedLayout().value();
 			layout_box = MakeUnique<CachedContainer>(element, parent_container, element->GetBox(), commited_layout.visible_overflow_size,
 				commited_layout.max_content_width, commited_layout.baseline_of_last_line);
 		}
 		else
 		{
-			DebugCacheTracyMessage(layout_node->HasCommittedLayout() ? "Cache miss" : "No cache");
+			RMLUI_ZONE_TEXT_CACHE_MESSAGE(layout_node->HasCommittedLayout() ? "Cache miss" : "No cache");
 		}
 	}
 	else
@@ -185,10 +183,7 @@ UniquePtr<LayoutBox> FormattingContext::FormatIndependent(ContainerBox* parent_c
 		}
 	}
 
-#ifdef RMLUI_DEBUG
-	if (tracker_entry)
-		debug_tracker->CloseEntry(*tracker_entry, layout_box.get());
-#endif
+	debug_tracker.CloseEntry(layout_box.get());
 
 	return layout_box;
 }
@@ -262,22 +257,15 @@ void FormattingContext::FormatFitContentWidth(Box& box, Element* element, Format
 	RMLUI_ZoneText(CreateString("%s    %x    Containing block: %g x %g", element->GetAddress(false, false).c_str(), element, containing_block.x,
 		containing_block.y));
 
-#ifdef RMLUI_DEBUG
-	auto* debug_tracker = FormatIndependentDebugTracker::GetIf();
-	FormatIndependentDebugTracker::Entry* tracker_entry = nullptr;
-	if (debug_tracker)
-		tracker_entry = &debug_tracker->PushEntry(FormatIndependentDebugTracker::FormatType::FormatFitContentWidth, nullptr, element, &box, type);
-#endif
-
 	const float box_height = box.GetSize().y;
 	LayoutNode* layout_node = element->GetLayoutNode();
 	float max_content_width = -1.f;
-	bool from_cache = false;
+	ScopedFormatFitContentWidthDebugTracker debug_tracker{element, type, box};
 
 	if (Optional<float> cached_width = (parent_formatting_mode.allow_max_content_cache ? layout_node->GetMaxContentWidthIfCached() : std::nullopt))
 	{
 		max_content_width = *cached_width;
-		from_cache = true;
+		debug_tracker.SetCacheHit();
 	}
 	else
 	{
@@ -304,14 +292,8 @@ void FormattingContext::FormatFitContentWidth(Box& box, Element* element, Format
 		layout_node->CommitMaxContentWidth(max_content_width);
 	}
 
-	RMLUI_ASSERTMSG(max_content_width >= 0.f, "Max-content width should evaluate to a positive size.")
-
-#ifdef RMLUI_DEBUG
-	if (tracker_entry)
-		debug_tracker->CloseEntry(*tracker_entry, max_content_width, from_cache);
-#else
-	(void)from_cache;
-#endif
+	RMLUI_ASSERTMSG(max_content_width >= 0.f, "Max-content width should evaluate to a positive size.");
+	debug_tracker.CloseEntry(max_content_width);
 
 	float fit_content_width = max_content_width;
 	if (containing_block.x >= 0.f)

+ 17 - 17
Source/Core/Layout/FormattingContextDebug.cpp

@@ -33,30 +33,30 @@
 namespace Rml {
 #ifdef RMLUI_DEBUG
 
-static FormatIndependentDebugTracker* g_debug_format_independent_tracker = nullptr;
+static FormattingContextDebugTracker* g_debug_format_independent_tracker = nullptr;
 
-FormatIndependentDebugTracker::FormatIndependentDebugTracker()
+FormattingContextDebugTracker::FormattingContextDebugTracker()
 {
-	RMLUI_ASSERTMSG(!g_debug_format_independent_tracker, "An instance of FormatIndependentDebugTracker already exists");
+	RMLUI_ASSERTMSG(!g_debug_format_independent_tracker, "An instance of FormattingContextDebugTracker already exists");
 	g_debug_format_independent_tracker = this;
 }
 
-FormatIndependentDebugTracker::~FormatIndependentDebugTracker()
+FormattingContextDebugTracker::~FormattingContextDebugTracker()
 {
 	RMLUI_ASSERT(g_debug_format_independent_tracker == this);
 	RMLUI_ASSERT(current_stack_level == 0);
 	g_debug_format_independent_tracker = nullptr;
 }
 
-FormatIndependentDebugTracker* FormatIndependentDebugTracker::GetIf()
+FormattingContextDebugTracker* FormattingContextDebugTracker::GetIf()
 {
 	return g_debug_format_independent_tracker;
 }
 
-FormatIndependentDebugTracker::Entry& FormatIndependentDebugTracker::PushEntry(FormatType format_type, ContainerBox* parent_container,
+FormattingContextDebugTracker::Entry& FormattingContextDebugTracker::PushEntry(FormatType format_type, ContainerBox* parent_container,
 	Element* element, const Box* override_initial_box, FormattingContextType type)
 {
-	Entry& result = entries.emplace_back(FormatIndependentDebugTracker::Entry{
+	Entry& result = entries.emplace_back(FormattingContextDebugTracker::Entry{
 		current_stack_level,
 		format_type,
 		parent_container && parent_container->GetElement() ? parent_container->GetElement()->GetAddress() : "",
@@ -73,33 +73,33 @@ FormatIndependentDebugTracker::Entry& FormatIndependentDebugTracker::PushEntry(F
 	return result;
 }
 
-void FormatIndependentDebugTracker::CloseEntry(Entry& entry, LayoutBox* layout_box)
+void FormattingContextDebugTracker::CloseEntry(Entry& entry, LayoutBox* layout_box)
 {
 	current_stack_level -= 1;
 	if (layout_box)
 	{
 		entry.from_cache = (layout_box->GetType() == LayoutBox::Type::CachedContainer);
-		entry.layout_result = Optional<FormatIndependentDebugTracker::Entry::LayoutResult>({
+		entry.layout_result = Optional<FormattingContextDebugTracker::Entry::LayoutResult>({
 			layout_box->GetVisibleOverflowSize(),
 			layout_box->GetIfBox() ? Optional<Box>{*layout_box->GetIfBox()} : std::nullopt,
 		});
 	}
 }
-void FormatIndependentDebugTracker::CloseEntry(Entry& entry, float max_content_width, bool from_cache)
+void FormattingContextDebugTracker::CloseEntry(Entry& entry, float max_content_width, bool from_cache)
 {
 	current_stack_level -= 1;
 	entry.from_cache = from_cache;
-	entry.fit_width_result = Optional<FormatIndependentDebugTracker::Entry::FitWidthResult>({
+	entry.fit_width_result = Optional<FormattingContextDebugTracker::Entry::FitWidthResult>({
 		max_content_width,
 	});
 }
 
-void FormatIndependentDebugTracker::Reset()
+void FormattingContextDebugTracker::Reset()
 {
 	*this = {};
 }
 
-String FormatIndependentDebugTracker::ToString() const
+String FormattingContextDebugTracker::ToString() const
 {
 	String result;
 
@@ -175,22 +175,22 @@ String FormatIndependentDebugTracker::ToString() const
 	return result;
 }
 
-void FormatIndependentDebugTracker::LogMessage() const
+void FormattingContextDebugTracker::LogMessage() const
 {
 	Log::Message(Log::LT_INFO, "%s", ToString().c_str());
 }
 
-int FormatIndependentDebugTracker::CountCachedEntries() const
+int FormattingContextDebugTracker::CountCachedEntries() const
 {
 	return (int)std::count_if(entries.begin(), entries.end(), [](const auto& entry) { return entry.from_cache; });
 }
 
-int FormatIndependentDebugTracker::CountFormattedEntries() const
+int FormattingContextDebugTracker::CountFormattedEntries() const
 {
 	return (int)entries.size() - CountCachedEntries();
 }
 
-int FormatIndependentDebugTracker::CountEntries() const
+int FormattingContextDebugTracker::CountEntries() const
 {
 	return (int)entries.size();
 }

+ 66 - 4
Source/Core/Layout/FormattingContextDebug.h

@@ -36,11 +36,11 @@
 namespace Rml {
 #ifdef RMLUI_DEBUG
 
-class FormatIndependentDebugTracker {
+class FormattingContextDebugTracker {
 public:
-	FormatIndependentDebugTracker();
-	~FormatIndependentDebugTracker();
-	static FormatIndependentDebugTracker* GetIf();
+	FormattingContextDebugTracker();
+	~FormattingContextDebugTracker();
+	static FormattingContextDebugTracker* GetIf();
 
 	enum class FormatType {
 		FormatIndependent,
@@ -89,6 +89,68 @@ private:
 	int current_stack_level = 0;
 };
 
+class ScopedFormatIndependentDebugTracker {
+public:
+	ScopedFormatIndependentDebugTracker(ContainerBox* parent_container, Element* element, const Box* override_initial_box, FormattingContextType type)
+	{
+		if (auto debug_tracker = FormattingContextDebugTracker::GetIf())
+		{
+			tracker_entry = &debug_tracker->PushEntry(FormattingContextDebugTracker::FormatType::FormatIndependent, parent_container, element,
+				override_initial_box, type);
+		}
+	}
+
+	void CloseEntry(LayoutBox* layout_box)
+	{
+		if (tracker_entry)
+			FormattingContextDebugTracker::GetIf()->CloseEntry(*tracker_entry, layout_box);
+	}
+
+private:
+	FormattingContextDebugTracker::Entry* tracker_entry = nullptr;
+};
+
+class ScopedFormatFitContentWidthDebugTracker {
+public:
+	ScopedFormatFitContentWidthDebugTracker(Element* element, FormattingContextType type, Box& box)
+	{
+		if (auto debug_tracker = FormattingContextDebugTracker::GetIf())
+		{
+			tracker_entry = &debug_tracker->PushEntry(FormattingContextDebugTracker::FormatType::FormatFitContentWidth, nullptr, element, &box, type);
+		}
+	}
+
+	void SetCacheHit() { from_cache = true; }
+
+	void CloseEntry(float max_content_width)
+	{
+		if (tracker_entry)
+			FormattingContextDebugTracker::GetIf()->CloseEntry(*tracker_entry, max_content_width, from_cache);
+	}
+
+private:
+	bool from_cache = false;
+	FormattingContextDebugTracker::Entry* tracker_entry = nullptr;
+};
+
+#else
+
+class ScopedFormatIndependentDebugTracker {
+public:
+	ScopedFormatIndependentDebugTracker(ContainerBox* /*parent_container*/, Element* /* element*/, const Box* /* override_initial_box*/,
+		FormattingContextType /* type*/)
+	{}
+	void CloseEntry(LayoutBox* /*layout_box*/) {}
+};
+
+class ScopedFormatFitContentWidthDebugTracker {
+public:
+	ScopedFormatFitContentWidthDebugTracker(Element* /*element*/, FormattingContextType /*type*/, Box& /*box*/) {}
+	void SetCacheHit() {}
+	void CloseEntry(float /*max_content_width*/) {}
+};
+
 #endif // RMLUI_DEBUG
+
 } // namespace Rml
 #endif

+ 9 - 9
Tests/Source/UnitTests/LayoutIsolation.cpp

@@ -266,7 +266,7 @@ TEST_CASE("LayoutIsolation.FullLayoutFormatIndependentCount")
 	ElementDocument* document = nullptr;
 
 	{
-		FormatIndependentDebugTracker format_independent_tracker;
+		FormattingContextDebugTracker format_independent_tracker;
 		document = context->LoadDocumentFromMemory(document_isolation_rml);
 		document->Show();
 		TestsShell::RenderLoop();
@@ -284,7 +284,7 @@ TEST_CASE("LayoutIsolation.FullLayoutFormatIndependentCount")
 	}
 
 	{
-		FormatIndependentDebugTracker format_independent_tracker;
+		FormattingContextDebugTracker format_independent_tracker;
 		Element* element = document->GetElementById("flex-item");
 		rmlui_dynamic_cast<ElementText*>(element->GetFirstChild())->SetText("Modified text that is long enough to cause line break");
 
@@ -362,7 +362,7 @@ TEST_CASE("LayoutIsolation.Absolute")
 
 	TestsShell::RenderLoop();
 
-	FormatIndependentDebugTracker format_independent_tracker;
+	FormattingContextDebugTracker format_independent_tracker;
 	SUBCASE("Modify absolute content")
 	{
 		Element* element = document->GetElementById("absolute-item");
@@ -509,7 +509,7 @@ TEST_CASE("LayoutIsolation.HiddenSkipsFormatting")
 		element->SetClass("absolute", true);
 	}
 
-	FormatIndependentDebugTracker format_independent_tracker;
+	FormattingContextDebugTracker format_independent_tracker;
 	document->Show();
 	TestsShell::RenderLoop();
 	CHECK(format_independent_tracker.CountFormattedEntries() == 1);
@@ -614,7 +614,7 @@ TEST_CASE("LayoutIsolation.Document")
 	Context* context = TestsShell::GetContext();
 	REQUIRE(context->GetDimensions() == Rml::Vector2i{1500, 800});
 
-	FormatIndependentDebugTracker format_independent_tracker;
+	FormattingContextDebugTracker format_independent_tracker;
 
 	ElementDocument* document = context->LoadDocumentFromMemory(layout_isolation_document_rml);
 	document->Show();
@@ -707,7 +707,7 @@ TEST_CASE("LayoutIsolation.FlexFormat.shrink-to-fit")
 			StringUtilities::RepeatString(R"(<div class="inner"><div class="outer">)", num_nest_levels - 1).c_str(),
 			StringUtilities::RepeatString(R"(</div></div>)", num_nest_levels - 1).c_str());
 
-		FormatIndependentDebugTracker format_independent_tracker;
+		FormattingContextDebugTracker format_independent_tracker;
 		ElementDocument* document = context->LoadDocumentFromMemory(document_rml);
 
 		document->Show();
@@ -739,7 +739,7 @@ TEST_CASE("LayoutIsolation.FlexFormat.shrink-to-fit.cache")
 
 	ElementDocument* document = nullptr;
 	{
-		FormatIndependentDebugTracker format_independent_tracker;
+		FormattingContextDebugTracker format_independent_tracker;
 		document = context->LoadDocumentFromMemory(document_rml);
 		document->Show();
 		TestsShell::RenderLoop();
@@ -747,14 +747,14 @@ TEST_CASE("LayoutIsolation.FlexFormat.shrink-to-fit.cache")
 	}
 
 	{
-		FormatIndependentDebugTracker format_independent_tracker;
+		FormattingContextDebugTracker format_independent_tracker;
 		document->GetElementById("innermost")->SetInnerRML("Flex");
 		TestsShell::RenderLoop();
 		MESSAGE("With cache: ", format_independent_tracker.CountFormattedEntries());
 	}
 
 	{
-		FormatIndependentDebugTracker format_independent_tracker;
+		FormattingContextDebugTracker format_independent_tracker;
 		document->GetElementById("innermost")->SetInnerRML("Flex");
 		document->SetAttribute("rmlui-disable-layout-cache", true);
 		TestsShell::RenderLoop();