Jonah Williams c4c545215a
Support backdrop key in flutter framework. (#157278)
The backdrop key functionality allows multiple backdrop filters to share the same input filter, dramatically improving raster performance. This is only supported on the Impeller backend.

The backdrop key class allocates a new int from a static and passes this to the engine layer. with 64 bit integers, we can allocate many backdrop filter ids per frame and never run out.

See also: https://github.com/flutter/flutter/issues/156455

```dart
import 'dart:math';
import 'dart:ui';

import 'package:flutter/material.dart';

final _random = Random();

void main() => runApp(const BackdropFilterDemo());

class BackdropFilterDemo extends StatelessWidget {
  const BackdropFilterDemo({super.key});

  static final listKey = BackdropKey();
  static final overlayKey = BackdropKey();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        body: Stack(
          children: [
            ListView.builder(
              itemCount: 120, // 60 pairs of red and blue containers
              itemBuilder: (context, index) {
                return Container(
                  height: 100,
                  color: index % 2 == 0 ? Colors.red : Colors.blue,
                );
              },
            ),
            Center(
              child: Container(
                width: 400,
                height: 400,
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.black),
                ),
                child: Image.network('https://picsum.photos/400'),
              ),
            ),
            ListView.separated(
              separatorBuilder: (_, __) => const SizedBox(height: 8),
              itemBuilder: (context, index) => BlurEffect(
                backdropKey: listKey,
                child: SizedBox(
                  height: 50,
                  child: Center(
                    child: Text(index.toString(),
                        style: const TextStyle(color: Colors.white)),
                  ),
                ),
              ),
              itemCount: 200,
            ),
            Positioned.fill(
              bottom: null,
              child: BlurEffect(
                backdropKey: overlayKey,
                child: Padding(
                  padding: EdgeInsets.only(
                    top: MediaQuery.of(context).viewPadding.top,
                  ),
                  child: const SizedBox(height: 45),
                ),
              ),
            ),
            Positioned.fill(
              top: null,
              child: BlurEffect(
                backdropKey: overlayKey,
                child: Padding(
                  padding: EdgeInsets.only(
                    top: MediaQuery.of(context).viewPadding.bottom,
                  ),
                  child: const SizedBox(height: 50),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class BlurEffect extends StatelessWidget {
  final Widget child;

  const BlurEffect({
    required this.child,
    required this.backdropKey,
    super.key,
  });

  final BackdropKey backdropKey;

  @override
  Widget build(BuildContext context) {
    return ClipRect(
      child: BackdropFilter(
        backdropKey: backdropKey,
        filter: ImageFilter.blur(
          sigmaX: 40,
          sigmaY: 40,
          // tileMode: TileMode.mirror,
        ),
        child: DecoratedBox(
          decoration: BoxDecoration(color: Colors.black.withOpacity(.65)),
          child: child,
        ),
      ),
    );
  }
}
```

### Skia

<img src="https://github.com/user-attachments/assets/4c08e92d-f0ba-42b2-a4c4-fc44efbcfae0" width="200"/>

### Impeller

<img src="https://github.com/user-attachments/assets/21e95efd-5e0c-4f41-8f84-af3f0e47d1aa" width="200"/>
2024-10-25 16:27:51 +00:00
..
2024-03-24 18:01:17 +00:00
2024-09-09 20:35:03 +00:00