Off Main Thread CSS Paint
BlinkOn 10 (Toronto, Canada)
xidachen@chromium.org, smcgruer@chromium.org
Before CSS Paint
.box {� background-image: url(“cat.jpg”);�}
CSS Paint enables new possibilities
<style>�.box {� background-image: paint(foo);�}�</style>�...�<script>�CSS.paintWorklet.addModule('foo.js');�</script>
class FooPainter {� paint(ctx, geometry, properties) {� // …� }�}��registerPaint('foo', FooPainter);
CSS Paint enables new possibilities
More interesting with animations
<style>�.box {� --size: 100;� background-image: paint(foo);�}�</style>�...
<script>�CSS.paintWorklet.addModule('foo.js');��myBox.animate({� [ --size: [ 100, 200 ] ],�}, {� duration: 2500,�});�</script>
Added to static getter function in FooPainter.
More interesting with animations
Behind the scene...
Main thread is very busy doing:
for all the 60 frames of that animation.�
Jank-free vs janky main thread
Wouldn't it be great if we could...
Solution: move it off the main thread
High-level idea:
A bit more technical detail
Now
Paint
Tiling,
Raster, etc.
Skia
draw
cmds
Commit
Blink (Main Thread)
Compositor (Impl Thread)
PaintWorklet context (v8)
Animations
SLOW!
A bit more technical detail
Future
Paint
Composited Animations
Commit
Blink (Main Thread)
Compositor (Impl Thread)
Create PaintWorkletInputs
Tiling,
Raster, etc.
PaintWorklet Thread
LayerTree
HostImpl
FAST!
PaintWorklet context (v8)
PWIs
Skia
draw cmds
Impl-side Invalidation
Deep Dive - PaintWorkletInput
PaintWorkletInput
"green"
Name
200x500
Size
{
--foo: 20,
left: 50px,
color: 'red',
}
StyleMap
Deep Dive - Compositor
PaintWorklet affecting
animations tick
Scheduler::Set
NeedsImplSide
Invalidation
LTHI::UpdateSync
TreeAfterCommit
OrImplSideInvalidation
Blink Commit
Dispatch paint to paint worklet thread
LTHI::HandlePaint
WorkletResults
LTHI::
PrepareTiles
Unblock activation
if no
dirty PWIs
Dirty PaintWorkletInputs
Results
Deep Dive - PaintWorklet Thread
PaintWorklet thread
Current Status
Summary
Questions?
Challenges