Skip to content

Commit 6912a06

Browse files
Add checks for disposed images in FragmentShader.setImageSampler (#165214)
1 parent 5f0b94f commit 6912a06

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

engine/src/flutter/lib/ui/painting.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5280,6 +5280,7 @@ base class FragmentShader extends Shader {
52805280
/// results will be undefined.
52815281
void setImageSampler(int index, Image image) {
52825282
assert(!debugDisposed, 'Tried to access uniforms on a disposed Shader: $this');
5283+
assert(!image.debugDisposed, 'Image has been disposed');
52835284
_setImageSampler(index, image._image);
52845285
}
52855286

engine/src/flutter/lib/ui/painting/fragment_shader.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,15 @@ void ReusableFragmentShader::SetImageSampler(Dart_Handle index_handle,
6666
tonic::DartConverter<CanvasImage*>::FromDart(image_handle);
6767
if (index >= samplers_.size()) {
6868
Dart_ThrowException(tonic::ToDart("Sampler index out of bounds"));
69+
return;
70+
}
71+
if (!image || !image->image()) {
72+
Dart_ThrowException(tonic::ToDart("Image has been disposed"));
73+
return;
6974
}
7075
if (!image->image()->isUIThreadSafe()) {
7176
Dart_ThrowException(tonic::ToDart("Image is not thread-safe"));
77+
return;
7278
}
7379

7480
// TODO(115794): Once the DlImageSampling enum is replaced, expose the

engine/src/flutter/testing/dart/fragment_shader_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,30 @@ void main() async {
9191
},
9292
);
9393

94+
test('FragmentShader setImageSampler asserts if image is disposed', () async {
95+
final FragmentProgram program = await FragmentProgram.fromAsset('blue_green_sampler.frag.iplr');
96+
final Image blueGreenImage = await _createBlueGreenImage();
97+
final FragmentShader fragmentShader = program.fragmentShader();
98+
99+
try {
100+
blueGreenImage.dispose();
101+
expect(
102+
() {
103+
fragmentShader.setImageSampler(0, blueGreenImage);
104+
},
105+
throwsA(
106+
isA<AssertionError>().having(
107+
(AssertionError e) => e.message,
108+
'message',
109+
contains('Image has been disposed'),
110+
),
111+
),
112+
);
113+
} finally {
114+
fragmentShader.dispose();
115+
}
116+
});
117+
94118
test('Disposed FragmentShader on Paint', () async {
95119
final FragmentProgram program = await FragmentProgram.fromAsset('blue_green_sampler.frag.iplr');
96120
final Image blueGreenImage = await _createBlueGreenImage();

0 commit comments

Comments
 (0)