Skip to content

[Impeller] : Opacity widget not working on a CustomPaint with a shader on iOS #158500

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

Closed
GiacomoPignoni opened this issue Nov 12, 2024 · 13 comments · Fixed by flutter/engine#56936
Labels
e: impeller Impeller rendering backend issues and features requests found in release: 3.24 Found to occur in 3.24 found in release: 3.27 Found to occur in 3.27 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 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

@GiacomoPignoni
Copy link

GiacomoPignoni commented Nov 12, 2024

Steps to reproduce

Put a CustomPaint widget, that paint a shader, into an Opacity widget

Expected results

The Opacity should be applied on the painted shader

Actual results

The Opacity is not applied

Code sample

Code sample
import 'dart:ui' as ui;

import 'package:flutter/services.dart';
import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: FutureBuilder(
          future: () async {
            final imageBytes = await rootBundle.load('lib/assets/img.jpeg');
            final image = await decodeImageFromList(imageBytes.buffer.asUint8List());
            final program = await ui.FragmentProgram.fromAsset('lib/assets/simple.frag');

            return (image, program);
          }(),
          builder: (context, snapshot) {
            if (snapshot.hasData == false) {
              return const Center(child: CircularProgressIndicator());
            }

            final image = snapshot.data!.$1;
            final program = snapshot.data!.$2;
            return Opacity(
              opacity: 0.5,
              child: Center(
                child: FittedBox(
                  child: SizedBox(
                    width: image.width.toDouble(),
                    height: image.height.toDouble(),
                    child: CustomPaint(
                      painter: MyCustomPainter(
                        image: image,
                        program: program,
                      ),
                    ),
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

class MyCustomPainter extends CustomPainter {
  const MyCustomPainter({
    required this.image,
    required this.program,
  });

  final ui.Image image;
  final ui.FragmentProgram program;

  @override
  void paint(Canvas canvas, Size size) {
    final shader = program.fragmentShader();
    shader.setFloat(0, image.width.toDouble());
    shader.setFloat(1, image.height.toDouble());
    shader.setImageSampler(0, image);

    final paint = Paint()..shader = shader;
    canvas.drawRect(Offset.zero & size, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

Shader

#include <flutter/runtime_effect.glsl>

uniform vec2 uSize;

uniform sampler2D uTexture;

out vec4 fragColor;

void main() {
    vec2 uv = FlutterFragCoord() / uSize;
   
    fragColor = texture(uTexture, uv);
}

Screenshots or Video

Screenshots

Expected
Simulator Screenshot - iPhone 15 Pro - 2024-11-12 at 15 31 26

Actual
Simulator Screenshot - iPhone 15 Pro - 2024-11-12 at 15 31 09

Logs

No response

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.24.3, on macOS 14.5 23F79 darwin-arm64, locale en-IT)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.0)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.3)
[✓] IntelliJ IDEA Community Edition (version 2024.2.1)
[✓] VS Code (version 1.95.2)
[✓] Connected device (5 available)
    ! Error: Browsing on the local area network for Giacomo’s iPhone. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources

• No issues found!
@GiacomoPignoni
Copy link
Author

If I can give a suggestion, I think the problem has been caused on the changed condition for the opacity peephole in this PR #52707

The method CanApplyOpacityPeephole is not also looking if the paint object has a shader
If this condition is invalided changing for example the blend mode, the opacity return to work correctly

@darshankawar darshankawar added the in triage Presently being triaged by the triage team label Nov 12, 2024
@darshankawar
Copy link
Member

@GiacomoPignoni
Can you provide the current vs expected result with this code ?
Also, please check if this could be related to your case or not.

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Nov 12, 2024
@GiacomoPignoni
Copy link
Author

GiacomoPignoni commented Nov 12, 2024

@darshankawar
I've added the screenshots

About the other issue, it is related, it's something similar but not the same use case.
Is this case I'm trying to apply an opacity on a CustomPaint with a shader that is drawing an ui.Image/texture
I can also say that this problem was not present in Flutter 3.22 or before

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Nov 12, 2024
@sroddy
Copy link
Contributor

sroddy commented Nov 12, 2024

@darshankawar it could actually be that the issue you have linked is strictly related to this issue, because I've verified that the behaviour that is described in that issue (to multiply the alpha value of the Paint color to the shader output) is no longer occurring, and the shader output is not taking anymore into consideration the alpha value of the color.

It can be that because of this new (unwanted?) behavior, the peephole optimizations of the Opacity layer, which are most likely affecting the color value of the Paint, are no longer able to effectively apply opacity on the shader's output.

@darshankawar
Copy link
Member

Thanks for the update @GiacomoPignoni and @sroddy
I tried the code sample using latest stable and observed that the opacity is applied, as shown below:

Screenshot 2024-11-13 at 11 16 29 AM

Original image I used:

Screenshot 2024-11-13 at 11 17 55 AM

I see that you verified on 3.24.3. Can you upgrade to 3.24.4 and re-run to confirm ?

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Nov 13, 2024
@GiacomoPignoni
Copy link
Author

GiacomoPignoni commented Nov 13, 2024

@darshankawar
I've tried it on Flutter 3.24.4 and the problem still present.
But I've tried it on iOS, and I've noticed you have tried it on Android.
So I've tried also other platforms (I wasn't able to try Windows) and I can say that this problem is present only on iOS and macOS also on Flutter 3.24.4

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Nov 13, 2024
@darshankawar
Copy link
Member

Thanks for the update. I tried on web, desktop (macOS) and iOS with latest stable and master and below is observation:

  1. iOS (occurs with impeller, not without impeller):
Screenshot 2024-11-13 at 6 01 43 PM Screenshot 2024-11-13 at 6 02 41 PM
  1. web (chrome) : doesn't occur.
  2. macOS : doesn't occur on latest master:
Screenshot 2024-11-13 at 6 04 58 PM
stable : 3.24.4
master : 3.27.0-1.0.pre.471

@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 found in release: 3.24 Found to occur in 3.24 found in release: 3.27 Found to occur in 3.27 framework flutter/packages/flutter repository. See also f: labels. team-ios Owned by iOS platform team and removed in triage Presently being triaged by the triage team labels Nov 13, 2024
@darshankawar darshankawar changed the title Opacity widget not working on a CustomPaint with a shader [Impeller] : Opacity widget not working on a CustomPaint with a shader on iOS Nov 13, 2024
@sroddy
Copy link
Contributor

sroddy commented Nov 13, 2024

@darshankawar I think that on macOS it's not happening because you didn't test it with the flag that enables impeller, as it's still not enabled by default

@jonahwilliams jonahwilliams added team-engine Owned by Engine team and removed engine flutter/engine repository. See also e: labels. platform-ios iOS applications specifically framework flutter/packages/flutter repository. See also f: labels. labels Nov 25, 2024
@jonahwilliams
Copy link
Member

FYI @flar , I think this needs to be fixed by marking runtime effect as not accepting opacity peephole

@flutter-triage-bot flutter-triage-bot bot removed the team-engine Owned by Engine team label Nov 25, 2024
@flutter-triage-bot flutter-triage-bot bot removed the team-ios Owned by iOS platform team label Nov 25, 2024
@flutter-triage-bot
Copy link

Issue is assigned to multiple teams (engine, ios). Please ensure the issue has only one team-* label at a time. Use fyi-* labels to have another team look at the issue without reassigning it.

@jonahwilliams jonahwilliams added the P1 High-priority issues at the top of the work list label Nov 25, 2024
@flar
Copy link
Contributor

flar commented Nov 25, 2024

FYI @flar , I think this needs to be fixed by marking runtime effect as not accepting opacity peephole

This would give up an opportunity. Skia is able to apply opacity on top of a Custom Shader. We can impose a restriction on the ability to peephole opacity as a "workaround bug fix", but it will move performance back compared to finding a way to implement opacity on top of a custom shader.

@darshankawar darshankawar added the team-engine Owned by Engine team label Nov 26, 2024
@jonahwilliams
Copy link
Member

We're not going to codegen new shaders to make opacity peephole work. please just add the opt out for runtime effect.

@jonahwilliams jonahwilliams added the triaged-engine Triaged by Engine team label Dec 2, 2024
auto-submit bot pushed a commit to flutter/engine that referenced this issue Dec 5, 2024
…56936)

Fixes flutter/flutter#158500

Impeller does not support group opacity for RuntimeEffects so we disable the optimization with a flag when it is detected.
@darshankawar darshankawar added the r: fixed Issue is closed as already fixed in a newer version label Dec 6, 2024
nick9822 pushed a commit to nick9822/flutter that referenced this issue Dec 18, 2024
…lutter/engine#56936)

Fixes flutter#158500

Impeller does not support group opacity for RuntimeEffects so we disable the optimization with a flag when it is detected.
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 20, 2024
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 found in release: 3.24 Found to occur in 3.24 found in release: 3.27 Found to occur in 3.27 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 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
None yet
5 participants