flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
166.38k stars 27.55k forks source link

Transparent images bug in Chrome 103 (works in Chrome 102) #106433

Closed luigi-rosso closed 2 years ago

luigi-rosso commented 2 years ago

It seems like images with alpha don't draw properly in Chrome (works in Safari) with Flutter. Using a simple image widget:

https://github.com/luigi-rosso/flutter_web_alpha_bug/blob/0cf2002f2174135b0a3f2cf274cf810c3ad50f45/lib/main.dart#L82

I'm not sure if this is a Flutter bug but I'd like to raise awareness and perhaps you can help us track down where this should be filed as it does severely impact Flutter.

Source for the example is here: https://github.com/luigi-rosso/flutter_web_alpha_bug

How it looks in Chrome Version 103.0.5060.53 (Official Build) (arm64):

CleanShot 2022-06-22 at 10 59 23

How it looks in Safari:

CleanShot 2022-06-22 at 11 02 59

In MacOS:

CleanShot 2022-06-22 at 10 59 55@2x

Works in CanvasKit's fiddle, but lots of other factors here including CanvasKit version... image

[✓] Flutter (Channel unknown, 3.0.0, on macOS 12.3.1 21E258 darwin-arm, locale en-US)
luigi-rosso commented 2 years ago

Same on 3.0.2, btw:

[✓] Flutter (Channel unknown, 3.0.2, on macOS 12.3.1 21E258 darwin-arm, locale en-US)

And also repros on latest master:

[✓] Flutter (Channel master, 3.1.0-0.0.pre.1346, on macOS 12.3.1 21E258 darwin-arm, locale en-US)
huycozy commented 2 years ago

Hi @luigi-rosso, thanks for filing the issue. This issue is reproducible on the latest stable: 3.0.3 and master: 3.1.0-0.0.pre.1354.

Chrome: Version 103.0.5060.53 (Official Build) (x8664) (latest version on macOS host machine)_ This issue only happens with Canvaskit renderer, it displays well with HTML renderer (see in demo)

Demo | Canvaskit | HTML | | --------------- | --------------- | | - The raw image: ![Screen Shot 2022-06-23 at 15 39 54](https://user-images.githubusercontent.com/104349824/175256074-fac8744b-6884-4aa7-a76e-3eed0833b210.png)
Sample code ```dart import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { int _counter = 0; void _incrementCounter() { setState(() { // This call to setState tells the Flutter framework that something has // changed in this State, which causes it to rerun the build method below // so that the display can reflect the updated values. If we changed // _counter without calling setState(), then the build method would not be // called again, and so nothing would appear to happen. _counter++; }); } @override Widget build(BuildContext context) { // This method is rerun every time setState is called, for instance as done // by the _incrementCounter method above. // // The Flutter framework has been optimized to make rerunning build methods // fast, so that you can just rebuild anything that needs updating rather // than having to individually change instances of widgets. return Scaffold( backgroundColor: const Color(0xFFFF0000), appBar: AppBar( // Here we take the value from the MyHomePage object that was created by // the App.build method, and use it to set our appbar title. title: Text(widget.title), ), body: Center( // Center is a layout widget. It takes a single child and positions it // in the middle of the parent. child: Image.asset('assets/eye.png'), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } } ```
flutter doctor -v ```bash [✓] Flutter (Channel stable, 3.0.3, on macOS 12.2.1 21D62 darwin-x64, locale en-VN) • Flutter version 3.0.3 at /Users/huynq/Documents/GitHub/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 676cefaaff (11 hours ago), 2022-06-22 11:34:49 -0700 • Engine revision ffe7b86a1e • Dart version 2.17.5 • DevTools version 2.12.2 [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0) • Android SDK at /Users/huynq/Library/Android/sdk • Platform android-33, build-tools 31.0.0 • ANDROID_HOME = /Users/huynq/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 13.3) • Xcode at /Applications/Xcode.app/Contents/Developer • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2021.2) • 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 11.0.12+0-b1504.28-7817840) [✓] Android Studio (version 4.1) • Android Studio at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.7042882/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 1.8.0_242-release-1644-b3-6915495) [✓] Android Studio • Android Studio at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-1/203.7185775/Android Studio Preview.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 11.0.8+10-b944.6842174) [✓] IntelliJ IDEA Community Edition (version 2020.3.3) • IntelliJ at /Applications/IntelliJ IDEA CE.app • 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 [✓] IntelliJ IDEA Community Edition (version 2022.1.1) • IntelliJ at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/IDEA-C/ch-0/221.5591.52/IntelliJ IDEA CE.app • 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 [✓] VS Code (version 1.68.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.42.0 [✓] Connected device (3 available) • iPhone (mobile) • d9a94afe2b649fef56ba0bfeb052f0f2a7dae95e • ios • iOS 15.5 19F77 • macOS (desktop) • macos • darwin-x64 • macOS 12.2.1 21D62 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 102.0.5005.115 [✓] HTTP Host Availability • All required HTTP hosts are available • No issues found! ``` ```bash [✓] Flutter (Channel master, 3.1.0-0.0.pre.1354, on macOS 12.2.1 21D62 darwin-x64, locale en-VN) • Flutter version 3.1.0-0.0.pre.1354 on channel master at /Users/huynq/Documents/GitHub/flutter_master • Upstream repository https://github.com/flutter/flutter.git • Framework revision a30012b275 (3 hours ago), 2022-06-22 17:04:07 -0700 • Engine revision fc08bf45b0 • Dart version 2.18.0 (build 2.18.0-216.0.dev) • DevTools version 2.14.0 [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0) • Android SDK at /Users/huynq/Library/Android/sdk • Platform android-33, build-tools 31.0.0 • ANDROID_HOME = /Users/huynq/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 13.3) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 13E113 • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2021.2) • 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 11.0.12+0-b1504.28-7817840) [✓] Android Studio (version 4.1) • Android Studio at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.7042882/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 1.8.0_242-release-1644-b3-6915495) [!] Android Studio • Android Studio at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-1/203.7185775/Android Studio Preview.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 ✗ Unable to find bundled Java version. • Try updating or re-installing Android Studio. [✓] IntelliJ IDEA Community Edition (version 2020.3.3) • IntelliJ at /Applications/IntelliJ IDEA CE.app • 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 [✓] IntelliJ IDEA Community Edition (version 2022.1.1) • IntelliJ at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/IDEA-C/ch-0/221.5591.52/IntelliJ IDEA CE.app • 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 [✓] VS Code (version 1.68.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.42.0 [✓] Connected device (3 available) • Pixel 3a (mobile) • 964AY0WL20 • android-arm64 • Android 12 (API 32) • macOS (desktop) • macos • darwin-x64 • macOS 12.2.1 21D62 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 102.0.5005.115 [✓] HTTP Host Availability • All required HTTP hosts are available ! Doctor found issues in 1 category. ```
duck-dev-go commented 2 years ago

Is there any e.t.a on this. We are launching a web game soon where this would set back the launch possibly quite a bit unless we opt for html rendering which is not tested for our game.

jason-simmons commented 2 years ago

This works as expected if I set BROWSER_IMAGE_DECODING_ENABLED=false to revert to the old image decoder implementation:

flutter -d chrome run --web-renderer=canvaskit --dart-define=BROWSER_IMAGE_DECODING_ENABLED=false --release

This is still reproducible in a current daily build of Chrome (105.0.5140.0).

The ImageDecoder API looks like it is returning the same output as it did in Chrome 102. But something has apparently changed downstream of that when the texture is rendered.

@yjbanov @kjlubick

daviddomkar commented 2 years ago

This works as expected if I set BROWSER_IMAGE_DECODING_ENABLED=false to revert to the old image decoder implementation:

flutter -d chrome run --web-renderer=canvaskit --dart-define=BROWSER_IMAGE_DECODING_ENABLED=false --release

This is still reproducible in a current daily build of Chrome (105.0.5140.0).

The ImageDecoder API looks like it is returning the same output as it did in Chrome 102. But something has apparently changed downstream of that when the texture is rendered.

@yjbanov @kjlubick

Can confirm this fix works. Without it my flutter canvaskit game has a lot of graphical glitches on Chrome 103 and newer.

kjlubick commented 2 years ago

Here's a different test case using CanvasKit 0.34.1 https://jsfiddle.skia.org/canvaskit/9c4a6f931f41d953d6c313deb14d9a6a192a56961b9a8ed84125e328708208af

This works fine for me on WebGL 2 on my Linux box and M1 Mac. It exercises some of the texture logic, which I was suspicious of. Does this work for others? If so, it means the issue is in different APIs or upstack of CanvasKit.

jason-simmons commented 2 years ago

Ran a bisect of Chromium versions, which yielded this result:

You are probably looking for a change made after 994565 (known good), but no later than 994569 (first known bad).
CHANGELOG URL:
  https://chromium.googlesource.com/chromium/src/+log/d2ed55fb4976616f764830105fb1fdaeb2adbccc..438551efcc62cb07ffa9b025c4338900d2daa631

That range contains this commit: "WebGLImageConversion::ImageExtractor: Remove alpha op" (https://chromium.googlesource.com/chromium/src/+/de0badc548a40620a49371622023ec333a1a5731%5E%21/#F0)

@ccameron-chromium @kenrussell

ccameron-chromium commented 2 years ago

That CL has been implicated in another bug as well (the other bug is performance, not correctness).

Could you write up instructions on how to set up to reproduce the bug? Or better yet is there a link I can visit which will reproduce it? (The jsfiddle link does not exhibit the bug on my machine).

jason-simmons commented 2 years ago

This can be reproduced by running the Flutter app linked in https://github.com/flutter/flutter/issues/106433#issue-1280665398:

git clone https://github.com/flutter/flutter
git clone https://github.com/luigi-rosso/flutter_web_alpha_bug
cd flutter_web_alpha_bug
flutter/bin/flutter -d chrome run

I can help with debugging inside the Flutter Web engine implementation.

ccameron-chromium commented 2 years ago

Thank you! I've done some investigation at: https://bugs.chromium.org/p/chromium/issues/detail?id=1340190#c3

Flutter is expecting its WebGL texture uploaded by texImage2D with a VideoFrame to be in premultiplied format, but the WebGL context has the UNPACK_PREMULTIPLY_ALPHA_WEBGL pixel storage parameter set to FALSE. In my reading of the various specifications, Flutter should set UNPACK_PREMULTIPLY_ALPHA_WEBGL to TRUE for this texImage2D call.

The patch linked above fixes a bug where, when uploading from a VideoFrame, Chrome would often ignore the value of UNPACK_PREMULTIPLY_ALPHA_WEBGL.

In either case, it will be safe to set UNPACK_PREMULTIPLY_ALPHA_WEBGL to TRUE during that specific texImage2D upload (and then restore it after the call). If we update the spec to reflect the behavior (and revert the behavior change I made in that patch), then this will still work.

I personally feel that the behavior of both ImageBitmap and WebCodecs, in allowing the user to specify things like premultiplyAlpha, is making a mistake. It is always most efficient to decode into the image's native format (especially for formats where the native format is YUV), and then have the consuming API perform whatever conversion is needed, to a well-defined target format, on the GPU. It is also, in my opinion, a mistake for APIs to expose the "native format" implicitly (because various vagaries of the internals of things may affect this -- we may not always be able to use YUV for images, or we may only support some color spaces, etc). But that's me rambling.

ccameron-chromium commented 2 years ago

I'm raising this issue to the WebGL and WebCodecs team, so they can decide if we should fix the spec to reflect the behavior before my patch, or if I should remove the behavior change caused by my patch.

ccameron-chromium commented 2 years ago

I'm leaning very heavily towards requiring that flutter set UNPACK_PREMULTIPLY_ALPHA_WEBGL (I'm very much against the pre-conversion behavior that ImageBitmapOptions and ImageDecoderInit want).

kjlubick commented 2 years ago

Is this something set when creating the <canvas>, getting the webgl2 context, or on/around the tex2d call? If it's the last option, that will need to be a CanvasKit change.

ccameron-chromium commented 2 years ago

It's something that needs to be done around the tex2d call, here.

kjlubick commented 2 years ago

Thanks. I now have a case that reproduces in a visually similar way: when I tell CanvasKit the image is Premul https://jsfiddle.skia.org/canvaskit/11c85ce8ad92b95e20c1246a6a51adce3c6b498cd8400e30a42a7b28b97175b7

theAugur commented 2 years ago

This happens for me in Edge browser as well: Version 103.0.1264.37 (Official build) (64-bit). My app uses CanvasKit by default.

eyebrowsoffire commented 2 years ago

CanvasKit roll definitely fixes this issue: https://github.com/flutter/engine/pull/34415

eyebrowsoffire commented 2 years ago

CanvasKit roll is merged. I'm going to go ahead and close this issue.

noinskit commented 2 years ago

Any chance for a stable hotfix release?

ccameron-chromium commented 2 years ago

FYI, RE clarifying the spec.

jpflick commented 2 years ago

3.0.4 and 3.0.5 patches have been released since this issue reported. Any update on a stable hotfix?

changhouw commented 2 years ago

it's still happen on 3.0.5 and chrome 103

theAugur commented 2 years ago

Is this fixed? I see the issue as closed and fixed but on 3.0.5 I am still getting the same problem, do I have to do something on my end to fix this permanently?

Paolo-N commented 2 years ago

Is this fixed? I see the issue as closed and fixed but on 3.0.5 I am still getting the same problem, do I have to do something on my end to fix this permanently?

Same for me, still happening. I also found this: issue

duck-dev-go commented 2 years ago

Also still see this issue on 3.0.5

willcalderbank commented 2 years ago

Im not sure how wise it is but you can build with a later version of CanvasKit.

flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=https://unpkg.com/canvaskit-wasm@0.35.0/bin/

Seems to resolve the problem at least until it rolled into stable.

github-actions[bot] commented 2 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.