More debug help. (#11308)

diff --git a/packages/flutter/lib/src/rendering/debug.dart b/packages/flutter/lib/src/rendering/debug.dart
index a4ad85c..d0302b7 100644
--- a/packages/flutter/lib/src/rendering/debug.dart
+++ b/packages/flutter/lib/src/rendering/debug.dart
@@ -95,9 +95,6 @@
 /// The amount to increment the hue of the current repaint color.
 double debugRepaintRainbowHueIncrement = _kDebugRepaintRainbowHueIncrement;
 
-/// Log the call stacks that mark render objects as needing paint.
-bool debugPrintMarkNeedsPaintStacks = false;
-
 /// Log the call stacks that mark render objects as needing layout.
 ///
 /// For sanity, this only logs the stack traces of cases where an object is
@@ -106,6 +103,29 @@
 /// up the tree.
 bool debugPrintMarkNeedsLayoutStacks = false;
 
+/// Log the call stacks that mark render objects as needing paint.
+bool debugPrintMarkNeedsPaintStacks = false;
+
+/// Log the dirty render objects that are laid out each frame.
+///
+/// Combined with [debugPrintBeginFrameBanner], this allows you to distinguish
+/// layouts triggered by the initial mounting of a render tree (e.g. in a call
+/// to [runApp]) from the regular layouts triggered by the pipeline.
+///
+/// Combined with [debugPrintMarkNeedsLayoutStacks], this lets you watch a
+/// render object's dirty/clean lifecycle.
+///
+/// See also:
+///
+///  * [debugProfilePaintsEnabled], which does something similar for
+///    painting but using the timeline view.
+///
+///  * [debugPrintRebuildDirtyWidgets], which does something similar for widgets
+///    being rebuilt.
+///
+///  * The discussion at [RendererBinding.drawFrame].
+bool debugPrintLayouts = false;
+
 /// Check the intrinsic sizes of each [RenderBox] during layout.
 ///
 /// By default this is turned off since these checks are expensive, but it is
@@ -121,6 +141,16 @@
 /// For details on how to use [dart:developer.Timeline] events in the Dart
 /// Observatory to optimize your app, see:
 /// <https://fuchsia.googlesource.com/sysui/+/master/docs/performance.md>
+///
+/// See also:
+///
+///  * [debugPrintLayouts], which does something similar for layout but using
+///    console output.
+///
+///  * [debugPrintRebuildDirtyWidgets], which does something similar for widgets
+///    being rebuilt.
+///
+///  * The discussion at [RendererBinding.drawFrame].
 bool debugProfilePaintsEnabled = false;
 
 
@@ -184,8 +214,9 @@
         debugPaintPointersEnabled ||
         debugRepaintRainbowEnabled ||
         debugRepaintTextRainbowEnabled ||
-        debugPrintMarkNeedsPaintStacks ||
         debugPrintMarkNeedsLayoutStacks ||
+        debugPrintMarkNeedsPaintStacks ||
+        debugPrintLayouts ||
         debugCheckIntrinsicSizes != debugCheckIntrinsicSizesOverride ||
         debugProfilePaintsEnabled ||
         debugPaintSizeColor != _kDebugPaintSizeColor ||
diff --git a/packages/flutter/lib/src/rendering/layer.dart b/packages/flutter/lib/src/rendering/layer.dart
index 453fe50..b47b2e8 100644
--- a/packages/flutter/lib/src/rendering/layer.dart
+++ b/packages/flutter/lib/src/rendering/layer.dart
@@ -754,6 +754,8 @@
   void debugFillDescription(List<String> description) {
     super.debugFillDescription(description);
     description.add('clipRRect: $clipRRect');
+    description.add('elevation: $elevation');
+    description.add('color: $color');
   }
 }
 
diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart
index 1b08db4..d720c2d 100644
--- a/packages/flutter/lib/src/rendering/object.dart
+++ b/packages/flutter/lib/src/rendering/object.dart
@@ -1743,6 +1743,8 @@
       _debugDoingThisLayout = true;
       debugPreviousActiveLayout = _debugActiveLayout;
       _debugActiveLayout = this;
+      if (debugPrintLayouts)
+        debugPrint('Laying out (without resize) $this');
       return true;
     });
     try {
@@ -1849,6 +1851,8 @@
     assert(!_doingThisLayoutWithCallback);
     assert(() {
       _debugMutationsLocked = true;
+      if (debugPrintLayouts)
+        debugPrint('Laying out (${sizedByParent ? "with separate resize" : "with resize allowed"}) $this');
       return true;
     });
     if (sizedByParent) {
diff --git a/packages/flutter/lib/src/scheduler/debug.dart b/packages/flutter/lib/src/scheduler/debug.dart
index 3e52836..4d9c127 100644
--- a/packages/flutter/lib/src/scheduler/debug.dart
+++ b/packages/flutter/lib/src/scheduler/debug.dart
@@ -21,7 +21,16 @@
 /// intra-frame output from inter-frame output, set [debugPrintEndFrameBanner]
 /// to true as well.
 ///
-/// See [SchedulerBinding.handleBeginFrame].
+/// See also:
+///
+///  * [debugProfilePaintsEnabled], which does something similar for
+///    painting but using the timeline view.
+///
+///  * [debugPrintLayouts], which does something similar for layout but using
+///    console output.
+///
+///  * The discussions at [WidgetsBinding.drawFrame] and at
+///    [SchedulerBinding.handleBeginFrame].
 bool debugPrintBeginFrameBanner = false;
 
 /// Print a banner at the end of each frame.