Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[skwasm] Always do backdrop filter operation even if empty. #54844

Merged
merged 2 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion lib/web_ui/lib/src/engine/layers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ class BackdropFilterOperation implements LayerOperation {

@override
PlatformViewStyling createPlatformViewStyling() => const PlatformViewStyling();

// The backdrop filter actually has an effect on the scene even if it contains
// no pictures, so we return true here.
@override
bool get shouldDrawIfEmpty => true;
}

class ClipPathLayer
Expand Down Expand Up @@ -70,6 +75,9 @@ class ClipPathOperation implements LayerOperation {
PlatformViewStyling createPlatformViewStyling() {
return PlatformViewStyling(clip: PlatformViewPathClip(path));
}

@override
bool get shouldDrawIfEmpty => false;
}

class ClipRectLayer
Expand Down Expand Up @@ -105,6 +113,9 @@ class ClipRectOperation implements LayerOperation {
PlatformViewStyling createPlatformViewStyling() {
return PlatformViewStyling(clip: PlatformViewRectClip(rect));
}

@override
bool get shouldDrawIfEmpty => false;
}

class ClipRRectLayer
Expand Down Expand Up @@ -140,6 +151,9 @@ class ClipRRectOperation implements LayerOperation {
PlatformViewStyling createPlatformViewStyling() {
return PlatformViewStyling(clip: PlatformViewRRectClip(rrect));
}

@override
bool get shouldDrawIfEmpty => false;
}

class ColorFilterLayer
Expand All @@ -165,6 +179,9 @@ class ColorFilterOperation implements LayerOperation {

@override
PlatformViewStyling createPlatformViewStyling() => const PlatformViewStyling();

@override
bool get shouldDrawIfEmpty => false;
}

class ImageFilterLayer
Expand Down Expand Up @@ -207,6 +224,9 @@ class ImageFilterOperation implements LayerOperation {
return const PlatformViewStyling();
}
}

@override
bool get shouldDrawIfEmpty => false;
}

class OffsetLayer
Expand Down Expand Up @@ -236,6 +256,9 @@ class OffsetOperation implements LayerOperation {
PlatformViewStyling createPlatformViewStyling() => PlatformViewStyling(
position: PlatformViewPosition.offset(ui.Offset(dx, dy))
);

@override
bool get shouldDrawIfEmpty => false;
}

class OpacityLayer
Expand Down Expand Up @@ -276,6 +299,9 @@ class OpacityOperation implements LayerOperation {
position: offset != ui.Offset.zero ? PlatformViewPosition.offset(offset) : const PlatformViewPosition.zero(),
opacity: alpha.toDouble() / 255.0,
);

@override
bool get shouldDrawIfEmpty => false;
}

class TransformLayer
Expand Down Expand Up @@ -307,6 +333,9 @@ class TransformOperation implements LayerOperation {
PlatformViewStyling createPlatformViewStyling() => PlatformViewStyling(
position: PlatformViewPosition.transform(matrix),
);

@override
bool get shouldDrawIfEmpty => false;
}

class ShaderMaskLayer
Expand Down Expand Up @@ -346,6 +375,9 @@ class ShaderMaskOperation implements LayerOperation {

@override
PlatformViewStyling createPlatformViewStyling() => const PlatformViewStyling();

@override
bool get shouldDrawIfEmpty => false;
}

class PlatformView {
Expand Down Expand Up @@ -414,6 +446,11 @@ abstract class LayerOperation {
void post(SceneCanvas canvas, ui.Rect contentRect);

PlatformViewStyling createPlatformViewStyling();

/// Indicates whether this operation's `pre` and `post` methods should be
/// invoked even if it contains no pictures. (Most operations don't need to
/// actually be performed at all if they don't contain any pictures.)
bool get shouldDrawIfEmpty;
}

class PictureDrawCommand {
Expand Down Expand Up @@ -771,7 +808,7 @@ class LayerBuilder {
}

void flushSlices() {
if (pendingPictures.isNotEmpty) {
if (pendingPictures.isNotEmpty || (operation?.shouldDrawIfEmpty ?? false)) {
// Merge the existing draw commands into a single picture and add a slice
// with that picture to the slice list.
final ui.Rect drawnRect = picturesRect ?? ui.Rect.zero;
Expand Down
28 changes: 28 additions & 0 deletions lib/web_ui/test/ui/scene_builder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,34 @@ Future<void> testMain() async {
await matchGoldenFile('scene_builder_backdrop_filter.png', region: region);
});

test('empty backdrop filter layer with clip', () async {
// Note that this test does not actually render properly in skwasm due to
// a Skia bug. See https://g-issues.skia.org/issues/362552959 and
// https://github.com/flutter/flutter/issues/152026
final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();

sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
// Create a red and blue checkerboard pattern
final ui.Paint redPaint = ui.Paint()..color = const ui.Color(0xFFFF0000);
final ui.Paint bluePaint = ui.Paint()..color = const ui.Color(0xFF0000FF);
for (double y = 0; y < 300; y += 10) {
for (double x = 0; x < 300; x += 10) {
final ui.Paint paint = ((x + y) % 20 == 0) ? redPaint : bluePaint;
canvas.drawRect(ui.Rect.fromLTWH(x, y, 10, 10), paint);
}
}
}));

sceneBuilder.pushClipRect(const ui.Rect.fromLTRB(100, 100, 200, 200));

sceneBuilder.pushBackdropFilter(ui.ImageFilter.blur(
sigmaX: 3.0,
sigmaY: 3.0,
));
await renderScene(sceneBuilder.build());
await matchGoldenFile('scene_builder_empty_backdrop_filter_with_clip.png', region: region);
});

test('image filter layer', () async {
final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
sceneBuilder.pushImageFilter(ui.ImageFilter.blur(
Expand Down