Unverified Commit 14cf4dae authored by Kenzie Davisson's avatar Kenzie Davisson Committed by GitHub

Add debugging flags to enhance the timeline arguments for Build, Layout, and Paint (#101602)

parent 675b9615
...@@ -100,6 +100,7 @@ void main() { ...@@ -100,6 +100,7 @@ void main() {
Map<String, String> args; Map<String, String> args;
debugProfileBuildsEnabled = true; debugProfileBuildsEnabled = true;
debugEnhanceBuildTimelineArguments = true;
await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey(), color: const Color(0xFFFFFFFF))); }); await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey(), color: const Color(0xFFFFFFFF))); });
events = await fetchInterestingEvents(interestingLabels); events = await fetchInterestingEvents(interestingLabels);
expect( expect(
...@@ -109,8 +110,10 @@ void main() { ...@@ -109,8 +110,10 @@ void main() {
args = (events.where((TimelineEvent event) => event.json!['name'] == '$Placeholder').single.json!['args'] as Map<String, Object?>).cast<String, String>(); args = (events.where((TimelineEvent event) => event.json!['name'] == '$Placeholder').single.json!['args'] as Map<String, Object?>).cast<String, String>();
expect(args['color'], 'Color(0xffffffff)'); expect(args['color'], 'Color(0xffffffff)');
debugProfileBuildsEnabled = false; debugProfileBuildsEnabled = false;
debugEnhanceBuildTimelineArguments = false;
debugProfileBuildsEnabledUserWidgets = true; debugProfileBuildsEnabledUserWidgets = true;
debugEnhanceBuildTimelineArguments = true;
await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey(), color: const Color(0xFFFFFFFF))); }); await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey(), color: const Color(0xFFFFFFFF))); });
events = await fetchInterestingEvents(interestingLabels); events = await fetchInterestingEvents(interestingLabels);
expect( expect(
...@@ -120,8 +123,10 @@ void main() { ...@@ -120,8 +123,10 @@ void main() {
args = (events.where((TimelineEvent event) => event.json!['name'] == '$Placeholder').single.json!['args'] as Map<String, Object?>).cast<String, String>(); args = (events.where((TimelineEvent event) => event.json!['name'] == '$Placeholder').single.json!['args'] as Map<String, Object?>).cast<String, String>();
expect(args['color'], 'Color(0xffffffff)'); expect(args['color'], 'Color(0xffffffff)');
debugProfileBuildsEnabledUserWidgets = false; debugProfileBuildsEnabledUserWidgets = false;
debugEnhanceBuildTimelineArguments = false;
debugProfileLayoutsEnabled = true; debugProfileLayoutsEnabled = true;
debugEnhanceLayoutTimelineArguments = true;
await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey())); }); await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey())); });
events = await fetchInterestingEvents(interestingLabels); events = await fetchInterestingEvents(interestingLabels);
expect( expect(
...@@ -133,8 +138,10 @@ void main() { ...@@ -133,8 +138,10 @@ void main() {
expect(args['creator'], contains('Placeholder')); expect(args['creator'], contains('Placeholder'));
expect(args['painter'], startsWith('_PlaceholderPainter#')); expect(args['painter'], startsWith('_PlaceholderPainter#'));
debugProfileLayoutsEnabled = false; debugProfileLayoutsEnabled = false;
debugEnhanceLayoutTimelineArguments = false;
debugProfilePaintsEnabled = true; debugProfilePaintsEnabled = true;
debugEnhancePaintTimelineArguments = true;
await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey())); }); await runFrame(() { TestRoot.state.updateWidget(Placeholder(key: UniqueKey())); });
events = await fetchInterestingEvents(interestingLabels); events = await fetchInterestingEvents(interestingLabels);
expect( expect(
...@@ -146,6 +153,7 @@ void main() { ...@@ -146,6 +153,7 @@ void main() {
expect(args['creator'], contains('Placeholder')); expect(args['creator'], contains('Placeholder'));
expect(args['painter'], startsWith('_PlaceholderPainter#')); expect(args['painter'], startsWith('_PlaceholderPainter#'));
debugProfilePaintsEnabled = false; debugProfilePaintsEnabled = false;
debugEnhancePaintTimelineArguments = false;
}, skip: isBrowser); // [intended] uses dart:isolate and io. }, skip: isBrowser); // [intended] uses dart:isolate and io.
} }
...@@ -1371,7 +1371,7 @@ abstract class RenderBox extends RenderObject { ...@@ -1371,7 +1371,7 @@ abstract class RenderBox extends RenderObject {
if (shouldCache) { if (shouldCache) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (debugProfileLayoutsEnabled) { if (debugEnhanceLayoutTimelineArguments) {
debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); debugTimelineArguments = toDiagnosticsNode().toTimelineArguments();
} else { } else {
debugTimelineArguments = Map<String, String>.of(debugTimelineArguments); debugTimelineArguments = Map<String, String>.of(debugTimelineArguments);
...@@ -1835,7 +1835,7 @@ abstract class RenderBox extends RenderObject { ...@@ -1835,7 +1835,7 @@ abstract class RenderBox extends RenderObject {
if (shouldCache) { if (shouldCache) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (debugProfileLayoutsEnabled) { if (debugEnhanceLayoutTimelineArguments) {
debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); debugTimelineArguments = toDiagnosticsNode().toTimelineArguments();
} else { } else {
debugTimelineArguments = Map<String, String>.of(debugTimelineArguments); debugTimelineArguments = Map<String, String>.of(debugTimelineArguments);
......
...@@ -116,6 +116,8 @@ bool debugCheckIntrinsicSizes = false; ...@@ -116,6 +116,8 @@ bool debugCheckIntrinsicSizes = false;
/// * [debugProfileBuildsEnabled], which does something similar for widgets /// * [debugProfileBuildsEnabled], which does something similar for widgets
/// being rebuilt. /// being rebuilt.
/// * [debugProfilePaintsEnabled], which does something similar for painting. /// * [debugProfilePaintsEnabled], which does something similar for painting.
/// * [debugEnhanceLayoutTimelineArguments], which enhances the trace with
/// debugging information related to [RenderObject] layouts.
bool debugProfileLayoutsEnabled = false; bool debugProfileLayoutsEnabled = false;
/// Adds [dart:developer.Timeline] events for every [RenderObject] painted. /// Adds [dart:developer.Timeline] events for every [RenderObject] painted.
...@@ -143,8 +145,52 @@ bool debugProfileLayoutsEnabled = false; ...@@ -143,8 +145,52 @@ bool debugProfileLayoutsEnabled = false;
/// * The discussion at [RendererBinding.drawFrame]. /// * The discussion at [RendererBinding.drawFrame].
/// * [RepaintBoundary], which can be used to contain repaints when unchanged /// * [RepaintBoundary], which can be used to contain repaints when unchanged
/// areas are being excessively repainted. /// areas are being excessively repainted.
/// * [debugEnhancePaintTimelineArguments], which enhances the trace with
/// debugging information related to [RenderObject] paints.
bool debugProfilePaintsEnabled = false; 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. /// Signature for [debugOnProfilePaint] implementations.
typedef ProfilePaintCallback = void Function(RenderObject renderObject); typedef ProfilePaintCallback = void Function(RenderObject renderObject);
......
...@@ -860,7 +860,7 @@ class PipelineOwner { ...@@ -860,7 +860,7 @@ class PipelineOwner {
if (!kReleaseMode) { if (!kReleaseMode) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (debugProfileLayoutsEnabled) { if (debugEnhanceLayoutTimelineArguments) {
debugTimelineArguments = <String, String>{ debugTimelineArguments = <String, String>{
...debugTimelineArguments, ...debugTimelineArguments,
'dirty count': '${_nodesNeedingLayout.length}', 'dirty count': '${_nodesNeedingLayout.length}',
...@@ -966,7 +966,7 @@ class PipelineOwner { ...@@ -966,7 +966,7 @@ class PipelineOwner {
if (!kReleaseMode) { if (!kReleaseMode) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (debugProfilePaintsEnabled) { if (debugEnhancePaintTimelineArguments) {
debugTimelineArguments = <String, String>{ debugTimelineArguments = <String, String>{
...debugTimelineArguments, ...debugTimelineArguments,
'dirty count': '${_nodesNeedingPaint.length}', 'dirty count': '${_nodesNeedingPaint.length}',
...@@ -1798,7 +1798,9 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -1798,7 +1798,9 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
if (!kReleaseMode && debugProfileLayoutsEnabled) { if (!kReleaseMode && debugProfileLayoutsEnabled) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (debugEnhanceLayoutTimelineArguments) {
debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); debugTimelineArguments = toDiagnosticsNode().toTimelineArguments();
}
return true; return true;
}()); }());
Timeline.startSync( Timeline.startSync(
...@@ -2402,7 +2404,9 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -2402,7 +2404,9 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
if (!kReleaseMode && debugProfilePaintsEnabled) { if (!kReleaseMode && debugProfilePaintsEnabled) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (debugEnhancePaintTimelineArguments) {
debugTimelineArguments = toDiagnosticsNode().toTimelineArguments(); debugTimelineArguments = toDiagnosticsNode().toTimelineArguments();
}
return true; return true;
}()); }());
Timeline.startSync( Timeline.startSync(
......
...@@ -116,6 +116,8 @@ bool debugPrintGlobalKeyedWidgetLifecycle = false; ...@@ -116,6 +116,8 @@ bool debugPrintGlobalKeyedWidgetLifecycle = false;
/// * [debugProfilePaintsEnabled], which does something similar for painting. /// * [debugProfilePaintsEnabled], which does something similar for painting.
/// * [debugProfileBuildsEnabledUserWidgets], which adds events for user-created /// * [debugProfileBuildsEnabledUserWidgets], which adds events for user-created
/// [Widget] build times and incurs less overhead. /// [Widget] build times and incurs less overhead.
/// * [debugEnhanceBuildTimelineArguments], which enhances the trace with
/// debugging information related to [Widget] builds.
bool debugProfileBuildsEnabled = false; bool debugProfileBuildsEnabled = false;
/// Adds [Timeline] events for every user-created [Widget] built. /// Adds [Timeline] events for every user-created [Widget] built.
...@@ -130,8 +132,32 @@ bool debugProfileBuildsEnabled = false; ...@@ -130,8 +132,32 @@ bool debugProfileBuildsEnabled = false;
/// ///
/// * [debugProfileBuildsEnabled], which functions similarly but shows events /// * [debugProfileBuildsEnabled], which functions similarly but shows events
/// for every widget and has a higher overhead cost. /// for every widget and has a higher overhead cost.
/// * [debugEnhanceBuildTimelineArguments], which enhances the trace with
/// debugging information related to [Widget] builds.
bool debugProfileBuildsEnabledUserWidgets = false; 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. /// Show banners for deprecated widgets.
bool debugHighlightDeprecatedWidgets = false; bool debugHighlightDeprecatedWidgets = false;
......
...@@ -2565,7 +2565,7 @@ class BuildOwner { ...@@ -2565,7 +2565,7 @@ class BuildOwner {
if (!kReleaseMode) { if (!kReleaseMode) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (debugProfileBuildsEnabled) { if (debugEnhanceBuildTimelineArguments) {
debugTimelineArguments = <String, String>{ debugTimelineArguments = <String, String>{
...debugTimelineArguments, ...debugTimelineArguments,
'dirty count': '${_dirtyElements.length}', 'dirty count': '${_dirtyElements.length}',
...@@ -2645,7 +2645,7 @@ class BuildOwner { ...@@ -2645,7 +2645,7 @@ class BuildOwner {
if (isTimelineTracked) { if (isTimelineTracked) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (kDebugMode) { if (kDebugMode && debugEnhanceBuildTimelineArguments) {
debugTimelineArguments = element.widget.toDiagnosticsNode().toTimelineArguments(); debugTimelineArguments = element.widget.toDiagnosticsNode().toTimelineArguments();
} }
return true; return true;
...@@ -3517,7 +3517,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext { ...@@ -3517,7 +3517,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
if (isTimelineTracked) { if (isTimelineTracked) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (kDebugMode) { if (kDebugMode && debugEnhanceBuildTimelineArguments) {
debugTimelineArguments = newWidget.toDiagnosticsNode().toTimelineArguments(); debugTimelineArguments = newWidget.toDiagnosticsNode().toTimelineArguments();
} }
return true; return true;
...@@ -3782,7 +3782,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext { ...@@ -3782,7 +3782,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
if (isTimelineTracked) { if (isTimelineTracked) {
Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent; Map<String, String> debugTimelineArguments = timelineArgumentsIndicatingLandmarkEvent;
assert(() { assert(() {
if (kDebugMode) { if (kDebugMode && debugEnhanceBuildTimelineArguments) {
debugTimelineArguments = newWidget.toDiagnosticsNode().toTimelineArguments(); debugTimelineArguments = newWidget.toDiagnosticsNode().toTimelineArguments();
} }
return true; return true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment