Skip to content

Conversation

@zanderso
Copy link
Member

@zanderso zanderso commented Apr 27, 2022

Fixes #99783

@zanderso zanderso force-pushed the ink-sparkle-asset branch from ef53dcc to be137a9 Compare April 27, 2022 17:56
@goderbauer goderbauer added tool Affects the "flutter" command-line tool. See also t: labels. framework flutter/packages/flutter repository. See also f: labels. labels Apr 27, 2022
@zanderso
Copy link
Member Author

@dnfield @jonahwilliams About the failing framework_tests_misc and framework_tests_libraries, do you happen to know how to get them to load the shader asset?

@zanderso
Copy link
Member Author

Also cc @goderbauer @clocksmith

This also still needs tool tests.

@jonahwilliams
Copy link
Contributor

We'd have to have each test manually load the asset. You could do that by overriding the root bundle and loading the bytes in with synchronous I/O. Unless we have a helper somewhere I've forgotten about

Uint8List data;
FakeAssetBundle  bundle;

setUpAll(() {
  data = File('assets/ink_sparkle.spriv).readAsBytesSync();
});

class FakeAssetBundle implements AssetBundle {
  FakeAssetBundle(this.data);
  
  final Uint8List data;
  
  ... override some methods...
}


testWidgets('test', (WidgetTester tester) {
  DefaultAssetBundle(... provide your bundle here);
});

@zanderso zanderso force-pushed the ink-sparkle-asset branch from be137a9 to 8cc2ecd Compare April 28, 2022 05:49
@jonahwilliams
Copy link
Contributor

The flutter tool can actually build an asset bundle for the test runner, but the problems are that this doesn't go down the same exact path as copyAssets and that technically the flutter framework doesn't have use-material-design on - since that would imply all apps that use flutter would use material design. Anyway, here is a small diff to work from, this outputs the compiled spirv in an easier to get to directory which you might be able to get at with regular asset loading:

diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart
index 1bbb098d05..195d6e8f57 100644
--- a/packages/flutter_tools/lib/src/asset.dart
+++ b/packages/flutter_tools/lib/src/asset.dart
@@ -410,8 +410,7 @@ class ManifestAssetBundle implements AssetBundle {
       }
     }
     final List<_Asset> materialAssets = <_Asset>[
-      if (flutterManifest.usesMaterialDesign)
-        ..._getMaterialAssets(),
+      ..._getMaterialAssets(),
     ];
     for (final _Asset asset in materialAssets) {
       final File assetFile = asset.lookupAssetFile(_fileSystem);
diff --git a/packages/flutter_tools/lib/src/build_system/targets/assets.dart b/packages/flutter_tools/lib/src/build_system/targets/assets.dart
index eaf4c7db5c..f6bd39660f 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/assets.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/assets.dart
@@ -112,7 +112,6 @@ Future<Depfile> copyAssets(
           ) && !await shaderCompiler.compileShader(
             input: content.file as File,
             outputPath: file.path,
-            relativePath: entry.key,
           )) {
             await (content.file as File).copy(file.path);
           }
diff --git a/packages/flutter_tools/lib/src/build_system/targets/shader_compiler.dart b/packages/flutter_tools/lib/src/build_system/targets/shader_compiler.dart
index b09b019f98..e73409339e 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/shader_compiler.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/shader_compiler.dart
@@ -53,7 +53,6 @@ class ShaderCompiler {
   Future<bool> compileShader({
     required File input,
     required String outputPath,
-    required String relativePath,
   }) async {
        if (!input.path.endsWith('.frag')) {
                return false;
diff --git a/packages/flutter_tools/lib/src/bundle_builder.dart b/packages/flutter_tools/lib/src/bundle_builder.dart
index 2ed5e99387..9a5f2f1072 100644
--- a/packages/flutter_tools/lib/src/bundle_builder.dart
+++ b/packages/flutter_tools/lib/src/bundle_builder.dart
@@ -13,6 +13,7 @@ import 'build_info.dart';
 import 'build_system/build_system.dart';
 import 'build_system/depfile.dart';
 import 'build_system/targets/common.dart';
+import 'build_system/targets/shader_compiler.dart';
 import 'bundle.dart';
 import 'cache.dart';
 import 'devfs.dart';
@@ -148,6 +149,13 @@ Future<void> writeBundle(
   }
   bundleDir.createSync(recursive: true);

+  final ShaderCompiler shaderCompiler = ShaderCompiler(
+    processManager: globals.processManager,
+    logger: globals.logger,
+    fileSystem: globals.fs,
+    artifacts: globals.artifacts!,
+  );
+
   // Limit number of open files to avoid running out of file descriptors.
   final Pool pool = Pool(64);
   await Future.wait<void>(
@@ -161,7 +169,15 @@ Future<void> writeBundle(
         // and the native APIs will look for files this way.
         final File file = globals.fs.file(globals.fs.path.join(bundleDir.path, entry.key));
         file.parent.createSync(recursive: true);
-        await file.writeAsBytes(await entry.value.contentsAsBytes());
+        final DevFSContent devFSContent = entry.value;
+        if (devFSContent is DevFSFileContent) {
+          final File input = devFSContent.file as File;
+          if (!await shaderCompiler.compileShader(input: input, outputPath: file.path)) {
+            input.copySync(file.path);
+          }
+        } else {
+          await file.writeAsBytes(await entry.value.contentsAsBytes());
+        }
       } finally {
         resource.release();
       }
diff --git a/packages/flutter_tools/lib/src/commands/test.dart b/packages/flutter_tools/lib/src/commands/test.dart
index 026529165d..22ad9f197f 100644
--- a/packages/flutter_tools/lib/src/commands/test.dart
+++ b/packages/flutter_tools/lib/src/commands/test.dart
@@ -479,10 +479,10 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
     if (build != 0) {
       throwToolExit('Error: Failed to build asset bundle');
     }
-    if (_needRebuild(assetBundle.entries)) {
+    // if (_needRebuild(assetBundle.entries)) {
       await writeBundle(globals.fs.directory(globals.fs.path.join('build', 'unit_test_assets')),
           assetBundle.entries);
-    }
+    //}
   }

   bool _needRebuild(Map<String, DevFSContent> entries) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How confident can we be that this won't get accessed before the future completes?

How important is it to synchronously access this value?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In particular, it lookslike the only actual callsite of this is line 524 above which is in an async method already. We should either expose this as a future or just remove it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newline at EOF

@zanderso zanderso force-pushed the ink-sparkle-asset branch 3 times, most recently from 4d38885 to dbc26ce Compare April 29, 2022 03:36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still isn't safe but we're no worse off than we used to be. We should file an issue to deprecate this and remove it. It's not safe for anyone to use.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnfield Can you be more specific about what isn't safe, and what should be removed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, providing sync access to a late initialized variable that gets initialized in a future.

So if some program invokes the getter below here that refers to this static late var before the future completes, it will get a late initialization exception and it has no way to know if that getter is safe to call yet or not.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. I think a bigger refactor to how these work is needed. In particular, the async nature of the shader load should probably be exposed in such a way that app developers know that they need to get it done before applying the shader in a widget tree. I'm not going to attempt that in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will that still be necessary once impeller is just using these as precompiled blobs?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need them as bytes, or could we load them in some other opaque format? I did re-open flutter/engine#32999 which would let you load assets into immutable buffers synchronously

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess technically we should be doing that async anyway to avoid jank on low end devices

Copy link
Member

@goderbauer goderbauer Apr 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnfield What is the unsafe code pass? The only way to obtain an instance of this is to await the inkSparkle "static factory" above. At that point, it is guaranteed that _program is initialized, no?

(Side-note: I think compile should be a private method since it should only be invoked by inkSparkle?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(we could assert that _program is initialized in the inkSparkle method before the return)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhhh I see, in that case this is fine. I missed that part because of the way GitHub collapsed part of the diff...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ShaderCompiler({
ShaderCompiler({

Comment on lines 23 to 27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}) : assert(processManager != null),
assert(logger != null),
assert(fileSystem != null),
assert(artifacts != null),
_processManager = processManager,
}) : _processManager = processManager,

Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test?

Comment on lines 68 to 71
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File or link bugs

@zanderso
Copy link
Member Author

This PR is blocked on #102805

@zanderso
Copy link
Member Author

Tests are still failing on Windows. Another fix to fml for Windows is here flutter/engine#33029.

@zanderso zanderso force-pushed the ink-sparkle-asset branch from 5a81b45 to 37df309 Compare April 30, 2022 20:11
Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as long as tests pass

@zanderso zanderso force-pushed the ink-sparkle-asset branch from 37df309 to e687e7b Compare May 1, 2022 15:16
@zanderso
Copy link
Member Author

zanderso commented May 1, 2022

There will be non-trivial work to do this in the internal build. I filed b/231004915 to track that. I am holding off on landing this until the internal roll catches up a bit, and I get feedback on the internal issue from the internal build team.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should just update the fragment_shader_manager to generate the right code. AFAICT, it's only used for this purpose and nothing else?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we'll probably want to have a code gen solution, but it should likely be based on the reflection info emitted by impellerc and not on that package. So, spot fixes to fragment_shader_manager will probably not actually be too helpful.

@zanderso zanderso force-pushed the ink-sparkle-asset branch from e687e7b to 9ec26a0 Compare May 3, 2022 18:24
@zanderso
Copy link
Member Author

zanderso commented May 3, 2022

The g3 side of this is in cl/446113910.

@zanderso zanderso force-pushed the ink-sparkle-asset branch 2 times, most recently from f97075f to 2bab21f Compare May 3, 2022 22:28
@zanderso
Copy link
Member Author

zanderso commented May 4, 2022

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 4, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 4, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 4, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 4, 2022
egramond pushed a commit to egramond/flutter that referenced this pull request May 5, 2022
@flutter-dashboard flutter-dashboard bot added f: material design flutter/packages/flutter/material repository. c: contributor-productivity Team-specific productivity, code health, technical debt. labels May 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c: contributor-productivity Team-specific productivity, code health, technical debt. f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Change InkSparkle SPIR-V byte code from static const to a file to prepare for Impeller

4 participants