Skip to content

[Impeller] Filtered rectangle with shader misplaced. #136504

@flar

Description

@flar

Both the unblurred and the blurred drawRect should be centered in their section, and that is what happens with Skia. But with Impeller the blurred version is drawn at the upper left of the entire drawing

Example code
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'ImageFilter on Rect Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            CustomPaint(
              painter: _MyPainter(),
              size: Size(600, 300),
            ),
          ],
        ),
      ),
    );
  }
}

class _MyPainter extends CustomPainter {
  const _MyPainter();

  ui.Image makeImage() {
    ui.PictureRecorder recorder = ui.PictureRecorder();
    Canvas canvas = Canvas(recorder);
    for (int y = 0; y < 5; y++) {
      for (int x = 0; x < 5; x++) {
        Rect rect = Rect.fromLTWH(x * 20.0, y * 20.0, 20.0, 20.0);
        Color color = ((x + y) & 1) == 0 ? Colors.yellow : Colors.blue;
        print('$color at $rect');
        canvas.drawRect(rect, Paint()..color = color);
      }
    }
    ui.Picture picture = recorder.endRecording();
    return picture.toImageSync(100, 100);
  }

  @override
  void paint(Canvas canvas, Size size) {
    ui.ImageFilter blur = ui.ImageFilter.blur(sigmaX: 5, sigmaY: 5, tileMode: TileMode.decal);
    ui.Shader shader = ui.ImageShader(makeImage(), TileMode.repeated, TileMode.repeated, Matrix4.identity().storage);
    canvas.drawRect(const Rect.fromLTRB(0, 0, 300, 300), Paint()..color = Colors.green);
    canvas.drawRect(const Rect.fromLTRB(100, 100, 200, 200), Paint()..shader = shader);
    canvas.drawRect(const Rect.fromLTRB(300, 0, 600, 300), Paint()..color = Colors.red);
    canvas.drawRect(const Rect.fromLTRB(400, 100, 500, 200), Paint()..shader = shader..imageFilter = blur);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
Skia output Screenshot 2023-10-12 at 5 39 27 PM
Impeller output Screenshot 2023-10-12 at 5 39 42 PM

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work liste: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.team-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions