Skip to content

[Impeller] Mipmaps aren't generated for the textures produced from Picture.toImage or toImageSync. #156161

@WeirdHat

Description

@WeirdHat

Steps to reproduce

Read an image from a file, draw it to a scaled canvas in a CustomPainter with FilterQuality.medium, it is correctly antialiased.

Now put the same image into a PictureRecorder. Draw the Picture in the CustomPainter, it looks identical, still antialiased.

Now convert the Picture to an Image with toImage or toImageSync. Draw the new Image in the CustomPainter. It should still look identical to the original image, but it doesn't!

I only tested this on macOS.

Expected results

Skia:
Screenshot 2024-10-03 at 1 55 17 PM

Actual results

Impeller:
Screenshot 2024-10-03 at 1 35 30 PM

Code sample

Code sample
import 'dart:io';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';

late ui.Image image1;
late ui.Image image2;
late ui.Picture picture;

void main() async {
  //read image from a PNG file
  const filepath = "/Users/weirdhat/Documents/test.png";
  final data = File(filepath).readAsBytesSync();
  final codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
  image1 = (await codec.getNextFrame()).image;

  //draw image into a PictureRecorder
  final recorder = ui.PictureRecorder();
  final canvas = Canvas(recorder);
  canvas.drawImage(image1, Offset.zero, Paint() .. filterQuality = FilterQuality.medium);

  //get a Picture from the PictureRecorder
  picture = recorder.endRecording();

  //get an Image from the Picture - should be an identical copy of the original image
  image2 = await picture.toImage(3840, 2160);

  //save the new image to a PNG file just so we can confirm it is identical to the original
  const filepath2 = "/Users/weirdhat/Documents/test2.png";
  final byteData = await image2.toByteData(format: ui.ImageByteFormat.png);
  File file = File(filepath2);
  await file.writeAsBytes(byteData!.buffer.asUint8List());

  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MainApp2());
}

class MainApp2 extends StatefulWidget {
  const MainApp2({super.key});
  
  @override
  State<MainApp2> createState() => _MainApp2State();
}

class _MainApp2State extends State<MainApp2> {
  @override
  Widget build(BuildContext context) {
    return CustomPaint(painter: CustomPainterTest());
  }
}

class CustomPainterTest extends CustomPainter {
  @override
  void paint(ui.Canvas canvas, ui.Size size) {
    canvas.drawColor(Colors.white, BlendMode.src);
    
    canvas.scale(0.10);
    canvas.drawImage(image1, Offset.zero, Paint() .. filterQuality = FilterQuality.medium); //antialiased
    canvas.translate(0, 2160);
    canvas.drawPicture(picture); //antialiased
    canvas.translate(0, 2160);
    canvas.drawImage(image2, Offset.zero, Paint() .. filterQuality = FilterQuality.medium); //NOT antialiased
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

My test image:
test

Screenshots or Video

No response

Logs

No response

Flutter Doctor output

Doctor output
[✓] Flutter (Channel master, 3.26.0-1.0.pre.226, on macOS 13.6.7 22G720 darwin-arm64, locale en-US)
    • Flutter version 3.26.0-1.0.pre.226 on channel master at /Users/weirdhat/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision cc0ca11ee4 (8 days ago), 2024-09-26 09:04:24 +0500
    • Engine revision 3719454a87
    • Dart version 3.6.0 (build 3.6.0-279.0.dev)
    • DevTools version 2.40.0-dev.1

[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/weirdhat/Library/Android/sdk
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/to/macos-android-setup for more details.

[!] Xcode - develop for iOS and macOS (Xcode 15.0)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15A240d
    ! CocoaPods 1.12.1 out of date (1.13.0 is recommended).
        CocoaPods is a package manager for iOS or macOS platform code.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/to/platform-plugins
      To update CocoaPods, see https://guides.cocoapods.org/using/getting-started.html#updating-cocoapods

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)

[✓] VS Code (version 1.93.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.98.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    e: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.found in release: 3.26Found to occur in 3.26has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionteam-engineOwned by Engine team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions