flushPaint method

void flushPaint()

Update the display lists for all render objects.

This function is one of the core stages of the rendering pipeline. Painting occurs after layout and before the scene is recomposited so that scene is composited with up-to-date display lists for every render object.

See RendererBinding for an example of how this function is used.

Implementation

void flushPaint() {
  if (!kReleaseMode) {
    Map<String, String>? debugTimelineArguments;
    assert(() {
      if (debugEnhancePaintTimelineArguments) {
        debugTimelineArguments = <String, String>{
          'dirty count': '${_nodesNeedingPaint.length}',
          'dirty list': '$_nodesNeedingPaint',
        };
      }
      return true;
    }());
    FlutterTimeline.startSync(
      'PAINT$_debugRootSuffixForTimelineEventNames',
      arguments: debugTimelineArguments,
    );
  }
  try {
    assert(() {
      _debugDoingPaint = true;
      return true;
    }());
    final List<RenderObject> dirtyNodes = _nodesNeedingPaint;
    _nodesNeedingPaint = <RenderObject>[];

    // Sort the dirty nodes in reverse order (deepest first).
    for (final RenderObject node in dirtyNodes..sort((RenderObject a, RenderObject b) => b.depth - a.depth)) {
      assert(node._layerHandle.layer != null);
      if ((node._needsPaint || node._needsCompositedLayerUpdate) && node.owner == this) {
        if (node._layerHandle.layer!.attached) {
          assert(node.isRepaintBoundary);
          if (node._needsPaint) {
            PaintingContext.repaintCompositedChild(node);
          } else {
            PaintingContext.updateLayerProperties(node);
          }
        } else {
          node._skippedPaintingOnLayer();
        }
      }
    }
    for (final PipelineOwner child in _children) {
      child.flushPaint();
    }
    assert(_nodesNeedingPaint.isEmpty, 'Child PipelineOwners must not dirty nodes in their parent.');
  } finally {
    assert(() {
      _debugDoingPaint = false;
      return true;
    }());
    if (!kReleaseMode) {
      FlutterTimeline.finishSync();
    }
  }
}