void markNeedsPaint()

Mark this render object as having changed its visual appearance.

Rather than eagerly updating this render object's display list in response to writes, we instead mark the the render object as needing to paint, which schedules a visual update. As part of the visual update, the rendering pipeline will give this render object an opportunity to update its display list.

This mechanism batches the painting work so that multiple sequential writes are coalesced, removing redundant computation.

Source

void markNeedsPaint() {
  assert(owner == null || !owner.debugDoingPaint);
  if (_needsPaint)
    return;
  _needsPaint = true;
  if (isRepaintBoundary) {
    assert(() {
      if (debugPrintMarkNeedsPaintStacks)
        debugPrintStack(label: 'markNeedsPaint() called for $this');
      return true;
    });
    // If we always have our own layer, then we can just repaint
    // ourselves without involving any other nodes.
    assert(_layer != null);
    if (owner != null) {
      owner._nodesNeedingPaint.add(this);
      owner.requestVisualUpdate();
    }
  } else if (parent is RenderObject) {
    // We don't have our own layer; one of our ancestors will take
    // care of updating the layer we're in and when they do that
    // we'll get our paint() method called.
    assert(_layer == null);
    final RenderObject parent = this.parent;
    parent.markNeedsPaint();
    assert(parent == this.parent);
  } else {
    // If we're the root of the render tree (probably a RenderView),
    // then we have to paint ourselves, since nobody else can paint
    // us. We don't add ourselves to _nodesNeedingPaint in this
    // case, because the root is always told to paint regardless.
    if (owner != null)
      owner.requestVisualUpdate();
  }
}