flutter_elinux/lib/features/benchmark/presentation/vsync_benchmark_screen.dart
2024-03-09 14:29:48 +01:00

97 lines
2.1 KiB
Dart

import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import '../../../common/widgets/floating_menu_button.dart';
class VsyncBenchmarkScreen extends StatelessWidget {
const VsyncBenchmarkScreen({super.key});
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Stack(
children: [
SizedBox(
width: double.infinity,
height: double.infinity,
child: ShaderHomePage(),
),
FloatingMenuButton(),
],
),
);
}
}
class ShaderHomePage extends StatefulWidget {
const ShaderHomePage({super.key});
@override
State<ShaderHomePage> createState() => _ShaderHomePageState();
}
class _ShaderHomePageState extends State<ShaderHomePage>
with SingleTickerProviderStateMixin {
double delta = 0;
FragmentShader? shader;
late final Ticker _ticker;
void loadMyShader() async {
var program = await FragmentProgram.fromAsset('shaders/vsync.frag');
shader = program.fragmentShader();
}
@override
void initState() {
super.initState();
loadMyShader();
_ticker = createTicker((elapsed) {
setState(() {
delta += 1 / 60;
});
});
_ticker.start();
}
@override
void dispose() {
_ticker.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (shader == null) {
return const Center(child: CircularProgressIndicator());
} else {
return Container(
color: Colors.white,
child: CustomPaint(painter: ShaderPainter(shader!, delta)));
}
}
}
class ShaderPainter extends CustomPainter {
final FragmentShader shader;
final double time;
ShaderPainter(FragmentShader fragmentShader, this.time)
: shader = fragmentShader;
@override
void paint(Canvas canvas, Size size) {
final paint = Paint();
shader.setFloat(0, size.width);
shader.setFloat(1, size.height);
shader.setFloat(2, time);
paint.shader = shader;
canvas.drawRect(Offset.zero & size, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}