Browse Source

[flutter] Batch by color as well, to avoid Impeller slow path

See https://github.com/flutter/flutter/issues/127486
Mario Zechner 2 years ago
parent
commit
bee4d4060c
2 changed files with 16 additions and 1 deletions
  1. 15 1
      spine-flutter/lib/spine_flutter.dart
  2. 1 0
      spine-flutter/src/spine_flutter.cpp

+ 15 - 1
spine-flutter/lib/spine_flutter.dart

@@ -4071,7 +4071,21 @@ class RenderCommand {
       // is copied, so it doesn't matter that we free up the underlying memory on the next
       // render call. See the implementation of Vertices.raw() here:
       // https://github.com/flutter/engine/blob/5c60785b802ad2c8b8899608d949342d5c624952/lib/ui/painting/vertices.cc#L21
-      vertices = Vertices.raw(VertexMode.triangles, positions, textureCoordinates: uvs, colors: colors, indices: indices);
+      //
+      // Impeller is currently using a slow path when using vertex colors.
+      // See https://github.com/flutter/flutter/issues/127486
+      //
+      // We thus batch all meshes not only by atlas page and blend mode, but also vertex color.
+      // See spine_flutter.cpp, batch_commands().
+      //
+      // If the vertex color equals (1, 1, 1, 1), we do not store
+      // colors, which will trigger the fast path in Impeller. Otherwise we have to go the slow path, which
+      // has to render to an offscreen surface.
+      if (colors.isNotEmpty && colors[0] == -1) {
+        vertices = Vertices.raw(VertexMode.triangles, positions, textureCoordinates: uvs, indices: indices);
+      } else {
+        vertices = Vertices.raw(VertexMode.triangles, positions, textureCoordinates: uvs, colors: colors, indices: indices);
+      }
     } else {
       // On the web, rendering is done through CanvasKit, which requires copies of the native data.
       final positionsCopy = Float32List.fromList(positions);

+ 1 - 0
spine-flutter/src/spine_flutter.cpp

@@ -695,6 +695,7 @@ static _spine_render_command *batch_commands(BlockAllocator &allocator, Vector<_
 		_spine_render_command *cmd = i < commands.size() ? commands[i] : nullptr;
 		if (cmd != nullptr && cmd->atlasPage == first->atlasPage &&
 			cmd->blendMode == first->blendMode &&
+			cmd->colors[0] == first->colors[0] &&
 			numIndices + cmd->numIndices < 0xffff) {
 			numVertices += cmd->numVertices;
 			numIndices += cmd->numIndices;