• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:developer';
6import 'dart:ui' as ui show PictureRecorder;
7
8import 'package:flutter/animation.dart';
9import 'package:flutter/foundation.dart';
10import 'package:flutter/gestures.dart';
11import 'package:flutter/painting.dart';
12import 'package:flutter/semantics.dart';
13import 'package:vector_math/vector_math_64.dart';
14
15import 'binding.dart';
16import 'debug.dart';
17import 'layer.dart';
18
19export 'package:flutter/foundation.dart' show FlutterError, InformationCollector, DiagnosticsNode, ErrorSummary, ErrorDescription, ErrorHint, DiagnosticsProperty, StringProperty, DoubleProperty, EnumProperty, FlagProperty, IntProperty, DiagnosticPropertiesBuilder;
20export 'package:flutter/gestures.dart' show HitTestEntry, HitTestResult;
21export 'package:flutter/painting.dart';
22
23/// Base class for data associated with a [RenderObject] by its parent.
24///
25/// Some render objects wish to store data on their children, such as their
26/// input parameters to the parent's layout algorithm or their position relative
27/// to other children.
28class ParentData {
29  /// Called when the RenderObject is removed from the tree.
30  @protected
31  @mustCallSuper
32  void detach() { }
33
34  @override
35  String toString() => '<none>';
36}
37
38/// Signature for painting into a [PaintingContext].
39///
40/// The `offset` argument is the offset from the origin of the coordinate system
41/// of the [PaintingContext.canvas] to the coordinate system of the callee.
42///
43/// Used by many of the methods of [PaintingContext].
44typedef PaintingContextCallback = void Function(PaintingContext context, Offset offset);
45
46/// A place to paint.
47///
48/// Rather than holding a canvas directly, [RenderObject]s paint using a painting
49/// context. The painting context has a [Canvas], which receives the
50/// individual draw operations, and also has functions for painting child
51/// render objects.
52///
53/// When painting a child render object, the canvas held by the painting context
54/// can change because the draw operations issued before and after painting the
55/// child might be recorded in separate compositing layers. For this reason, do
56/// not hold a reference to the canvas across operations that might paint
57/// child render objects.
58///
59/// New [PaintingContext] objects are created automatically when using
60/// [PaintingContext.repaintCompositedChild] and [pushLayer].
61class PaintingContext extends ClipContext {
62
63  /// Creates a painting context.
64  ///
65  /// Typically only called by [PaintingContext.repaintCompositedChild]
66  /// and [pushLayer].
67  @protected
68  PaintingContext(this._containerLayer, this.estimatedBounds)
69    : assert(_containerLayer != null),
70      assert(estimatedBounds != null);
71
72  final ContainerLayer _containerLayer;
73
74  /// An estimate of the bounds within which the painting context's [canvas]
75  /// will record painting commands. This can be useful for debugging.
76  ///
77  /// The canvas will allow painting outside these bounds.
78  ///
79  /// The [estimatedBounds] rectangle is in the [canvas] coordinate system.
80  final Rect estimatedBounds;
81
82  /// Repaint the given render object.
83  ///
84  /// The render object must be attached to a [PipelineOwner], must have a
85  /// composited layer, and must be in need of painting. The render object's
86  /// layer, if any, is re-used, along with any layers in the subtree that don't
87  /// need to be repainted.
88  ///
89  /// See also:
90  ///
91  ///  * [RenderObject.isRepaintBoundary], which determines if a [RenderObject]
92  ///    has a composited layer.
93  static void repaintCompositedChild(RenderObject child, { bool debugAlsoPaintedParent = false }) {
94    assert(child._needsPaint);
95    _repaintCompositedChild(
96      child,
97      debugAlsoPaintedParent: debugAlsoPaintedParent,
98    );
99  }
100
101  static void _repaintCompositedChild(
102    RenderObject child, {
103    bool debugAlsoPaintedParent = false,
104    PaintingContext childContext,
105  }) {
106    assert(child.isRepaintBoundary);
107    assert(() {
108      // register the call for RepaintBoundary metrics
109      child.debugRegisterRepaintBoundaryPaint(
110        includedParent: debugAlsoPaintedParent,
111        includedChild: true,
112      );
113      return true;
114    }());
115    OffsetLayer childLayer = child._layer;
116    if (childLayer == null) {
117      assert(debugAlsoPaintedParent);
118      // Not using the `layer` setter because the setter asserts that we not
119      // replace the layer for repaint boundaries. That assertion does not
120      // apply here because this is exactly the place designed to create a
121      // layer for repaint boundaries.
122      child._layer = childLayer = OffsetLayer();
123    } else {
124      assert(childLayer is OffsetLayer);
125      assert(debugAlsoPaintedParent || childLayer.attached);
126      childLayer.removeAllChildren();
127    }
128    assert(identical(childLayer, child._layer));
129    assert(child._layer is OffsetLayer);
130    assert(() {
131      child._layer.debugCreator = child.debugCreator ?? child.runtimeType;
132      return true;
133    }());
134    childContext ??= PaintingContext(child._layer, child.paintBounds);
135    child._paintWithContext(childContext, Offset.zero);
136
137    // Double-check that the paint method did not replace the layer (the first
138    // check is done in the [layer] setter itself).
139    assert(identical(childLayer, child._layer));
140    childContext.stopRecordingIfNeeded();
141  }
142
143  /// In debug mode, repaint the given render object using a custom painting
144  /// context that can record the results of the painting operation in addition
145  /// to performing the regular paint of the child.
146  ///
147  /// See also:
148  ///
149  ///  * [repaintCompositedChild], for repainting a composited child without
150  ///    instrumentation.
151  static void debugInstrumentRepaintCompositedChild(
152    RenderObject child, {
153    bool debugAlsoPaintedParent = false,
154    @required PaintingContext customContext,
155  }) {
156    assert(() {
157      _repaintCompositedChild(
158        child,
159        debugAlsoPaintedParent: debugAlsoPaintedParent,
160        childContext: customContext,
161      );
162      return true;
163    }());
164  }
165
166  /// Paint a child [RenderObject].
167  ///
168  /// If the child has its own composited layer, the child will be composited
169  /// into the layer subtree associated with this painting context. Otherwise,
170  /// the child will be painted into the current PictureLayer for this context.
171  void paintChild(RenderObject child, Offset offset) {
172    assert(() {
173      if (debugProfilePaintsEnabled)
174        Timeline.startSync('${child.runtimeType}', arguments: timelineWhitelistArguments);
175      if (debugOnProfilePaint != null)
176        debugOnProfilePaint(child);
177      return true;
178    }());
179
180    if (child.isRepaintBoundary) {
181      stopRecordingIfNeeded();
182      _compositeChild(child, offset);
183    } else {
184      child._paintWithContext(this, offset);
185    }
186
187    assert(() {
188      if (debugProfilePaintsEnabled)
189        Timeline.finishSync();
190      return true;
191    }());
192  }
193
194  void _compositeChild(RenderObject child, Offset offset) {
195    assert(!_isRecording);
196    assert(child.isRepaintBoundary);
197    assert(_canvas == null || _canvas.getSaveCount() == 1);
198
199    // Create a layer for our child, and paint the child into it.
200    if (child._needsPaint) {
201      repaintCompositedChild(child, debugAlsoPaintedParent: true);
202    } else {
203      assert(() {
204        // register the call for RepaintBoundary metrics
205        child.debugRegisterRepaintBoundaryPaint(
206          includedParent: true,
207          includedChild: false,
208        );
209        child._layer.debugCreator = child.debugCreator ?? child;
210        return true;
211      }());
212    }
213    assert(child._layer is OffsetLayer);
214    final OffsetLayer childOffsetLayer = child._layer;
215    childOffsetLayer.offset = offset;
216    appendLayer(child._layer);
217  }
218
219  /// Adds a layer to the recording requiring that the recording is already
220  /// stopped.
221  ///
222  /// Do not call this function directly: call [addLayer] or [pushLayer]
223  /// instead. This function is called internally when all layers not
224  /// generated from the [canvas] are added.
225  ///
226  /// Subclasses that need to customize how layers are added should override
227  /// this method.
228  @protected
229  void appendLayer(Layer layer) {
230    assert(!_isRecording);
231    layer.remove();
232    _containerLayer.append(layer);
233  }
234
235  bool get _isRecording {
236    final bool hasCanvas = _canvas != null;
237    assert(() {
238      if (hasCanvas) {
239        assert(_currentLayer != null);
240        assert(_recorder != null);
241        assert(_canvas != null);
242      } else {
243        assert(_currentLayer == null);
244        assert(_recorder == null);
245        assert(_canvas == null);
246      }
247      return true;
248    }());
249    return hasCanvas;
250  }
251
252  // Recording state
253  PictureLayer _currentLayer;
254  ui.PictureRecorder _recorder;
255  Canvas _canvas;
256
257  /// The canvas on which to paint.
258  ///
259  /// The current canvas can change whenever you paint a child using this
260  /// context, which means it's fragile to hold a reference to the canvas
261  /// returned by this getter.
262  @override
263  Canvas get canvas {
264    if (_canvas == null)
265      _startRecording();
266    return _canvas;
267  }
268
269  void _startRecording() {
270    assert(!_isRecording);
271    _currentLayer = PictureLayer(estimatedBounds);
272    _recorder = ui.PictureRecorder();
273    _canvas = Canvas(_recorder);
274    _containerLayer.append(_currentLayer);
275  }
276
277  /// Stop recording to a canvas if recording has started.
278  ///
279  /// Do not call this function directly: functions in this class will call
280  /// this method as needed. This function is called internally to ensure that
281  /// recording is stopped before adding layers or finalizing the results of a
282  /// paint.
283  ///
284  /// Subclasses that need to customize how recording to a canvas is performed
285  /// should override this method to save the results of the custom canvas
286  /// recordings.
287  @protected
288  @mustCallSuper
289  void stopRecordingIfNeeded() {
290    if (!_isRecording)
291      return;
292    assert(() {
293      if (debugRepaintRainbowEnabled) {
294        final Paint paint = Paint()
295          ..style = PaintingStyle.stroke
296          ..strokeWidth = 6.0
297          ..color = debugCurrentRepaintColor.toColor();
298        canvas.drawRect(estimatedBounds.deflate(3.0), paint);
299      }
300      if (debugPaintLayerBordersEnabled) {
301        final Paint paint = Paint()
302          ..style = PaintingStyle.stroke
303          ..strokeWidth = 1.0
304          ..color = const Color(0xFFFF9800);
305        canvas.drawRect(estimatedBounds, paint);
306      }
307      return true;
308    }());
309    _currentLayer.picture = _recorder.endRecording();
310    _currentLayer = null;
311    _recorder = null;
312    _canvas = null;
313  }
314
315  /// Hints that the painting in the current layer is complex and would benefit
316  /// from caching.
317  ///
318  /// If this hint is not set, the compositor will apply its own heuristics to
319  /// decide whether the current layer is complex enough to benefit from
320  /// caching.
321  void setIsComplexHint() {
322    _currentLayer?.isComplexHint = true;
323  }
324
325  /// Hints that the painting in the current layer is likely to change next frame.
326  ///
327  /// This hint tells the compositor not to cache the current layer because the
328  /// cache will not be used in the future. If this hint is not set, the
329  /// compositor will apply its own heuristics to decide whether the current
330  /// layer is likely to be reused in the future.
331  void setWillChangeHint() {
332    _currentLayer?.willChangeHint = true;
333  }
334
335  /// Adds a composited leaf layer to the recording.
336  ///
337  /// After calling this function, the [canvas] property will change to refer to
338  /// a new [Canvas] that draws on top of the given layer.
339  ///
340  /// A [RenderObject] that uses this function is very likely to require its
341  /// [RenderObject.alwaysNeedsCompositing] property to return true. That informs
342  /// ancestor render objects that this render object will include a composited
343  /// layer, which, for example, causes them to use composited clips.
344  ///
345  /// See also:
346  ///
347  ///  * [pushLayer], for adding a layer and using its canvas to paint with that
348  ///    layer.
349  void addLayer(Layer layer) {
350    stopRecordingIfNeeded();
351    appendLayer(layer);
352  }
353
354  /// Appends the given layer to the recording, and calls the `painter` callback
355  /// with that layer, providing the `childPaintBounds` as the estimated paint
356  /// bounds of the child. The `childPaintBounds` can be used for debugging but
357  /// have no effect on painting.
358  ///
359  /// The given layer must be an unattached orphan. (Providing a newly created
360  /// object, rather than reusing an existing layer, satisfies that
361  /// requirement.)
362  ///
363  /// The `offset` is the offset to pass to the `painter`.
364  ///
365  /// If the `childPaintBounds` are not specified then the current layer's paint
366  /// bounds are used. This is appropriate if the child layer does not apply any
367  /// transformation or clipping to its contents. The `childPaintBounds`, if
368  /// specified, must be in the coordinate system of the new layer, and should
369  /// not go outside the current layer's paint bounds.
370  ///
371  /// See also:
372  ///
373  ///  * [addLayer], for pushing a leaf layer whose canvas is not used.
374  void pushLayer(ContainerLayer childLayer, PaintingContextCallback painter, Offset offset, { Rect childPaintBounds }) {
375    assert(painter != null);
376    // If a layer is being reused, it may already contain children. We remove
377    // them so that `painter` can add children that are relevant for this frame.
378    if (childLayer.hasChildren) {
379      childLayer.removeAllChildren();
380    }
381    stopRecordingIfNeeded();
382    appendLayer(childLayer);
383    final PaintingContext childContext = createChildContext(childLayer, childPaintBounds ?? estimatedBounds);
384    painter(childContext, offset);
385    childContext.stopRecordingIfNeeded();
386  }
387
388  /// Creates a compatible painting context to paint onto [childLayer].
389  @protected
390  PaintingContext createChildContext(ContainerLayer childLayer, Rect bounds) {
391    return PaintingContext(childLayer, bounds);
392  }
393
394  /// Clip further painting using a rectangle.
395  ///
396  /// {@template flutter.rendering.object.needsCompositing}
397  /// * `needsCompositing` is whether the child needs compositing. Typically
398  ///   matches the value of [RenderObject.needsCompositing] for the caller. If
399  ///   false, this method returns null, indicating that a layer is no longer
400  ///   necessary. If a render object calling this method stores the `oldLayer`
401  ///   in its [RenderObject.layer] field, it should set that field to null.
402  /// {@end template}
403  /// * `offset` is the offset from the origin of the canvas' coordinate system
404  ///   to the origin of the caller's coordinate system.
405  /// * `clipRect` is rectangle (in the caller's coordinate system) to use to
406  ///   clip the painting done by [painter].
407  /// * `painter` is a callback that will paint with the [clipRect] applied. This
408  ///   function calls the [painter] synchronously.
409  /// * `clipBehavior` controls how the rectangle is clipped.
410  /// {@template flutter.rendering.object.oldLayer}
411  /// * `oldLayer` is the layer created in the previous frame. Specifying the
412  ///   old layer gives the engine more information for performance
413  ///   optimizations. Typically this is the value of [RenderObject.layer] that
414  ///   a render object creates once, then reuses for all subsequent frames
415  ///   until a layer is no longer needed (e.g. the render object no longer
416  ///   needs compositing) or until the render object changes the type of the
417  ///   layer (e.g. from opacity layer to a clip rect layer).
418  /// {@end template}
419  ClipRectLayer pushClipRect(bool needsCompositing, Offset offset, Rect clipRect, PaintingContextCallback painter, { Clip clipBehavior = Clip.hardEdge, ClipRectLayer oldLayer }) {
420    final Rect offsetClipRect = clipRect.shift(offset);
421    if (needsCompositing) {
422      final ClipRectLayer layer = oldLayer ?? ClipRectLayer();
423      layer
424        ..clipRect = offsetClipRect
425        ..clipBehavior = clipBehavior;
426      pushLayer(layer, painter, offset, childPaintBounds: offsetClipRect);
427      return layer;
428    } else {
429      clipRectAndPaint(offsetClipRect, clipBehavior, offsetClipRect, () => painter(this, offset));
430      return null;
431    }
432  }
433
434  /// Clip further painting using a rounded rectangle.
435  ///
436  /// {@macro flutter.rendering.object.needsCompositing}
437  /// * `offset` is the offset from the origin of the canvas' coordinate system
438  ///   to the origin of the caller's coordinate system.
439  /// * `bounds` is the region of the canvas (in the caller's coordinate system)
440  ///   into which `painter` will paint in.
441  /// * `clipRRect` is the rounded-rectangle (in the caller's coordinate system)
442  ///   to use to clip the painting done by `painter`.
443  /// * `painter` is a callback that will paint with the `clipRRect` applied. This
444  ///   function calls the `painter` synchronously.
445  /// * `clipBehavior` controls how the path is clipped.
446  /// {@macro flutter.rendering.object.oldLayer}
447  ClipRRectLayer pushClipRRect(bool needsCompositing, Offset offset, Rect bounds, RRect clipRRect, PaintingContextCallback painter, { Clip clipBehavior = Clip.antiAlias, ClipRRectLayer oldLayer }) {
448    assert(clipBehavior != null);
449    final Rect offsetBounds = bounds.shift(offset);
450    final RRect offsetClipRRect = clipRRect.shift(offset);
451    if (needsCompositing) {
452      final ClipRRectLayer layer = oldLayer ?? ClipRRectLayer();
453      layer
454        ..clipRRect = offsetClipRRect
455        ..clipBehavior = clipBehavior;
456      pushLayer(layer, painter, offset, childPaintBounds: offsetBounds);
457      return layer;
458    } else {
459      clipRRectAndPaint(offsetClipRRect, clipBehavior, offsetBounds, () => painter(this, offset));
460      return null;
461    }
462  }
463
464  /// Clip further painting using a path.
465  ///
466  /// {@macro flutter.rendering.object.needsCompositing}
467  /// * `offset` is the offset from the origin of the canvas' coordinate system
468  ///   to the origin of the caller's coordinate system.
469  /// * `bounds` is the region of the canvas (in the caller's coordinate system)
470  ///   into which `painter` will paint in.
471  /// * `clipPath` is the path (in the coordinate system of the caller) to use to
472  ///   clip the painting done by `painter`.
473  /// * `painter` is a callback that will paint with the `clipPath` applied. This
474  ///   function calls the `painter` synchronously.
475  /// * `clipBehavior` controls how the rounded rectangle is clipped.
476  /// {@macro flutter.rendering.object.oldLayer}
477  ClipPathLayer pushClipPath(bool needsCompositing, Offset offset, Rect bounds, Path clipPath, PaintingContextCallback painter, { Clip clipBehavior = Clip.antiAlias, ClipPathLayer oldLayer }) {
478    assert(clipBehavior != null);
479    final Rect offsetBounds = bounds.shift(offset);
480    final Path offsetClipPath = clipPath.shift(offset);
481    if (needsCompositing) {
482      final ClipPathLayer layer = oldLayer ?? ClipPathLayer();
483      layer
484        ..clipPath = offsetClipPath
485        ..clipBehavior = clipBehavior;
486      pushLayer(layer, painter, offset, childPaintBounds: offsetBounds);
487      return layer;
488    } else {
489      clipPathAndPaint(offsetClipPath, clipBehavior, offsetBounds, () => painter(this, offset));
490      return null;
491    }
492  }
493
494  /// Blend further painting with a color filter.
495  ///
496  /// * `offset` is the offset from the origin of the canvas' coordinate system
497  ///   to the origin of the caller's coordinate system.
498  /// * `colorFilter` is the [ColorFilter] value to use when blending the
499  ///   painting done by `painter`.
500  /// * `painter` is a callback that will paint with the `colorFilter` applied.
501  ///   This function calls the `painter` synchronously.
502  /// {@macro flutter.rendering.object.oldLayer}
503  ///
504  /// A [RenderObject] that uses this function is very likely to require its
505  /// [RenderObject.alwaysNeedsCompositing] property to return true. That informs
506  /// ancestor render objects that this render object will include a composited
507  /// layer, which, for example, causes them to use composited clips.
508  ColorFilterLayer pushColorFilter(Offset offset, ColorFilter colorFilter, PaintingContextCallback painter, { ColorFilterLayer oldLayer }) {
509    assert(colorFilter != null);
510    final ColorFilterLayer layer = oldLayer ?? ColorFilterLayer();
511    layer.colorFilter = colorFilter;
512    pushLayer(layer, painter, offset);
513    return layer;
514  }
515
516  /// Transform further painting using a matrix.
517  ///
518  /// {@macro flutter.rendering.object.needsCompositing}
519  /// * `offset` is the offset from the origin of the canvas' coordinate system
520  ///   to the origin of the caller's coordinate system.
521  /// * `transform` is the matrix to apply to the painting done by `painter`.
522  /// * `painter` is a callback that will paint with the `transform` applied. This
523  ///   function calls the `painter` synchronously.
524  /// {@macro flutter.rendering.object.oldLayer}
525  TransformLayer pushTransform(bool needsCompositing, Offset offset, Matrix4 transform, PaintingContextCallback painter, { TransformLayer oldLayer }) {
526    final Matrix4 effectiveTransform = Matrix4.translationValues(offset.dx, offset.dy, 0.0)
527      ..multiply(transform)..translate(-offset.dx, -offset.dy);
528    if (needsCompositing) {
529      final TransformLayer layer = oldLayer ?? TransformLayer();
530      layer.transform = effectiveTransform;
531      pushLayer(
532        layer,
533        painter,
534        offset,
535        childPaintBounds: MatrixUtils.inverseTransformRect(effectiveTransform, estimatedBounds),
536      );
537      return layer;
538    } else {
539      canvas
540        ..save()
541        ..transform(effectiveTransform.storage);
542      painter(this, offset);
543      canvas
544        ..restore();
545      return null;
546    }
547  }
548
549  /// Blend further painting with an alpha value.
550  ///
551  /// * `offset` is the offset from the origin of the canvas' coordinate system
552  ///   to the origin of the caller's coordinate system.
553  /// * `alpha` is the alpha value to use when blending the painting done by
554  ///   `painter`. An alpha value of 0 means the painting is fully transparent
555  ///   and an alpha value of 255 means the painting is fully opaque.
556  /// * `painter` is a callback that will paint with the `alpha` applied. This
557  ///   function calls the `painter` synchronously.
558  /// {@macro flutter.rendering.object.oldLayer}
559  ///
560  /// A [RenderObject] that uses this function is very likely to require its
561  /// [RenderObject.alwaysNeedsCompositing] property to return true. That informs
562  /// ancestor render objects that this render object will include a composited
563  /// layer, which, for example, causes them to use composited clips.
564  OpacityLayer pushOpacity(Offset offset, int alpha, PaintingContextCallback painter, { OpacityLayer oldLayer }) {
565    final OpacityLayer layer = oldLayer ?? OpacityLayer();
566    layer
567      ..alpha = alpha
568      ..offset = offset;
569    pushLayer(layer, painter, Offset.zero);
570    return layer;
571  }
572
573  @override
574  String toString() => '$runtimeType#$hashCode(layer: $_containerLayer, canvas bounds: $estimatedBounds)';
575}
576
577/// An abstract set of layout constraints.
578///
579/// Concrete layout models (such as box) will create concrete subclasses to
580/// communicate layout constraints between parents and children.
581///
582/// ## Writing a Constraints subclass
583///
584/// When creating a new [RenderObject] subclass with a new layout protocol, one
585/// will usually need to create a new [Constraints] subclass to express the
586/// input to the layout algorithms.
587///
588/// A [Constraints] subclass should be immutable (all fields final). There are
589/// several members to implement, in addition to whatever fields, constructors,
590/// and helper methods one may find useful for a particular layout protocol:
591///
592/// * The [isTight] getter, which should return true if the object represents a
593///   case where the [RenderObject] class has no choice for how to lay itself
594///   out. For example, [BoxConstraints] returns true for [isTight] when both
595///   the minimum and maximum widths and the minimum and maximum heights are
596///   equal.
597///
598/// * The [isNormalized] getter, which should return true if the object
599///   represents its data in its canonical form. Sometimes, it is possible for
600///   fields to be redundant with each other, such that several different
601///   representations have the same implications. For example, a
602///   [BoxConstraints] instance with its minimum width greater than its maximum
603///   width is equivalent to one where the maximum width is set to that minimum
604///   width (`2<w<1` is equivalent to `2<w<2`, since minimum constraints have
605///   priority). This getter is used by the default implementation of
606///   [debugAssertIsValid].
607///
608/// * The [debugAssertIsValid] method, which should assert if there's anything
609///   wrong with the constraints object. (We use this approach rather than
610///   asserting in constructors so that our constructors can be `const` and so
611///   that it is possible to create invalid constraints temporarily while
612///   building valid ones.) See the implementation of
613///   [BoxConstraints.debugAssertIsValid] for an example of the detailed checks
614///   that can be made.
615///
616/// * The [==] operator and the [hashCode] getter, so that constraints can be
617///   compared for equality. If a render object is given constraints that are
618///   equal, then the rendering library will avoid laying the object out again
619///   if it is not dirty.
620///
621/// * The [toString] method, which should describe the constraints so that they
622///   appear in a usefully readable form in the output of [debugDumpRenderTree].
623@immutable
624abstract class Constraints {
625  /// Abstract const constructor. This constructor enables subclasses to provide
626  /// const constructors so that they can be used in const expressions.
627  const Constraints();
628
629  /// Whether there is exactly one size possible given these constraints
630  bool get isTight;
631
632  /// Whether the constraint is expressed in a consistent manner.
633  bool get isNormalized;
634
635  /// Asserts that the constraints are valid.
636  ///
637  /// This might involve checks more detailed than [isNormalized].
638  ///
639  /// For example, the [BoxConstraints] subclass verifies that the constraints
640  /// are not [double.nan].
641  ///
642  /// If the `isAppliedConstraint` argument is true, then even stricter rules
643  /// are enforced. This argument is set to true when checking constraints that
644  /// are about to be applied to a [RenderObject] during layout, as opposed to
645  /// constraints that may be further affected by other constraints. For
646  /// example, the asserts for verifying the validity of
647  /// [RenderConstrainedBox.additionalConstraints] do not set this argument, but
648  /// the asserts for verifying the argument passed to the [RenderObject.layout]
649  /// method do.
650  ///
651  /// The `informationCollector` argument takes an optional callback which is
652  /// called when an exception is to be thrown. The collected information is
653  /// then included in the message after the error line.
654  ///
655  /// Returns the same as [isNormalized] if asserts are disabled.
656  bool debugAssertIsValid({
657    bool isAppliedConstraint = false,
658    InformationCollector informationCollector,
659  }) {
660    assert(isNormalized);
661    return isNormalized;
662  }
663}
664
665/// Signature for a function that is called for each [RenderObject].
666///
667/// Used by [RenderObject.visitChildren] and [RenderObject.visitChildrenForSemantics].
668typedef RenderObjectVisitor = void Function(RenderObject child);
669
670/// Signature for a function that is called during layout.
671///
672/// Used by [RenderObject.invokeLayoutCallback].
673typedef LayoutCallback<T extends Constraints> = void Function(T constraints);
674
675/// A reference to the semantics tree.
676///
677/// The framework maintains the semantics tree (used for accessibility and
678/// indexing) only when there is at least one client holding an open
679/// [SemanticsHandle].
680///
681/// The framework notifies the client that it has updated the semantics tree by
682/// calling the [listener] callback. When the client no longer needs the
683/// semantics tree, the client can call [dispose] on the [SemanticsHandle],
684/// which stops these callbacks and closes the [SemanticsHandle]. When all the
685/// outstanding [SemanticsHandle] objects are closed, the framework stops
686/// updating the semantics tree.
687///
688/// To obtain a [SemanticsHandle], call [PipelineOwner.ensureSemantics] on the
689/// [PipelineOwner] for the render tree from which you wish to read semantics.
690/// You can obtain the [PipelineOwner] using the [RenderObject.owner] property.
691class SemanticsHandle {
692  SemanticsHandle._(this._owner, this.listener)
693      : assert(_owner != null) {
694    if (listener != null)
695      _owner.semanticsOwner.addListener(listener);
696  }
697
698  PipelineOwner _owner;
699
700  /// The callback that will be notified when the semantics tree updates.
701  final VoidCallback listener;
702
703  /// Closes the semantics handle and stops calling [listener] when the
704  /// semantics updates.
705  ///
706  /// When all the outstanding [SemanticsHandle] objects for a given
707  /// [PipelineOwner] are closed, the [PipelineOwner] will stop updating the
708  /// semantics tree.
709  @mustCallSuper
710  void dispose() {
711    assert(() {
712      if (_owner == null) {
713        throw FlutterError(
714          'SemanticsHandle has already been disposed.\n'
715          'Each SemanticsHandle should be disposed exactly once.'
716        );
717      }
718      return true;
719    }());
720    if (_owner != null) {
721      if (listener != null)
722        _owner.semanticsOwner.removeListener(listener);
723      _owner._didDisposeSemanticsHandle();
724      _owner = null;
725    }
726  }
727}
728
729/// The pipeline owner manages the rendering pipeline.
730///
731/// The pipeline owner provides an interface for driving the rendering pipeline
732/// and stores the state about which render objects have requested to be visited
733/// in each stage of the pipeline. To flush the pipeline, call the following
734/// functions in order:
735///
736/// 1. [flushLayout] updates any render objects that need to compute their
737///    layout. During this phase, the size and position of each render
738///    object is calculated. Render objects might dirty their painting or
739///    compositing state during this phase.
740/// 2. [flushCompositingBits] updates any render objects that have dirty
741///    compositing bits. During this phase, each render object learns whether
742///    any of its children require compositing. This information is used during
743///    the painting phase when selecting how to implement visual effects such as
744///    clipping. If a render object has a composited child, its needs to use a
745///    [Layer] to create the clip in order for the clip to apply to the
746///    composited child (which will be painted into its own [Layer]).
747/// 3. [flushPaint] visits any render objects that need to paint. During this
748///    phase, render objects get a chance to record painting commands into
749///    [PictureLayer]s and construct other composited [Layer]s.
750/// 4. Finally, if semantics are enabled, [flushSemantics] will compile the
751///    semantics for the render objects. This semantic information is used by
752///    assistive technology to improve the accessibility of the render tree.
753///
754/// The [RendererBinding] holds the pipeline owner for the render objects that
755/// are visible on screen. You can create other pipeline owners to manage
756/// off-screen objects, which can flush their pipelines independently of the
757/// on-screen render objects.
758class PipelineOwner {
759  /// Creates a pipeline owner.
760  ///
761  /// Typically created by the binding (e.g., [RendererBinding]), but can be
762  /// created separately from the binding to drive off-screen render objects
763  /// through the rendering pipeline.
764  PipelineOwner({
765    this.onNeedVisualUpdate,
766    this.onSemanticsOwnerCreated,
767    this.onSemanticsOwnerDisposed,
768  });
769
770  /// Called when a render object associated with this pipeline owner wishes to
771  /// update its visual appearance.
772  ///
773  /// Typical implementations of this function will schedule a task to flush the
774  /// various stages of the pipeline. This function might be called multiple
775  /// times in quick succession. Implementations should take care to discard
776  /// duplicate calls quickly.
777  final VoidCallback onNeedVisualUpdate;
778
779  /// Called whenever this pipeline owner creates a semantics object.
780  ///
781  /// Typical implementations will schedule the creation of the initial
782  /// semantics tree.
783  final VoidCallback onSemanticsOwnerCreated;
784
785  /// Called whenever this pipeline owner disposes its semantics owner.
786  ///
787  /// Typical implementations will tear down the semantics tree.
788  final VoidCallback onSemanticsOwnerDisposed;
789
790  /// Calls [onNeedVisualUpdate] if [onNeedVisualUpdate] is not null.
791  ///
792  /// Used to notify the pipeline owner that an associated render object wishes
793  /// to update its visual appearance.
794  void requestVisualUpdate() {
795    if (onNeedVisualUpdate != null)
796      onNeedVisualUpdate();
797  }
798
799  /// The unique object managed by this pipeline that has no parent.
800  ///
801  /// This object does not have to be a [RenderObject].
802  AbstractNode get rootNode => _rootNode;
803  AbstractNode _rootNode;
804  set rootNode(AbstractNode value) {
805    if (_rootNode == value)
806      return;
807    _rootNode?.detach();
808    _rootNode = value;
809    _rootNode?.attach(this);
810  }
811
812  List<RenderObject> _nodesNeedingLayout = <RenderObject>[];
813
814  /// Whether this pipeline is currently in the layout phase.
815  ///
816  /// Specifically, whether [flushLayout] is currently running.
817  ///
818  /// Only valid when asserts are enabled.
819  bool get debugDoingLayout => _debugDoingLayout;
820  bool _debugDoingLayout = false;
821
822  /// Update the layout information for all dirty render objects.
823  ///
824  /// This function is one of the core stages of the rendering pipeline. Layout
825  /// information is cleaned prior to painting so that render objects will
826  /// appear on screen in their up-to-date locations.
827  ///
828  /// See [RendererBinding] for an example of how this function is used.
829  void flushLayout() {
830    if (!kReleaseMode) {
831      Timeline.startSync('Layout', arguments: timelineWhitelistArguments);
832    }
833    assert(() {
834      _debugDoingLayout = true;
835      return true;
836    }());
837    try {
838      // TODO(ianh): assert that we're not allowing previously dirty nodes to redirty themselves
839      while (_nodesNeedingLayout.isNotEmpty) {
840        final List<RenderObject> dirtyNodes = _nodesNeedingLayout;
841        _nodesNeedingLayout = <RenderObject>[];
842        for (RenderObject node in dirtyNodes..sort((RenderObject a, RenderObject b) => a.depth - b.depth)) {
843          if (node._needsLayout && node.owner == this)
844            node._layoutWithoutResize();
845        }
846      }
847    } finally {
848      assert(() {
849        _debugDoingLayout = false;
850        return true;
851      }());
852      if (!kReleaseMode) {
853        Timeline.finishSync();
854      }
855    }
856  }
857
858  // This flag is used to allow the kinds of mutations performed by GlobalKey
859  // reparenting while a LayoutBuilder is being rebuilt and in so doing tries to
860  // move a node from another LayoutBuilder subtree that hasn't been updated
861  // yet. To set this, call [_enableMutationsToDirtySubtrees], which is called
862  // by [RenderObject.invokeLayoutCallback].
863  bool _debugAllowMutationsToDirtySubtrees = false;
864
865  // See [RenderObject.invokeLayoutCallback].
866  void _enableMutationsToDirtySubtrees(VoidCallback callback) {
867    assert(_debugDoingLayout);
868    bool oldState;
869    assert(() {
870      oldState = _debugAllowMutationsToDirtySubtrees;
871      _debugAllowMutationsToDirtySubtrees = true;
872      return true;
873    }());
874    try {
875      callback();
876    } finally {
877      assert(() {
878        _debugAllowMutationsToDirtySubtrees = oldState;
879        return true;
880      }());
881    }
882  }
883
884  final List<RenderObject> _nodesNeedingCompositingBitsUpdate = <RenderObject>[];
885  /// Updates the [RenderObject.needsCompositing] bits.
886  ///
887  /// Called as part of the rendering pipeline after [flushLayout] and before
888  /// [flushPaint].
889  void flushCompositingBits() {
890    if (!kReleaseMode) {
891      Timeline.startSync('Compositing bits');
892    }
893    _nodesNeedingCompositingBitsUpdate.sort((RenderObject a, RenderObject b) => a.depth - b.depth);
894    for (RenderObject node in _nodesNeedingCompositingBitsUpdate) {
895      if (node._needsCompositingBitsUpdate && node.owner == this)
896        node._updateCompositingBits();
897    }
898    _nodesNeedingCompositingBitsUpdate.clear();
899    if (!kReleaseMode) {
900      Timeline.finishSync();
901    }
902  }
903
904  List<RenderObject> _nodesNeedingPaint = <RenderObject>[];
905
906  /// Whether this pipeline is currently in the paint phase.
907  ///
908  /// Specifically, whether [flushPaint] is currently running.
909  ///
910  /// Only valid when asserts are enabled.
911  bool get debugDoingPaint => _debugDoingPaint;
912  bool _debugDoingPaint = false;
913
914  /// Update the display lists for all render objects.
915  ///
916  /// This function is one of the core stages of the rendering pipeline.
917  /// Painting occurs after layout and before the scene is recomposited so that
918  /// scene is composited with up-to-date display lists for every render object.
919  ///
920  /// See [RendererBinding] for an example of how this function is used.
921  void flushPaint() {
922    if (!kReleaseMode) {
923      Timeline.startSync('Paint', arguments: timelineWhitelistArguments);
924    }
925    assert(() {
926      _debugDoingPaint = true;
927      return true;
928    }());
929    try {
930      final List<RenderObject> dirtyNodes = _nodesNeedingPaint;
931      _nodesNeedingPaint = <RenderObject>[];
932      // Sort the dirty nodes in reverse order (deepest first).
933      for (RenderObject node in dirtyNodes..sort((RenderObject a, RenderObject b) => b.depth - a.depth)) {
934        assert(node._layer != null);
935        if (node._needsPaint && node.owner == this) {
936          if (node._layer.attached) {
937            PaintingContext.repaintCompositedChild(node);
938          } else {
939            node._skippedPaintingOnLayer();
940          }
941        }
942      }
943      assert(_nodesNeedingPaint.isEmpty);
944    } finally {
945      assert(() {
946        _debugDoingPaint = false;
947        return true;
948      }());
949      if (!kReleaseMode) {
950        Timeline.finishSync();
951      }
952    }
953  }
954
955  /// The object that is managing semantics for this pipeline owner, if any.
956  ///
957  /// An owner is created by [ensureSemantics]. The owner is valid for as long
958  /// there are [SemanticsHandle]s returned by [ensureSemantics] that have not
959  /// yet been disposed. Once the last handle has been disposed, the
960  /// [semanticsOwner] field will revert to null, and the previous owner will be
961  /// disposed.
962  ///
963  /// When [semanticsOwner] is null, the [PipelineOwner] skips all steps
964  /// relating to semantics.
965  SemanticsOwner get semanticsOwner => _semanticsOwner;
966  SemanticsOwner _semanticsOwner;
967
968  /// The number of clients registered to listen for semantics.
969  ///
970  /// The number is increased whenever [ensureSemantics] is called and decreased
971  /// when [SemanticsHandle.dispose] is called.
972  int get debugOutstandingSemanticsHandles => _outstandingSemanticsHandles;
973  int _outstandingSemanticsHandles = 0;
974
975  /// Opens a [SemanticsHandle] and calls [listener] whenever the semantics tree
976  /// updates.
977  ///
978  /// The [PipelineOwner] updates the semantics tree only when there are clients
979  /// that wish to use the semantics tree. These clients express their interest
980  /// by holding [SemanticsHandle] objects that notify them whenever the
981  /// semantics tree updates.
982  ///
983  /// Clients can close their [SemanticsHandle] by calling
984  /// [SemanticsHandle.dispose]. Once all the outstanding [SemanticsHandle]
985  /// objects for a given [PipelineOwner] are closed, the [PipelineOwner] stops
986  /// maintaining the semantics tree.
987  SemanticsHandle ensureSemantics({ VoidCallback listener }) {
988    _outstandingSemanticsHandles += 1;
989    if (_outstandingSemanticsHandles == 1) {
990      assert(_semanticsOwner == null);
991      _semanticsOwner = SemanticsOwner();
992      if (onSemanticsOwnerCreated != null)
993        onSemanticsOwnerCreated();
994    }
995    return SemanticsHandle._(this, listener);
996  }
997
998  void _didDisposeSemanticsHandle() {
999    assert(_semanticsOwner != null);
1000    _outstandingSemanticsHandles -= 1;
1001    if (_outstandingSemanticsHandles == 0) {
1002      _semanticsOwner.dispose();
1003      _semanticsOwner = null;
1004      if (onSemanticsOwnerDisposed != null)
1005        onSemanticsOwnerDisposed();
1006    }
1007  }
1008
1009  bool _debugDoingSemantics = false;
1010  final Set<RenderObject> _nodesNeedingSemantics = <RenderObject>{};
1011
1012  /// Update the semantics for render objects marked as needing a semantics
1013  /// update.
1014  ///
1015  /// Initially, only the root node, as scheduled by
1016  /// [RenderObject.scheduleInitialSemantics], needs a semantics update.
1017  ///
1018  /// This function is one of the core stages of the rendering pipeline. The
1019  /// semantics are compiled after painting and only after
1020  /// [RenderObject.scheduleInitialSemantics] has been called.
1021  ///
1022  /// See [RendererBinding] for an example of how this function is used.
1023  void flushSemantics() {
1024    if (_semanticsOwner == null)
1025      return;
1026    if (!kReleaseMode) {
1027      Timeline.startSync('Semantics');
1028    }
1029    assert(_semanticsOwner != null);
1030    assert(() { _debugDoingSemantics = true; return true; }());
1031    try {
1032      final List<RenderObject> nodesToProcess = _nodesNeedingSemantics.toList()
1033        ..sort((RenderObject a, RenderObject b) => a.depth - b.depth);
1034      _nodesNeedingSemantics.clear();
1035      for (RenderObject node in nodesToProcess) {
1036        if (node._needsSemanticsUpdate && node.owner == this)
1037          node._updateSemantics();
1038      }
1039      _semanticsOwner.sendSemanticsUpdate();
1040    } finally {
1041      assert(_nodesNeedingSemantics.isEmpty);
1042      assert(() { _debugDoingSemantics = false; return true; }());
1043      if (!kReleaseMode) {
1044        Timeline.finishSync();
1045      }
1046    }
1047  }
1048}
1049
1050/// An object in the render tree.
1051///
1052/// The [RenderObject] class hierarchy is the core of the rendering
1053/// library's reason for being.
1054///
1055/// [RenderObject]s have a [parent], and have a slot called [parentData] in
1056/// which the parent [RenderObject] can store child-specific data, for example,
1057/// the child position. The [RenderObject] class also implements the basic
1058/// layout and paint protocols.
1059///
1060/// The [RenderObject] class, however, does not define a child model (e.g.
1061/// whether a node has zero, one, or more children). It also doesn't define a
1062/// coordinate system (e.g. whether children are positioned in Cartesian
1063/// coordinates, in polar coordinates, etc) or a specific layout protocol (e.g.
1064/// whether the layout is width-in-height-out, or constraint-in-size-out, or
1065/// whether the parent sets the size and position of the child before or after
1066/// the child lays out, etc; or indeed whether the children are allowed to read
1067/// their parent's [parentData] slot).
1068///
1069/// The [RenderBox] subclass introduces the opinion that the layout
1070/// system uses Cartesian coordinates.
1071///
1072/// ## Writing a RenderObject subclass
1073///
1074/// In most cases, subclassing [RenderObject] itself is overkill, and
1075/// [RenderBox] would be a better starting point. However, if a render object
1076/// doesn't want to use a Cartesian coordinate system, then it should indeed
1077/// inherit from [RenderObject] directly. This allows it to define its own
1078/// layout protocol by using a new subclass of [Constraints] rather than using
1079/// [BoxConstraints], and by potentially using an entirely new set of objects
1080/// and values to represent the result of the output rather than just a [Size].
1081/// This increased flexibility comes at the cost of not being able to rely on
1082/// the features of [RenderBox]. For example, [RenderBox] implements an
1083/// intrinsic sizing protocol that allows you to measure a child without fully
1084/// laying it out, in such a way that if that child changes size, the parent
1085/// will be laid out again (to take into account the new dimensions of the
1086/// child). This is a subtle and bug-prone feature to get right.
1087///
1088/// Most aspects of writing a [RenderBox] apply to writing a [RenderObject] as
1089/// well, and therefore the discussion at [RenderBox] is recommended background
1090/// reading. The main differences are around layout and hit testing, since those
1091/// are the aspects that [RenderBox] primarily specializes.
1092///
1093/// ### Layout
1094///
1095/// A layout protocol begins with a subclass of [Constraints]. See the
1096/// discussion at [Constraints] for more information on how to write a
1097/// [Constraints] subclass.
1098///
1099/// The [performLayout] method should take the [constraints], and apply them.
1100/// The output of the layout algorithm is fields set on the object that describe
1101/// the geometry of the object for the purposes of the parent's layout. For
1102/// example, with [RenderBox] the output is the [RenderBox.size] field. This
1103/// output should only be read by the parent if the parent specified
1104/// `parentUsesSize` as true when calling [layout] on the child.
1105///
1106/// Anytime anything changes on a render object that would affect the layout of
1107/// that object, it should call [markNeedsLayout].
1108///
1109/// ### Hit Testing
1110///
1111/// Hit testing is even more open-ended than layout. There is no method to
1112/// override, you are expected to provide one.
1113///
1114/// The general behavior of your hit-testing method should be similar to the
1115/// behavior described for [RenderBox]. The main difference is that the input
1116/// need not be an [Offset]. You are also allowed to use a different subclass of
1117/// [HitTestEntry] when adding entries to the [HitTestResult]. When the
1118/// [handleEvent] method is called, the same object that was added to the
1119/// [HitTestResult] will be passed in, so it can be used to track information
1120/// like the precise coordinate of the hit, in whatever coordinate system is
1121/// used by the new layout protocol.
1122///
1123/// ### Adapting from one protocol to another
1124///
1125/// In general, the root of a Flutter render object tree is a [RenderView]. This
1126/// object has a single child, which must be a [RenderBox]. Thus, if you want to
1127/// have a custom [RenderObject] subclass in the render tree, you have two
1128/// choices: you either need to replace the [RenderView] itself, or you need to
1129/// have a [RenderBox] that has your class as its child. (The latter is the much
1130/// more common case.)
1131///
1132/// This [RenderBox] subclass converts from the box protocol to the protocol of
1133/// your class.
1134///
1135/// In particular, this means that for hit testing it overrides
1136/// [RenderBox.hitTest], and calls whatever method you have in your class for
1137/// hit testing.
1138///
1139/// Similarly, it overrides [performLayout] to create a [Constraints] object
1140/// appropriate for your class and passes that to the child's [layout] method.
1141///
1142/// ### Layout interactions between render objects
1143///
1144/// In general, the layout of a render object should only depend on the output of
1145/// its child's layout, and then only if `parentUsesSize` is set to true in the
1146/// [layout] call. Furthermore, if it is set to true, the parent must call the
1147/// child's [layout] if the child is to be rendered, because otherwise the
1148/// parent will not be notified when the child changes its layout outputs.
1149///
1150/// It is possible to set up render object protocols that transfer additional
1151/// information. For example, in the [RenderBox] protocol you can query your
1152/// children's intrinsic dimensions and baseline geometry. However, if this is
1153/// done then it is imperative that the child call [markNeedsLayout] on the
1154/// parent any time that additional information changes, if the parent used it
1155/// in the last layout phase. For an example of how to implement this, see the
1156/// [RenderBox.markNeedsLayout] method. It overrides
1157/// [RenderObject.markNeedsLayout] so that if a parent has queried the intrinsic
1158/// or baseline information, it gets marked dirty whenever the child's geometry
1159/// changes.
1160abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin implements HitTestTarget {
1161  /// Initializes internal fields for subclasses.
1162  RenderObject() {
1163    _needsCompositing = isRepaintBoundary || alwaysNeedsCompositing;
1164  }
1165
1166  /// Cause the entire subtree rooted at the given [RenderObject] to be marked
1167  /// dirty for layout, paint, etc, so that the effects of a hot reload can be
1168  /// seen, or so that the effect of changing a global debug flag (such as
1169  /// [debugPaintSizeEnabled]) can be applied.
1170  ///
1171  /// This is called by the [RendererBinding] in response to the
1172  /// `ext.flutter.reassemble` hook, which is used by development tools when the
1173  /// application code has changed, to cause the widget tree to pick up any
1174  /// changed implementations.
1175  ///
1176  /// This is expensive and should not be called except during development.
1177  ///
1178  /// See also:
1179  ///
1180  ///  * [BindingBase.reassembleApplication]
1181  void reassemble() {
1182    markNeedsLayout();
1183    markNeedsCompositingBitsUpdate();
1184    markNeedsPaint();
1185    markNeedsSemanticsUpdate();
1186    visitChildren((RenderObject child) {
1187      child.reassemble();
1188    });
1189  }
1190
1191  // LAYOUT
1192
1193  /// Data for use by the parent render object.
1194  ///
1195  /// The parent data is used by the render object that lays out this object
1196  /// (typically this object's parent in the render tree) to store information
1197  /// relevant to itself and to any other nodes who happen to know exactly what
1198  /// the data means. The parent data is opaque to the child.
1199  ///
1200  ///  * The parent data field must not be directly set, except by calling
1201  ///    [setupParentData] on the parent node.
1202  ///  * The parent data can be set before the child is added to the parent, by
1203  ///    calling [setupParentData] on the future parent node.
1204  ///  * The conventions for using the parent data depend on the layout protocol
1205  ///    used between the parent and child. For example, in box layout, the
1206  ///    parent data is completely opaque but in sector layout the child is
1207  ///    permitted to read some fields of the parent data.
1208  ParentData parentData;
1209
1210  /// Override to setup parent data correctly for your children.
1211  ///
1212  /// You can call this function to set up the parent data for child before the
1213  /// child is added to the parent's child list.
1214  void setupParentData(covariant RenderObject child) {
1215    assert(_debugCanPerformMutations);
1216    if (child.parentData is! ParentData)
1217      child.parentData = ParentData();
1218  }
1219
1220  /// Called by subclasses when they decide a render object is a child.
1221  ///
1222  /// Only for use by subclasses when changing their child lists. Calling this
1223  /// in other cases will lead to an inconsistent tree and probably cause crashes.
1224  @override
1225  void adoptChild(RenderObject child) {
1226    assert(_debugCanPerformMutations);
1227    assert(child != null);
1228    setupParentData(child);
1229    markNeedsLayout();
1230    markNeedsCompositingBitsUpdate();
1231    markNeedsSemanticsUpdate();
1232    super.adoptChild(child);
1233  }
1234
1235  /// Called by subclasses when they decide a render object is no longer a child.
1236  ///
1237  /// Only for use by subclasses when changing their child lists. Calling this
1238  /// in other cases will lead to an inconsistent tree and probably cause crashes.
1239  @override
1240  void dropChild(RenderObject child) {
1241    assert(_debugCanPerformMutations);
1242    assert(child != null);
1243    assert(child.parentData != null);
1244    child._cleanRelayoutBoundary();
1245    child.parentData.detach();
1246    child.parentData = null;
1247    super.dropChild(child);
1248    markNeedsLayout();
1249    markNeedsCompositingBitsUpdate();
1250    markNeedsSemanticsUpdate();
1251  }
1252
1253  /// Calls visitor for each immediate child of this render object.
1254  ///
1255  /// Override in subclasses with children and call the visitor for each child.
1256  void visitChildren(RenderObjectVisitor visitor) { }
1257
1258  /// The object responsible for creating this render object.
1259  ///
1260  /// Used in debug messages.
1261  dynamic debugCreator;
1262
1263  void _debugReportException(String method, dynamic exception, StackTrace stack) {
1264    FlutterError.reportError(FlutterErrorDetailsForRendering(
1265      exception: exception,
1266      stack: stack,
1267      library: 'rendering library',
1268      context: ErrorDescription('during $method()'),
1269      renderObject: this,
1270      informationCollector: () sync* {
1271        if (debugCreator != null)
1272          yield DiagnosticsDebugCreator(debugCreator);
1273        yield describeForError('The following RenderObject was being processed when the exception was fired');
1274        // TODO(jacobr): this error message has a code smell. Consider whether
1275        // displaying the truncated children is really useful for command line
1276        // users. Inspector users can see the full tree by clicking on the
1277        // render object so this may not be that useful.
1278        yield describeForError('RenderObject', style: DiagnosticsTreeStyle.truncateChildren);
1279      }
1280    ));
1281  }
1282
1283  /// Whether [performResize] for this render object is currently running.
1284  ///
1285  /// Only valid when asserts are enabled. In release builds, always returns
1286  /// false.
1287  bool get debugDoingThisResize => _debugDoingThisResize;
1288  bool _debugDoingThisResize = false;
1289
1290  /// Whether [performLayout] for this render object is currently running.
1291  ///
1292  /// Only valid when asserts are enabled. In release builds, always returns
1293  /// false.
1294  bool get debugDoingThisLayout => _debugDoingThisLayout;
1295  bool _debugDoingThisLayout = false;
1296
1297  /// The render object that is actively computing layout.
1298  ///
1299  /// Only valid when asserts are enabled. In release builds, always returns
1300  /// null.
1301  static RenderObject get debugActiveLayout => _debugActiveLayout;
1302  static RenderObject _debugActiveLayout;
1303
1304  /// Whether the parent render object is permitted to use this render object's
1305  /// size.
1306  ///
1307  /// Determined by the `parentUsesSize` parameter to [layout].
1308  ///
1309  /// Only valid when asserts are enabled. In release builds, always returns
1310  /// null.
1311  bool get debugCanParentUseSize => _debugCanParentUseSize;
1312  bool _debugCanParentUseSize;
1313
1314  bool _debugMutationsLocked = false;
1315
1316  /// Whether tree mutations are currently permitted.
1317  ///
1318  /// Only valid when asserts are enabled. In release builds, always returns
1319  /// null.
1320  bool get _debugCanPerformMutations {
1321    bool result;
1322    assert(() {
1323      RenderObject node = this;
1324      while (true) {
1325        if (node._doingThisLayoutWithCallback) {
1326          result = true;
1327          break;
1328        }
1329        if (owner != null && owner._debugAllowMutationsToDirtySubtrees && node._needsLayout) {
1330          result = true;
1331          break;
1332        }
1333        if (node._debugMutationsLocked) {
1334          result = false;
1335          break;
1336        }
1337        if (node.parent is! RenderObject) {
1338          result = true;
1339          break;
1340        }
1341        node = node.parent;
1342      }
1343      return true;
1344    }());
1345    return result;
1346  }
1347
1348  @override
1349  PipelineOwner get owner => super.owner;
1350
1351  @override
1352  void attach(PipelineOwner owner) {
1353    super.attach(owner);
1354    // If the node was dirtied in some way while unattached, make sure to add
1355    // it to the appropriate dirty list now that an owner is available
1356    if (_needsLayout && _relayoutBoundary != null) {
1357      // Don't enter this block if we've never laid out at all;
1358      // scheduleInitialLayout() will handle it
1359      _needsLayout = false;
1360      markNeedsLayout();
1361    }
1362    if (_needsCompositingBitsUpdate) {
1363      _needsCompositingBitsUpdate = false;
1364      markNeedsCompositingBitsUpdate();
1365    }
1366    if (_needsPaint && _layer != null) {
1367      // Don't enter this block if we've never painted at all;
1368      // scheduleInitialPaint() will handle it
1369      _needsPaint = false;
1370      markNeedsPaint();
1371    }
1372    if (_needsSemanticsUpdate && _semanticsConfiguration.isSemanticBoundary) {
1373      // Don't enter this block if we've never updated semantics at all;
1374      // scheduleInitialSemantics() will handle it
1375      _needsSemanticsUpdate = false;
1376      markNeedsSemanticsUpdate();
1377    }
1378  }
1379
1380  /// Whether this render object's layout information is dirty.
1381  ///
1382  /// This is only set in debug mode. In general, render objects should not need
1383  /// to condition their runtime behavior on whether they are dirty or not,
1384  /// since they should only be marked dirty immediately prior to being laid
1385  /// out and painted.
1386  ///
1387  /// It is intended to be used by tests and asserts.
1388  bool get debugNeedsLayout {
1389    bool result;
1390    assert(() {
1391      result = _needsLayout;
1392      return true;
1393    }());
1394    return result;
1395  }
1396  bool _needsLayout = true;
1397
1398  RenderObject _relayoutBoundary;
1399  bool _doingThisLayoutWithCallback = false;
1400
1401  /// The layout constraints most recently supplied by the parent.
1402  @protected
1403  Constraints get constraints => _constraints;
1404  Constraints _constraints;
1405
1406  /// Verify that the object's constraints are being met. Override
1407  /// this function in a subclass to verify that your state matches
1408  /// the constraints object. This function is only called in checked
1409  /// mode and only when needsLayout is false. If the constraints are
1410  /// not met, it should assert or throw an exception.
1411  @protected
1412  void debugAssertDoesMeetConstraints();
1413
1414  /// When true, debugAssertDoesMeetConstraints() is currently
1415  /// executing asserts for verifying the consistent behavior of
1416  /// intrinsic dimensions methods.
1417  ///
1418  /// This should only be set by debugAssertDoesMeetConstraints()
1419  /// implementations. It is used by tests to selectively ignore
1420  /// custom layout callbacks. It should not be set outside of
1421  /// debugAssertDoesMeetConstraints(), and should not be checked in
1422  /// release mode (where it will always be false).
1423  static bool debugCheckingIntrinsics = false;
1424  bool _debugSubtreeRelayoutRootAlreadyMarkedNeedsLayout() {
1425    if (_relayoutBoundary == null)
1426      return true; // we haven't yet done layout even once, so there's nothing for us to do
1427    RenderObject node = this;
1428    while (node != _relayoutBoundary) {
1429      assert(node._relayoutBoundary == _relayoutBoundary);
1430      assert(node.parent != null);
1431      node = node.parent;
1432      if ((!node._needsLayout) && (!node._debugDoingThisLayout))
1433        return false;
1434    }
1435    assert(node._relayoutBoundary == node);
1436    return true;
1437  }
1438
1439  /// Mark this render object's layout information as dirty, and either register
1440  /// this object with its [PipelineOwner], or defer to the parent, depending on
1441  /// whether this object is a relayout boundary or not respectively.
1442  ///
1443  /// ## Background
1444  ///
1445  /// Rather than eagerly updating layout information in response to writes into
1446  /// a render object, we instead mark the layout information as dirty, which
1447  /// schedules a visual update. As part of the visual update, the rendering
1448  /// pipeline updates the render object's layout information.
1449  ///
1450  /// This mechanism batches the layout work so that multiple sequential writes
1451  /// are coalesced, removing redundant computation.
1452  ///
1453  /// If a render object's parent indicates that it uses the size of one of its
1454  /// render object children when computing its layout information, this
1455  /// function, when called for the child, will also mark the parent as needing
1456  /// layout. In that case, since both the parent and the child need to have
1457  /// their layout recomputed, the pipeline owner is only notified about the
1458  /// parent; when the parent is laid out, it will call the child's [layout]
1459  /// method and thus the child will be laid out as well.
1460  ///
1461  /// Once [markNeedsLayout] has been called on a render object,
1462  /// [debugNeedsLayout] returns true for that render object until just after
1463  /// the pipeline owner has called [layout] on the render object.
1464  ///
1465  /// ## Special cases
1466  ///
1467  /// Some subclasses of [RenderObject], notably [RenderBox], have other
1468  /// situations in which the parent needs to be notified if the child is
1469  /// dirtied (e.g., if the child's intrinsic dimensions or baseline changes).
1470  /// Such subclasses override markNeedsLayout and either call
1471  /// `super.markNeedsLayout()`, in the normal case, or call
1472  /// [markParentNeedsLayout], in the case where the parent needs to be laid out
1473  /// as well as the child.
1474  ///
1475  /// If [sizedByParent] has changed, calls
1476  /// [markNeedsLayoutForSizedByParentChange] instead of [markNeedsLayout].
1477  void markNeedsLayout() {
1478    assert(_debugCanPerformMutations);
1479    if (_needsLayout) {
1480      assert(_debugSubtreeRelayoutRootAlreadyMarkedNeedsLayout());
1481      return;
1482    }
1483    assert(_relayoutBoundary != null);
1484    if (_relayoutBoundary != this) {
1485      markParentNeedsLayout();
1486    } else {
1487      _needsLayout = true;
1488      if (owner != null) {
1489        assert(() {
1490          if (debugPrintMarkNeedsLayoutStacks)
1491            debugPrintStack(label: 'markNeedsLayout() called for $this');
1492          return true;
1493        }());
1494        owner._nodesNeedingLayout.add(this);
1495        owner.requestVisualUpdate();
1496      }
1497    }
1498  }
1499
1500  /// Mark this render object's layout information as dirty, and then defer to
1501  /// the parent.
1502  ///
1503  /// This function should only be called from [markNeedsLayout] or
1504  /// [markNeedsLayoutForSizedByParentChange] implementations of subclasses that
1505  /// introduce more reasons for deferring the handling of dirty layout to the
1506  /// parent. See [markNeedsLayout] for details.
1507  ///
1508  /// Only call this if [parent] is not null.
1509  @protected
1510  void markParentNeedsLayout() {
1511    _needsLayout = true;
1512    final RenderObject parent = this.parent;
1513    if (!_doingThisLayoutWithCallback) {
1514      parent.markNeedsLayout();
1515    } else {
1516      assert(parent._debugDoingThisLayout);
1517    }
1518    assert(parent == this.parent);
1519  }
1520
1521  /// Mark this render object's layout information as dirty (like
1522  /// [markNeedsLayout]), and additionally also handle any necessary work to
1523  /// handle the case where [sizedByParent] has changed value.
1524  ///
1525  /// This should be called whenever [sizedByParent] might have changed.
1526  ///
1527  /// Only call this if [parent] is not null.
1528  void markNeedsLayoutForSizedByParentChange() {
1529    markNeedsLayout();
1530    markParentNeedsLayout();
1531  }
1532
1533  void _cleanRelayoutBoundary() {
1534    if (_relayoutBoundary != this) {
1535      _relayoutBoundary = null;
1536      _needsLayout = true;
1537      visitChildren((RenderObject child) {
1538        child._cleanRelayoutBoundary();
1539      });
1540    }
1541  }
1542
1543  /// Bootstrap the rendering pipeline by scheduling the very first layout.
1544  ///
1545  /// Requires this render object to be attached and that this render object
1546  /// is the root of the render tree.
1547  ///
1548  /// See [RenderView] for an example of how this function is used.
1549  void scheduleInitialLayout() {
1550    assert(attached);
1551    assert(parent is! RenderObject);
1552    assert(!owner._debugDoingLayout);
1553    assert(_relayoutBoundary == null);
1554    _relayoutBoundary = this;
1555    assert(() {
1556      _debugCanParentUseSize = false;
1557      return true;
1558    }());
1559    owner._nodesNeedingLayout.add(this);
1560  }
1561
1562  void _layoutWithoutResize() {
1563    assert(_relayoutBoundary == this);
1564    RenderObject debugPreviousActiveLayout;
1565    assert(!_debugMutationsLocked);
1566    assert(!_doingThisLayoutWithCallback);
1567    assert(_debugCanParentUseSize != null);
1568    assert(() {
1569      _debugMutationsLocked = true;
1570      _debugDoingThisLayout = true;
1571      debugPreviousActiveLayout = _debugActiveLayout;
1572      _debugActiveLayout = this;
1573      if (debugPrintLayouts)
1574        debugPrint('Laying out (without resize) $this');
1575      return true;
1576    }());
1577    try {
1578      performLayout();
1579      markNeedsSemanticsUpdate();
1580    } catch (e, stack) {
1581      _debugReportException('performLayout', e, stack);
1582    }
1583    assert(() {
1584      _debugActiveLayout = debugPreviousActiveLayout;
1585      _debugDoingThisLayout = false;
1586      _debugMutationsLocked = false;
1587      return true;
1588    }());
1589    _needsLayout = false;
1590    markNeedsPaint();
1591  }
1592
1593  /// Compute the layout for this render object.
1594  ///
1595  /// This method is the main entry point for parents to ask their children to
1596  /// update their layout information. The parent passes a constraints object,
1597  /// which informs the child as to which layouts are permissible. The child is
1598  /// required to obey the given constraints.
1599  ///
1600  /// If the parent reads information computed during the child's layout, the
1601  /// parent must pass true for `parentUsesSize`. In that case, the parent will
1602  /// be marked as needing layout whenever the child is marked as needing layout
1603  /// because the parent's layout information depends on the child's layout
1604  /// information. If the parent uses the default value (false) for
1605  /// `parentUsesSize`, the child can change its layout information (subject to
1606  /// the given constraints) without informing the parent.
1607  ///
1608  /// Subclasses should not override [layout] directly. Instead, they should
1609  /// override [performResize] and/or [performLayout]. The [layout] method
1610  /// delegates the actual work to [performResize] and [performLayout].
1611  ///
1612  /// The parent's [performLayout] method should call the [layout] of all its
1613  /// children unconditionally. It is the [layout] method's responsibility (as
1614  /// implemented here) to return early if the child does not need to do any
1615  /// work to update its layout information.
1616  void layout(Constraints constraints, { bool parentUsesSize = false }) {
1617    assert(constraints != null);
1618    assert(constraints.debugAssertIsValid(
1619      isAppliedConstraint: true,
1620      informationCollector: () sync* {
1621        final List<String> stack = StackTrace.current.toString().split('\n');
1622        int targetFrame;
1623        final Pattern layoutFramePattern = RegExp(r'^#[0-9]+ +RenderObject.layout \(');
1624        for (int i = 0; i < stack.length; i += 1) {
1625          if (layoutFramePattern.matchAsPrefix(stack[i]) != null) {
1626            targetFrame = i + 1;
1627            break;
1628          }
1629        }
1630        if (targetFrame != null && targetFrame < stack.length) {
1631          final Pattern targetFramePattern = RegExp(r'^#[0-9]+ +(.+)$');
1632          final Match targetFrameMatch = targetFramePattern.matchAsPrefix(stack[targetFrame]);
1633          final String problemFunction = (targetFrameMatch != null && targetFrameMatch.groupCount > 0) ? targetFrameMatch.group(1) : stack[targetFrame].trim();
1634          // TODO(jacobr): this case is similar to displaying a single stack frame.
1635          yield ErrorDescription(
1636            'These invalid constraints were provided to $runtimeType\'s layout() '
1637            'function by the following function, which probably computed the '
1638            'invalid constraints in question:\n'
1639            '  $problemFunction'
1640          );
1641        }
1642      },
1643    ));
1644    assert(!_debugDoingThisResize);
1645    assert(!_debugDoingThisLayout);
1646    RenderObject relayoutBoundary;
1647    if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! RenderObject) {
1648      relayoutBoundary = this;
1649    } else {
1650      final RenderObject parent = this.parent;
1651      relayoutBoundary = parent._relayoutBoundary;
1652    }
1653    assert(() {
1654      _debugCanParentUseSize = parentUsesSize;
1655      return true;
1656    }());
1657    if (!_needsLayout && constraints == _constraints && relayoutBoundary == _relayoutBoundary) {
1658      assert(() {
1659        // in case parentUsesSize changed since the last invocation, set size
1660        // to itself, so it has the right internal debug values.
1661        _debugDoingThisResize = sizedByParent;
1662        _debugDoingThisLayout = !sizedByParent;
1663        final RenderObject debugPreviousActiveLayout = _debugActiveLayout;
1664        _debugActiveLayout = this;
1665        debugResetSize();
1666        _debugActiveLayout = debugPreviousActiveLayout;
1667        _debugDoingThisLayout = false;
1668        _debugDoingThisResize = false;
1669        return true;
1670      }());
1671      return;
1672    }
1673    _constraints = constraints;
1674    _relayoutBoundary = relayoutBoundary;
1675    assert(!_debugMutationsLocked);
1676    assert(!_doingThisLayoutWithCallback);
1677    assert(() {
1678      _debugMutationsLocked = true;
1679      if (debugPrintLayouts)
1680        debugPrint('Laying out (${sizedByParent ? "with separate resize" : "with resize allowed"}) $this');
1681      return true;
1682    }());
1683    if (sizedByParent) {
1684      assert(() { _debugDoingThisResize = true; return true; }());
1685      try {
1686        performResize();
1687        assert(() { debugAssertDoesMeetConstraints(); return true; }());
1688      } catch (e, stack) {
1689        _debugReportException('performResize', e, stack);
1690      }
1691      assert(() { _debugDoingThisResize = false; return true; }());
1692    }
1693    RenderObject debugPreviousActiveLayout;
1694    assert(() {
1695      _debugDoingThisLayout = true;
1696      debugPreviousActiveLayout = _debugActiveLayout;
1697      _debugActiveLayout = this;
1698      return true;
1699    }());
1700    try {
1701      performLayout();
1702      markNeedsSemanticsUpdate();
1703      assert(() { debugAssertDoesMeetConstraints(); return true; }());
1704    } catch (e, stack) {
1705      _debugReportException('performLayout', e, stack);
1706    }
1707    assert(() {
1708      _debugActiveLayout = debugPreviousActiveLayout;
1709      _debugDoingThisLayout = false;
1710      _debugMutationsLocked = false;
1711      return true;
1712    }());
1713    _needsLayout = false;
1714    markNeedsPaint();
1715  }
1716
1717  /// If a subclass has a "size" (the state controlled by `parentUsesSize`,
1718  /// whatever it is in the subclass, e.g. the actual `size` property of
1719  /// [RenderBox]), and the subclass verifies that in checked mode this "size"
1720  /// property isn't used when [debugCanParentUseSize] isn't set, then that
1721  /// subclass should override [debugResetSize] to reapply the current values of
1722  /// [debugCanParentUseSize] to that state.
1723  @protected
1724  void debugResetSize() { }
1725
1726  /// Whether the constraints are the only input to the sizing algorithm (in
1727  /// particular, child nodes have no impact).
1728  ///
1729  /// Returning false is always correct, but returning true can be more
1730  /// efficient when computing the size of this render object because we don't
1731  /// need to recompute the size if the constraints don't change.
1732  ///
1733  /// Typically, subclasses will always return the same value. If the value can
1734  /// change, then, when it does change, the subclass should make sure to call
1735  /// [markNeedsLayoutForSizedByParentChange].
1736  @protected
1737  bool get sizedByParent => false;
1738
1739  /// Updates the render objects size using only the constraints.
1740  ///
1741  /// Do not call this function directly: call [layout] instead. This function
1742  /// is called by [layout] when there is actually work to be done by this
1743  /// render object during layout. The layout constraints provided by your
1744  /// parent are available via the [constraints] getter.
1745  ///
1746  /// Subclasses that set [sizedByParent] to true should override this method
1747  /// to compute their size.
1748  ///
1749  /// This function is called only if [sizedByParent] is true.
1750  @protected
1751  void performResize();
1752
1753  /// Do the work of computing the layout for this render object.
1754  ///
1755  /// Do not call this function directly: call [layout] instead. This function
1756  /// is called by [layout] when there is actually work to be done by this
1757  /// render object during layout. The layout constraints provided by your
1758  /// parent are available via the [constraints] getter.
1759  ///
1760  /// If [sizedByParent] is true, then this function should not actually change
1761  /// the dimensions of this render object. Instead, that work should be done by
1762  /// [performResize]. If [sizedByParent] is false, then this function should
1763  /// both change the dimensions of this render object and instruct its children
1764  /// to layout.
1765  ///
1766  /// In implementing this function, you must call [layout] on each of your
1767  /// children, passing true for parentUsesSize if your layout information is
1768  /// dependent on your child's layout information. Passing true for
1769  /// parentUsesSize ensures that this render object will undergo layout if the
1770  /// child undergoes layout. Otherwise, the child can change its layout
1771  /// information without informing this render object.
1772  @protected
1773  void performLayout();
1774
1775  /// Allows mutations to be made to this object's child list (and any
1776  /// descendants) as well as to any other dirty nodes in the render tree owned
1777  /// by the same [PipelineOwner] as this object. The `callback` argument is
1778  /// invoked synchronously, and the mutations are allowed only during that
1779  /// callback's execution.
1780  ///
1781  /// This exists to allow child lists to be built on-demand during layout (e.g.
1782  /// based on the object's size), and to enable nodes to be moved around the
1783  /// tree as this happens (e.g. to handle [GlobalKey] reparenting), while still
1784  /// ensuring that any particular node is only laid out once per frame.
1785  ///
1786  /// Calling this function disables a number of assertions that are intended to
1787  /// catch likely bugs. As such, using this function is generally discouraged.
1788  ///
1789  /// This function can only be called during layout.
1790  @protected
1791  void invokeLayoutCallback<T extends Constraints>(LayoutCallback<T> callback) {
1792    assert(_debugMutationsLocked);
1793    assert(_debugDoingThisLayout);
1794    assert(!_doingThisLayoutWithCallback);
1795    _doingThisLayoutWithCallback = true;
1796    try {
1797      owner._enableMutationsToDirtySubtrees(() { callback(constraints); });
1798    } finally {
1799      _doingThisLayoutWithCallback = false;
1800    }
1801  }
1802
1803  /// Rotate this render object (not yet implemented).
1804  void rotate({
1805    int oldAngle, // 0..3
1806    int newAngle, // 0..3
1807    Duration time,
1808  }) { }
1809
1810  // when the parent has rotated (e.g. when the screen has been turned
1811  // 90 degrees), immediately prior to layout() being called for the
1812  // new dimensions, rotate() is called with the old and new angles.
1813  // The next time paint() is called, the coordinate space will have
1814  // been rotated N quarter-turns clockwise, where:
1815  //    N = newAngle-oldAngle
1816  // ...but the rendering is expected to remain the same, pixel for
1817  // pixel, on the output device. Then, the layout() method or
1818  // equivalent will be called.
1819
1820
1821  // PAINTING
1822
1823  /// Whether [paint] for this render object is currently running.
1824  ///
1825  /// Only valid when asserts are enabled. In release builds, always returns
1826  /// false.
1827  bool get debugDoingThisPaint => _debugDoingThisPaint;
1828  bool _debugDoingThisPaint = false;
1829
1830  /// The render object that is actively painting.
1831  ///
1832  /// Only valid when asserts are enabled. In release builds, always returns
1833  /// null.
1834  static RenderObject get debugActivePaint => _debugActivePaint;
1835  static RenderObject _debugActivePaint;
1836
1837  /// Whether this render object repaints separately from its parent.
1838  ///
1839  /// Override this in subclasses to indicate that instances of your class ought
1840  /// to repaint independently. For example, render objects that repaint
1841  /// frequently might want to repaint themselves without requiring their parent
1842  /// to repaint.
1843  ///
1844  /// If this getter returns true, the [paintBounds] are applied to this object
1845  /// and all descendants. The framework automatically creates an [OffsetLayer]
1846  /// and assigns it to the [layer] field. Render objects that declare
1847  /// themselves as repaint boundaries must not replace the layer created by
1848  /// the framework.
1849  ///
1850  /// Warning: This getter must not change value over the lifetime of this object.
1851  bool get isRepaintBoundary => false;
1852
1853  /// Called, in checked mode, if [isRepaintBoundary] is true, when either the
1854  /// this render object or its parent attempt to paint.
1855  ///
1856  /// This can be used to record metrics about whether the node should actually
1857  /// be a repaint boundary.
1858  void debugRegisterRepaintBoundaryPaint({ bool includedParent = true, bool includedChild = false }) { }
1859
1860  /// Whether this render object always needs compositing.
1861  ///
1862  /// Override this in subclasses to indicate that your paint function always
1863  /// creates at least one composited layer. For example, videos should return
1864  /// true if they use hardware decoders.
1865  ///
1866  /// You must call [markNeedsCompositingBitsUpdate] if the value of this getter
1867  /// changes. (This is implied when [adoptChild] or [dropChild] are called.)
1868  @protected
1869  bool get alwaysNeedsCompositing => false;
1870
1871  /// The compositing layer that this render object uses to repaint.
1872  ///
1873  /// If this render object is not a repaint boundary, it is the responsibility
1874  /// of the [paint] method to populate this field. If [needsCompositing] is
1875  /// true, this field may be populated with the root-most layer used by the
1876  /// render object implementation. When repainting, instead of creating a new
1877  /// layer the render object may update the layer stored in this field for better
1878  /// performance. It is also OK to leave this field as null and create a new
1879  /// layer on every repaint, but without the performance benefit. If
1880  /// [needsCompositing] is false, this field must be set to null either by
1881  /// never populating this field, or by setting it to null when the value of
1882  /// [needsCompositing] changes from true to false.
1883  ///
1884  /// If this render object is a repaint boundary, the framework automatically
1885  /// creates an [OffsetLayer] and populates this field prior to calling the
1886  /// [paint] method. The [paint] method must not replace the value of this
1887  /// field.
1888  @protected
1889  ContainerLayer get layer {
1890    assert(!isRepaintBoundary || (_layer == null || _layer is OffsetLayer));
1891    return _layer;
1892  }
1893
1894  @protected
1895  set layer(ContainerLayer newLayer) {
1896    assert(
1897      !isRepaintBoundary,
1898      'Attempted to set a layer to a repaint boundary render object.\n'
1899      'The framework creates and assigns an OffsetLayer to a repaint '
1900      'boundary automatically.',
1901    );
1902    _layer = newLayer;
1903  }
1904  ContainerLayer _layer;
1905
1906  /// In debug mode, the compositing layer that this render object uses to repaint.
1907  ///
1908  /// This getter is intended for debugging purposes only. In release builds, it
1909  /// always returns null. In debug builds, it returns the layer even if the layer
1910  /// is dirty.
1911  ///
1912  /// For production code, consider [layer].
1913  ContainerLayer get debugLayer {
1914    ContainerLayer result;
1915    assert(() {
1916      result = _layer;
1917      return true;
1918    }());
1919    return result;
1920  }
1921
1922  bool _needsCompositingBitsUpdate = false; // set to true when a child is added
1923  /// Mark the compositing state for this render object as dirty.
1924  ///
1925  /// This is called to indicate that the value for [needsCompositing] needs to
1926  /// be recomputed during the next [PipelineOwner.flushCompositingBits] engine
1927  /// phase.
1928  ///
1929  /// When the subtree is mutated, we need to recompute our
1930  /// [needsCompositing] bit, and some of our ancestors need to do the
1931  /// same (in case ours changed in a way that will change theirs). To
1932  /// this end, [adoptChild] and [dropChild] call this method, and, as
1933  /// necessary, this method calls the parent's, etc, walking up the
1934  /// tree to mark all the nodes that need updating.
1935  ///
1936  /// This method does not schedule a rendering frame, because since
1937  /// it cannot be the case that _only_ the compositing bits changed,
1938  /// something else will have scheduled a frame for us.
1939  void markNeedsCompositingBitsUpdate() {
1940    if (_needsCompositingBitsUpdate)
1941      return;
1942    _needsCompositingBitsUpdate = true;
1943    if (parent is RenderObject) {
1944      final RenderObject parent = this.parent;
1945      if (parent._needsCompositingBitsUpdate)
1946        return;
1947      if (!isRepaintBoundary && !parent.isRepaintBoundary) {
1948        parent.markNeedsCompositingBitsUpdate();
1949        return;
1950      }
1951    }
1952    assert(() {
1953      final AbstractNode parent = this.parent;
1954      if (parent is RenderObject)
1955        return parent._needsCompositing;
1956      return true;
1957    }());
1958    // parent is fine (or there isn't one), but we are dirty
1959    if (owner != null)
1960      owner._nodesNeedingCompositingBitsUpdate.add(this);
1961  }
1962
1963  bool _needsCompositing; // initialized in the constructor
1964  /// Whether we or one of our descendants has a compositing layer.
1965  ///
1966  /// If this node needs compositing as indicated by this bit, then all ancestor
1967  /// nodes will also need compositing.
1968  ///
1969  /// Only legal to call after [PipelineOwner.flushLayout] and
1970  /// [PipelineOwner.flushCompositingBits] have been called.
1971  bool get needsCompositing {
1972    assert(!_needsCompositingBitsUpdate); // make sure we don't use this bit when it is dirty
1973    return _needsCompositing;
1974  }
1975
1976  void _updateCompositingBits() {
1977    if (!_needsCompositingBitsUpdate)
1978      return;
1979    final bool oldNeedsCompositing = _needsCompositing;
1980    _needsCompositing = false;
1981    visitChildren((RenderObject child) {
1982      child._updateCompositingBits();
1983      if (child.needsCompositing)
1984        _needsCompositing = true;
1985    });
1986    if (isRepaintBoundary || alwaysNeedsCompositing)
1987      _needsCompositing = true;
1988    if (oldNeedsCompositing != _needsCompositing)
1989      markNeedsPaint();
1990    _needsCompositingBitsUpdate = false;
1991  }
1992
1993  /// Whether this render object's paint information is dirty.
1994  ///
1995  /// This is only set in debug mode. In general, render objects should not need
1996  /// to condition their runtime behavior on whether they are dirty or not,
1997  /// since they should only be marked dirty immediately prior to being laid
1998  /// out and painted.
1999  ///
2000  /// It is intended to be used by tests and asserts.
2001  ///
2002  /// It is possible (and indeed, quite common) for [debugNeedsPaint] to be
2003  /// false and [debugNeedsLayout] to be true. The render object will still be
2004  /// repainted in the next frame when this is the case, because the
2005  /// [markNeedsPaint] method is implicitly called by the framework after a
2006  /// render object is laid out, prior to the paint phase.
2007  bool get debugNeedsPaint {
2008    bool result;
2009    assert(() {
2010      result = _needsPaint;
2011      return true;
2012    }());
2013    return result;
2014  }
2015  bool _needsPaint = true;
2016
2017  /// Mark this render object as having changed its visual appearance.
2018  ///
2019  /// Rather than eagerly updating this render object's display list
2020  /// in response to writes, we instead mark the render object as needing to
2021  /// paint, which schedules a visual update. As part of the visual update, the
2022  /// rendering pipeline will give this render object an opportunity to update
2023  /// its display list.
2024  ///
2025  /// This mechanism batches the painting work so that multiple sequential
2026  /// writes are coalesced, removing redundant computation.
2027  ///
2028  /// Once [markNeedsPaint] has been called on a render object,
2029  /// [debugNeedsPaint] returns true for that render object until just after
2030  /// the pipeline owner has called [paint] on the render object.
2031  ///
2032  /// See also:
2033  ///
2034  ///  * [RepaintBoundary], to scope a subtree of render objects to their own
2035  ///    layer, thus limiting the number of nodes that [markNeedsPaint] must mark
2036  ///    dirty.
2037  void markNeedsPaint() {
2038    assert(owner == null || !owner.debugDoingPaint);
2039    if (_needsPaint)
2040      return;
2041    _needsPaint = true;
2042    if (isRepaintBoundary) {
2043      assert(() {
2044        if (debugPrintMarkNeedsPaintStacks)
2045          debugPrintStack(label: 'markNeedsPaint() called for $this');
2046        return true;
2047      }());
2048      // If we always have our own layer, then we can just repaint
2049      // ourselves without involving any other nodes.
2050      assert(_layer is OffsetLayer);
2051      if (owner != null) {
2052        owner._nodesNeedingPaint.add(this);
2053        owner.requestVisualUpdate();
2054      }
2055    } else if (parent is RenderObject) {
2056      final RenderObject parent = this.parent;
2057      parent.markNeedsPaint();
2058      assert(parent == this.parent);
2059    } else {
2060      assert(() {
2061        if (debugPrintMarkNeedsPaintStacks)
2062          debugPrintStack(label: 'markNeedsPaint() called for $this (root of render tree)');
2063        return true;
2064      }());
2065      // If we're the root of the render tree (probably a RenderView),
2066      // then we have to paint ourselves, since nobody else can paint
2067      // us. We don't add ourselves to _nodesNeedingPaint in this
2068      // case, because the root is always told to paint regardless.
2069      if (owner != null)
2070        owner.requestVisualUpdate();
2071    }
2072  }
2073
2074  // Called when flushPaint() tries to make us paint but our layer is detached.
2075  // To make sure that our subtree is repainted when it's finally reattached,
2076  // even in the case where some ancestor layer is itself never marked dirty, we
2077  // have to mark our entire detached subtree as dirty and needing to be
2078  // repainted. That way, we'll eventually be repainted.
2079  void _skippedPaintingOnLayer() {
2080    assert(attached);
2081    assert(isRepaintBoundary);
2082    assert(_needsPaint);
2083    assert(_layer != null);
2084    assert(!_layer.attached);
2085    AbstractNode ancestor = parent;
2086    while (ancestor is RenderObject) {
2087      final RenderObject node = ancestor;
2088      if (node.isRepaintBoundary) {
2089        if (node._layer == null)
2090          break; // looks like the subtree here has never been painted. let it handle itself.
2091        if (node._layer.attached)
2092          break; // it's the one that detached us, so it's the one that will decide to repaint us.
2093        node._needsPaint = true;
2094      }
2095      ancestor = node.parent;
2096    }
2097  }
2098
2099  /// Bootstrap the rendering pipeline by scheduling the very first paint.
2100  ///
2101  /// Requires that this render object is attached, is the root of the render
2102  /// tree, and has a composited layer.
2103  ///
2104  /// See [RenderView] for an example of how this function is used.
2105  void scheduleInitialPaint(ContainerLayer rootLayer) {
2106    assert(rootLayer.attached);
2107    assert(attached);
2108    assert(parent is! RenderObject);
2109    assert(!owner._debugDoingPaint);
2110    assert(isRepaintBoundary);
2111    assert(_layer == null);
2112    _layer = rootLayer;
2113    assert(_needsPaint);
2114    owner._nodesNeedingPaint.add(this);
2115  }
2116
2117  /// Replace the layer. This is only valid for the root of a render
2118  /// object subtree (whatever object [scheduleInitialPaint] was
2119  /// called on).
2120  ///
2121  /// This might be called if, e.g., the device pixel ratio changed.
2122  void replaceRootLayer(OffsetLayer rootLayer) {
2123    assert(rootLayer.attached);
2124    assert(attached);
2125    assert(parent is! RenderObject);
2126    assert(!owner._debugDoingPaint);
2127    assert(isRepaintBoundary);
2128    assert(_layer != null); // use scheduleInitialPaint the first time
2129    _layer.detach();
2130    _layer = rootLayer;
2131    markNeedsPaint();
2132  }
2133
2134  void _paintWithContext(PaintingContext context, Offset offset) {
2135    assert(() {
2136      if (_debugDoingThisPaint) {
2137        throw FlutterError.fromParts(<DiagnosticsNode>[
2138          ErrorSummary('Tried to paint a RenderObject reentrantly.'),
2139          describeForError(
2140            'The following RenderObject was already being painted when it was '
2141            'painted again'
2142          ),
2143          ErrorDescription(
2144            'Since this typically indicates an infinite recursion, it is '
2145            'disallowed.'
2146          )
2147        ]);
2148      }
2149      return true;
2150    }());
2151    // If we still need layout, then that means that we were skipped in the
2152    // layout phase and therefore don't need painting. We might not know that
2153    // yet (that is, our layer might not have been detached yet), because the
2154    // same node that skipped us in layout is above us in the tree (obviously)
2155    // and therefore may not have had a chance to paint yet (since the tree
2156    // paints in reverse order). In particular this will happen if they have
2157    // a different layer, because there's a repaint boundary between us.
2158    if (_needsLayout)
2159      return;
2160    assert(() {
2161      if (_needsCompositingBitsUpdate) {
2162        throw FlutterError.fromParts(<DiagnosticsNode>[
2163          ErrorSummary(
2164            'Tried to paint a RenderObject before its compositing bits were '
2165            'updated.'
2166          ),
2167          describeForError(
2168            'The following RenderObject was marked as having dirty compositing '
2169            'bits at the time that it was painted',
2170          ),
2171          ErrorDescription(
2172            'A RenderObject that still has dirty compositing bits cannot be '
2173            'painted because this indicates that the tree has not yet been '
2174            'properly configured for creating the layer tree.'
2175          ),
2176          ErrorHint(
2177            'This usually indicates an error in the Flutter framework itself.'
2178          )
2179        ]);
2180      }
2181      return true;
2182    }());
2183    RenderObject debugLastActivePaint;
2184    assert(() {
2185      _debugDoingThisPaint = true;
2186      debugLastActivePaint = _debugActivePaint;
2187      _debugActivePaint = this;
2188      assert(!isRepaintBoundary || _layer != null);
2189      return true;
2190    }());
2191    _needsPaint = false;
2192    try {
2193      paint(context, offset);
2194      assert(!_needsLayout); // check that the paint() method didn't mark us dirty again
2195      assert(!_needsPaint); // check that the paint() method didn't mark us dirty again
2196    } catch (e, stack) {
2197      _debugReportException('paint', e, stack);
2198    }
2199    assert(() {
2200      debugPaint(context, offset);
2201      _debugActivePaint = debugLastActivePaint;
2202      _debugDoingThisPaint = false;
2203      return true;
2204    }());
2205  }
2206
2207  /// An estimate of the bounds within which this render object will paint.
2208  /// Useful for debugging flags such as [debugPaintLayerBordersEnabled].
2209  ///
2210  /// These are also the bounds used by [showOnScreen] to make a [RenderObject]
2211  /// visible on screen.
2212  Rect get paintBounds;
2213
2214  /// Override this method to paint debugging information.
2215  void debugPaint(PaintingContext context, Offset offset) { }
2216
2217  /// Paint this render object into the given context at the given offset.
2218  ///
2219  /// Subclasses should override this method to provide a visual appearance
2220  /// for themselves. The render object's local coordinate system is
2221  /// axis-aligned with the coordinate system of the context's canvas and the
2222  /// render object's local origin (i.e, x=0 and y=0) is placed at the given
2223  /// offset in the context's canvas.
2224  ///
2225  /// Do not call this function directly. If you wish to paint yourself, call
2226  /// [markNeedsPaint] instead to schedule a call to this function. If you wish
2227  /// to paint one of your children, call [PaintingContext.paintChild] on the
2228  /// given `context`.
2229  ///
2230  /// When painting one of your children (via a paint child function on the
2231  /// given context), the current canvas held by the context might change
2232  /// because draw operations before and after painting children might need to
2233  /// be recorded on separate compositing layers.
2234  void paint(PaintingContext context, Offset offset) { }
2235
2236  /// Applies the transform that would be applied when painting the given child
2237  /// to the given matrix.
2238  ///
2239  /// Used by coordinate conversion functions to translate coordinates local to
2240  /// one render object into coordinates local to another render object.
2241  void applyPaintTransform(covariant RenderObject child, Matrix4 transform) {
2242    assert(child.parent == this);
2243  }
2244
2245  /// Applies the paint transform up the tree to `ancestor`.
2246  ///
2247  /// Returns a matrix that maps the local paint coordinate system to the
2248  /// coordinate system of `ancestor`.
2249  ///
2250  /// If `ancestor` is null, this method returns a matrix that maps from the
2251  /// local paint coordinate system to the coordinate system of the
2252  /// [PipelineOwner.rootNode]. For the render tree owner by the
2253  /// [RendererBinding] (i.e. for the main render tree displayed on the device)
2254  /// this means that this method maps to the global coordinate system in
2255  /// logical pixels. To get physical pixels, use [applyPaintTransform] from the
2256  /// [RenderView] to further transform the coordinate.
2257  Matrix4 getTransformTo(RenderObject ancestor) {
2258    final bool ancestorSpecified = ancestor != null;
2259    assert(attached);
2260    if (ancestor == null) {
2261      final AbstractNode rootNode = owner.rootNode;
2262      if (rootNode is RenderObject)
2263        ancestor = rootNode;
2264    }
2265    final List<RenderObject> renderers = <RenderObject>[];
2266    for (RenderObject renderer = this; renderer != ancestor; renderer = renderer.parent) {
2267      assert(renderer != null); // Failed to find ancestor in parent chain.
2268      renderers.add(renderer);
2269    }
2270    if (ancestorSpecified)
2271      renderers.add(ancestor);
2272    final Matrix4 transform = Matrix4.identity();
2273    for (int index = renderers.length - 1; index > 0; index -= 1) {
2274      renderers[index].applyPaintTransform(renderers[index - 1], transform);
2275    }
2276    return transform;
2277  }
2278
2279
2280  /// Returns a rect in this object's coordinate system that describes
2281  /// the approximate bounding box of the clip rect that would be
2282  /// applied to the given child during the paint phase, if any.
2283  ///
2284  /// Returns null if the child would not be clipped.
2285  ///
2286  /// This is used in the semantics phase to avoid including children
2287  /// that are not physically visible.
2288  Rect describeApproximatePaintClip(covariant RenderObject child) => null;
2289
2290  /// Returns a rect in this object's coordinate system that describes
2291  /// which [SemanticsNode]s produced by the `child` should be included in the
2292  /// semantics tree. [SemanticsNode]s from the `child` that are positioned
2293  /// outside of this rect will be dropped. Child [SemanticsNode]s that are
2294  /// positioned inside this rect, but outside of [describeApproximatePaintClip]
2295  /// will be included in the tree marked as hidden. Child [SemanticsNode]s
2296  /// that are inside of both rect will be included in the tree as regular
2297  /// nodes.
2298  ///
2299  /// This method only returns a non-null value if the semantics clip rect
2300  /// is different from the rect returned by [describeApproximatePaintClip].
2301  /// If the semantics clip rect and the paint clip rect are the same, this
2302  /// method returns null.
2303  ///
2304  /// A viewport would typically implement this method to include semantic nodes
2305  /// in the semantics tree that are currently hidden just before the leading
2306  /// or just after the trailing edge. These nodes have to be included in the
2307  /// semantics tree to implement implicit accessibility scrolling on iOS where
2308  /// the viewport scrolls implicitly when moving the accessibility focus from
2309  /// a the last visible node in the viewport to the first hidden one.
2310  Rect describeSemanticsClip(covariant RenderObject child) => null;
2311
2312  // SEMANTICS
2313
2314  /// Bootstrap the semantics reporting mechanism by marking this node
2315  /// as needing a semantics update.
2316  ///
2317  /// Requires that this render object is attached, and is the root of
2318  /// the render tree.
2319  ///
2320  /// See [RendererBinding] for an example of how this function is used.
2321  void scheduleInitialSemantics() {
2322    assert(attached);
2323    assert(parent is! RenderObject);
2324    assert(!owner._debugDoingSemantics);
2325    assert(_semantics == null);
2326    assert(_needsSemanticsUpdate);
2327    assert(owner._semanticsOwner != null);
2328    owner._nodesNeedingSemantics.add(this);
2329    owner.requestVisualUpdate();
2330  }
2331
2332  /// Report the semantics of this node, for example for accessibility purposes.
2333  ///
2334  /// This method should be overridden by subclasses that have interesting
2335  /// semantic information.
2336  ///
2337  /// The given [SemanticsConfiguration] object is mutable and should be
2338  /// annotated in a manner that describes the current state. No reference
2339  /// should be kept to that object; mutating it outside of the context of the
2340  /// [describeSemanticsConfiguration] call (for example as a result of
2341  /// asynchronous computation) will at best have no useful effect and at worse
2342  /// will cause crashes as the data will be in an inconsistent state.
2343  ///
2344  /// {@tool sample}
2345  ///
2346  /// The following snippet will describe the node as a button that responds to
2347  /// tap actions.
2348  ///
2349  /// ```dart
2350  /// abstract class SemanticButtonRenderObject extends RenderObject {
2351  ///   @override
2352  ///   void describeSemanticsConfiguration(SemanticsConfiguration config) {
2353  ///     super.describeSemanticsConfiguration(config);
2354  ///     config
2355  ///       ..onTap = _handleTap
2356  ///       ..label = 'I am a button'
2357  ///       ..isButton = true;
2358  ///   }
2359  ///
2360  ///   void _handleTap() {
2361  ///     // Do something.
2362  ///   }
2363  /// }
2364  /// ```
2365  /// {@end-tool}
2366  @protected
2367  void describeSemanticsConfiguration(SemanticsConfiguration config) {
2368    // Nothing to do by default.
2369  }
2370
2371  /// Sends a [SemanticsEvent] associated with this render object's [SemanticsNode].
2372  ///
2373  /// If this render object has no semantics information, the first parent
2374  /// render object with a non-null semantic node is used.
2375  ///
2376  /// If semantics are disabled, no events are dispatched.
2377  ///
2378  /// See [SemanticsNode.sendEvent] for a full description of the behavior.
2379  void sendSemanticsEvent(SemanticsEvent semanticsEvent) {
2380    if (owner.semanticsOwner == null)
2381      return;
2382    if (_semantics != null && !_semantics.isMergedIntoParent) {
2383      _semantics.sendEvent(semanticsEvent);
2384    } else if (parent != null) {
2385      final RenderObject renderParent = parent;
2386      renderParent.sendSemanticsEvent(semanticsEvent);
2387    }
2388  }
2389
2390  // Use [_semanticsConfiguration] to access.
2391  SemanticsConfiguration _cachedSemanticsConfiguration;
2392
2393  SemanticsConfiguration get _semanticsConfiguration {
2394    if (_cachedSemanticsConfiguration == null) {
2395      _cachedSemanticsConfiguration = SemanticsConfiguration();
2396      describeSemanticsConfiguration(_cachedSemanticsConfiguration);
2397    }
2398    return _cachedSemanticsConfiguration;
2399  }
2400
2401  /// The bounding box, in the local coordinate system, of this
2402  /// object, for accessibility purposes.
2403  Rect get semanticBounds;
2404
2405  bool _needsSemanticsUpdate = true;
2406  SemanticsNode _semantics;
2407
2408  /// The semantics of this render object.
2409  ///
2410  /// Exposed only for testing and debugging. To learn about the semantics of
2411  /// render objects in production, obtain a [SemanticsHandle] from
2412  /// [PipelineOwner.ensureSemantics].
2413  ///
2414  /// Only valid when asserts are enabled. In release builds, always returns
2415  /// null.
2416  SemanticsNode get debugSemantics {
2417    SemanticsNode result;
2418    assert(() {
2419      result = _semantics;
2420      return true;
2421    }());
2422    return result;
2423  }
2424
2425  /// Removes all semantics from this render object and its descendants.
2426  ///
2427  /// Should only be called on objects whose [parent] is not a [RenderObject].
2428  ///
2429  /// Override this method if you instantiate new [SemanticsNode]s in an
2430  /// overridden [assembleSemanticsNode] method, to dispose of those nodes.
2431  @mustCallSuper
2432  void clearSemantics() {
2433    _needsSemanticsUpdate = true;
2434    _semantics = null;
2435    visitChildren((RenderObject child) {
2436      child.clearSemantics();
2437    });
2438  }
2439
2440  /// Mark this node as needing an update to its semantics description.
2441  ///
2442  /// This must be called whenever the semantics configuration of this
2443  /// [RenderObject] as annotated by [describeSemanticsConfiguration] changes in
2444  /// any way to update the semantics tree.
2445  void markNeedsSemanticsUpdate() {
2446    assert(!attached || !owner._debugDoingSemantics);
2447    if (!attached || owner._semanticsOwner == null) {
2448      _cachedSemanticsConfiguration = null;
2449      return;
2450    }
2451
2452    // Dirty the semantics tree starting at `this` until we have reached a
2453    // RenderObject that is a semantics boundary. All semantics past this
2454    // RenderObject are still up-to date. Therefore, we will later only rebuild
2455    // the semantics subtree starting at the identified semantics boundary.
2456
2457    final bool wasSemanticsBoundary = _semantics != null && _cachedSemanticsConfiguration?.isSemanticBoundary == true;
2458    _cachedSemanticsConfiguration = null;
2459    bool isEffectiveSemanticsBoundary = _semanticsConfiguration.isSemanticBoundary && wasSemanticsBoundary;
2460    RenderObject node = this;
2461
2462    while (!isEffectiveSemanticsBoundary && node.parent is RenderObject) {
2463      if (node != this && node._needsSemanticsUpdate)
2464        break;
2465      node._needsSemanticsUpdate = true;
2466
2467      node = node.parent;
2468      isEffectiveSemanticsBoundary = node._semanticsConfiguration.isSemanticBoundary;
2469      if (isEffectiveSemanticsBoundary && node._semantics == null) {
2470        // We have reached a semantics boundary that doesn't own a semantics node.
2471        // That means the semantics of this branch are currently blocked and will
2472        // not appear in the semantics tree. We can abort the walk here.
2473        return;
2474      }
2475    }
2476    if (node != this && _semantics != null && _needsSemanticsUpdate) {
2477      // If `this` node has already been added to [owner._nodesNeedingSemantics]
2478      // remove it as it is no longer guaranteed that its semantics
2479      // node will continue to be in the tree. If it still is in the tree, the
2480      // ancestor `node` added to [owner._nodesNeedingSemantics] at the end of
2481      // this block will ensure that the semantics of `this` node actually gets
2482      // updated.
2483      // (See semantics_10_test.dart for an example why this is required).
2484      owner._nodesNeedingSemantics.remove(this);
2485    }
2486    if (!node._needsSemanticsUpdate) {
2487      node._needsSemanticsUpdate = true;
2488      if (owner != null) {
2489        assert(node._semanticsConfiguration.isSemanticBoundary || node.parent is! RenderObject);
2490        owner._nodesNeedingSemantics.add(node);
2491        owner.requestVisualUpdate();
2492      }
2493    }
2494  }
2495
2496  /// Updates the semantic information of the render object.
2497  void _updateSemantics() {
2498    assert(_semanticsConfiguration.isSemanticBoundary || parent is! RenderObject);
2499    if (_needsLayout) {
2500      // There's not enough information in this subtree to compute semantics.
2501      // The subtree is probably being kept alive by a viewport but not laid out.
2502      return;
2503    }
2504    final _SemanticsFragment fragment = _getSemanticsForParent(
2505      mergeIntoParent: _semantics?.parent?.isPartOfNodeMerging ?? false,
2506    );
2507    assert(fragment is _InterestingSemanticsFragment);
2508    final _InterestingSemanticsFragment interestingFragment = fragment;
2509    final SemanticsNode node = interestingFragment.compileChildren(
2510      parentSemanticsClipRect: _semantics?.parentSemanticsClipRect,
2511      parentPaintClipRect: _semantics?.parentPaintClipRect,
2512      elevationAdjustment: _semantics?.elevationAdjustment ?? 0.0,
2513    ).single;
2514    // Fragment only wants to add this node's SemanticsNode to the parent.
2515    assert(interestingFragment.config == null && node == _semantics);
2516  }
2517
2518  /// Returns the semantics that this node would like to add to its parent.
2519  _SemanticsFragment _getSemanticsForParent({
2520    @required bool mergeIntoParent,
2521  }) {
2522    assert(mergeIntoParent != null);
2523    assert(!_needsLayout, 'Updated layout information required for $this to calculate semantics.');
2524
2525    final SemanticsConfiguration config = _semanticsConfiguration;
2526    bool dropSemanticsOfPreviousSiblings = config.isBlockingSemanticsOfPreviouslyPaintedNodes;
2527
2528    final bool producesForkingFragment = !config.hasBeenAnnotated && !config.isSemanticBoundary;
2529    final List<_InterestingSemanticsFragment> fragments = <_InterestingSemanticsFragment>[];
2530    final Set<_InterestingSemanticsFragment> toBeMarkedExplicit = <_InterestingSemanticsFragment>{};
2531    final bool childrenMergeIntoParent = mergeIntoParent || config.isMergingSemanticsOfDescendants;
2532
2533    // When set to true there's currently not enough information in this subtree
2534    // to compute semantics. In this case the walk needs to be aborted and no
2535    // SemanticsNodes in the subtree should be updated.
2536    // This will be true for subtrees that are currently kept alive by a
2537    // viewport but not laid out.
2538    bool abortWalk = false;
2539
2540    visitChildrenForSemantics((RenderObject renderChild) {
2541      if (abortWalk || _needsLayout) {
2542        abortWalk = true;
2543        return;
2544      }
2545      final _SemanticsFragment parentFragment = renderChild._getSemanticsForParent(
2546        mergeIntoParent: childrenMergeIntoParent,
2547      );
2548      if (parentFragment.abortsWalk) {
2549        abortWalk = true;
2550        return;
2551      }
2552      if (parentFragment.dropsSemanticsOfPreviousSiblings) {
2553        fragments.clear();
2554        toBeMarkedExplicit.clear();
2555        if (!config.isSemanticBoundary)
2556          dropSemanticsOfPreviousSiblings = true;
2557      }
2558      // Figure out which child fragments are to be made explicit.
2559      for (_InterestingSemanticsFragment fragment in parentFragment.interestingFragments) {
2560        fragments.add(fragment);
2561        fragment.addAncestor(this);
2562        fragment.addTags(config.tagsForChildren);
2563        if (config.explicitChildNodes || parent is! RenderObject) {
2564          fragment.markAsExplicit();
2565          continue;
2566        }
2567        if (!fragment.hasConfigForParent || producesForkingFragment)
2568          continue;
2569        if (!config.isCompatibleWith(fragment.config))
2570          toBeMarkedExplicit.add(fragment);
2571        for (_InterestingSemanticsFragment siblingFragment in fragments.sublist(0, fragments.length - 1)) {
2572          if (!fragment.config.isCompatibleWith(siblingFragment.config)) {
2573            toBeMarkedExplicit.add(fragment);
2574            toBeMarkedExplicit.add(siblingFragment);
2575          }
2576        }
2577      }
2578    });
2579
2580    if (abortWalk) {
2581      return _AbortingSemanticsFragment(owner: this);
2582    }
2583
2584    for (_InterestingSemanticsFragment fragment in toBeMarkedExplicit)
2585      fragment.markAsExplicit();
2586
2587    _needsSemanticsUpdate = false;
2588
2589    _SemanticsFragment result;
2590    if (parent is! RenderObject) {
2591      assert(!config.hasBeenAnnotated);
2592      assert(!mergeIntoParent);
2593      result = _RootSemanticsFragment(
2594        owner: this,
2595        dropsSemanticsOfPreviousSiblings: dropSemanticsOfPreviousSiblings,
2596      );
2597    } else if (producesForkingFragment) {
2598      result = _ContainerSemanticsFragment(
2599        dropsSemanticsOfPreviousSiblings: dropSemanticsOfPreviousSiblings,
2600      );
2601    } else {
2602      result = _SwitchableSemanticsFragment(
2603        config: config,
2604        mergeIntoParent: mergeIntoParent,
2605        owner: this,
2606        dropsSemanticsOfPreviousSiblings: dropSemanticsOfPreviousSiblings,
2607      );
2608      if (config.isSemanticBoundary) {
2609        final _SwitchableSemanticsFragment fragment = result;
2610        fragment.markAsExplicit();
2611      }
2612    }
2613
2614    result.addAll(fragments);
2615
2616    return result;
2617  }
2618
2619  /// Called when collecting the semantics of this node.
2620  ///
2621  /// The implementation has to return the children in paint order skipping all
2622  /// children that are not semantically relevant (e.g. because they are
2623  /// invisible).
2624  ///
2625  /// The default implementation mirrors the behavior of
2626  /// [visitChildren()] (which is supposed to walk all the children).
2627  void visitChildrenForSemantics(RenderObjectVisitor visitor) {
2628    visitChildren(visitor);
2629  }
2630
2631  /// Assemble the [SemanticsNode] for this [RenderObject].
2632  ///
2633  /// If [isSemanticBoundary] is true, this method is called with the `node`
2634  /// created for this [RenderObject], the `config` to be applied to that node
2635  /// and the `children` [SemanticNode]s that descendants of this RenderObject
2636  /// have generated.
2637  ///
2638  /// By default, the method will annotate `node` with `config` and add the
2639  /// `children` to it.
2640  ///
2641  /// Subclasses can override this method to add additional [SemanticsNode]s
2642  /// to the tree. If new [SemanticsNode]s are instantiated in this method
2643  /// they must be disposed in [clearSemantics].
2644  void assembleSemanticsNode(
2645    SemanticsNode node,
2646    SemanticsConfiguration config,
2647    Iterable<SemanticsNode> children,
2648  ) {
2649    assert(node == _semantics);
2650    node.updateWith(config: config, childrenInInversePaintOrder: children);
2651  }
2652
2653  // EVENTS
2654
2655  /// Override this method to handle pointer events that hit this render object.
2656  @override
2657  void handleEvent(PointerEvent event, covariant HitTestEntry entry) { }
2658
2659
2660  // HIT TESTING
2661
2662  // RenderObject subclasses are expected to have a method like the following
2663  // (with the signature being whatever passes for coordinates for this
2664  // particular class):
2665  //
2666  // bool hitTest(HitTestResult result, { Offset position }) {
2667  //   // If the given position is not inside this node, then return false.
2668  //   // Otherwise:
2669  //   // For each child that intersects the position, in z-order starting from
2670  //   // the top, call hitTest() for that child, passing it /result/, and the
2671  //   // coordinates converted to the child's coordinate origin, and stop at
2672  //   // the first child that returns true.
2673  //   // Then, add yourself to /result/, and return true.
2674  // }
2675  //
2676  // If you add yourself to /result/ and still return false, then that means you
2677  // will see events but so will objects below you.
2678
2679
2680  /// Returns a human understandable name.
2681  @override
2682  String toStringShort() {
2683    String header = describeIdentity(this);
2684    if (_relayoutBoundary != null && _relayoutBoundary != this) {
2685      int count = 1;
2686      RenderObject target = parent;
2687      while (target != null && target != _relayoutBoundary) {
2688        target = target.parent;
2689        count += 1;
2690      }
2691      header += ' relayoutBoundary=up$count';
2692    }
2693    if (_needsLayout)
2694      header += ' NEEDS-LAYOUT';
2695    if (_needsPaint)
2696      header += ' NEEDS-PAINT';
2697    if (_needsCompositingBitsUpdate)
2698      header += ' NEEDS-COMPOSITING-BITS-UPDATE';
2699    if (!attached)
2700      header += ' DETACHED';
2701    return header;
2702  }
2703
2704  @override
2705  String toString({ DiagnosticLevel minLevel = DiagnosticLevel.debug }) => toStringShort();
2706
2707  /// Returns a description of the tree rooted at this node.
2708  /// If the prefix argument is provided, then every line in the output
2709  /// will be prefixed by that string.
2710  @override
2711  String toStringDeep({
2712    String prefixLineOne = '',
2713    String prefixOtherLines = '',
2714    DiagnosticLevel minLevel = DiagnosticLevel.debug,
2715  }) {
2716    RenderObject debugPreviousActiveLayout;
2717    assert(() {
2718      debugPreviousActiveLayout = _debugActiveLayout;
2719      _debugActiveLayout = null;
2720      return true;
2721    }());
2722    final String result = super.toStringDeep(
2723      prefixLineOne: prefixLineOne,
2724      prefixOtherLines: prefixOtherLines,
2725      minLevel: minLevel,
2726    );
2727    assert(() {
2728      _debugActiveLayout = debugPreviousActiveLayout;
2729      return true;
2730    }());
2731    return result;
2732  }
2733
2734  /// Returns a one-line detailed description of the render object.
2735  /// This description is often somewhat long.
2736  ///
2737  /// This includes the same information for this RenderObject as given by
2738  /// [toStringDeep], but does not recurse to any children.
2739  @override
2740  String toStringShallow({
2741    String joiner = ', ',
2742    DiagnosticLevel minLevel = DiagnosticLevel.debug,
2743  }) {
2744    RenderObject debugPreviousActiveLayout;
2745    assert(() {
2746      debugPreviousActiveLayout = _debugActiveLayout;
2747      _debugActiveLayout = null;
2748      return true;
2749    }());
2750    final String result = super.toStringShallow(joiner: joiner, minLevel: minLevel);
2751    assert(() {
2752      _debugActiveLayout = debugPreviousActiveLayout;
2753      return true;
2754    }());
2755    return result;
2756  }
2757
2758  @protected
2759  @override
2760  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2761    super.debugFillProperties(properties);
2762    properties.add(FlagProperty('needsCompositing', value: _needsCompositing, ifTrue: 'needs compositing'));
2763    properties.add(DiagnosticsProperty<dynamic>('creator', debugCreator, defaultValue: null, level: DiagnosticLevel.debug));
2764    properties.add(DiagnosticsProperty<ParentData>('parentData', parentData, tooltip: _debugCanParentUseSize == true ? 'can use size' : null, missingIfNull: true));
2765    properties.add(DiagnosticsProperty<Constraints>('constraints', constraints, missingIfNull: true));
2766    // don't access it via the "layer" getter since that's only valid when we don't need paint
2767    properties.add(DiagnosticsProperty<ContainerLayer>('layer', _layer, defaultValue: null));
2768    properties.add(DiagnosticsProperty<SemanticsNode>('semantics node', _semantics, defaultValue: null));
2769    properties.add(FlagProperty(
2770      'isBlockingSemanticsOfPreviouslyPaintedNodes',
2771      value: _semanticsConfiguration.isBlockingSemanticsOfPreviouslyPaintedNodes,
2772      ifTrue: 'blocks semantics of earlier render objects below the common boundary',
2773    ));
2774    properties.add(FlagProperty('isSemanticBoundary', value: _semanticsConfiguration.isSemanticBoundary, ifTrue: 'semantic boundary'));
2775  }
2776
2777  @override
2778  List<DiagnosticsNode> debugDescribeChildren() => <DiagnosticsNode>[];
2779
2780  /// Attempt to make (a portion of) this or a descendant [RenderObject] visible
2781  /// on screen.
2782  ///
2783  /// If `descendant` is provided, that [RenderObject] is made visible. If
2784  /// `descendant` is omitted, this [RenderObject] is made visible.
2785  ///
2786  /// The optional `rect` parameter describes which area of that [RenderObject]
2787  /// should be shown on screen. If `rect` is null, the entire
2788  /// [RenderObject] (as defined by its [paintBounds]) will be revealed. The
2789  /// `rect` parameter is interpreted relative to the coordinate system of
2790  /// `descendant` if that argument is provided and relative to this
2791  /// [RenderObject] otherwise.
2792  ///
2793  /// The `duration` parameter can be set to a non-zero value to bring the
2794  /// target object on screen in an animation defined by `curve`.
2795  void showOnScreen({
2796    RenderObject descendant,
2797    Rect rect,
2798    Duration duration = Duration.zero,
2799    Curve curve = Curves.ease,
2800  }) {
2801    if (parent is RenderObject) {
2802      final RenderObject renderParent = parent;
2803      renderParent.showOnScreen(
2804        descendant: descendant ?? this,
2805        rect: rect,
2806        duration: duration,
2807        curve: curve,
2808      );
2809    }
2810  }
2811
2812  /// Adds a debug representation of a [RenderObject] optimized for including in
2813  /// error messages.
2814  ///
2815  /// The default [style] of [DiagnosticsTreeStyle.shallow] ensures that all of
2816  /// the properties of the render object are included in the error output but
2817  /// none of the children of the object are.
2818  ///
2819  /// You should always include a RenderObject in an error message if it is the
2820  /// [RenderObject] causing the failure or contract violation of the error.
2821  DiagnosticsNode describeForError(String name, { DiagnosticsTreeStyle style = DiagnosticsTreeStyle.shallow }) {
2822    return toDiagnosticsNode(name: name, style: style);
2823  }
2824}
2825
2826/// Generic mixin for render objects with one child.
2827///
2828/// Provides a child model for a render object subclass that has a unique child.
2829mixin RenderObjectWithChildMixin<ChildType extends RenderObject> on RenderObject {
2830
2831  /// Checks whether the given render object has the correct [runtimeType] to be
2832  /// a child of this render object.
2833  ///
2834  /// Does nothing if assertions are disabled.
2835  ///
2836  /// Always returns true.
2837  bool debugValidateChild(RenderObject child) {
2838    assert(() {
2839      if (child is! ChildType) {
2840        throw FlutterError.fromParts(<DiagnosticsNode>[
2841          ErrorSummary(
2842            'A $runtimeType expected a child of type $ChildType but received a '
2843            'child of type ${child.runtimeType}.'
2844          ),
2845          ErrorDescription(
2846            'RenderObjects expect specific types of children because they '
2847            'coordinate with their children during layout and paint. For '
2848            'example, a RenderSliver cannot be the child of a RenderBox because '
2849            'a RenderSliver does not understand the RenderBox layout protocol.',
2850          ),
2851          ErrorSpacer(),
2852          DiagnosticsProperty<dynamic>(
2853            'The $runtimeType that expected a $ChildType child was created by',
2854            debugCreator,
2855            style: DiagnosticsTreeStyle.errorProperty,
2856          ),
2857          ErrorSpacer(),
2858          DiagnosticsProperty<dynamic>(
2859            'The ${child.runtimeType} that did not match the expected child type '
2860            'was created by',
2861            child.debugCreator,
2862            style: DiagnosticsTreeStyle.errorProperty,
2863          )
2864        ]);
2865      }
2866      return true;
2867    }());
2868    return true;
2869  }
2870
2871  ChildType _child;
2872  /// The render object's unique child
2873  ChildType get child => _child;
2874  set child(ChildType value) {
2875    if (_child != null)
2876      dropChild(_child);
2877    _child = value;
2878    if (_child != null)
2879      adoptChild(_child);
2880  }
2881
2882  @override
2883  void attach(PipelineOwner owner) {
2884    super.attach(owner);
2885    if (_child != null)
2886      _child.attach(owner);
2887  }
2888
2889  @override
2890  void detach() {
2891    super.detach();
2892    if (_child != null)
2893      _child.detach();
2894  }
2895
2896  @override
2897  void redepthChildren() {
2898    if (_child != null)
2899      redepthChild(_child);
2900  }
2901
2902  @override
2903  void visitChildren(RenderObjectVisitor visitor) {
2904    if (_child != null)
2905      visitor(_child);
2906  }
2907
2908  @override
2909  List<DiagnosticsNode> debugDescribeChildren() {
2910    return child != null ? <DiagnosticsNode>[child.toDiagnosticsNode(name: 'child')] : <DiagnosticsNode>[];
2911  }
2912}
2913
2914/// Parent data to support a doubly-linked list of children.
2915mixin ContainerParentDataMixin<ChildType extends RenderObject> on ParentData {
2916  /// The previous sibling in the parent's child list.
2917  ChildType previousSibling;
2918  /// The next sibling in the parent's child list.
2919  ChildType nextSibling;
2920
2921  /// Clear the sibling pointers.
2922  @override
2923  void detach() {
2924    assert(previousSibling == null, 'Pointers to siblings must be nulled before detaching ParentData.');
2925    assert(nextSibling == null, 'Pointers to siblings must be nulled before detaching ParentData.');
2926    super.detach();
2927  }
2928}
2929
2930/// Generic mixin for render objects with a list of children.
2931///
2932/// Provides a child model for a render object subclass that has a doubly-linked
2933/// list of children.
2934mixin ContainerRenderObjectMixin<ChildType extends RenderObject, ParentDataType extends ContainerParentDataMixin<ChildType>> on RenderObject {
2935  bool _debugUltimatePreviousSiblingOf(ChildType child, { ChildType equals }) {
2936    ParentDataType childParentData = child.parentData;
2937    while (childParentData.previousSibling != null) {
2938      assert(childParentData.previousSibling != child);
2939      child = childParentData.previousSibling;
2940      childParentData = child.parentData;
2941    }
2942    return child == equals;
2943  }
2944  bool _debugUltimateNextSiblingOf(ChildType child, { ChildType equals }) {
2945    ParentDataType childParentData = child.parentData;
2946    while (childParentData.nextSibling != null) {
2947      assert(childParentData.nextSibling != child);
2948      child = childParentData.nextSibling;
2949      childParentData = child.parentData;
2950    }
2951    return child == equals;
2952  }
2953
2954  int _childCount = 0;
2955  /// The number of children.
2956  int get childCount => _childCount;
2957
2958  /// Checks whether the given render object has the correct [runtimeType] to be
2959  /// a child of this render object.
2960  ///
2961  /// Does nothing if assertions are disabled.
2962  ///
2963  /// Always returns true.
2964  bool debugValidateChild(RenderObject child) {
2965    assert(() {
2966      if (child is! ChildType) {
2967        throw FlutterError.fromParts(<DiagnosticsNode>[
2968          ErrorSummary(
2969            'A $runtimeType expected a child of type $ChildType but received a '
2970            'child of type ${child.runtimeType}.'
2971          ),
2972          ErrorDescription(
2973            'RenderObjects expect specific types of children because they '
2974            'coordinate with their children during layout and paint. For '
2975            'example, a RenderSliver cannot be the child of a RenderBox because '
2976            'a RenderSliver does not understand the RenderBox layout protocol.'
2977          ),
2978          ErrorSpacer(),
2979          DiagnosticsProperty<dynamic>(
2980            'The $runtimeType that expected a $ChildType child was created by',
2981            debugCreator,
2982            style: DiagnosticsTreeStyle.errorProperty,
2983          ),
2984          ErrorSpacer(),
2985          DiagnosticsProperty<dynamic>(
2986            'The ${child.runtimeType} that did not match the expected child type '
2987            'was created by',
2988            child.debugCreator,
2989            style: DiagnosticsTreeStyle.errorProperty,
2990          ),
2991        ]);
2992      }
2993      return true;
2994    }());
2995    return true;
2996  }
2997
2998  ChildType _firstChild;
2999  ChildType _lastChild;
3000  void _insertIntoChildList(ChildType child, { ChildType after }) {
3001    final ParentDataType childParentData = child.parentData;
3002    assert(childParentData.nextSibling == null);
3003    assert(childParentData.previousSibling == null);
3004    _childCount += 1;
3005    assert(_childCount > 0);
3006    if (after == null) {
3007      // insert at the start (_firstChild)
3008      childParentData.nextSibling = _firstChild;
3009      if (_firstChild != null) {
3010        final ParentDataType _firstChildParentData = _firstChild.parentData;
3011        _firstChildParentData.previousSibling = child;
3012      }
3013      _firstChild = child;
3014      _lastChild ??= child;
3015    } else {
3016      assert(_firstChild != null);
3017      assert(_lastChild != null);
3018      assert(_debugUltimatePreviousSiblingOf(after, equals: _firstChild));
3019      assert(_debugUltimateNextSiblingOf(after, equals: _lastChild));
3020      final ParentDataType afterParentData = after.parentData;
3021      if (afterParentData.nextSibling == null) {
3022        // insert at the end (_lastChild); we'll end up with two or more children
3023        assert(after == _lastChild);
3024        childParentData.previousSibling = after;
3025        afterParentData.nextSibling = child;
3026        _lastChild = child;
3027      } else {
3028        // insert in the middle; we'll end up with three or more children
3029        // set up links from child to siblings
3030        childParentData.nextSibling = afterParentData.nextSibling;
3031        childParentData.previousSibling = after;
3032        // set up links from siblings to child
3033        final ParentDataType childPreviousSiblingParentData = childParentData.previousSibling.parentData;
3034        final ParentDataType childNextSiblingParentData = childParentData.nextSibling.parentData;
3035        childPreviousSiblingParentData.nextSibling = child;
3036        childNextSiblingParentData.previousSibling = child;
3037        assert(afterParentData.nextSibling == child);
3038      }
3039    }
3040  }
3041  /// Insert child into this render object's child list after the given child.
3042  ///
3043  /// If `after` is null, then this inserts the child at the start of the list,
3044  /// and the child becomes the new [firstChild].
3045  void insert(ChildType child, { ChildType after }) {
3046    assert(child != this, 'A RenderObject cannot be inserted into itself.');
3047    assert(after != this, 'A RenderObject cannot simultaneously be both the parent and the sibling of another RenderObject.');
3048    assert(child != after, 'A RenderObject cannot be inserted after itself.');
3049    assert(child != _firstChild);
3050    assert(child != _lastChild);
3051    adoptChild(child);
3052    _insertIntoChildList(child, after: after);
3053  }
3054
3055  /// Append child to the end of this render object's child list.
3056  void add(ChildType child) {
3057    insert(child, after: _lastChild);
3058  }
3059
3060  /// Add all the children to the end of this render object's child list.
3061  void addAll(List<ChildType> children) {
3062    children?.forEach(add);
3063  }
3064
3065  void _removeFromChildList(ChildType child) {
3066    final ParentDataType childParentData = child.parentData;
3067    assert(_debugUltimatePreviousSiblingOf(child, equals: _firstChild));
3068    assert(_debugUltimateNextSiblingOf(child, equals: _lastChild));
3069    assert(_childCount >= 0);
3070    if (childParentData.previousSibling == null) {
3071      assert(_firstChild == child);
3072      _firstChild = childParentData.nextSibling;
3073    } else {
3074      final ParentDataType childPreviousSiblingParentData = childParentData.previousSibling.parentData;
3075      childPreviousSiblingParentData.nextSibling = childParentData.nextSibling;
3076    }
3077    if (childParentData.nextSibling == null) {
3078      assert(_lastChild == child);
3079      _lastChild = childParentData.previousSibling;
3080    } else {
3081      final ParentDataType childNextSiblingParentData = childParentData.nextSibling.parentData;
3082      childNextSiblingParentData.previousSibling = childParentData.previousSibling;
3083    }
3084    childParentData.previousSibling = null;
3085    childParentData.nextSibling = null;
3086    _childCount -= 1;
3087  }
3088
3089  /// Remove this child from the child list.
3090  ///
3091  /// Requires the child to be present in the child list.
3092  void remove(ChildType child) {
3093    _removeFromChildList(child);
3094    dropChild(child);
3095  }
3096
3097  /// Remove all their children from this render object's child list.
3098  ///
3099  /// More efficient than removing them individually.
3100  void removeAll() {
3101    ChildType child = _firstChild;
3102    while (child != null) {
3103      final ParentDataType childParentData = child.parentData;
3104      final ChildType next = childParentData.nextSibling;
3105      childParentData.previousSibling = null;
3106      childParentData.nextSibling = null;
3107      dropChild(child);
3108      child = next;
3109    }
3110    _firstChild = null;
3111    _lastChild = null;
3112    _childCount = 0;
3113  }
3114
3115  /// Move the given `child` in the child list to be after another child.
3116  ///
3117  /// More efficient than removing and re-adding the child. Requires the child
3118  /// to already be in the child list at some position. Pass null for `after` to
3119  /// move the child to the start of the child list.
3120  void move(ChildType child, { ChildType after }) {
3121    assert(child != this);
3122    assert(after != this);
3123    assert(child != after);
3124    assert(child.parent == this);
3125    final ParentDataType childParentData = child.parentData;
3126    if (childParentData.previousSibling == after)
3127      return;
3128    _removeFromChildList(child);
3129    _insertIntoChildList(child, after: after);
3130    markNeedsLayout();
3131  }
3132
3133  @override
3134  void attach(PipelineOwner owner) {
3135    super.attach(owner);
3136    ChildType child = _firstChild;
3137    while (child != null) {
3138      child.attach(owner);
3139      final ParentDataType childParentData = child.parentData;
3140      child = childParentData.nextSibling;
3141    }
3142  }
3143
3144  @override
3145  void detach() {
3146    super.detach();
3147    ChildType child = _firstChild;
3148    while (child != null) {
3149      child.detach();
3150      final ParentDataType childParentData = child.parentData;
3151      child = childParentData.nextSibling;
3152    }
3153  }
3154
3155  @override
3156  void redepthChildren() {
3157    ChildType child = _firstChild;
3158    while (child != null) {
3159      redepthChild(child);
3160      final ParentDataType childParentData = child.parentData;
3161      child = childParentData.nextSibling;
3162    }
3163  }
3164
3165  @override
3166  void visitChildren(RenderObjectVisitor visitor) {
3167    ChildType child = _firstChild;
3168    while (child != null) {
3169      visitor(child);
3170      final ParentDataType childParentData = child.parentData;
3171      child = childParentData.nextSibling;
3172    }
3173  }
3174
3175  /// The first child in the child list.
3176  ChildType get firstChild => _firstChild;
3177
3178  /// The last child in the child list.
3179  ChildType get lastChild => _lastChild;
3180
3181  /// The previous child before the given child in the child list.
3182  ChildType childBefore(ChildType child) {
3183    assert(child != null);
3184    assert(child.parent == this);
3185    final ParentDataType childParentData = child.parentData;
3186    return childParentData.previousSibling;
3187  }
3188
3189  /// The next child after the given child in the child list.
3190  ChildType childAfter(ChildType child) {
3191    assert(child != null);
3192    assert(child.parent == this);
3193    final ParentDataType childParentData = child.parentData;
3194    return childParentData.nextSibling;
3195  }
3196
3197  @override
3198  List<DiagnosticsNode> debugDescribeChildren() {
3199    final List<DiagnosticsNode> children = <DiagnosticsNode>[];
3200    if (firstChild != null) {
3201      ChildType child = firstChild;
3202      int count = 1;
3203      while (true) {
3204        children.add(child.toDiagnosticsNode(name: 'child $count'));
3205        if (child == lastChild)
3206          break;
3207        count += 1;
3208        final ParentDataType childParentData = child.parentData;
3209        child = childParentData.nextSibling;
3210      }
3211    }
3212    return children;
3213  }
3214}
3215
3216/// Variant of [FlutterErrorDetails] with extra fields for the rendering
3217/// library.
3218class FlutterErrorDetailsForRendering extends FlutterErrorDetails {
3219  /// Creates a [FlutterErrorDetailsForRendering] object with the given
3220  /// arguments setting the object's properties.
3221  ///
3222  /// The rendering library calls this constructor when catching an exception
3223  /// that will subsequently be reported using [FlutterError.onError].
3224  const FlutterErrorDetailsForRendering({
3225    dynamic exception,
3226    StackTrace stack,
3227    String library,
3228    DiagnosticsNode context,
3229    this.renderObject,
3230    InformationCollector informationCollector,
3231    bool silent = false,
3232  }) : super(
3233    exception: exception,
3234    stack: stack,
3235    library: library,
3236    context: context,
3237    informationCollector: informationCollector,
3238    silent: silent
3239  );
3240
3241  /// The RenderObject that was being processed when the exception was caught.
3242  final RenderObject renderObject;
3243}
3244
3245/// Describes the semantics information a [RenderObject] wants to add to its
3246/// parent.
3247///
3248/// It has two notable subclasses:
3249///  * [_InterestingSemanticsFragment] describing actual semantic information to
3250///    be added to the parent.
3251///  * [_ContainerSemanticsFragment]: a container class to transport the semantic
3252///    information of multiple [_InterestingSemanticsFragment] to a parent.
3253abstract class _SemanticsFragment {
3254  _SemanticsFragment({@required this.dropsSemanticsOfPreviousSiblings })
3255    : assert (dropsSemanticsOfPreviousSiblings != null);
3256
3257  /// Incorporate the fragments of children into this fragment.
3258  void addAll(Iterable<_InterestingSemanticsFragment> fragments);
3259
3260  /// Whether this fragment wants to make the semantics information of
3261  /// previously painted [RenderObject]s unreachable for accessibility purposes.
3262  ///
3263  /// See also:
3264  ///
3265  ///  * [SemanticsConfiguration.isBlockingSemanticsOfPreviouslyPaintedNodes]
3266  ///    describes what semantics are dropped in more detail.
3267  final bool dropsSemanticsOfPreviousSiblings;
3268
3269  /// Returns [_InterestingSemanticsFragment] describing the actual semantic
3270  /// information that this fragment wants to add to the parent.
3271  Iterable<_InterestingSemanticsFragment> get interestingFragments;
3272
3273  /// Whether this fragment wants to abort the semantics walk because the
3274  /// information in the tree are not sufficient to calculate semantics.
3275  ///
3276  /// This happens for subtrees that are currently kept alive by a viewport but
3277  /// not laid out.
3278  ///
3279  /// See also:
3280  ///
3281  ///  * [_AbortingSemanticsFragment], which sets this to true.
3282  bool get abortsWalk => false;
3283}
3284
3285/// A container used when a [RenderObject] wants to add multiple independent
3286/// [_InterestingSemanticsFragment] to its parent.
3287///
3288/// The [_InterestingSemanticsFragment] to be added to the parent can be
3289/// obtained via [interestingFragments].
3290class _ContainerSemanticsFragment extends _SemanticsFragment {
3291
3292  _ContainerSemanticsFragment({ @required bool dropsSemanticsOfPreviousSiblings })
3293    : super(dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings);
3294
3295  @override
3296  void addAll(Iterable<_InterestingSemanticsFragment> fragments) {
3297    interestingFragments.addAll(fragments);
3298  }
3299
3300  @override
3301  final List<_InterestingSemanticsFragment> interestingFragments = <_InterestingSemanticsFragment>[];
3302}
3303
3304/// A [_SemanticsFragment] that describes which concrete semantic information
3305/// a [RenderObject] wants to add to the [SemanticsNode] of its parent.
3306///
3307/// Specifically, it describes which children (as returned by [compileChildren])
3308/// should be added to the parent's [SemanticsNode] and which [config] should be
3309/// merged into the parent's [SemanticsNode].
3310abstract class _InterestingSemanticsFragment extends _SemanticsFragment {
3311  _InterestingSemanticsFragment({
3312    @required RenderObject owner,
3313    @required bool dropsSemanticsOfPreviousSiblings,
3314  }) : assert(owner != null),
3315       _ancestorChain = <RenderObject>[owner],
3316       super(dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings);
3317
3318  /// The [RenderObject] that owns this fragment (and any new [SemanticNode]
3319  /// introduced by it).
3320  RenderObject get owner => _ancestorChain.first;
3321
3322  final List<RenderObject> _ancestorChain;
3323
3324  /// The children to be added to the parent.
3325  ///
3326  /// See also:
3327  ///
3328  ///  * [SemanticsNode.parentSemanticsClipRect] for the source and definition
3329  ///    of the `parentSemanticsClipRect` argument.
3330  ///  * [SemanticsNode.parentPaintClipRect] for the source and definition
3331  //     of the `parentPaintClipRect` argument.
3332  ///  * [SemanticsNode.elevationAdjustment] for the source and definition
3333  //    of the `elevationAdjustment` argument.
3334  Iterable<SemanticsNode> compileChildren({
3335    @required Rect parentSemanticsClipRect,
3336    @required Rect parentPaintClipRect,
3337    @required double elevationAdjustment,
3338  });
3339
3340  /// The [SemanticsConfiguration] the child wants to merge into the parent's
3341  /// [SemanticsNode] or null if it doesn't want to merge anything.
3342  SemanticsConfiguration get config;
3343
3344  /// Disallows this fragment to merge any configuration into its parent's
3345  /// [SemanticsNode].
3346  ///
3347  /// After calling this the fragment will only produce children to be added
3348  /// to the parent and it will return null for [config].
3349  void markAsExplicit();
3350
3351  /// Consume the fragments of children.
3352  ///
3353  /// For each provided fragment it will add that fragment's children to
3354  /// this fragment's children (as returned by [compileChildren]) and merge that
3355  /// fragment's [config] into this fragment's [config].
3356  ///
3357  /// If a provided fragment should not merge anything into [config] call
3358  /// [markAsExplicit] before passing the fragment to this method.
3359  @override
3360  void addAll(Iterable<_InterestingSemanticsFragment> fragments);
3361
3362  /// Whether this fragment wants to add any semantic information to the parent
3363  /// [SemanticsNode].
3364  bool get hasConfigForParent => config != null;
3365
3366  @override
3367  Iterable<_InterestingSemanticsFragment> get interestingFragments sync* {
3368    yield this;
3369  }
3370
3371  Set<SemanticsTag> _tagsForChildren;
3372
3373  /// Tag all children produced by [compileChildren] with `tags`.
3374  void addTags(Iterable<SemanticsTag> tags) {
3375    if (tags == null || tags.isEmpty)
3376      return;
3377    _tagsForChildren ??= <SemanticsTag>{};
3378    _tagsForChildren.addAll(tags);
3379  }
3380
3381  /// Adds the geometric information of `ancestor` to this object.
3382  ///
3383  /// Those information are required to properly compute the value for
3384  /// [SemanticsNode.transform], [SemanticsNode.clipRect], and
3385  /// [SemanticsNode.rect].
3386  ///
3387  /// Ancestors have to be added in order from [owner] up until the next
3388  /// [RenderObject] that owns a [SemanticsNode] is reached.
3389  void addAncestor(RenderObject ancestor) {
3390    _ancestorChain.add(ancestor);
3391  }
3392}
3393
3394/// An [_InterestingSemanticsFragment] that produces the root [SemanticsNode] of
3395/// the semantics tree.
3396///
3397/// The root node is available as the only element in the Iterable returned by
3398/// [children].
3399class _RootSemanticsFragment extends _InterestingSemanticsFragment {
3400  _RootSemanticsFragment({
3401    @required RenderObject owner,
3402    @required bool dropsSemanticsOfPreviousSiblings,
3403  }) : super(owner: owner, dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings);
3404
3405  @override
3406  Iterable<SemanticsNode> compileChildren({ Rect parentSemanticsClipRect, Rect parentPaintClipRect, double elevationAdjustment }) sync* {
3407    assert(_tagsForChildren == null || _tagsForChildren.isEmpty);
3408    assert(parentSemanticsClipRect == null);
3409    assert(parentPaintClipRect == null);
3410    assert(_ancestorChain.length == 1);
3411    assert(elevationAdjustment == 0.0);
3412
3413    owner._semantics ??= SemanticsNode.root(
3414      showOnScreen: owner.showOnScreen,
3415      owner: owner.owner.semanticsOwner,
3416    );
3417    final SemanticsNode node = owner._semantics;
3418    assert(MatrixUtils.matrixEquals(node.transform, Matrix4.identity()));
3419    assert(node.parentSemanticsClipRect == null);
3420    assert(node.parentPaintClipRect == null);
3421
3422    node.rect = owner.semanticBounds;
3423
3424    final List<SemanticsNode> children = _children
3425      .expand((_InterestingSemanticsFragment fragment) {
3426        assert(fragment.config == null);
3427        return fragment.compileChildren(
3428          parentSemanticsClipRect: parentSemanticsClipRect,
3429          parentPaintClipRect: parentPaintClipRect,
3430          elevationAdjustment: 0.0,
3431        );
3432      })
3433      .toList();
3434    node.updateWith(config: null, childrenInInversePaintOrder: children);
3435
3436    // The root node is the only semantics node allowed to be invisible. This
3437    // can happen when the canvas the app is drawn on has a size of 0 by 0
3438    // pixel. If this happens, the root node must not have any children (because
3439    // these would be invisible as well and are therefore excluded from the
3440    // tree).
3441    assert(!node.isInvisible || children.isEmpty);
3442    yield node;
3443  }
3444
3445  @override
3446  SemanticsConfiguration get config => null;
3447
3448  final List<_InterestingSemanticsFragment> _children = <_InterestingSemanticsFragment>[];
3449
3450  @override
3451  void markAsExplicit() {
3452    // nothing to do, we are always explicit.
3453  }
3454
3455  @override
3456  void addAll(Iterable<_InterestingSemanticsFragment> fragments) {
3457    _children.addAll(fragments);
3458  }
3459}
3460
3461/// An [_InterestingSemanticsFragment] that can be told to only add explicit
3462/// [SemanticsNode]s to the parent.
3463///
3464/// If [markAsExplicit] was not called before this fragment is added to
3465/// another fragment it will merge [config] into the parent's [SemanticsNode]
3466/// and add its [children] to it.
3467///
3468/// If [markAsExplicit] was called before adding this fragment to another
3469/// fragment it will create a new [SemanticsNode]. The newly created node will
3470/// be annotated with the [SemanticsConfiguration] that - without the call to
3471/// [markAsExplicit] - would have been merged into the parent's [SemanticsNode].
3472/// Similarly, the new node will also take over the children that otherwise
3473/// would have been added to the parent's [SemanticsNode].
3474///
3475/// After a call to [markAsExplicit] the only element returned by [children]
3476/// is the newly created node and [config] will return null as the fragment
3477/// no longer wants to merge any semantic information into the parent's
3478/// [SemanticsNode].
3479class _SwitchableSemanticsFragment extends _InterestingSemanticsFragment {
3480  _SwitchableSemanticsFragment({
3481    @required bool mergeIntoParent,
3482    @required SemanticsConfiguration config,
3483    @required RenderObject owner,
3484    @required bool dropsSemanticsOfPreviousSiblings,
3485  }) : _mergeIntoParent = mergeIntoParent,
3486       _config = config,
3487       assert(mergeIntoParent != null),
3488       assert(config != null),
3489       super(owner: owner, dropsSemanticsOfPreviousSiblings: dropsSemanticsOfPreviousSiblings);
3490
3491  final bool _mergeIntoParent;
3492  SemanticsConfiguration _config;
3493  bool _isConfigWritable = false;
3494  final List<_InterestingSemanticsFragment> _children = <_InterestingSemanticsFragment>[];
3495
3496  @override
3497  Iterable<SemanticsNode> compileChildren({ Rect parentSemanticsClipRect, Rect parentPaintClipRect, double elevationAdjustment }) sync* {
3498    if (!_isExplicit) {
3499      owner._semantics = null;
3500      for (_InterestingSemanticsFragment fragment in _children) {
3501        assert(_ancestorChain.first == fragment._ancestorChain.last);
3502        fragment._ancestorChain.addAll(_ancestorChain.sublist(1));
3503        yield* fragment.compileChildren(
3504          parentSemanticsClipRect: parentSemanticsClipRect,
3505          parentPaintClipRect: parentPaintClipRect,
3506          // The fragment is not explicit, its elevation has been absorbed by
3507          // the parent config (as thickness). We still need to make sure that
3508          // its children are placed at the elevation dictated by this config.
3509          elevationAdjustment: elevationAdjustment + _config.elevation,
3510        );
3511      }
3512      return;
3513    }
3514
3515    final _SemanticsGeometry geometry = _needsGeometryUpdate
3516        ? _SemanticsGeometry(parentSemanticsClipRect: parentSemanticsClipRect, parentPaintClipRect: parentPaintClipRect, ancestors: _ancestorChain)
3517        : null;
3518
3519    if (!_mergeIntoParent && (geometry?.dropFromTree == true))
3520      return;  // Drop the node, it's not going to be visible.
3521
3522    owner._semantics ??= SemanticsNode(showOnScreen: owner.showOnScreen);
3523    final SemanticsNode node = owner._semantics
3524      ..isMergedIntoParent = _mergeIntoParent
3525      ..tags = _tagsForChildren;
3526
3527    node.elevationAdjustment = elevationAdjustment;
3528    if (elevationAdjustment != 0.0) {
3529      _ensureConfigIsWritable();
3530      _config.elevation += elevationAdjustment;
3531    }
3532
3533    if (geometry != null) {
3534      assert(_needsGeometryUpdate);
3535      node
3536        ..rect = geometry.rect
3537        ..transform = geometry.transform
3538        ..parentSemanticsClipRect = geometry.semanticsClipRect
3539        ..parentPaintClipRect = geometry.paintClipRect;
3540      if (!_mergeIntoParent && geometry.markAsHidden) {
3541        _ensureConfigIsWritable();
3542        _config.isHidden = true;
3543      }
3544    }
3545
3546    final List<SemanticsNode> children = _children
3547      .expand((_InterestingSemanticsFragment fragment) => fragment.compileChildren(
3548        parentSemanticsClipRect: node.parentSemanticsClipRect,
3549        parentPaintClipRect: node.parentPaintClipRect,
3550        elevationAdjustment: 0.0,
3551      ))
3552      .toList();
3553
3554    if (_config.isSemanticBoundary) {
3555      owner.assembleSemanticsNode(node, _config, children);
3556    } else {
3557      node.updateWith(config: _config, childrenInInversePaintOrder: children);
3558    }
3559
3560    yield node;
3561  }
3562
3563  @override
3564  SemanticsConfiguration get config {
3565    return _isExplicit ? null : _config;
3566  }
3567
3568  @override
3569  void addAll(Iterable<_InterestingSemanticsFragment> fragments) {
3570    for (_InterestingSemanticsFragment fragment in fragments) {
3571      _children.add(fragment);
3572      if (fragment.config == null)
3573        continue;
3574      _ensureConfigIsWritable();
3575      _config.absorb(fragment.config);
3576    }
3577  }
3578
3579  void _ensureConfigIsWritable() {
3580    if (!_isConfigWritable) {
3581      _config = _config.copy();
3582      _isConfigWritable = true;
3583    }
3584  }
3585
3586  bool _isExplicit = false;
3587
3588  @override
3589  void markAsExplicit() {
3590    _isExplicit = true;
3591  }
3592
3593  bool get _needsGeometryUpdate => _ancestorChain.length > 1;
3594}
3595
3596
3597/// [_SemanticsFragment] used to indicate that the current information in this
3598/// subtree is not sufficient to update semantics.
3599///
3600/// Anybody processing this [_SemanticsFragment] should abort the walk of the
3601/// current subtree without updating any [SemanticsNode]s as there is no semantic
3602/// information to compute. As a result, this fragment also doesn't carry any
3603/// semantics information either.
3604class _AbortingSemanticsFragment extends _InterestingSemanticsFragment {
3605  _AbortingSemanticsFragment({@required RenderObject owner}) : super(owner: owner, dropsSemanticsOfPreviousSiblings: false);
3606
3607  @override
3608  bool get abortsWalk => true;
3609
3610  @override
3611  SemanticsConfiguration get config => null;
3612
3613  @override
3614  void addAll(Iterable<_InterestingSemanticsFragment> fragments) {
3615    assert(false);
3616  }
3617
3618  @override
3619  Iterable<SemanticsNode> compileChildren({ Rect parentSemanticsClipRect, Rect parentPaintClipRect, double elevationAdjustment }) sync* {
3620    yield owner._semantics;
3621  }
3622
3623  @override
3624  void markAsExplicit() {
3625    // Is never explicit.
3626  }
3627}
3628
3629/// Helper class that keeps track of the geometry of a [SemanticsNode].
3630///
3631/// It is used to annotate a [SemanticsNode] with the current information for
3632/// [SemanticsNode.rect] and [SemanticsNode.transform].
3633class _SemanticsGeometry {
3634
3635  /// The `parentClippingRect` may be null if no clip is to be applied.
3636  ///
3637  /// The `ancestors` list has to include all [RenderObject] in order that are
3638  /// located between the [SemanticsNode] whose geometry is represented here
3639  /// (first [RenderObject] in the list) and its closest ancestor [RenderObject]
3640  /// that also owns its own [SemanticsNode] (last [RenderObject] in the list).
3641  _SemanticsGeometry({
3642    @required Rect parentSemanticsClipRect,
3643    @required Rect parentPaintClipRect,
3644    @required List<RenderObject> ancestors,
3645  }) {
3646    _computeValues(parentSemanticsClipRect, parentPaintClipRect, ancestors);
3647  }
3648
3649  Rect _paintClipRect;
3650  Rect _semanticsClipRect;
3651  Matrix4 _transform;
3652  Rect _rect;
3653
3654  /// Value for [SemanticsNode.transform].
3655  Matrix4 get transform => _transform;
3656
3657  /// Value for [SemanticsNode.parentSemanticsClipRect].
3658  Rect get semanticsClipRect => _semanticsClipRect;
3659
3660  /// Value for [SemanticsNode.parentPaintClipRect].
3661  Rect get paintClipRect => _paintClipRect;
3662
3663  /// Value for [SemanticsNode.rect].
3664  Rect get rect => _rect;
3665
3666  void _computeValues(Rect parentSemanticsClipRect, Rect parentPaintClipRect, List<RenderObject> ancestors) {
3667    assert(ancestors.length > 1);
3668
3669    _transform = Matrix4.identity();
3670    _semanticsClipRect = parentSemanticsClipRect;
3671    _paintClipRect = parentPaintClipRect;
3672    for (int index = ancestors.length-1; index > 0; index -= 1) {
3673      final RenderObject parent = ancestors[index];
3674      final RenderObject child = ancestors[index-1];
3675      final Rect parentSemanticsClipRect = parent.describeSemanticsClip(child);
3676      if (parentSemanticsClipRect != null) {
3677        _semanticsClipRect = parentSemanticsClipRect;
3678        _paintClipRect = _intersectRects(_paintClipRect, parent.describeApproximatePaintClip(child));
3679      } else {
3680        _semanticsClipRect = _intersectRects(_semanticsClipRect, parent.describeApproximatePaintClip(child));
3681      }
3682      _temporaryTransformHolder.setIdentity(); // clears data from previous call(s)
3683      _applyIntermediatePaintTransforms(parent, child, _transform, _temporaryTransformHolder);
3684      _semanticsClipRect = _transformRect(_semanticsClipRect, _temporaryTransformHolder);
3685      _paintClipRect = _transformRect(_paintClipRect, _temporaryTransformHolder);
3686    }
3687
3688    final RenderObject owner = ancestors.first;
3689    _rect = _semanticsClipRect == null ? owner.semanticBounds : _semanticsClipRect.intersect(owner.semanticBounds);
3690    if (_paintClipRect != null) {
3691      final Rect paintRect = _paintClipRect.intersect(_rect);
3692      _markAsHidden = paintRect.isEmpty && !_rect.isEmpty;
3693      if (!_markAsHidden)
3694        _rect = paintRect;
3695    }
3696  }
3697
3698  // A matrix used to store transient transform data.
3699  //
3700  // Reusing this matrix avoids allocating a new matrix every time a temporary
3701  // matrix is needed.
3702  //
3703  // This instance should never be returned to the caller. Otherwise, the data
3704  // stored in it will be overwritten unpredictably by subsequent reuses.
3705  static final Matrix4 _temporaryTransformHolder = Matrix4.zero();
3706
3707  /// From parent to child coordinate system.
3708  static Rect _transformRect(Rect rect, Matrix4 transform) {
3709    assert(transform != null);
3710    if (rect == null)
3711      return null;
3712    if (rect.isEmpty || transform.isZero())
3713      return Rect.zero;
3714    return MatrixUtils.inverseTransformRect(transform, rect);
3715  }
3716
3717  // Calls applyPaintTransform on all of the render objects between [child] and
3718  // [ancestor]. This method handles cases where the immediate semantic parent
3719  // is not the immediate render object parent of the child.
3720  //
3721  // It will mutate both transform and clipRectTransform.
3722  static void _applyIntermediatePaintTransforms(
3723    RenderObject ancestor,
3724    RenderObject child,
3725    Matrix4 transform,
3726    Matrix4 clipRectTransform,
3727  ) {
3728    assert(ancestor != null);
3729    assert(child != null);
3730    assert(transform != null);
3731    assert(clipRectTransform != null);
3732    assert(clipRectTransform.isIdentity());
3733    RenderObject intermediateParent = child.parent;
3734    assert(intermediateParent != null);
3735    while (intermediateParent != ancestor) {
3736      intermediateParent.applyPaintTransform(child, transform);
3737      intermediateParent = intermediateParent.parent;
3738      child = child.parent;
3739      assert(intermediateParent != null);
3740    }
3741    ancestor.applyPaintTransform(child, transform);
3742    ancestor.applyPaintTransform(child, clipRectTransform);
3743  }
3744
3745  static Rect _intersectRects(Rect a, Rect b) {
3746    if (a == null)
3747      return b;
3748    if (b == null)
3749      return a;
3750    return a.intersect(b);
3751  }
3752
3753  /// Whether the [SemanticsNode] annotated with the geometric information tracked
3754  /// by this object can be dropped from the semantics tree without losing
3755  /// semantics information.
3756  bool get dropFromTree {
3757    return _rect.isEmpty;
3758  }
3759
3760  /// Whether the [SemanticsNode] annotated with the geometric information
3761  /// tracked by this object should be marked as hidden because it is not
3762  /// visible on screen.
3763  ///
3764  /// Hidden elements should still be included in the tree to work around
3765  /// platform limitations (e.g. accessibility scrolling on iOS).
3766  ///
3767  /// See also:
3768  ///
3769  ///  * [SemanticsFlag.isHidden] for the purpose of marking a node as hidden.
3770  bool get markAsHidden => _markAsHidden;
3771  bool _markAsHidden = false;
3772}
3773
3774/// A class that creates [DiagnosticsNode] by wrapping [RenderObject.debugCreator].
3775///
3776/// Attach a [DiagnosticsDebugCreator] into [FlutterErrorDetails.informationCollector]
3777/// when a [RenderObject.debugCreator] is available. This will lead to improved
3778/// error message.
3779class DiagnosticsDebugCreator extends DiagnosticsProperty<Object> {
3780  /// Create a [DiagnosticsProperty] with its [value] initialized to input
3781  /// [RenderObject.debugCreator].
3782  DiagnosticsDebugCreator(Object value):
3783    assert(value != null),
3784    super(
3785      'debugCreator',
3786      value,
3787      level: DiagnosticLevel.hidden
3788    );
3789}
3790