Skip to content

Leak within Vertices #54762

@cmkweber

Description

@cmkweber

Vertices, when used for dynamic batching such as particles, etc, that regenerate every frame eventually leads to a crash.

Reproduction:

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;

void main() { runApp(App()); }

class App extends StatelessWidget
{
  @override Widget build(BuildContext context)
  {
    return MaterialApp(
      home: View(),
      showPerformanceOverlay: true,
      title: 'vertices'
    );
  }
}

class View extends StatefulWidget { @override ViewState createState() { return ViewState(); } }

class ViewState extends State<View> with TickerProviderStateMixin
{
  final ViewPainter _painter = ViewPainter();
  Ticker _ticker;

  @override void initState()
  {
    super.initState();
    _ticker = createTicker(_painter.update);
    _ticker.start();
  }

  @override void dispose()
  {
    _ticker.stop();
    _ticker.dispose();
    super.dispose();
  }

  @override Widget build(BuildContext context)
  {
    return CustomPaint(
      isComplex: false,
      painter: _painter,
      willChange: true
    );
  }
}

class ViewPainter extends ChangeNotifier implements CustomPainter
{
  static const int uint16max = 65535;
  static const double verticesMB = 1.44177;

  final Int32List colors = Int32List(uint16max);
  final Float32List coords = Float32List(uint16max * 2);
  final Uint16List indices = Uint16List(uint16max);
  final Float32List positions = Float32List(uint16max * 2);

  double memory = 0.0;
  List<ui.Vertices> vertices = [];

  ViewPainter()
  {
    colors[0] = Colors.red.value;
    colors[1] = Colors.green.value;
    colors[2] = Colors.blue.value;
    colors[3] = Colors.yellow.value;
    indices[1] = indices[3] = 1;
    indices[2] = indices[5] = 3;
    indices[4] = 2;
    positions[2] = positions[4] = positions[5] = positions[7] = 250.0;
  }

  void update(Duration timeStamp)
  {
    vertices.clear();
    for(int v = 0; v < 3; v++)
    {
      vertices.add(ui.Vertices.raw(ui.VertexMode.triangles, positions, textureCoordinates: coords, colors: colors, indices: indices));
      memory += verticesMB;
    }
    debugPrint('total vert memory allocated: ' + memory.toStringAsFixed(1));
    notifyListeners();
  }

  void paint(ui.Canvas canvas, ui.Size size)
  {
    canvas.drawColor(Colors.white, BlendMode.srcOver);
    for(int v = 0; v < vertices.length; v++)
      canvas.drawVertices(vertices[v], BlendMode.srcOver, Paint());
  }

  @override bool hitTest(Offset position) { return true; }
  @override bool shouldRebuildSemantics(CustomPainter previous) { return false; }
  @override bool shouldRepaint(CustomPainter previous) { return true; }
  @override get semanticsBuilder { return null; }
}

I have not had a chance to verify this through a local engine, but is it possible this line:

sk_sp<SkVertices> vertices_;

should be:

flutter::SkiaGPUObject<SkVertices> vertices_;

so that it gets added to the unref queue?

Doctor:

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel master, v1.18.1-pre.11, on Microsoft Windows [Version 10.0.18362.720], locale en-US)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Android Studio (version 3.6)
[√] VS Code, 64-bit edition (version 1.44.0)
[√] Connected device (1 available)

• No issues found!

C:\Users\User>flutter doctor -v
[√] Flutter (Channel master, v1.18.1-pre.11, on Microsoft Windows [Version 10.0.18362.720], locale en-US)
    • Flutter version 1.18.1-pre.11 at C:\flutter
    • Framework revision 2ce36f6199 (7 days ago), 2020-04-07 12:26:02 -0700
    • Engine revision 47f17a9ec3
    • Dart version 2.8.0 (build 2.8.0-dev.20.0 275a76f2fc)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at C:\Users\User\AppData\Local\Android\sdk
    • Platform android-29, build-tools 28.0.3
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
    • All Android licenses accepted.

[√] Android Studio (version 3.6)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 45.0.1
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[√] VS Code, 64-bit edition (version 1.44.0)
    • VS Code at C:\Program Files\Microsoft VS Code
    • Flutter extension version 3.9.1

[√] Connected device (1 available)
    • SM J727P • 20c0f2a5 • android-arm64 • Android 8.1.0 (API 27)

• No issues found!

Metadata

Metadata

Assignees

Labels

c: performanceRelates to speed or footprint issues (see "perf:" labels)engineflutter/engine related. See also e: labels.perf: memoryPerformance issues related to memory

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions