From 14cf4daeabcb40bf252ffd96f2125f760be33f89 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Mon, 11 Apr 2022 20:56:10 +0000 Subject: [PATCH] Add debugging flags to enhance the timeline arguments for Build, Layout, and Paint (#101602) --- dev/tracing_tests/test/timeline_test.dart | 8 ++++ packages/flutter/lib/src/rendering/box.dart | 4 +- packages/flutter/lib/src/rendering/debug.dart | 46 +++++++++++++++++++ .../flutter/lib/src/rendering/object.dart | 12 +++-- packages/flutter/lib/src/widgets/debug.dart | 26 +++++++++++ .../flutter/lib/src/widgets/framework.dart | 8 ++-- 6 files changed, 94 insertions(+), 10 deletions(-) diff --git a/dev/tracing_tests/test/timeline_test.dart b/dev/tracing_tests/test/timeline_test.dart index 10306e33dd4..6fd4b6cd8ad 100644 --- a/dev/tracing_tests/test/timeline_test.dart +++ b/dev/tracing_tests/test/timeline_test.dart @@ -100,6 +100,7 @@ void main() { Map args; debugProfileBuildsEnabled = true; + debugEnhanceBuildTimelineArguments = true; await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey(), color: const Color(0xFFFFFFFF))); }); events = await fetchInterestingEvents(interestingLabels); expect( @@ -109,8 +110,10 @@ void main() { args = (events.where((TimelineEvent event) => event.json!['name'] == '$Placeholder').single.json!['args'] as Map).cast(); expect(args['color'], 'Color(0xffffffff)'); debugProfileBuildsEnabled = false; + debugEnhanceBuildTimelineArguments = false; debugProfileBuildsEnabledUserWidgets = true; + debugEnhanceBuildTimelineArguments = true; await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey(), color: const Color(0xFFFFFFFF))); }); events = await fetchInterestingEvents(interestingLabels); expect( @@ -120,8 +123,10 @@ void main() { args = (events.where((TimelineEvent event) => event.json!['name'] == '$Placeholder').single.json!['args'] as Map).cast(); expect(args['color'], 'Color(0xffffffff)'); debugProfileBuildsEnabledUserWidgets = false; + debugEnhanceBuildTimelineArguments = false; debugProfileLayoutsEnabled = true; + debugEnhanceLayoutTimelineArguments = true; await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey())); }); events = await fetchInterestingEvents(interestingLabels); expect( @@ -133,8 +138,10 @@ void main() { expect(args['creator'], contains('Placeholder')); expect(args['painter'], startsWith('_PlaceholderPainter#')); debugProfileLayoutsEnabled = false; + debugEnhanceLayoutTimelineArguments = false; debugProfilePaintsEnabled = true; + debugEnhancePaintTimelineArguments = true; await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey())); }); events = await fetchInterestingEvents(interestingLabels); expect( @@ -146,6 +153,7 @@ void main() { expect(args['creator'], contains('Placeholder')); expect(args['painter'], startsWith('_PlaceholderPainter#')); debugProfilePaintsEnabled = false; + debugEnhancePaintTimelineArguments = false; }, skip: isBrowser); // [intended] uses dart:isolate and io. } diff --git a/packages/flutter/lib/src/rendering/box.dart b/packages/flutter/lib/src/rendering/box.dart index bd092ee6103..6f1dfd28329 100644 --- a/packages/flutter/lib/src/rendering/box.dart +++ b/packages/flutter/lib/src/rendering/box.dart @@ -1371,7 +1371,7 @@ abstract class RenderBox extends RenderObject { if (shouldCache) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - if (debugProfileLayoutsEnabled) { + if (debugEnhanceLayoutTimelineArguments) { debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); } else { debugTimelineArguments = Map.of(debugTimelineArguments); @@ -1835,7 +1835,7 @@ abstract class RenderBox extends RenderObject { if (shouldCache) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - if (debugProfileLayoutsEnabled) { + if (debugEnhanceLayoutTimelineArguments) { debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); } else { debugTimelineArguments = Map.of(debugTimelineArguments); diff --git a/packages/flutter/lib/src/rendering/debug.dart b/packages/flutter/lib/src/rendering/debug.dart index 0c0e84babcd..88f1cd4875a 100644 --- a/packages/flutter/lib/src/rendering/debug.dart +++ b/packages/flutter/lib/src/rendering/debug.dart @@ -116,6 +116,8 @@ bool debugCheckIntrinsicSizes = false; /// * [debugProfileBuildsEnabled], which does something similar for widgets /// being rebuilt. /// * [debugProfilePaintsEnabled], which does something similar for painting. +/// * [debugEnhanceLayoutTimelineArguments], which enhances the trace with +/// debugging information related to [RenderObject] layouts. bool debugProfileLayoutsEnabled = false; /// Adds [dart:developer.Timeline] events for every [RenderObject] painted. @@ -143,8 +145,52 @@ bool debugProfileLayoutsEnabled = false; /// * The discussion at [RendererBinding.drawFrame]. /// * [RepaintBoundary], which can be used to contain repaints when unchanged /// areas are being excessively repainted. +/// * [debugEnhancePaintTimelineArguments], which enhances the trace with +/// debugging information related to [RenderObject] paints. bool debugProfilePaintsEnabled = false; +/// Adds debugging information to [Timeline] events related to [RenderObject] +/// layouts. +/// +/// This flag will only add [Timeline] event arguments for debug builds. +/// Additional arguments will be added for the "LAYOUT" timeline event and for +/// all [RenderObject] layout [Timeline] events, which are the events that are +/// added when [debugProfileLayoutsEnabled] is true. The debugging information +/// that will be added in trace arguments includes stats around [RenderObject] +/// dirty states and [RenderObject] diagnostic information (i.e. [RenderObject] +/// properties). +/// +/// See also: +/// +/// * [debugProfileLayoutsEnabled], which adds [Timeline] events for every +/// [RenderObject] layout. +/// * [debugEnhancePaintTimelineArguments], which does something similar for +/// events related to [RenderObject] paints. +/// * [debugEnhanceBuildTimelineArguments], which does something similar for +/// events related to [Widget] builds. +bool debugEnhanceLayoutTimelineArguments = false; + +/// Adds debugging information to [Timeline] events related to [RenderObject] +/// paints. +/// +/// This flag will only add [Timeline] event arguments for debug builds. +/// Additional arguments will be added for the "PAINT" timeline event and for +/// all [RenderObject] paint [Timeline] events, which are the [Timeline] events +/// that are added when [debugProfilePaintsEnabled] is true. The debugging +/// information that will be added in trace arguments includes stats around +/// [RenderObject] dirty states and [RenderObject] diagnostic information +/// (i.e. [RenderObject] properties). +/// +/// See also: +/// +/// * [debugProfilePaintsEnabled], which adds [Timeline] events for every +/// [RenderObject] paint. +/// * [debugEnhanceLayoutTimelineArguments], which does something similar for +/// events related to [RenderObject] layouts. +/// * [debugEnhanceBuildTimelineArguments], which does something similar for +/// events related to [Widget] builds. +bool debugEnhancePaintTimelineArguments = false; + /// Signature for [debugOnProfilePaint] implementations. typedef ProfilePaintCallback = void Function(RenderObject renderObject); diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 3c176c57932..d8da76625d3 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -860,7 +860,7 @@ class PipelineOwner { if (!kReleaseMode) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - if (debugProfileLayoutsEnabled) { + if (debugEnhanceLayoutTimelineArguments) { debugTimelineArguments = { ...debugTimelineArguments, 'dirty count': '${_nodesNeedingLayout.length}', @@ -966,7 +966,7 @@ class PipelineOwner { if (!kReleaseMode) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - if (debugProfilePaintsEnabled) { + if (debugEnhancePaintTimelineArguments) { debugTimelineArguments = { ...debugTimelineArguments, 'dirty count': '${_nodesNeedingPaint.length}', @@ -1798,7 +1798,9 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im if (!kReleaseMode && debugProfileLayoutsEnabled) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); + if (debugEnhanceLayoutTimelineArguments) { + debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); + } return true; }()); Timeline.startSync( @@ -2402,7 +2404,9 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im if (!kReleaseMode && debugProfilePaintsEnabled) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); + if (debugEnhancePaintTimelineArguments) { + debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); + } return true; }()); Timeline.startSync( diff --git a/packages/flutter/lib/src/widgets/debug.dart b/packages/flutter/lib/src/widgets/debug.dart index 6688e1fb14f..3885a69277b 100644 --- a/packages/flutter/lib/src/widgets/debug.dart +++ b/packages/flutter/lib/src/widgets/debug.dart @@ -116,6 +116,8 @@ bool debugPrintGlobalKeyedWidgetLifecycle = false; /// * [debugProfilePaintsEnabled], which does something similar for painting. /// * [debugProfileBuildsEnabledUserWidgets], which adds events for user-created /// [Widget] build times and incurs less overhead. +/// * [debugEnhanceBuildTimelineArguments], which enhances the trace with +/// debugging information related to [Widget] builds. bool debugProfileBuildsEnabled = false; /// Adds [Timeline] events for every user-created [Widget] built. @@ -130,8 +132,32 @@ bool debugProfileBuildsEnabled = false; /// /// * [debugProfileBuildsEnabled], which functions similarly but shows events /// for every widget and has a higher overhead cost. +/// * [debugEnhanceBuildTimelineArguments], which enhances the trace with +/// debugging information related to [Widget] builds. bool debugProfileBuildsEnabledUserWidgets = false; +/// Adds debugging information to [Timeline] events related to [Widget] builds. +/// +/// This flag will only add [Timeline] event arguments for debug builds. +/// Additional arguments will be added for the "BUILD" [Timeline] event and for +/// all [Widget] build [Timeline] events, which are the [Timeline] events that +/// are added when either of [debugProfileBuildsEnabled] and +/// [debugProfileBuildsEnabledUserWidgets] are true. The debugging information +/// that will be added in trace arguments includes stats around [Widget] dirty +/// states and [Widget] diagnostic information (i.e. [Widget] properties). +/// +/// See also: +/// +/// * [debugProfileBuildsEnabled], which adds [Timeline] events for every +/// [Widget] built. +/// * [debugProfileBuildsEnabledUserWidgets], which adds [Timeline] events for +/// every user-created [Widget] built. +/// * [debugEnhanceLayoutTimelineArguments], which does something similar for +/// events related to [RenderObject] layouts. +/// * [debugEnhancePaintTimelineArguments], which does something similar for +/// events related to [RenderObject] paints. +bool debugEnhanceBuildTimelineArguments = false; + /// Show banners for deprecated widgets. bool debugHighlightDeprecatedWidgets = false; diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index ac3673efe4d..75b874dc103 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -2565,7 +2565,7 @@ class BuildOwner { if (!kReleaseMode) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - if (debugProfileBuildsEnabled) { + if (debugEnhanceBuildTimelineArguments) { debugTimelineArguments = { ...debugTimelineArguments, 'dirty count': '${_dirtyElements.length}', @@ -2645,7 +2645,7 @@ class BuildOwner { if (isTimelineTracked) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - if (kDebugMode) { + if (kDebugMode && debugEnhanceBuildTimelineArguments) { debugTimelineArguments = element.widget.toDiagnosticsNode().toTimelineArguments(); } return true; @@ -3517,7 +3517,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext { if (isTimelineTracked) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - if (kDebugMode) { + if (kDebugMode && debugEnhanceBuildTimelineArguments) { debugTimelineArguments = newWidget.toDiagnosticsNode().toTimelineArguments(); } return true; @@ -3782,7 +3782,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext { if (isTimelineTracked) { Map debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; assert(() { - if (kDebugMode) { + if (kDebugMode && debugEnhanceBuildTimelineArguments) { debugTimelineArguments = newWidget.toDiagnosticsNode().toTimelineArguments(); } return true;