Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
7e683c02
Unverified
Commit
7e683c02
authored
Jul 27, 2022
by
Jonah Williams
Committed by
GitHub
Jul 27, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] add tool support for shader hot reload (#107963)
parent
0b27bd30
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
624 additions
and
37 deletions
+624
-37
ink_sparkle.dart
packages/flutter/lib/src/material/ink_sparkle.dart
+1
-2
ink_sparkle_test.dart
packages/flutter/test/material/ink_sparkle_test.dart
+8
-9
android.dart
...s/flutter_tools/lib/src/build_system/targets/android.dart
+2
-0
assets.dart
...es/flutter_tools/lib/src/build_system/targets/assets.dart
+3
-0
common.dart
...es/flutter_tools/lib/src/build_system/targets/common.dart
+1
-0
ios.dart
packages/flutter_tools/lib/src/build_system/targets/ios.dart
+1
-0
linux.dart
...ges/flutter_tools/lib/src/build_system/targets/linux.dart
+3
-1
macos.dart
...ges/flutter_tools/lib/src/build_system/targets/macos.dart
+2
-0
shader_compiler.dart
...r_tools/lib/src/build_system/targets/shader_compiler.dart
+116
-9
web.dart
packages/flutter_tools/lib/src/build_system/targets/web.dart
+2
-0
windows.dart
...s/flutter_tools/lib/src/build_system/targets/windows.dart
+2
-0
bundle_builder.dart
packages/flutter_tools/lib/src/bundle_builder.dart
+1
-0
devfs.dart
packages/flutter_tools/lib/src/devfs.dart
+33
-4
devfs_web.dart
packages/flutter_tools/lib/src/isolated/devfs_web.dart
+5
-0
resident_web_runner.dart
...s/flutter_tools/lib/src/isolated/resident_web_runner.dart
+1
-0
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+15
-0
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+15
-1
vmservice.dart
packages/flutter_tools/lib/src/vmservice.dart
+13
-0
shader_compiler_test.dart
...eral.shard/build_system/targets/shader_compiler_test.dart
+169
-1
cold_test.dart
packages/flutter_tools/test/general.shard/cold_test.dart
+15
-1
devfs_test.dart
packages/flutter_tools/test/general.shard/devfs_test.dart
+83
-2
hot_test.dart
packages/flutter_tools/test/general.shard/hot_test.dart
+21
-4
resident_runner_test.dart
...lutter_tools/test/general.shard/resident_runner_test.dart
+57
-2
resident_web_runner_test.dart
...er_tools/test/general.shard/resident_web_runner_test.dart
+17
-0
terminal_handler_test.dart
...utter_tools/test/general.shard/terminal_handler_test.dart
+21
-1
devfs_web_test.dart
.../flutter_tools/test/general.shard/web/devfs_web_test.dart
+17
-0
No files found.
packages/flutter/lib/src/material/ink_sparkle.dart
View file @
7e683c02
...
...
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:math'
as
math
;
import
'dart:typed_data'
;
import
'dart:ui'
as
ui
;
...
...
@@ -431,7 +430,6 @@ class _InkSparkleFactory extends InteractiveInkFeatureFactory {
const
_InkSparkleFactory
.
constantTurbulenceSeed
()
:
turbulenceSeed
=
1337.0
;
// TODO(clocksmith): Update this once shaders are precompiled.
static
void
compileShaderIfNeccessary
()
{
if
(!
_initCalled
)
{
FragmentShaderManager
.
inkSparkle
().
then
((
FragmentShaderManager
manager
)
{
...
...
@@ -440,6 +438,7 @@ class _InkSparkleFactory extends InteractiveInkFeatureFactory {
_initCalled
=
true
;
}
}
static
bool
_initCalled
=
false
;
static
FragmentShaderManager
?
_shaderManager
;
...
...
packages/flutter/test/material/ink_sparkle_test.dart
View file @
7e683c02
...
...
@@ -30,7 +30,7 @@ void main() {
await
tester
.
pump
();
await
tester
.
pumpAndSettle
();
},
skip:
kIsWeb
,
// [intended]
SPIR-V
shaders are not yet supported for web.
skip:
kIsWeb
,
// [intended] shaders are not yet supported for web.
);
testWidgets
(
'InkSparkle default splashFactory paints with drawRect when bounded'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -61,7 +61,7 @@ void main() {
// ignore: avoid_dynamic_calls
expect
((
material
as
dynamic
).
debugInkFeatures
,
isEmpty
);
},
skip:
kIsWeb
,
// [intended]
SPIR-V
shaders are not yet supported for web.
skip:
kIsWeb
,
// [intended] shaders are not yet supported for web.
);
testWidgets
(
'InkSparkle default splashFactory paints with drawPaint when unbounded'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -84,7 +84,7 @@ void main() {
final
MaterialInkController
material
=
Material
.
of
(
tester
.
element
(
buttonFinder
))!;
expect
(
material
,
paintsExactlyCountTimes
(
#drawPaint
,
1
));
},
skip:
kIsWeb
,
// [intended]
SPIR-V
shaders are not yet supported for web.
skip:
kIsWeb
,
// [intended] shaders are not yet supported for web.
);
/////////////
...
...
@@ -94,19 +94,19 @@ void main() {
testWidgets
(
'InkSparkle renders with sparkles when top left of button is tapped'
,
(
WidgetTester
tester
)
async
{
await
_runTest
(
tester
,
'top_left'
,
0.2
);
},
skip:
kIsWeb
,
// [intended]
SPIR-V
shaders are not yet supported for web.
skip:
kIsWeb
,
// [intended] shaders are not yet supported for web.
);
testWidgets
(
'InkSparkle renders with sparkles when center of button is tapped'
,
(
WidgetTester
tester
)
async
{
await
_runTest
(
tester
,
'center'
,
0.5
);
},
skip:
kIsWeb
,
// [intended]
SPIR-V
shaders are not yet supported for web.
skip:
kIsWeb
,
// [intended] shaders are not yet supported for web.
);
testWidgets
(
'InkSparkle renders with sparkles when bottom right of button is tapped'
,
(
WidgetTester
tester
)
async
{
await
_runTest
(
tester
,
'bottom_right'
,
0.8
);
},
skip:
kIsWeb
,
// [intended]
SPIR-V
shaders are not yet supported for web.
skip:
kIsWeb
,
// [intended] shaders are not yet supported for web.
);
}
...
...
@@ -132,12 +132,11 @@ Future<void> _runTest(WidgetTester tester, String positionName, double distanceF
final
Finder
buttonFinder
=
find
.
byKey
(
buttonKey
);
final
Finder
repaintFinder
=
find
.
byKey
(
repaintKey
);
await
_warmUpShader
(
tester
,
buttonFinder
);
final
Offset
topLeft
=
tester
.
getTopLeft
(
buttonFinder
);
final
Offset
bottomRight
=
tester
.
getBottomRight
(
buttonFinder
);
await
_warmUpShader
(
tester
,
buttonFinder
);
final
Offset
target
=
topLeft
+
(
bottomRight
-
topLeft
)
*
distanceFromTopLeft
;
await
tester
.
tapAt
(
target
);
for
(
int
i
=
0
;
i
<=
5
;
i
++)
{
...
...
packages/flutter_tools/lib/src/build_system/targets/android.dart
View file @
7e683c02
...
...
@@ -15,6 +15,7 @@ import '../exceptions.dart';
import
'assets.dart'
;
import
'common.dart'
;
import
'icon_tree_shaker.dart'
;
import
'shader_compiler.dart'
;
/// Prepares the asset bundle in the format expected by flutter.gradle.
///
...
...
@@ -66,6 +67,7 @@ abstract class AndroidAssetBundle extends Target {
outputDirectory
,
targetPlatform:
TargetPlatform
.
android
,
buildMode:
buildMode
,
shaderTarget:
ShaderTarget
.
sksl
,
);
final
DepfileService
depfileService
=
DepfileService
(
fileSystem:
environment
.
fileSystem
,
...
...
packages/flutter_tools/lib/src/build_system/targets/assets.dart
View file @
7e683c02
...
...
@@ -31,6 +31,7 @@ Future<Depfile> copyAssets(
Map
<
String
,
DevFSContent
>?
additionalContent
,
required
TargetPlatform
targetPlatform
,
BuildMode
?
buildMode
,
required
ShaderTarget
shaderTarget
,
})
async
{
// Check for an SkSL bundle.
final
String
?
shaderBundlePath
=
environment
.
defines
[
kBundleSkSLPath
]
??
environment
.
inputs
[
kBundleSkSLPath
];
...
...
@@ -124,6 +125,7 @@ Future<Depfile> copyAssets(
doCopy
=
!
await
shaderCompiler
.
compileShader
(
input:
content
.
file
as
File
,
outputPath:
file
.
path
,
target:
shaderTarget
,
);
break
;
}
...
...
@@ -306,6 +308,7 @@ class CopyAssets extends Target {
environment
,
output
,
targetPlatform:
TargetPlatform
.
android
,
shaderTarget:
ShaderTarget
.
sksl
,
);
final
DepfileService
depfileService
=
DepfileService
(
fileSystem:
environment
.
fileSystem
,
...
...
packages/flutter_tools/lib/src/build_system/targets/common.dart
View file @
7e683c02
...
...
@@ -74,6 +74,7 @@ class CopyFlutterBundle extends Target {
environment
.
outputDir
,
targetPlatform:
TargetPlatform
.
android
,
buildMode:
buildMode
,
shaderTarget:
ShaderTarget
.
sksl
,
);
final
DepfileService
depfileService
=
DepfileService
(
fileSystem:
environment
.
fileSystem
,
...
...
packages/flutter_tools/lib/src/build_system/targets/ios.dart
View file @
7e683c02
...
...
@@ -493,6 +493,7 @@ abstract class IosAssetBundle extends Target {
environment
,
assetDirectory
,
targetPlatform:
TargetPlatform
.
ios
,
shaderTarget:
ShaderTarget
.
sksl
,
);
final
DepfileService
depfileService
=
DepfileService
(
fileSystem:
environment
.
fileSystem
,
...
...
packages/flutter_tools/lib/src/build_system/targets/linux.dart
View file @
7e683c02
...
...
@@ -15,6 +15,7 @@ import 'assets.dart';
import
'common.dart'
;
import
'desktop.dart'
;
import
'icon_tree_shaker.dart'
;
import
'shader_compiler.dart'
;
/// The only files/subdirectories we care out.
const
List
<
String
>
_kLinuxArtifacts
=
<
String
>[
...
...
@@ -143,7 +144,8 @@ abstract class BundleLinuxAssets extends Target {
targetPlatform:
targetPlatform
,
additionalContent:
<
String
,
DevFSContent
>{
'version.json'
:
DevFSStringContent
(
versionInfo
),
}
},
shaderTarget:
ShaderTarget
.
sksl
,
);
final
DepfileService
depfileService
=
DepfileService
(
fileSystem:
environment
.
fileSystem
,
...
...
packages/flutter_tools/lib/src/build_system/targets/macos.dart
View file @
7e683c02
...
...
@@ -15,6 +15,7 @@ import '../exceptions.dart';
import
'assets.dart'
;
import
'common.dart'
;
import
'icon_tree_shaker.dart'
;
import
'shader_compiler.dart'
;
/// Copy the macOS framework to the correct copy dir by invoking 'rsync'.
///
...
...
@@ -390,6 +391,7 @@ abstract class MacOSBundleFlutterAssets extends Target {
environment
,
assetDirectory
,
targetPlatform:
TargetPlatform
.
darwin
,
shaderTarget:
ShaderTarget
.
sksl
,
);
final
DepfileService
depfileService
=
DepfileService
(
fileSystem:
environment
.
fileSystem
,
...
...
packages/flutter_tools/lib/src/build_system/targets/shader_compiler.dart
View file @
7e683c02
...
...
@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'dart:typed_data'
;
import
'package:meta/meta.dart'
;
import
'package:pool/pool.dart'
;
import
'package:process/process.dart'
;
import
'../../artifacts.dart'
;
...
...
@@ -9,9 +14,110 @@ import '../../base/error_handling_io.dart';
import
'../../base/file_system.dart'
;
import
'../../base/io.dart'
;
import
'../../base/logger.dart'
;
import
'../../build_info.dart'
;
import
'../../convert.dart'
;
import
'../../devfs.dart'
;
import
'../build_system.dart'
;
/// The output shader format that should be used by the [ShaderCompiler].
enum
ShaderTarget
{
impellerAndroid
(
'--opengl-es'
),
impelleriOS
(
'--metal-ios'
),
sksl
(
'--sksl'
);
const
ShaderTarget
(
this
.
target
);
final
String
target
;
}
/// A wrapper around [ShaderCompiler] to support hot reload of shader sources.
class
DevelopmentShaderCompiler
{
DevelopmentShaderCompiler
({
required
ShaderCompiler
shaderCompiler
,
required
FileSystem
fileSystem
,
@visibleForTesting
math
.
Random
?
random
,
})
:
_shaderCompiler
=
shaderCompiler
,
_fileSystem
=
fileSystem
,
_random
=
random
??
math
.
Random
();
final
ShaderCompiler
_shaderCompiler
;
final
FileSystem
_fileSystem
;
final
Pool
_compilationPool
=
Pool
(
4
);
final
math
.
Random
_random
;
late
ShaderTarget
_shaderTarget
;
bool
_debugConfigured
=
false
;
/// Configure the output format of the shader compiler for a particular
/// flutter device.
void
configureCompiler
(
TargetPlatform
?
platform
,
{
required
bool
enableImpeller
})
{
switch
(
platform
)
{
case
TargetPlatform
.
ios
:
_shaderTarget
=
enableImpeller
?
ShaderTarget
.
impelleriOS
:
ShaderTarget
.
sksl
;
break
;
case
TargetPlatform
.
android_arm64
:
case
TargetPlatform
.
android_x64
:
case
TargetPlatform
.
android_x86
:
case
TargetPlatform
.
android_arm
:
case
TargetPlatform
.
android
:
_shaderTarget
=
enableImpeller
?
ShaderTarget
.
impellerAndroid
:
ShaderTarget
.
sksl
;
break
;
case
TargetPlatform
.
darwin
:
case
TargetPlatform
.
linux_x64
:
case
TargetPlatform
.
linux_arm64
:
case
TargetPlatform
.
windows_x64
:
case
TargetPlatform
.
fuchsia_arm64
:
case
TargetPlatform
.
fuchsia_x64
:
case
TargetPlatform
.
tester
:
case
TargetPlatform
.
web_javascript
:
assert
(!
enableImpeller
);
_shaderTarget
=
ShaderTarget
.
sksl
;
break
;
case
null
:
return
;
}
_debugConfigured
=
true
;
}
/// Recompile the input shader and return a devfs content that should be synced
/// to the attached device in its place.
Future
<
DevFSContent
?>
recompileShader
(
DevFSContent
inputShader
)
async
{
assert
(
_debugConfigured
);
final
File
output
=
_fileSystem
.
systemTempDirectory
.
childFile
(
'
${_random.nextDouble()}
.temp'
);
late
File
inputFile
;
bool
cleanupInput
=
false
;
Uint8List
result
;
PoolResource
?
resource
;
try
{
resource
=
await
_compilationPool
.
request
();
if
(
inputShader
is
DevFSFileContent
)
{
inputFile
=
inputShader
.
file
as
File
;
}
else
{
inputFile
=
_fileSystem
.
systemTempDirectory
.
childFile
(
'
${_random.nextDouble()}
.temp'
);
inputFile
.
writeAsBytesSync
(
await
inputShader
.
contentsAsBytes
());
cleanupInput
=
true
;
}
final
bool
success
=
await
_shaderCompiler
.
compileShader
(
input:
inputFile
,
outputPath:
output
.
path
,
target:
_shaderTarget
,
fatal:
false
,
);
if
(!
success
)
{
return
null
;
}
result
=
output
.
readAsBytesSync
();
}
finally
{
resource
?.
release
();
ErrorHandlingFileSystem
.
deleteIfExists
(
output
);
if
(
cleanupInput
)
{
ErrorHandlingFileSystem
.
deleteIfExists
(
inputFile
);
}
}
return
DevFSByteContent
(
result
);
}
}
/// A class the wraps the functionality of the Impeller shader compiler
/// impellerc.
class
ShaderCompiler
{
...
...
@@ -49,6 +155,8 @@ class ShaderCompiler {
Future
<
bool
>
compileShader
({
required
File
input
,
required
String
outputPath
,
required
ShaderTarget
target
,
bool
fatal
=
true
,
})
async
{
final
File
impellerc
=
_fs
.
file
(
_artifacts
.
getHostArtifact
(
HostArtifact
.
impellerc
),
...
...
@@ -62,10 +170,7 @@ class ShaderCompiler {
final
List
<
String
>
cmd
=
<
String
>[
impellerc
.
path
,
// TODO(zanderso): When impeller is enabled, the correct flags for the
// target backend will need to be passed.
// https://github.com/flutter/flutter/issues/102853
'--sksl'
,
target
.
target
,
'--iplr'
,
'--sl=
$outputPath
'
,
'--spirv=
$outputPath
.spirv'
,
...
...
@@ -78,12 +183,14 @@ class ShaderCompiler {
if
(
code
!=
0
)
{
_logger
.
printTrace
(
await
utf8
.
decodeStream
(
impellercProcess
.
stdout
));
_logger
.
printError
(
await
utf8
.
decodeStream
(
impellercProcess
.
stderr
));
throw
ShaderCompilerException
.
_
(
'Shader compilation of "
${input.path}
" to "
$outputPath
" '
'failed with exit code
$code
.'
,
);
if
(
fatal
)
{
throw
ShaderCompilerException
.
_
(
'Shader compilation of "
${input.path}
" to "
$outputPath
" '
'failed with exit code
$code
.'
,
);
}
return
false
;
}
ErrorHandlingFileSystem
.
deleteIfExists
(
_fs
.
file
(
'
$outputPath
.spirv'
));
return
true
;
}
...
...
packages/flutter_tools/lib/src/build_system/targets/web.dart
View file @
7e683c02
...
...
@@ -26,6 +26,7 @@ import '../depfile.dart';
import
'../exceptions.dart'
;
import
'assets.dart'
;
import
'localizations.dart'
;
import
'shader_compiler.dart'
;
/// Whether the application has web plugins.
const
String
kHasWebPlugins
=
'HasWebPlugins'
;
...
...
@@ -306,6 +307,7 @@ class WebReleaseBundle extends Target {
environment
,
environment
.
outputDir
.
childDirectory
(
'assets'
),
targetPlatform:
TargetPlatform
.
web_javascript
,
shaderTarget:
ShaderTarget
.
sksl
,
);
final
DepfileService
depfileService
=
DepfileService
(
fileSystem:
globals
.
fs
,
...
...
packages/flutter_tools/lib/src/build_system/targets/windows.dart
View file @
7e683c02
...
...
@@ -12,6 +12,7 @@ import 'assets.dart';
import
'common.dart'
;
import
'desktop.dart'
;
import
'icon_tree_shaker.dart'
;
import
'shader_compiler.dart'
;
/// The only files/subdirectories we care about.
const
List
<
String
>
_kWindowsArtifacts
=
<
String
>[
...
...
@@ -142,6 +143,7 @@ abstract class BundleWindowsAssets extends Target {
environment
,
outputDirectory
,
targetPlatform:
TargetPlatform
.
windows_x64
,
shaderTarget:
ShaderTarget
.
sksl
,
);
final
DepfileService
depfileService
=
DepfileService
(
fileSystem:
environment
.
fileSystem
,
...
...
packages/flutter_tools/lib/src/bundle_builder.dart
View file @
7e683c02
...
...
@@ -184,6 +184,7 @@ Future<void> writeBundle(
doCopy
=
!
await
shaderCompiler
.
compileShader
(
input:
input
,
outputPath:
file
.
path
,
target:
ShaderTarget
.
sksl
,
// TODO(zanderso): configure impeller target when enabled.
);
break
;
}
...
...
packages/flutter_tools/lib/src/devfs.dart
View file @
7e683c02
...
...
@@ -15,6 +15,7 @@ import 'base/logger.dart';
import
'base/net.dart'
;
import
'base/os.dart'
;
import
'build_info.dart'
;
import
'build_system/targets/shader_compiler.dart'
;
import
'compile.dart'
;
import
'convert.dart'
show
base64
,
utf8
;
import
'vmservice.dart'
;
...
...
@@ -479,6 +480,7 @@ class DevFS {
final
String
fsName
;
final
Directory
?
rootDirectory
;
final
Set
<
String
>
assetPathsToEvict
=
<
String
>{};
final
Set
<
String
>
shaderPathsToEvict
=
<
String
>{};
// A flag to indicate whether we have called `setAssetDirectory` on the target device.
bool
hasSetAssetDirectory
=
false
;
...
...
@@ -574,6 +576,7 @@ class DevFS {
required
List
<
Uri
>
invalidatedFiles
,
required
PackageConfig
packageConfig
,
required
String
dillOutputPath
,
required
DevelopmentShaderCompiler
shaderCompiler
,
DevFSWriter
?
devFSWriter
,
String
?
target
,
AssetBundle
?
bundle
,
...
...
@@ -591,6 +594,8 @@ class DevFS {
// Update modified files
final
Map
<
Uri
,
DevFSContent
>
dirtyEntries
=
<
Uri
,
DevFSContent
>{};
final
List
<
Future
<
void
>>
pendingShaderCompiles
=
<
Future
<
void
>>[];
bool
shaderCompilationFailed
=
false
;
int
syncedBytes
=
0
;
if
(
fullRestart
)
{
generator
.
reset
();
...
...
@@ -634,14 +639,32 @@ class DevFS {
if
(!
content
.
isModified
||
bundleFirstUpload
)
{
return
;
}
// Modified shaders must be recompiled per-target platform.
final
Uri
deviceUri
=
_fileSystem
.
path
.
toUri
(
_fileSystem
.
path
.
join
(
assetDirectory
,
archivePath
));
if
(
deviceUri
.
path
.
startsWith
(
assetBuildDirPrefix
))
{
archivePath
=
deviceUri
.
path
.
substring
(
assetBuildDirPrefix
.
length
);
}
dirtyEntries
[
deviceUri
]
=
content
;
syncedBytes
+=
content
.
size
;
if
(
archivePath
!=
null
&&
!
bundleFirstUpload
)
{
assetPathsToEvict
.
add
(
archivePath
);
if
(
bundle
.
entryKinds
[
archivePath
]
==
AssetKind
.
shader
)
{
final
Future
<
DevFSContent
?>
pending
=
shaderCompiler
.
recompileShader
(
content
);
pendingShaderCompiles
.
add
(
pending
);
pending
.
then
((
DevFSContent
?
content
)
{
if
(
content
==
null
)
{
shaderCompilationFailed
=
true
;
return
;
}
dirtyEntries
[
deviceUri
]
=
content
;
syncedBytes
+=
content
.
size
;
if
(
archivePath
!=
null
&&
!
bundleFirstUpload
)
{
shaderPathsToEvict
.
add
(
archivePath
);
}
});
}
else
{
dirtyEntries
[
deviceUri
]
=
content
;
syncedBytes
+=
content
.
size
;
if
(
archivePath
!=
null
&&
!
bundleFirstUpload
)
{
assetPathsToEvict
.
add
(
archivePath
);
}
}
});
...
...
@@ -672,6 +695,12 @@ class DevFS {
}
_logger
.
printTrace
(
'Updating files.'
);
final
Stopwatch
transferTimer
=
_stopwatchFactory
.
createStopwatch
(
'transfer'
)..
start
();
await
Future
.
wait
(
pendingShaderCompiles
);
if
(
shaderCompilationFailed
)
{
return
UpdateFSReport
();
}
if
(
dirtyEntries
.
isNotEmpty
)
{
await
(
devFSWriter
??
_httpWriter
).
write
(
dirtyEntries
,
_baseUri
!,
_httpWriter
);
}
...
...
packages/flutter_tools/lib/src/isolated/devfs_web.dart
View file @
7e683c02
...
...
@@ -27,6 +27,7 @@ import '../base/logger.dart';
import
'../base/net.dart'
;
import
'../base/platform.dart'
;
import
'../build_info.dart'
;
import
'../build_system/targets/shader_compiler.dart'
;
import
'../build_system/targets/web.dart'
;
import
'../bundle_builder.dart'
;
import
'../cache.dart'
;
...
...
@@ -792,6 +793,7 @@ class WebDevFS implements DevFS {
required
List
<
Uri
>
invalidatedFiles
,
required
PackageConfig
packageConfig
,
required
String
dillOutputPath
,
required
DevelopmentShaderCompiler
shaderCompiler
,
DevFSWriter
?
devFSWriter
,
String
?
target
,
AssetBundle
?
bundle
,
...
...
@@ -923,6 +925,9 @@ class WebDevFS implements DevFS {
void
resetLastCompiled
()
{
// Not used for web compilation.
}
@override
Set
<
String
>
get
shaderPathsToEvict
=>
<
String
>{};
}
class
ReleaseAssetServer
{
...
...
packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
View file @
7e683c02
...
...
@@ -502,6 +502,7 @@ class ResidentWebRunner extends ResidentRunner {
invalidatedFiles:
invalidationResult
.
uris
!,
packageConfig:
invalidationResult
.
packageConfig
!,
trackWidgetCreation:
debuggingOptions
.
buildInfo
.
trackWidgetCreation
,
shaderCompiler:
device
!.
developmentShaderCompiler
,
);
devFSStatus
.
stop
();
_logger
!.
printTrace
(
'Synced
${getSizeAsMB(report.syncedBytes)}
.'
);
...
...
packages/flutter_tools/lib/src/resident_runner.dart
View file @
7e683c02
...
...
@@ -26,6 +26,7 @@ import 'build_info.dart';
import
'build_system/build_system.dart'
;
import
'build_system/targets/dart_plugin_registrant.dart'
;
import
'build_system/targets/localizations.dart'
;
import
'build_system/targets/shader_compiler.dart'
;
import
'bundle.dart'
;
import
'cache.dart'
;
import
'compile.dart'
;
...
...
@@ -49,6 +50,7 @@ class FlutterDevice {
this
.
targetPlatform
,
ResidentCompiler
?
generator
,
this
.
userIdentifier
,
required
this
.
developmentShaderCompiler
,
})
:
assert
(
buildInfo
.
trackWidgetCreation
!=
null
),
generator
=
generator
??
ResidentCompiler
(
globals
.
artifacts
!.
getArtifactPath
(
...
...
@@ -87,6 +89,16 @@ class FlutterDevice {
if
(
device
.
platformType
==
PlatformType
.
fuchsia
)
{
targetModel
=
TargetModel
.
flutterRunner
;
}
final
DevelopmentShaderCompiler
shaderCompiler
=
DevelopmentShaderCompiler
(
shaderCompiler:
ShaderCompiler
(
artifacts:
globals
.
artifacts
!,
logger:
globals
.
logger
,
processManager:
globals
.
processManager
,
fileSystem:
globals
.
fs
,
),
fileSystem:
globals
.
fs
,
);
// For both web and non-web platforms we initialize dill to/from
// a shared location for faster bootstrapping. If the compiler fails
// due to a kernel target or version mismatch, no error is reported
...
...
@@ -184,6 +196,7 @@ class FlutterDevice {
generator:
generator
,
buildInfo:
buildInfo
,
userIdentifier:
userIdentifier
,
developmentShaderCompiler:
shaderCompiler
,
);
}
...
...
@@ -192,6 +205,7 @@ class FlutterDevice {
final
ResidentCompiler
?
generator
;
final
BuildInfo
buildInfo
;
final
String
?
userIdentifier
;
final
DevelopmentShaderCompiler
developmentShaderCompiler
;
DevFSWriter
?
devFSWriter
;
Stream
<
Uri
?>?
observatoryUris
;
...
...
@@ -563,6 +577,7 @@ class FlutterDevice {
invalidatedFiles:
invalidatedFiles
,
packageConfig:
packageConfig
,
devFSWriter:
devFSWriter
,
shaderCompiler:
developmentShaderCompiler
,
dartPluginRegistrant:
FlutterProject
.
current
().
dartPluginRegistrant
,
);
}
on
DevFSException
{
...
...
packages/flutter_tools/lib/src/run_hot.dart
View file @
7e683c02
...
...
@@ -247,6 +247,9 @@ class HotRunner extends ResidentRunner {
for
(
final
FlutterDevice
?
device
in
flutterDevices
)
{
await
device
!.
initLogReader
();
device
.
developmentShaderCompiler
.
configureCompiler
(
device
.
targetPlatform
,
enableImpeller:
debuggingOptions
.
enableImpeller
);
}
try
{
final
List
<
Uri
?>
baseUris
=
await
_initDevFS
();
...
...
@@ -496,6 +499,7 @@ class HotRunner extends ResidentRunner {
void
_resetDirtyAssets
()
{
for
(
final
FlutterDevice
?
device
in
flutterDevices
)
{
device
!.
devFS
!.
assetPathsToEvict
.
clear
();
device
.
devFS
!.
shaderPathsToEvict
.
clear
();
}
}
...
...
@@ -1027,7 +1031,7 @@ class HotRunner extends ResidentRunner {
Future
<
void
>
evictDirtyAssets
()
async
{
final
List
<
Future
<
Map
<
String
,
dynamic
>?>>
futures
=
<
Future
<
Map
<
String
,
dynamic
>>>[];
for
(
final
FlutterDevice
?
device
in
flutterDevices
)
{
if
(
device
!.
devFS
!.
assetPathsToEvict
.
isEmpty
)
{
if
(
device
!.
devFS
!.
assetPathsToEvict
.
isEmpty
&&
device
.
devFS
!.
shaderPathsToEvict
.
isEmpty
)
{
continue
;
}
final
List
<
FlutterView
>
views
=
await
device
.
vmService
!.
getFlutterViews
();
...
...
@@ -1061,7 +1065,17 @@ class HotRunner extends ResidentRunner {
)
);
}
for
(
final
String
assetPath
in
device
.
devFS
!.
shaderPathsToEvict
)
{
futures
.
add
(
device
.
vmService
!
.
flutterEvictShader
(
assetPath
,
isolateId:
views
.
first
.
uiIsolate
!.
id
!,
)
);
}
device
.
devFS
!.
assetPathsToEvict
.
clear
();
device
.
devFS
!.
shaderPathsToEvict
.
clear
();
}
await
Future
.
wait
<
Map
<
String
,
Object
?>?>(
futures
);
}
...
...
packages/flutter_tools/lib/src/vmservice.dart
View file @
7e683c02
...
...
@@ -727,6 +727,19 @@ class FlutterVmService {
);
}
Future
<
Map
<
String
,
Object
?>?>
flutterEvictShader
(
String
assetPath
,
{
required
String
isolateId
,
})
{
return
invokeFlutterExtensionRpcRaw
(
'ext.ui.window.reinitializeShader'
,
isolateId:
isolateId
,
args:
<
String
,
Object
?>{
'assetKey'
:
assetPath
,
},
);
}
/// Exit the application by calling [exit] from `dart:io`.
///
/// This method is only supported by certain embedders. This is
...
...
packages/flutter_tools/test/general.shard/build_system/targets/shader_compiler_test.dart
View file @
7e683c02
...
...
@@ -2,10 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'package:file/memory.dart'
;
import
'package:file_testing/file_testing.dart'
;
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/targets/shader_compiler.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'../../../src/common.dart'
;
import
'../../../src/fake_process_manager.dart'
;
...
...
@@ -33,7 +38,7 @@ void main() {
fileSystem
.
file
(
notFragPath
).
createSync
(
recursive:
true
);
});
testWithoutContext
(
'compileShader invokes impellerc for .frag files'
,
()
async
{
testWithoutContext
(
'compileShader invokes impellerc for .frag files
and sksl target
'
,
()
async
{
final
FakeProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
FakeCommand
(
command:
<
String
>[
...
...
@@ -63,6 +68,7 @@ void main() {
await
shaderCompiler
.
compileShader
(
input:
fileSystem
.
file
(
fragPath
),
outputPath:
outputPath
,
target:
ShaderTarget
.
sksl
,
),
true
,
);
...
...
@@ -70,6 +76,78 @@ void main() {
expect
(
fileSystem
.
file
(
outputSpirvPath
).
existsSync
(),
false
);
});
testWithoutContext
(
'compileShader invokes impellerc for .frag files and metal ios target'
,
()
async
{
final
FakeProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
FakeCommand
(
command:
<
String
>[
impellerc
,
'--metal-ios'
,
'--iplr'
,
'--sl=
$outputPath
'
,
'--spirv=
$outputPath
.spirv'
,
'--input=
$fragPath
'
,
'--input-type=frag'
,
'--include=
$fragDir
'
,
],
onRun:
()
{
fileSystem
.
file
(
outputPath
).
createSync
(
recursive:
true
);
},
),
]);
final
ShaderCompiler
shaderCompiler
=
ShaderCompiler
(
processManager:
processManager
,
logger:
logger
,
fileSystem:
fileSystem
,
artifacts:
artifacts
,
);
expect
(
await
shaderCompiler
.
compileShader
(
input:
fileSystem
.
file
(
fragPath
),
outputPath:
outputPath
,
target:
ShaderTarget
.
impelleriOS
,
),
true
,
);
expect
(
fileSystem
.
file
(
outputPath
).
existsSync
(),
true
);
});
testWithoutContext
(
'compileShader invokes impellerc for .frag files and opengl es'
,
()
async
{
final
FakeProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
FakeCommand
(
command:
<
String
>[
impellerc
,
'--opengl-es'
,
'--iplr'
,
'--sl=
$outputPath
'
,
'--spirv=
$outputPath
.spirv'
,
'--input=
$fragPath
'
,
'--input-type=frag'
,
'--include=
$fragDir
'
,
],
onRun:
()
{
fileSystem
.
file
(
outputPath
).
createSync
(
recursive:
true
);
},
),
]);
final
ShaderCompiler
shaderCompiler
=
ShaderCompiler
(
processManager:
processManager
,
logger:
logger
,
fileSystem:
fileSystem
,
artifacts:
artifacts
,
);
expect
(
await
shaderCompiler
.
compileShader
(
input:
fileSystem
.
file
(
fragPath
),
outputPath:
outputPath
,
target:
ShaderTarget
.
impellerAndroid
,
),
true
,
);
expect
(
fileSystem
.
file
(
outputPath
).
existsSync
(),
true
);
});
testWithoutContext
(
'compileShader invokes impellerc for non-.frag files'
,
()
async
{
final
FakeProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
FakeCommand
(
...
...
@@ -100,6 +178,7 @@ void main() {
await
shaderCompiler
.
compileShader
(
input:
fileSystem
.
file
(
notFragPath
),
outputPath:
outputPath
,
target:
ShaderTarget
.
sksl
,
),
true
,
);
...
...
@@ -134,9 +213,98 @@ void main() {
()
=>
shaderCompiler
.
compileShader
(
input:
fileSystem
.
file
(
notFragPath
),
outputPath:
outputPath
,
target:
ShaderTarget
.
sksl
,
),
throwsA
(
isA
<
ShaderCompilerException
>()),
);
expect
(
fileSystem
.
file
(
outputPath
).
existsSync
(),
false
);
});
testWithoutContext
(
'DevelopmentShaderCompiler can compile for android non-impeller'
,
()
async
{
final
FakeProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
FakeCommand
(
command:
<
String
>[
impellerc
,
'--sksl'
,
'--iplr'
,
'--sl=/.tmp_rand0/0.8255140718871702.temp'
,
'--spirv=/.tmp_rand0/0.8255140718871702.temp.spirv'
,
'--input=
$fragPath
'
,
'--input-type=frag'
,
'--include=
$fragDir
'
,
],
onRun:
()
{
fileSystem
.
file
(
'/.tmp_rand0/0.8255140718871702.temp.spirv'
).
createSync
();
fileSystem
.
file
(
'/.tmp_rand0/0.8255140718871702.temp'
)
..
createSync
()
..
writeAsBytesSync
(<
int
>[
1
,
2
,
3
,
4
]);
}
),
]);
fileSystem
.
file
(
fragPath
).
writeAsBytesSync
(<
int
>[
1
,
2
,
3
,
4
]);
final
ShaderCompiler
shaderCompiler
=
ShaderCompiler
(
processManager:
processManager
,
logger:
logger
,
fileSystem:
fileSystem
,
artifacts:
artifacts
,
);
final
DevelopmentShaderCompiler
developmentShaderCompiler
=
DevelopmentShaderCompiler
(
shaderCompiler:
shaderCompiler
,
fileSystem:
fileSystem
,
random:
math
.
Random
(
0
),
);
developmentShaderCompiler
.
configureCompiler
(
TargetPlatform
.
android
,
enableImpeller:
false
);
final
DevFSContent
?
content
=
await
developmentShaderCompiler
.
recompileShader
(
DevFSFileContent
(
fileSystem
.
file
(
fragPath
)));
expect
(
await
content
!.
contentsAsBytes
(),
<
int
>[
1
,
2
,
3
,
4
]);
expect
(
fileSystem
.
file
(
'/.tmp_rand0/0.8255140718871702.temp.spirv'
),
isNot
(
exists
));
expect
(
fileSystem
.
file
(
'/.tmp_rand0/0.8255140718871702.temp'
),
isNot
(
exists
));
});
testWithoutContext
(
'DevelopmentShaderCompiler can compile for android with impeller'
,
()
async
{
final
FakeProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
FakeCommand
(
command:
<
String
>[
impellerc
,
'--opengl-es'
,
'--iplr'
,
'--sl=/.tmp_rand0/0.8255140718871702.temp'
,
'--spirv=/.tmp_rand0/0.8255140718871702.temp.spirv'
,
'--input=
$fragPath
'
,
'--input-type=frag'
,
'--include=
$fragDir
'
,
],
onRun:
()
{
fileSystem
.
file
(
'/.tmp_rand0/0.8255140718871702.temp.spirv'
).
createSync
();
fileSystem
.
file
(
'/.tmp_rand0/0.8255140718871702.temp'
)
..
createSync
()
..
writeAsBytesSync
(<
int
>[
1
,
2
,
3
,
4
]);
}
),
]);
fileSystem
.
file
(
fragPath
).
writeAsBytesSync
(<
int
>[
1
,
2
,
3
,
4
]);
final
ShaderCompiler
shaderCompiler
=
ShaderCompiler
(
processManager:
processManager
,
logger:
logger
,
fileSystem:
fileSystem
,
artifacts:
artifacts
,
);
final
DevelopmentShaderCompiler
developmentShaderCompiler
=
DevelopmentShaderCompiler
(
shaderCompiler:
shaderCompiler
,
fileSystem:
fileSystem
,
random:
math
.
Random
(
0
),
);
developmentShaderCompiler
.
configureCompiler
(
TargetPlatform
.
android
,
enableImpeller:
true
);
final
DevFSContent
?
content
=
await
developmentShaderCompiler
.
recompileShader
(
DevFSFileContent
(
fileSystem
.
file
(
fragPath
)));
expect
(
await
content
!.
contentsAsBytes
(),
<
int
>[
1
,
2
,
3
,
4
]);
expect
(
fileSystem
.
file
(
'/.tmp_rand0/0.8255140718871702.temp.spirv'
),
isNot
(
exists
));
expect
(
fileSystem
.
file
(
'/.tmp_rand0/0.8255140718871702.temp'
),
isNot
(
exists
));
});
}
packages/flutter_tools/test/general.shard/cold_test.dart
View file @
7e683c02
...
...
@@ -7,7 +7,9 @@ import 'package:flutter_tools/src/base/file_system.dart';
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/targets/shader_compiler.dart'
;
import
'package:flutter_tools/src/compile.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/resident_runner.dart'
;
import
'package:flutter_tools/src/run_cold.dart'
;
...
...
@@ -201,7 +203,7 @@ class TestFlutterDevice extends FlutterDevice {
required
this
.
exception
,
required
ResidentCompiler
generator
,
})
:
assert
(
exception
!=
null
),
super
(
device
,
buildInfo:
BuildInfo
.
debug
,
generator:
generator
);
super
(
device
,
buildInfo:
BuildInfo
.
debug
,
generator:
generator
,
developmentShaderCompiler:
const
FakeShaderCompiler
()
);
/// The exception to throw when the connect method is called.
final
Exception
exception
;
...
...
@@ -274,3 +276,15 @@ class FakeVmService extends Fake implements VmService {
]);
}
}
class
FakeShaderCompiler
implements
DevelopmentShaderCompiler
{
const
FakeShaderCompiler
();
@override
void
configureCompiler
(
TargetPlatform
?
platform
,
{
required
bool
enableImpeller
})
{
}
@override
Future
<
DevFSContent
>
recompileShader
(
DevFSContent
inputShader
)
{
throw
UnimplementedError
();
}
}
packages/flutter_tools/test/general.shard/devfs_test.dart
View file @
7e683c02
...
...
@@ -18,6 +18,7 @@ import 'package:flutter_tools/src/base/os.dart';
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/base/terminal.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/targets/shader_compiler.dart'
;
import
'package:flutter_tools/src/compile.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/vmservice.dart'
;
...
...
@@ -223,6 +224,7 @@ void main() {
trackWidgetCreation:
false
,
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
report
.
syncedBytes
,
5
);
...
...
@@ -262,6 +264,7 @@ void main() {
trackWidgetCreation:
false
,
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
report
.
success
,
false
);
...
...
@@ -302,6 +305,7 @@ void main() {
trackWidgetCreation:
false
,
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
report
.
success
,
true
);
...
...
@@ -344,6 +348,7 @@ void main() {
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
devFSWriter:
localDevFSWriter
,
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
report
.
success
,
true
);
...
...
@@ -393,6 +398,7 @@ void main() {
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
devFSWriter:
writer
,
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
report
.
success
,
true
);
...
...
@@ -466,6 +472,7 @@ void main() {
trackWidgetCreation:
false
,
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
report
.
success
,
true
);
...
...
@@ -551,6 +558,7 @@ void main() {
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
bundle:
FakeBundle
(),
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
report1
.
success
,
true
);
logger
.
messages
.
clear
();
...
...
@@ -564,6 +572,7 @@ void main() {
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
bundle:
FakeBundle
(),
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
report2
.
success
,
true
);
...
...
@@ -575,6 +584,66 @@ void main() {
expect
(
compileLibMainIndex
,
greaterThanOrEqualTo
(
0
));
expect
(
bundleProcessingDoneIndex
,
greaterThan
(
compileLibMainIndex
));
});
group
(
'Shader compilation'
,
()
{
late
FileSystem
fileSystem
;
late
ProcessManager
processManager
;
setUp
(()
{
fileSystem
=
MemoryFileSystem
.
test
();
processManager
=
FakeProcessManager
.
any
();
});
testUsingContext
(
'DevFS recompiles shaders'
,
()
async
{
final
FakeVmServiceHost
fakeVmServiceHost
=
FakeVmServiceHost
(
requests:
<
VmServiceExpectation
>[
createDevFSRequest
],
httpAddress:
Uri
.
parse
(
'http://localhost'
),
);
final
BufferLogger
logger
=
BufferLogger
.
test
();
final
DevFS
devFS
=
DevFS
(
fakeVmServiceHost
.
vmService
,
'test'
,
fileSystem
.
currentDirectory
,
fileSystem:
fileSystem
,
logger:
logger
,
osUtils:
FakeOperatingSystemUtils
(),
httpClient:
FakeHttpClient
.
any
(),
);
await
devFS
.
create
();
final
FakeResidentCompiler
residentCompiler
=
FakeResidentCompiler
()
..
onRecompile
=
(
Uri
mainUri
,
List
<
Uri
>?
invalidatedFiles
)
async
{
fileSystem
.
file
(
'lib/foo.dill'
)
..
createSync
(
recursive:
true
)
..
writeAsBytesSync
(<
int
>[
1
,
2
,
3
,
4
,
5
]);
return
const
CompilerOutput
(
'lib/foo.dill'
,
0
,
<
Uri
>[]);
};
final
FakeBundle
bundle
=
FakeBundle
()
..
entries
[
'foo.frag'
]
=
DevFSByteContent
(<
int
>[
1
,
2
,
3
,
4
])
..
entries
[
'not.frag'
]
=
DevFSByteContent
(<
int
>[
1
,
2
,
3
,
4
])
..
entryKinds
[
'foo.frag'
]
=
AssetKind
.
shader
;
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainUri:
Uri
.
parse
(
'lib/main.dart'
),
generator:
residentCompiler
,
dillOutputPath:
'lib/foo.dill'
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
shaderCompiler:
const
FakeShaderCompiler
(),
bundle:
bundle
,
);
expect
(
report
.
success
,
true
);
expect
(
devFS
.
shaderPathsToEvict
,
<
String
>{
'foo.frag'
});
expect
(
devFS
.
assetPathsToEvict
,
<
String
>{
'not.frag'
});
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
processManager
,
});
});
}
class
FakeResidentCompiler
extends
Fake
implements
ResidentCompiler
{
...
...
@@ -630,10 +699,10 @@ class FakeBundle extends AssetBundle {
Map
<
String
,
Map
<
String
,
DevFSContent
>>
get
deferredComponentsEntries
=>
<
String
,
Map
<
String
,
DevFSContent
>>{};
@override
Map
<
String
,
DevFSContent
>
get
entries
=>
<
String
,
DevFSContent
>{};
final
Map
<
String
,
DevFSContent
>
entries
=
<
String
,
DevFSContent
>{};
@override
Map
<
String
,
AssetKind
>
get
entryKinds
=>
<
String
,
AssetKind
>{};
final
Map
<
String
,
AssetKind
>
entryKinds
=
<
String
,
AssetKind
>{};
@override
List
<
File
>
get
inputFiles
=>
<
File
>[];
...
...
@@ -703,3 +772,15 @@ class AnsweringFakeProcess implements io.Process {
@override
int
get
pid
=>
42
;
}
class
FakeShaderCompiler
implements
DevelopmentShaderCompiler
{
const
FakeShaderCompiler
();
@override
void
configureCompiler
(
TargetPlatform
?
platform
,
{
required
bool
enableImpeller
})
{
}
@override
Future
<
DevFSContent
>
recompileShader
(
DevFSContent
inputShader
)
async
{
return
DevFSByteContent
(
await
inputShader
.
contentsAsBytes
());
}
}
packages/flutter_tools/test/general.shard/hot_test.dart
View file @
7e683c02
...
...
@@ -12,6 +12,7 @@ import 'package:flutter_tools/src/base/file_system.dart';
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/targets/shader_compiler.dart'
;
import
'package:flutter_tools/src/compile.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/device.dart'
;
...
...
@@ -138,7 +139,8 @@ void main() {
..
writeAsStringSync
(
'
\n
'
);
final
FakeDevice
device
=
FakeDevice
();
final
List
<
FlutterDevice
>
devices
=
<
FlutterDevice
>[
FlutterDevice
(
device
,
generator:
residentCompiler
,
buildInfo:
BuildInfo
.
debug
)..
devFS
=
FakeDevFs
(),
FlutterDevice
(
device
,
generator:
residentCompiler
,
buildInfo:
BuildInfo
.
debug
,
developmentShaderCompiler:
const
FakeShaderCompiler
())
..
devFS
=
FakeDevFs
(),
];
final
OperationResult
result
=
await
HotRunner
(
devices
,
...
...
@@ -208,7 +210,7 @@ void main() {
..
writeAsStringSync
(
'
\n
'
);
final
FakeDevice
device
=
FakeDevice
();
final
List
<
FlutterDevice
>
devices
=
<
FlutterDevice
>[
FlutterDevice
(
device
,
generator:
residentCompiler
,
buildInfo:
BuildInfo
.
debug
),
FlutterDevice
(
device
,
generator:
residentCompiler
,
buildInfo:
BuildInfo
.
debug
,
developmentShaderCompiler:
const
FakeShaderCompiler
()
),
];
await
HotRunner
(
devices
,
...
...
@@ -230,7 +232,7 @@ void main() {
..
writeAsStringSync
(
'
\n
'
);
final
FakeDevice
device
=
FakeDevice
();
final
List
<
FlutterDevice
>
devices
=
<
FlutterDevice
>[
FlutterDevice
(
device
,
generator:
residentCompiler
,
buildInfo:
BuildInfo
.
debug
),
FlutterDevice
(
device
,
generator:
residentCompiler
,
buildInfo:
BuildInfo
.
debug
,
developmentShaderCompiler:
const
FakeShaderCompiler
()
),
];
await
HotRunner
(
devices
,
...
...
@@ -567,6 +569,9 @@ class FakeDevFs extends Fake implements DevFS {
@override
Set
<
String
>
assetPathsToEvict
=
<
String
>{};
@override
Set
<
String
>
shaderPathsToEvict
=
<
String
>{};
@override
Uri
baseUri
;
}
...
...
@@ -661,7 +666,7 @@ class TestFlutterDevice extends FlutterDevice {
@required
this
.
exception
,
@required
ResidentCompiler
generator
,
})
:
assert
(
exception
!=
null
),
super
(
device
,
buildInfo:
BuildInfo
.
debug
,
generator:
generator
);
super
(
device
,
buildInfo:
BuildInfo
.
debug
,
generator:
generator
,
developmentShaderCompiler:
const
FakeShaderCompiler
()
);
/// The exception to throw when the connect method is called.
final
Exception
exception
;
...
...
@@ -739,3 +744,15 @@ class FakeVm extends Fake implements vm_service.VM {
@override
List
<
vm_service
.
IsolateRef
>
get
isolates
=>
<
vm_service
.
IsolateRef
>[];
}
class
FakeShaderCompiler
implements
DevelopmentShaderCompiler
{
const
FakeShaderCompiler
();
@override
void
configureCompiler
(
TargetPlatform
platform
,
{
@required
bool
enableImpeller
})
{
}
@override
Future
<
DevFSContent
>
recompileShader
(
DevFSContent
inputShader
)
{
throw
UnimplementedError
();
}
}
packages/flutter_tools/test/general.shard/resident_runner_test.dart
View file @
7e683c02
...
...
@@ -20,6 +20,7 @@ import 'package:flutter_tools/src/base/io.dart' as io;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/targets/shader_compiler.dart'
;
import
'package:flutter_tools/src/compile.dart'
;
import
'package:flutter_tools/src/convert.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
...
...
@@ -145,6 +146,14 @@ const FakeVmServiceRequest evict = FakeVmServiceRequest(
}
);
const
FakeVmServiceRequest
evictShader
=
FakeVmServiceRequest
(
method:
'ext.ui.window.reinitializeShader'
,
args:
<
String
,
Object
>{
'assetKey'
:
'foo.frag'
,
'isolateId'
:
'1'
,
}
);
final
Uri
testUri
=
Uri
.
parse
(
'foo://bar'
);
void
main
(
)
{
...
...
@@ -2240,6 +2249,30 @@ flutter:
expect
(
fakeVmServiceHost
.
hasRemainingExpectations
,
false
);
}));
testUsingContext
(
'HotRunner sets asset directory when first evict shaders'
,
()
=>
testbed
.
run
(()
async
{
fakeVmServiceHost
=
FakeVmServiceHost
(
requests:
<
VmServiceExpectation
>[
listViews
,
setAssetBundlePath
,
evictShader
,
]);
residentRunner
=
HotRunner
(
<
FlutterDevice
>[
flutterDevice
,
],
stayResident:
false
,
debuggingOptions:
DebuggingOptions
.
enabled
(
BuildInfo
.
debug
),
target:
'main.dart'
,
devtoolsHandler:
createNoOpHandler
,
);
(
flutterDevice
.
devFS
as
FakeDevFS
).
shaderPathsToEvict
=
<
String
>{
'foo.frag'
};
expect
(
flutterDevice
.
devFS
.
hasSetAssetDirectory
,
false
);
await
(
residentRunner
as
HotRunner
).
evictDirtyAssets
();
expect
(
flutterDevice
.
devFS
.
hasSetAssetDirectory
,
true
);
expect
(
fakeVmServiceHost
.
hasRemainingExpectations
,
false
);
}));
testUsingContext
(
'HotRunner does not sets asset directory when no assets to evict'
,
()
=>
testbed
.
run
(()
async
{
fakeVmServiceHost
=
FakeVmServiceHost
(
requests:
<
VmServiceExpectation
>[
]);
...
...
@@ -2296,7 +2329,7 @@ class FakeDartDevelopmentServiceException implements dds.DartDevelopmentServiceE
class
TestFlutterDevice
extends
FlutterDevice
{
TestFlutterDevice
(
Device
device
,
{
Stream
<
Uri
>
observatoryUris
})
:
super
(
device
,
buildInfo:
BuildInfo
.
debug
)
{
:
super
(
device
,
buildInfo:
BuildInfo
.
debug
,
developmentShaderCompiler:
const
FakeShaderCompiler
()
)
{
_observatoryUris
=
observatoryUris
;
}
...
...
@@ -2332,6 +2365,12 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
@override
ResidentCompiler
generator
;
@override
DevelopmentShaderCompiler
get
developmentShaderCompiler
=>
const
FakeShaderCompiler
();
@override
TargetPlatform
get
targetPlatform
=>
TargetPlatform
.
android
;
@override
Stream
<
Uri
>
get
observatoryUris
=>
Stream
<
Uri
>.
value
(
testUri
);
...
...
@@ -2420,7 +2459,7 @@ class FakeDelegateFlutterDevice extends FlutterDevice {
BuildInfo
buildInfo
,
ResidentCompiler
residentCompiler
,
this
.
fakeDevFS
,
)
:
super
(
device
,
buildInfo:
buildInfo
,
generator:
residentCompiler
);
)
:
super
(
device
,
buildInfo:
buildInfo
,
generator:
residentCompiler
,
developmentShaderCompiler:
const
FakeShaderCompiler
()
);
@override
Future
<
void
>
connect
({
...
...
@@ -2591,6 +2630,9 @@ class FakeDevFS extends Fake implements DevFS {
@override
Set
<
String
>
assetPathsToEvict
=
<
String
>{};
@override
Set
<
String
>
shaderPathsToEvict
=
<
String
>{};
UpdateFSReport
nextUpdateReport
=
UpdateFSReport
(
success:
true
);
@override
...
...
@@ -2615,6 +2657,7 @@ class FakeDevFS extends Fake implements DevFS {
@required
List
<
Uri
>
invalidatedFiles
,
@required
PackageConfig
packageConfig
,
@required
String
dillOutputPath
,
@required
DevelopmentShaderCompiler
shaderCompiler
,
DevFSWriter
devFSWriter
,
String
target
,
AssetBundle
bundle
,
...
...
@@ -2627,3 +2670,15 @@ class FakeDevFS extends Fake implements DevFS {
return
nextUpdateReport
;
}
}
class
FakeShaderCompiler
implements
DevelopmentShaderCompiler
{
const
FakeShaderCompiler
();
@override
void
configureCompiler
(
TargetPlatform
platform
,
{
@required
bool
enableImpeller
})
{
}
@override
Future
<
DevFSContent
>
recompileShader
(
DevFSContent
inputShader
)
{
throw
UnimplementedError
();
}
}
packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
View file @
7e683c02
...
...
@@ -18,6 +18,7 @@ import 'package:flutter_tools/src/base/logger.dart';
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/base/time.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/targets/shader_compiler.dart'
;
import
'package:flutter_tools/src/compile.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/device.dart'
;
...
...
@@ -1336,6 +1337,7 @@ class FakeWebDevFS extends Fake implements WebDevFS {
@required
List
<
Uri
>
invalidatedFiles
,
@required
PackageConfig
packageConfig
,
@required
String
dillOutputPath
,
@required
DevelopmentShaderCompiler
shaderCompiler
,
DevFSWriter
devFSWriter
,
String
target
,
AssetBundle
bundle
,
...
...
@@ -1454,6 +1456,9 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
@override
Stream
<
Uri
>
get
observatoryUris
=>
Stream
<
Uri
>.
value
(
testUri
);
@override
DevelopmentShaderCompiler
get
developmentShaderCompiler
=>
const
FakeShaderCompiler
();
@override
FlutterVmService
vmService
;
...
...
@@ -1524,3 +1529,15 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
@override
Future
<
void
>
updateReloadStatus
(
bool
wasReloadSuccessful
)
async
{}
}
class
FakeShaderCompiler
implements
DevelopmentShaderCompiler
{
const
FakeShaderCompiler
();
@override
void
configureCompiler
(
TargetPlatform
platform
,
{
@required
bool
enableImpeller
})
{
}
@override
Future
<
DevFSContent
>
recompileShader
(
DevFSContent
inputShader
)
{
throw
UnimplementedError
();
}
}
packages/flutter_tools/test/general.shard/terminal_handler_test.dart
View file @
7e683c02
...
...
@@ -12,8 +12,10 @@ import 'package:flutter_tools/src/base/logger.dart';
import
'package:flutter_tools/src/base/signals.dart'
;
import
'package:flutter_tools/src/base/terminal.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/targets/shader_compiler.dart'
;
import
'package:flutter_tools/src/compile.dart'
;
import
'package:flutter_tools/src/convert.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/resident_devtools_handler.dart'
;
import
'package:flutter_tools/src/resident_runner.dart'
;
...
...
@@ -1215,7 +1217,12 @@ void main() {
final
MemoryFileSystem
fs
=
MemoryFileSystem
.
test
();
final
ProcessInfo
processInfo
=
ProcessInfo
.
test
(
fs
);
final
FakeResidentRunner
residentRunner
=
FakeResidentRunner
(
FlutterDevice
(
FakeDevice
(),
buildInfo:
BuildInfo
.
debug
,
generator:
FakeResidentCompiler
()),
FlutterDevice
(
FakeDevice
(),
buildInfo:
BuildInfo
.
debug
,
generator:
FakeResidentCompiler
(),
developmentShaderCompiler:
const
FakeShaderCompiler
(),
),
testLogger
,
fs
,
);
...
...
@@ -1391,6 +1398,7 @@ TerminalHandler setUpTerminalHandler(List<FakeVmServiceRequest> requests, {
FakeDevice
()..
supportsScreenshot
=
supportsScreenshot
,
buildInfo:
BuildInfo
(
buildMode
,
''
,
treeShakeIcons:
false
),
generator:
FakeResidentCompiler
(),
developmentShaderCompiler:
const
FakeShaderCompiler
(),
targetPlatform:
web
?
TargetPlatform
.
web_javascript
:
TargetPlatform
.
android_arm
,
...
...
@@ -1499,3 +1507,15 @@ class _TestSignals implements Signals {
Stream
<
Object
>
get
errors
=>
_errors
.
stream
;
final
StreamController
<
Object
>
_errors
=
StreamController
<
Object
>();
}
class
FakeShaderCompiler
implements
DevelopmentShaderCompiler
{
const
FakeShaderCompiler
();
@override
void
configureCompiler
(
TargetPlatform
?
platform
,
{
required
bool
enableImpeller
})
{
}
@override
Future
<
DevFSContent
>
recompileShader
(
DevFSContent
inputShader
)
{
throw
UnimplementedError
();
}
}
packages/flutter_tools/test/general.shard/web/devfs_web_test.dart
View file @
7e683c02
...
...
@@ -13,13 +13,16 @@ import 'package:flutter_tools/src/base/file_system.dart';
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/targets/shader_compiler.dart'
;
import
'package:flutter_tools/src/build_system/targets/web.dart'
;
import
'package:flutter_tools/src/compile.dart'
;
import
'package:flutter_tools/src/convert.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/globals.dart'
as
globals
;
import
'package:flutter_tools/src/isolated/devfs_web.dart'
;
import
'package:flutter_tools/src/web/compile.dart'
;
import
'package:logging/logging.dart'
as
logging
;
import
'package:meta/meta.dart'
;
import
'package:package_config/package_config.dart'
;
import
'package:shelf/shelf.dart'
;
import
'package:test/fake.dart'
;
...
...
@@ -721,6 +724,7 @@ void main() {
packageConfig:
PackageConfig
.
empty
,
pathToReload:
''
,
dillOutputPath:
'out.dill'
,
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
webDevFS
.
webAssetServer
.
getFile
(
'require.js'
),
isNotNull
);
...
...
@@ -832,6 +836,7 @@ void main() {
packageConfig:
PackageConfig
.
empty
,
pathToReload:
''
,
dillOutputPath:
''
,
shaderCompiler:
const
FakeShaderCompiler
(),
);
expect
(
webDevFS
.
webAssetServer
.
getFile
(
'require.js'
),
isNotNull
);
...
...
@@ -1125,3 +1130,15 @@ class FakeResidentCompiler extends Fake implements ResidentCompiler {
return
output
;
}
}
class
FakeShaderCompiler
implements
DevelopmentShaderCompiler
{
const
FakeShaderCompiler
();
@override
void
configureCompiler
(
TargetPlatform
platform
,
{
@required
bool
enableImpeller
})
{
}
@override
Future
<
DevFSContent
>
recompileShader
(
DevFSContent
inputShader
)
{
throw
UnimplementedError
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment