Yegor 6bddf99dc0 [web:canvaskit] switch to temporary SkPaint objects (flutter/engine#54818)
Do not eagerly create an `SkPaint` object that's strongly referenced by `CkPaint`. Instead, when a `Canvas.draw*` is called, create a temporary `SkPaint` object, pass it to Skia, then immediately delete it. This way there are no persistent `SkPaint` handles lurking in the system that transitively hold onto expensive native resources.

Addresses the `Paint` issue in https://github.com/flutter/flutter/issues/153678 in CanvasKit

Spot checking some benchmarks. Here's the effect of this PR on `draw_rect_variable_paint`. It's a bit of a stress test as it creates 300K distinct `Paint` objects to render 600 pictures (a typical ratio does not normally exceed ten paints to one picture). Even so, the effect of creating an extra `SkPaint` on every `draw*` command does not look significant. However, removing a dependency on the GC for 300K objects looks like a good trade-off.

## Before

Allocation stats:

```
  Paint Created: 300000
  Paint Deleted: 300000
  Paint Leaked: 300000
  Picture Created: 600
  Picture Deleted: 599
  Picture Leaked: 599
```

Performance stats:

```
windowRenderDuration: (samples: 98 clean/2 outliers/100 measured/300 total)
 | average: 4679.551020408163 μs
 | outlier average: 5100 μs
 | outlier/clean ratio: 1.0898481452084188x
 | noise: 3.11%

sceneBuildDuration: (samples: 98 clean/2 outliers/100 measured/300 total)
 | average: 4689.765306122449 μs
 | outlier average: 5100 μs
 | outlier/clean ratio: 1.087474461321549x
 | noise: 3.19%

drawFrameDuration: (samples: 97 clean/3 outliers/100 measured/300 total)
 | average: 8447.474226804125 μs
 | outlier average: 9332.666666666666 μs
 | outlier/clean ratio: 1.1047878236850721x
 | noise: 3.52%
```

## After

Allocation stats:

```
  Picture Created: 600
  Picture Deleted: 599
  Picture Leaked: 599
```

Performance stats:

```
windowRenderDuration: (samples: 97 clean/3 outliers/100 measured/300 total)
 | average: 4780.40206185567 μs
 | outlier average: 5133.666666666667 μs
 | outlier/clean ratio: 1.0738985131877936x
 | noise: 2.70%

sceneBuildDuration: (samples: 97 clean/3 outliers/100 measured/300 total)
 | average: 4787.6082474226805 μs
 | outlier average: 5133.666666666667 μs
 | outlier/clean ratio: 1.0722821085936345x
 | noise: 2.72%

drawFrameDuration: (samples: 97 clean/3 outliers/100 measured/300 total)
 | average: 8243.309278350516 μs
 | outlier average: 9033.333333333334 μs
 | outlier/clean ratio: 1.0958382159768851x
 | noise: 2.60%
```
2024-08-30 22:06:18 +00:00
..