markNeedsPaint method

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 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.

Once markNeedsPaint has been called on a render object, debugNeedsPaint returns true for that render object until just after the pipeline owner has called paint on the render object.

See also:

Implementation

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 {
    assert(() {
      if (debugPrintMarkNeedsPaintStacks)
        debugPrintStack(label: 'markNeedsPaint() called for $this (root of render tree)');
      return true;
    }());
    // 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();
  }
}