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:

  • RepaintBoundary, to scope a subtree of render objects to their own layer, thus limiting the number of nodes that markNeedsPaint must mark dirty.


void markNeedsPaint() {
  assert(owner == null || !owner.debugDoingPaint);
  if (_needsPaint)
  _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 is OffsetLayer);
    if (owner != null) {
  } else if (parent is RenderObject) {
    final RenderObject parent = this.parent as RenderObject;
    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)