Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS][Impeller] AnimatedOpacity affects blended color overlay render #139571

Closed
2 tasks done
TatsuUkraine opened this issue Dec 5, 2023 · 13 comments · Fixed by flutter/engine#49038
Closed
2 tasks done
Assignees
Labels
e: impeller Impeller rendering backend issues and features requests engine flutter/engine repository. See also e: labels. found in release: 3.16 Found to occur in 3.16 found in release: 3.18 Found to occur in 3.18 has reproducible steps The issue has been confirmed reproducible and is ready to work on P1 High-priority issues at the top of the work list platform-ios iOS applications specifically r: fixed Issue is closed as already fixed in a newer version team-engine Owned by Engine team triaged-engine Triaged by Engine team

Comments

@TatsuUkraine
Copy link

Is there an existing issue for this?

Steps to reproduce

  1. Create opacity animation for a widget
  2. overlay it with layers that have color filters
  3. run opacity animation

Expected results

animated widget changes without affecting overlay

Actual results

widget rebuild affects overlay with blended color

Overall this is a very simple case with the error, in real life, it causes much bigger problems when it comes to render elements

Code sample

Code sample
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),
      ),
      home: const MyHomePage(title: 'Flutter Demo Home 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> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Stack(
        children: [
          Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                AnimatedSwitcher(
                  duration: const Duration(seconds: 2),
                  child: Text('Animated container: $_counter', key: Key(_counter.toString()),),
                ),
              ],
            ),
          ),
          Positioned.fill(
            child: Stack(
              children: [
                Positioned.fill(
                  child: Stack(
                    children: [
                      ColorFiltered(
                        colorFilter: ColorFilter.mode(
                          Colors.black54,
                          BlendMode.srcOut,
                        ),
                        child: Stack(
                          children: [
                            Positioned.fill(
                              child: Container(
                                decoration: const BoxDecoration(
                                  color: Colors.white,
                                  backgroundBlendMode: BlendMode.dstOut,
                                ),
                              ),
                            ),
                            Positioned(
                              top: 200,
                              left: 50,
                              child: DecoratedBox(
                                decoration: BoxDecoration(
                                  color: Colors.white,
                                ),
                                child: SizedBox.square(dimension: 100),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

iOS with Impeller

Simulator.Screen.Recording.-.iPhone.15.-.2023-12-05.at.18.33.10.mp4

iOS without Impeller

Simulator.Screen.Recording.-.iPhone.15.-.2023-12-05.at.18.32.24.mp4

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.16.2, on macOS 13.5.2 22G91 darwin-arm64, locale ru)
    • Flutter version 3.16.2 on channel stable at /Users/tatsu/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 9e1c857886 (5 days ago), 2023-11-30 11:51:18 -0600
    • Engine revision cf7a9d0800
    • Dart version 3.2.2
    • DevTools version 2.28.3

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at 
    • Platform android-34, build-tools 33.0.0
    • ANDROID_HOME = 
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
• Build 15A507
    • CocoaPods version 1.13.0

[✓] Android Studio (version 2022.3)
    • 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.6+0-17.0.6b829.9-10027231)

[✓] Connected device (4 available)

[✓] Network resources
    • All expected network resources are available.

• No issues found!
@TatsuUkraine TatsuUkraine changed the title [iOS][Impeller] AnimatedOpacity causing artifacts during the render with blended color overlay [iOS][Impeller] AnimatedOpacity affects blended color overlay render Dec 5, 2023
@TatsuUkraine
Copy link
Author

this sample was working fine in 3.13 stable release

@darshankawar darshankawar added the in triage Presently being triaged by the triage team label Dec 6, 2023
@darshankawar
Copy link
Member

Thanks for the report. Replicable using latest master and stable versions.

139571.mov
stable, master flutter doctor -v
[!] Flutter (Channel stable, 3.16.0, on macOS 12.2.1 21D62 darwin-x64, locale
    en-GB)
    • Flutter version 3.16.0 on channel stable at
      /Users/dhs/documents/fluttersdk/flutter
    ! Warning: `flutter` on your path resolves to
      /Users/dhs/Documents/Fluttersdk/flutter/bin/flutter, which is not inside
      your current Flutter SDK checkout at
      /Users/dhs/documents/fluttersdk/flutter. Consider adding
      /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path.
    ! Warning: `dart` on your path resolves to
      /Users/dhs/Documents/Fluttersdk/flutter/bin/dart, which is not inside your
      current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter.
      Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front
      of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision db7ef5bf9f (12 days ago), 2023-11-15 11:25:44 -0800
    • Engine revision 74d16627b9
    • Dart version 3.2.0
    • DevTools version 2.28.2
    • If those were intentional, you can disregard the above warnings; however
      it is recommended to use "git" directly to perform update checks and
      upgrades.

[!] Xcode - develop for iOS and macOS (Xcode 12.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    ! Flutter recommends a minimum Xcode version of 13.
      Download the latest version or update via the Mac App Store.
    • CocoaPods version 1.11.2

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

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

[✓] Connected device (5 available)
    • SM G975F (mobile)       • RZ8M802WY0X • android-arm64   • Android 11 (API 30)
    • Darshan's iphone (mobile)  • 21150b119064aecc249dfcfe05e259197461ce23 •
      ios            • iOS 14.4.1 18D61
    • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729     •
      ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
    • macOS (desktop)            • macos                                    •
      darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
    • Chrome (web)               • chrome                                   •
      web-javascript • Google Chrome 98.0.4758.80

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 1 category.

[!] Flutter (Channel master, 3.18.0-5.0.pre.17, on macOS 12.2.1 21D62
    darwin-x64, locale en-GB)
    • Flutter version 3.18.0-5.0.pre.17 on channel master at
      /Users/dhs/documents/fluttersdk/flutter
    ! Warning: `flutter` on your path resolves to
      /Users/dhs/Documents/Fluttersdk/flutter/bin/flutter, which is not inside
      your current Flutter SDK checkout at
      /Users/dhs/documents/fluttersdk/flutter. Consider adding
      /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path.
    ! Warning: `dart` on your path resolves to
      /Users/dhs/Documents/Fluttersdk/flutter/bin/dart, which is not inside your
      current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter.
      Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front
      of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision a0f4265575 (2 hours ago), 2023-12-05 21:28:40 -0500
    • Engine revision fe96317750
    • Dart version 3.3.0 (build 3.3.0-194.0.dev)
    • DevTools version 2.30.0
    • If those were intentional, you can disregard the above warnings; however
      it is recommended to use "git" directly to perform update checks and
      upgrades.

[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Users/dhs/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/docs/get-started/install/macos#android-setup for
      more details.

[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 13C100
    • CocoaPods version 1.11.2

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

[✓] IntelliJ IDEA Ultimate Edition (version 2021.3.2)
    • IntelliJ at /Applications/IntelliJ IDEA.app
    • Flutter plugin version 65.1.4
    • Dart plugin version 213.7228

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

[✓] Connected device (3 available)
    • Darshan's iphone (mobile) • 21150b119064aecc249dfcfe05e259197461ce23 • ios
      • iOS 15.3.1 19D52
    • macOS (desktop)           • macos                                    •
      darwin-x64     • macOS 12.2.1 21D62 darwin-x64
    • Chrome (web)              • chrome                                   •
      web-javascript • Google Chrome 109.0.5414.119

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.
      
[!] Xcode - develop for iOS and macOS (Xcode 12.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    ! Flutter recommends a minimum Xcode version of 13.
      Download the latest version or update via the Mac App Store.
    • CocoaPods version 1.11.2

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

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

[✓] Connected device (5 available)
    • SM G975F (mobile)       • RZ8M802WY0X • android-arm64   • Android 11 (API 30)
    • Darshan's iphone (mobile)  • 21150b119064aecc249dfcfe05e259197461ce23 •
      ios            • iOS 14.4.1 18D61
    • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729     •
      ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
    • macOS (desktop)            • macos                                    •
      darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
    • Chrome (web)               • chrome                                   •
      web-javascript • Google Chrome 98.0.4758.80

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 1 category.



@darshankawar darshankawar added platform-ios iOS applications specifically engine flutter/engine repository. See also e: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on e: impeller Impeller rendering backend issues and features requests team-engine Owned by Engine team found in release: 3.16 Found to occur in 3.16 found in release: 3.18 Found to occur in 3.18 and removed in triage Presently being triaged by the triage team labels Dec 6, 2023
@TatsuUkraine
Copy link
Author

I there any news regarding this issue? We currently blocked with flutter upgrade because of this issue( we have some elements flickering here and there across the app(

@TatsuUkraine
Copy link
Author

Just trying to understand if it's something that may be fixed in near future or we will need to wait till next stable release, or maybe even turn off impeller (

@jason-simmons
Copy link
Member

You can work around this issue by disabling partial repaint in Impeller. To do that, set FLTDisablePartialRepaint to true in the app's Info.plist.

I also noticed that the issue does not appear if you patch Canvas::SaveLayer to reinstate the ClipRect operation that was removed in flutter/engine@410838b

  if (bounds.has_value() && !backdrop_filter) {
    ClipGeometry(Geometry::MakeRect(bounds.value()), Entity::ClipOperation::kIntersect);
    IntersectCulling(bounds.value());
  }

@jonahwilliams @bdero

@jonahwilliams
Copy link
Member

Is the optimization in the linked commit misfiring because partial repaint adds a translation to the canvas?

@TatsuUkraine
Copy link
Author

You can work around this issue by disabling partial repaint in Impeller.

@jason-simmons do you know how bad it will impact performance? At least rawly

@TatsuUkraine
Copy link
Author

Just a guess maybe) I'm curious if I need to spend time on benchmark at all if it's going to be very bad 😅

@jonahwilliams
Copy link
Member

I will look into fixing this one.

@jonahwilliams
Copy link
Member

The behavior is different on ToT, instead the text is flashing black. Upon investigation the surface has NaNs, and disabling the clear color optimization causes it to render correctly. This might be similar to previous clear color optimization bugs.

@jonahwilliams
Copy link
Member

I have a fix. If I can confirm that this is fixable on stable by turning off entity culling then we can put together a cherry pick

@jonahwilliams
Copy link
Member

The problem is that the logic to force pass creation isn't general enough: https://github.com/flutter/engine/blob/main/impeller/entity/entity_pass.cc#L848-L853

This uses a transparent color as a signal that we don't need to force create the pass, but its entirely valid to clear to transparent black and then create UI which feeds that texture elsewhere, as the following test demonstrates. You should

TEST_P(AiksTest, SubpassWithClearColorOptimization) {
  Canvas canvas;

  // Use a non-srcOver blend mode to ensure that we don't detect this as an
  // opacity peephole optimization.
  canvas.SaveLayer(
      {.color = Color::Blue().WithAlpha(0.5), .blend_mode = BlendMode::kSource},
      Rect::MakeLTRB(0, 0, 200, 200));
  canvas.DrawPaint(
      {.color = Color::BlackTransparent(), .blend_mode = BlendMode::kSource});
  canvas.Restore();

  canvas.SaveLayer(
      {.color = Color::Blue(), .blend_mode = BlendMode::kDestinationOver});
  canvas.Restore();

  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

As a fix I would propose that

auto-submit bot pushed a commit to flutter/engine that referenced this issue Dec 14, 2023
…lear color. (#49038)

If we clear to transparent black, we're not forcing the pass to be constructed. Change the entity pass API so that we can tell the difference between clearing transparent black and not having a clear color.

In flutter/flutter#139571 , the app is creating a layer that is clearing to a transparent color, which is getting skipped. That invalid texture is fed into a blend which produces either black or magenta error texture.

Fixes flutter/flutter#139571
@darshankawar darshankawar added the r: fixed Issue is closed as already fixed in a newer version label Dec 15, 2023
zanderso pushed a commit to zanderso/engine that referenced this issue Dec 15, 2023
…lear color. (flutter#49038)

If we clear to transparent black, we're not forcing the pass to be constructed. Change the entity pass API so that we can tell the difference between clearing transparent black and not having a clear color.

In flutter/flutter#139571 , the app is creating a layer that is clearing to a transparent color, which is getting skipped. That invalid texture is fed into a blend which produces either black or magenta error texture.

Fixes flutter/flutter#139571
zanderso pushed a commit to zanderso/engine that referenced this issue Dec 15, 2023
…lear color. (flutter#49038)

If we clear to transparent black, we're not forcing the pass to be constructed. Change the entity pass API so that we can tell the difference between clearing transparent black and not having a clear color.

In flutter/flutter#139571 , the app is creating a layer that is clearing to a transparent color, which is getting skipped. That invalid texture is fed into a blend which produces either black or magenta error texture.

Fixes flutter/flutter#139571
zanderso pushed a commit to zanderso/engine that referenced this issue Dec 18, 2023
…lear color. (flutter#49038)

If we clear to transparent black, we're not forcing the pass to be constructed. Change the entity pass API so that we can tell the difference between clearing transparent black and not having a clear color.

In flutter/flutter#139571 , the app is creating a layer that is clearing to a transparent color, which is getting skipped. That invalid texture is fed into a blend which produces either black or magenta error texture.

Fixes flutter/flutter#139571
auto-submit bot pushed a commit to flutter/engine that referenced this issue Dec 18, 2023
Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
e: impeller Impeller rendering backend issues and features requests engine flutter/engine repository. See also e: labels. found in release: 3.16 Found to occur in 3.16 found in release: 3.18 Found to occur in 3.18 has reproducible steps The issue has been confirmed reproducible and is ready to work on P1 High-priority issues at the top of the work list platform-ios iOS applications specifically r: fixed Issue is closed as already fixed in a newer version team-engine Owned by Engine team triaged-engine Triaged by Engine team
Projects
No open projects
Status: ✅ Done
4 participants