bcc blink-dev
A paint-under-invalidation means that a DisplayItemClient (normally a LayoutObject) has not been invalidated (via DisplayItemClient::Invalidate) while its painted result will change. In production (with under-invalidation checking disabled by default) that may cause stale painting displayed. For some web tests, we enable under-invalidaton checking to crash on such problems. See
this doc for more details about paint invalidation.
In your case, the DisplayItemClient is "LayoutHTMLCanvas CANVAS id='canvas'". It painted an empty foreground in the previous document life cycle, and paints (forced by under-invalidation checking) an image rect in the current cycle, but it has not been invalidated. If under-invalidation checking is disabled, you'll see missing image rect.
Based on the code, I guess canvas() changed from false to true in the current cycle, but we don't invalidate in this case. We seem to have some code (maybe in HTMLCanvasElement) that invalidates the DisplayItemClient when IsPaintable() changes, so the previous code works.
I think you just need to call SetShouldDoFullPaintInvalidation when canvas() changes.