Add some more dart doc to RepaintBoundary (#17183)
diff --git a/packages/flutter/lib/src/foundation/diagnostics.dart b/packages/flutter/lib/src/foundation/diagnostics.dart
index d929c79..44208dc 100644
--- a/packages/flutter/lib/src/foundation/diagnostics.dart
+++ b/packages/flutter/lib/src/foundation/diagnostics.dart
@@ -743,7 +743,7 @@
String get _separator => showSeparator ? ':' : '';
- /// Serialize the node excluding its descendents to a JSON map.
+ /// Serialize the node excluding its descendants to a JSON map.
///
/// Subclasses should override if they have additional properties that are
/// useful for the GUI tools that consume this JSON.
diff --git a/packages/flutter/lib/src/rendering/debug.dart b/packages/flutter/lib/src/rendering/debug.dart
index 104bfd7..99f8e16 100644
--- a/packages/flutter/lib/src/rendering/debug.dart
+++ b/packages/flutter/lib/src/rendering/debug.dart
@@ -38,6 +38,11 @@
bool debugPaintPointersEnabled = false;
/// Overlay a rotating set of colors when repainting layers in checked mode.
+///
+/// See also:
+///
+/// * [RepaintBoundary], which can be used to contain repaints when unchanged
+/// areas are being excessively repainted.
bool debugRepaintRainbowEnabled = false;
/// Overlay a rotating set of colors when repainting text in checked mode.
@@ -103,12 +108,12 @@
///
/// * [debugPrintLayouts], which does something similar for layout but using
/// console output.
-///
/// * [debugProfileBuildsEnabled], which does something similar for widgets
/// being rebuilt, and [debugPrintRebuildDirtyWidgets], its console
/// equivalent.
-///
/// * The discussion at [RendererBinding.drawFrame].
+/// * [RepaintBoundary], which can be used to contain repaints when unchanged
+/// areas are being excessively repainted.
bool debugProfilePaintsEnabled = false;
/// Setting to true will cause all clipping effects from the layer tree to be
diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart
index 85b3d9c..5aa707e 100644
--- a/packages/flutter/lib/src/rendering/object.dart
+++ b/packages/flutter/lib/src/rendering/object.dart
@@ -1871,6 +1871,12 @@
/// Once [markNeedsPaint] has been called on a render object,
/// [debugNeedsPaint] returns true for that render object until just after
/// the pipeline owner has called [paint] on the render object.
+ ///
+ /// See also:
+ ///
+ /// * [RepaintBoundary], to scope a subtree of render objects to their own
+ /// layer, thus limiting the number of nodes that [markNeedsPaint] must mark
+ /// dirty.
void markNeedsPaint() {
assert(owner == null || !owner.debugDoingPaint);
if (_needsPaint)
diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart
index be5c27e..a5752e9 100644
--- a/packages/flutter/lib/src/widgets/basic.dart
+++ b/packages/flutter/lib/src/widgets/basic.dart
@@ -4774,11 +4774,53 @@
///
/// This widget creates a separate display list for its child, which
/// can improve performance if the subtree repaints at different times than
-/// the surrounding parts of the tree. Specifically, when the child does not
-/// repaint but its parent does, we can re-use the display list we recorded
-/// previously. Similarly, when the child repaints but the surround tree does
-/// not, we can re-record its display list without re-recording the display list
-/// for the surround tree.
+/// the surrounding parts of the tree.
+///
+/// This is useful since [RenderObject.paint] may be triggered even if its
+/// associated [Widget] instances did not change or rebuild. A [RenderObject]
+/// will repaint whenever any [RenderObject] that shares the same [Layer] is
+/// marked as being dirty and needing paint (see [RenderObject.markNeedsPaint]),
+/// such as when an ancestor scrolls or when an ancestor or descendant animates.
+///
+/// Containing [RenderObject.paint] to parts of the render subtree that are
+/// actually visually changing using [RepaintBoundary] explicitly or implicitly
+/// is therefore critical to minimizing redundant work and improving the app's
+/// performance.
+///
+/// When a [RenderObject] is flagged as needing to paint via
+/// [RenderObject.markNeedsPaint], the nearest ancestor [RenderObject] with
+/// [RenderObject.isRepaintBoundary], up to possibly the root of the application,
+/// is requested to repaint. That nearest ancestor's [RenderObject.paint] method
+/// will cause _all_ of its descendant [RenderObject]s to repaint in the same
+/// layer.
+///
+/// [RepaintBoundary] is therefore used, both while propagating the
+/// `markNeedsPaint` flag up the render tree and while traversing down the
+/// render tree via [RenderObject.paintChild], to strategically contain repaints
+/// to the render subtree that visually changed for performance. This is done
+/// because the [RepaintBoundary] widget creates a [RenderObject] that always
+/// has a [Layer], decoupling ancestor render objects from the descendant
+/// render objects.
+///
+/// [RepaintBoundary] has the further side-effect of possibly hinting to the
+/// engine that it should further optimize animation performance if the render
+/// subtree behind the [RepaintBoundary] is sufficiently complex and is static
+/// while the surrounding tree changes frequently. In those cases, the engine
+/// may choose to pay a one time cost of rasterizing and caching the pixel
+/// values of the subtree for faster future GPU re-rendering speed.
+///
+/// Several framework widgets insert [RepaintBoundary] widgets to mark natural
+/// separation points in applications. For instance, contents in Material Design
+/// drawers typically don't change while the drawer opens and closes, so
+/// repaints are automatically contained to regions inside or outside the drawer
+/// when using the [Drawer] widget during transitions.
+///
+/// See also:
+///
+/// * [debugRepaintRainbowEnabled], a debugging flag to help visually monitor
+/// render tree repaints in a running app.
+/// * [debugProfilePaintsEnabled], a debugging flag to show render tree
+/// repaints in the observatory's timeline view.
class RepaintBoundary extends SingleChildRenderObjectWidget {
/// Creates a widget that isolates repaints.
const RepaintBoundary({ Key key, Widget child }) : super(key: key, child: child);
diff --git a/packages/flutter/lib/src/widgets/media_query.dart b/packages/flutter/lib/src/widgets/media_query.dart
index d5cd755..a9440e0 100644
--- a/packages/flutter/lib/src/widgets/media_query.dart
+++ b/packages/flutter/lib/src/widgets/media_query.dart
@@ -98,7 +98,7 @@
/// If you consumed this padding (e.g. by building a widget that envelops or
/// accounts for this padding in its layout in such a way that children are
/// no longer exposed to this padding), you should remove this padding
- /// for subsequent descendents in the widget tree by inserting a new
+ /// for subsequent descendants in the widget tree by inserting a new
/// [MediaQuery] widget using the [MediaQuery.removePadding] factory.
///
/// See also:
@@ -283,7 +283,7 @@
///
/// This should be inserted into the widget tree when the [MediaQuery] padding
/// is consumed by a widget in such a way that the padding is no longer
- /// exposed to the widget's descendents or siblings.
+ /// exposed to the widget's descendants or siblings.
///
/// The [context] argument is required, must not be null, and must have a
/// [MediaQuery] in scope.
@@ -327,7 +327,7 @@
///
/// This should be inserted into the widget tree when the [MediaQuery] view
/// insets are consumed by a widget in such a way that the view insets are no
- /// longer exposed to the widget's descendents or siblings.
+ /// longer exposed to the widget's descendants or siblings.
///
/// The [context] argument is required, must not be null, and must have a
/// [MediaQuery] in scope.