Skip to content

[Impeller] Canvas.drawVertices causes a crash. #135441

@sarah707

Description

@sarah707

Is there an existing issue for this?

Steps to reproduce

I tried to use canvas.drawVertices to render a local png image. The code works normally on web, windows, android, and macOS, but it throws an EXC_BAD_ACCESS error and crashes when it executes canvas.drawVertices on my iPhone(iOS16.5) and IOS simulator(IOS16.4).

I use

 AssetImage('assets/c1_body.png').resolve(ImageConfiguration()).addListener(
      ImageStreamListener(
        (ImageInfo info, bool _) => completer.complete(info.image),
      ),

to get the Image, pass the Image into the ImageShader of the paint, use canvas.drawVertices for rendering.

class MyPainter extends CustomPainter {
  final ui.Image image;

  MyPainter(this.image);

  @override
  void paint(Canvas canvas, Size size) {

    final mypaint = Paint();
    mypaint.shader = ImageShader(
        image,
        TileMode.repeated,
        TileMode.clamp,
        Matrix4.identity().storage,
      );


    final vertices = ui.Vertices(
      ui.VertexMode.triangleStrip,
      [
        Offset(0, 0),
        Offset(0, image.height.toDouble()),
        Offset(image.width.toDouble(), 0),
        Offset(image.width.toDouble(), image.height.toDouble())
      ],
      
    );
    
    //canvas.drawRect(Offset.zero & size, mypaint);//canvas.drawRect can work normally

    canvas.drawVertices(vertices, rendering.BlendMode.srcOver, mypaint);//causes a crash
  }

Expected results

Render the image on the page as normal.

Actual results

throws an EXC_BAD_ACCESS error and crashes on IOS

Code sample

Code sample
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:spine_flutter/spine_flutter.dart';
import 'dart:math';
import 'dart:ui' as ui;
import 'package:flutter/rendering.dart' as rendering;

import 'dart:async';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initSpineFlutter(enableMemoryDebugging: false);
  runApp(const MyApp());
}


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

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => MyAppState(),
      child: MaterialApp(
        title: 'Namer App',
        theme: ThemeData(
          useMaterial3: true,
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyAppState extends ChangeNotifier {
  var current = WordPair.random();
}


 

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late Future<ui.Image> _imageFuture;

  @override
  void initState() {
    super.initState();
    _imageFuture = _loadImage();
  }

  Future<ui.Image> _loadImage() {
    Completer<ui.Image> completer = Completer();
    AssetImage('assets/c1_body.png').resolve(ImageConfiguration()).addListener(
      ImageStreamListener(
        (ImageInfo info, bool _) => completer.complete(info.image),
      ),
    );
    return completer.future;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Column(children: [
        ElevatedButton(
          onPressed: () async {
            var image = await _imageFuture;
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context) => MyDrawingPage(image),
              ),
          );
           
          },
          child: Text('Go to Drawing Page'),
        ),

      ],
      ),
    );
  }
}



class MyDrawingPage extends StatelessWidget {
  final ui.Image image;

  MyDrawingPage(this.image);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Drawing Page'),
      ),
      body: Column(children: [
     
      CustomPaint(
        painter: MyPainter(image),
     size: Size(image.width.toDouble(), image.height.toDouble()), 
      ),
       ],
       ),
    );
 
  }
}

class MyPainter extends CustomPainter {
  final ui.Image image;

  MyPainter(this.image);

  @override
  void paint(Canvas canvas, Size size) {

    final mypaint = Paint();
    mypaint.shader = ImageShader(
        image,
        TileMode.repeated,
        TileMode.clamp,
        Matrix4.identity().storage,
      );


    final vertices = ui.Vertices(
      ui.VertexMode.triangleStrip,
      [
        Offset(0, 0),
        Offset(0, image.height.toDouble()),
        Offset(image.width.toDouble(), 0),
        Offset(image.width.toDouble(), image.height.toDouble())
      ],
      
    );
    
    //canvas.drawRect(Offset.zero & size, mypaint);//canvas.drawRect can work normally

    canvas.drawVertices(vertices, rendering.BlendMode.srcOver, mypaint);//causes a crash
  }

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

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
Launching lib/main.dart on “myiphone”的 iPhone in debug mode...
Automatically signing iOS for device deployment using specified development team in Xcode project: 6D8P3527WG
Xcode build done.                                            8.0s
(lldb) 2023-09-25 12:17:50.334380-0400 Runner[26535:1699992] [VERBOSE-2:FlutterDarwinContextMetalImpeller.mm(37)] Using the Impeller rendering backend.
Connecting to VM Service at ws://127.0.0.1:58951/wBUuFzuedZI=/ws
* thread #10, name = 'io.flutter.1.raster', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x000000010581972c Flutter`impeller::DlVerticesGeometry::GetPositionUVBuffer(impeller::TRect<float>, impeller::Matrix, impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) + 232
Flutter`impeller::DlVerticesGeometry::GetPositionUVBuffer:
->  0x10581972c <+232>: ldp    s2, s3, [x10, #-0x4]
    0x105819730 <+236>: fsub   s2, s2, s11
    0x105819734 <+240>: fdiv   s2, s2, s9
    0x105819738 <+244>: fsub   s3, s3, s10
Target 0: (Runner) stopped.
Lost connection to device.

Exited.

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.13.5, on macOS 13.2 22D49 darwin-arm64, locale zh-Hans-CN)
    • Flutter version 3.13.5 on channel stable at /Users/jiayuli/mybuild/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 12fccda598 (6 days ago), 2023-09-19 13:56:11 -0700
    • Engine revision bd986c5ed2
    • Dart version 3.1.2
    • DevTools version 2.25.0

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/jiayuli/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • 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 14.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E222b
    • CocoaPods version 1.13.0

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

[✓] 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)

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

[✓] Connected device (3 available)
    • “myiphone”的 iPhone (mobile) • 00008101-000C11401A10001E • ios            • iOS 16.5 20F66
    • macOS (desktop)               • macos                     • darwin-arm64   • macOS 13.2
      22D49 darwin-arm64
    • Chrome (web)                  • chrome                    • web-javascript • Google Chrome
      117.0.5938.92

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

• No issues found!

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work liste: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions