mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Check for shader data validity and add tests (flutter/engine#34793)
This commit is contained in:
parent
131f0a3555
commit
69f22945ed
@ -65,9 +65,6 @@ RuntimeStage::RuntimeStage(std::shared_ptr<fml::Mapping> payload)
|
||||
return;
|
||||
}
|
||||
if (!fb::RuntimeStageBufferHasIdentifier(payload_->GetMapping())) {
|
||||
VALIDATION_LOG
|
||||
<< "Impeller Runtime stage has invalid magic. Perhaps the stage "
|
||||
"information is for the incorrect backend or the data is corrupted?";
|
||||
return;
|
||||
}
|
||||
auto runtime_stage = fb::GetRuntimeStage(payload_->GetMapping());
|
||||
|
||||
@ -4126,7 +4126,10 @@ class FragmentProgram extends NativeFieldWrapperClass1 {
|
||||
@pragma('vm:entry-point')
|
||||
FragmentProgram._fromAsset(String assetKey) {
|
||||
_constructor();
|
||||
_initFromAsset(assetKey);
|
||||
final String result = _initFromAsset(assetKey);
|
||||
if (result.isNotEmpty) {
|
||||
throw result;
|
||||
}
|
||||
}
|
||||
|
||||
static void _reinitializeShader(String assetKey) {
|
||||
@ -4145,7 +4148,10 @@ class FragmentProgram extends NativeFieldWrapperClass1 {
|
||||
return;
|
||||
}
|
||||
|
||||
program._initFromAsset(assetKey);
|
||||
final result = program._initFromAsset(assetKey);
|
||||
if (result.isNotEmpty) {
|
||||
throw result;
|
||||
}
|
||||
}
|
||||
|
||||
late final int _uniformFloatCount;
|
||||
@ -4157,8 +4163,8 @@ class FragmentProgram extends NativeFieldWrapperClass1 {
|
||||
@FfiNative<Void Function(Pointer<Void>, Handle, Bool)>('FragmentProgram::init')
|
||||
external void _init(String sksl, bool debugPrint);
|
||||
|
||||
@FfiNative<Void Function(Pointer<Void>, Handle)>('FragmentProgram::initFromAsset')
|
||||
external void _initFromAsset(String assetKey);
|
||||
@FfiNative<Handle Function(Pointer<Void>, Handle)>('FragmentProgram::initFromAsset')
|
||||
external String _initFromAsset(String assetKey);
|
||||
|
||||
/// Constructs a [Shader] object suitable for use by [Paint.shader] with
|
||||
/// the given uniforms.
|
||||
|
||||
@ -22,18 +22,21 @@ namespace flutter {
|
||||
|
||||
IMPLEMENT_WRAPPERTYPEINFO(ui, FragmentProgram);
|
||||
|
||||
void FragmentProgram::initFromAsset(std::string asset_name) {
|
||||
std::string FragmentProgram::initFromAsset(std::string asset_name) {
|
||||
std::shared_ptr<AssetManager> asset_manager = UIDartState::Current()
|
||||
->platform_configuration()
|
||||
->client()
|
||||
->GetAssetManager();
|
||||
std::unique_ptr<fml::Mapping> data = asset_manager->GetAsMapping(asset_name);
|
||||
if (data == nullptr) {
|
||||
Dart_ThrowException(tonic::ToDart("Asset '" + asset_name + "' not found"));
|
||||
return;
|
||||
return std::string("Asset '") + asset_name + std::string("' not found");
|
||||
}
|
||||
|
||||
auto runtime_stage = impeller::RuntimeStage(std::move(data));
|
||||
if (!runtime_stage.IsValid()) {
|
||||
return std::string("Asset '") + asset_name +
|
||||
std::string("' does not contain valid shader data.");
|
||||
}
|
||||
{
|
||||
auto code_mapping = runtime_stage.GetCodeMapping();
|
||||
auto code_size = code_mapping->GetSize();
|
||||
@ -43,10 +46,8 @@ void FragmentProgram::initFromAsset(std::string asset_name) {
|
||||
SkRuntimeEffect::Result result =
|
||||
SkRuntimeEffect::MakeForShader(SkString(sksl, code_size));
|
||||
if (result.effect == nullptr) {
|
||||
Dart_ThrowException(tonic::ToDart(std::string("Invalid SkSL:\n") + sksl +
|
||||
std::string("\nSkSL Error:\n") +
|
||||
result.errorText.c_str()));
|
||||
return;
|
||||
return std::string("Invalid SkSL:\n") + sksl +
|
||||
std::string("\nSkSL Error:\n") + result.errorText.c_str();
|
||||
}
|
||||
runtime_effect_ = result.effect;
|
||||
}
|
||||
@ -84,6 +85,8 @@ void FragmentProgram::initFromAsset(std::string asset_name) {
|
||||
if (Dart_IsError(result)) {
|
||||
Dart_PropagateError(result);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void FragmentProgram::init(std::string sksl, bool debugPrintSksl) {
|
||||
|
||||
@ -24,7 +24,7 @@ class FragmentProgram : public RefCountedDartWrappable<FragmentProgram> {
|
||||
~FragmentProgram() override;
|
||||
static void Create(Dart_Handle wrapper);
|
||||
|
||||
void initFromAsset(std::string asset_name);
|
||||
std::string initFromAsset(std::string asset_name);
|
||||
|
||||
void init(std::string sksl, bool debugPrintSksl);
|
||||
|
||||
|
||||
@ -295,6 +295,30 @@ void main() {
|
||||
await _expectShaderRendersGreen(shader);
|
||||
});
|
||||
|
||||
test('iplr throws an exception on invalid assetKey', () async {
|
||||
bool throws = false;
|
||||
try {
|
||||
final FragmentProgram program = FragmentProgram.fromAsset(
|
||||
'<invalid>',
|
||||
);
|
||||
} catch (e) {
|
||||
throws = true;
|
||||
}
|
||||
expect(throws, equals(true));
|
||||
});
|
||||
|
||||
test('iplr throws an exception on invalid data', () async {
|
||||
bool throws = false;
|
||||
try {
|
||||
final FragmentProgram program = FragmentProgram.fromAsset(
|
||||
'DashInNooglerHat.jpg',
|
||||
);
|
||||
} catch (e) {
|
||||
throws = true;
|
||||
}
|
||||
expect(throws, equals(true));
|
||||
});
|
||||
|
||||
// Test all supported GLSL ops. See lib/spirv/lib/src/constants.dart
|
||||
final Map<String, ByteBuffer> supportedGLSLOpShaders = _loadShaders(
|
||||
path.join('supported_glsl_op_shaders', 'spirv'),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user