[Flutter Web(HTML)] fix: shader mask is painted incorrectly on shared offscreen canvas (flutter/engine#44998)

Hi from [Dora team](https://www.dora.run/), which powers web developers to build their 3d websites in just a few seconds.

This PR fixes https://github.com/flutter/flutter/issues/133134.

The size of the shared canvas should not only be updated if both width and height are not the same.

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
Kingtous 2024-07-04 02:22:59 +08:00 committed by GitHub
parent 86642a856c
commit 2ee4fd4317
2 changed files with 58 additions and 1 deletions

View File

@ -961,7 +961,7 @@ class OffScreenCanvas {
}
void resize(int requestedWidth, int requestedHeight) {
if(requestedWidth != width && requestedHeight != height) {
if(requestedWidth != width || requestedHeight != height) {
width = requestedWidth;
height = requestedHeight;
if(offScreenCanvas != null) {

View File

@ -635,6 +635,63 @@ Future<void> testMain() async {
region: region,
);
}, skip: isFirefox);
test('Paints two gradient with same width and different height', () async {
final RecordingCanvas canvas =
RecordingCanvas(const Rect.fromLTRB(0, 0, 400, 300));
canvas.save();
const List<Color> colors = <Color>[
Color(0xFF000000),
Color(0xFFFF3C38),
Color(0xFFFF8C42),
Color(0xFFFFF275),
Color(0xFF6699CC),
Color(0xFF656D78),
];
const List<double> stops = <double>[0.0, 0.05, 0.4, 0.6, 0.9, 1.0];
final Matrix4 transform = Matrix4.identity()
..translate(100, 150)
..scale(0.3, 0.7)
..rotateZ(0.5);
final GradientSweep sweepGradient = GradientSweep(
const Offset(0.5, 0.5),
colors,
stops,
TileMode.clamp,
0.0,
2 * math.pi,
transform.storage,
);
const double kBoxWidth = 150;
const double kBoxHeight1 = 40;
const double kBoxHeight2 = 80;
const Rect rectBounds1 = Rect.fromLTWH(10, 20, kBoxWidth, kBoxHeight1);
const Rect rectBounds2 = Rect.fromLTWH(10, 80, kBoxWidth, kBoxHeight2);
canvas.drawRect(
rectBounds1,
SurfacePaint()
..shader = engineGradientToShader(sweepGradient, rectBounds1),
);
canvas.drawRect(
rectBounds2,
SurfacePaint()
..shader = engineGradientToShader(sweepGradient, rectBounds2),
);
canvas.restore();
await canvasScreenshot(
canvas,
'radial_gradient_double_item',
canvasRect: screenRect,
region: region,
);
}, skip: isFirefox);
}
Shader engineGradientToShader(GradientSweep gradient, Rect rect) {