Skip to content

Commit 1e2583e

Browse files
author
Jonah Williams
authored
[ui] Fix ImageFilter.shader equality to consider uniform values. (#163348)
Fixes flutter/flutter#163302 Framework widgets check for ImageFIlter.== to determine whether to mark themselves dirty. The filter obejct needs to delegate its equality to the underlying native filter so that uniform values are considered.
1 parent 35eaaaa commit 1e2583e

File tree

5 files changed

+40
-1
lines changed

5 files changed

+40
-1
lines changed

engine/src/flutter/lib/ui/dart_ui.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ typedef CanvasPath Path;
207207
V(ImageFilter, initComposeFilter) \
208208
V(ImageFilter, initShader) \
209209
V(ImageFilter, initMatrix) \
210+
V(ImageFilter, equals) \
210211
V(ImageShader, dispose) \
211212
V(ImageShader, initWithImage) \
212213
V(ImmutableBuffer, dispose) \

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4474,9 +4474,14 @@ class _FragmentShaderImageFilter implements ImageFilter {
44744474
if (other.runtimeType != runtimeType) {
44754475
return false;
44764476
}
4477-
return other is _FragmentShaderImageFilter && other.shader == shader;
4477+
return other is _FragmentShaderImageFilter &&
4478+
other.shader == shader &&
4479+
_equals(nativeFilter, other.nativeFilter);
44784480
}
44794481

4482+
@Native<Bool Function(Handle, Handle)>(symbol: 'ImageFilter::equal')
4483+
external static bool _equals(_ImageFilter a, _ImageFilter b);
4484+
44804485
@override
44814486
int get hashCode => shader.hashCode;
44824487
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,8 @@ void ImageFilter::initShader(ReusableFragmentShader* shader) {
125125
filter_ = shader->as_image_filter();
126126
}
127127

128+
bool ImageFilter::equals(ImageFilter* a, ImageFilter* b) {
129+
return a->filter_ == b->filter_;
130+
}
131+
128132
} // namespace flutter

engine/src/flutter/lib/ui/painting/image_filter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class ImageFilter : public RefCountedDartWrappable<ImageFilter> {
3636
void initColorFilter(ColorFilter* colorFilter);
3737
void initComposeFilter(ImageFilter* outer, ImageFilter* inner);
3838
void initShader(ReusableFragmentShader* shader);
39+
bool equals(ImageFilter* a, ImageFilter* b);
3940

4041
const std::shared_ptr<DlImageFilter> filter(DlTileMode mode) const;
4142

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,34 @@ void main() async {
415415
expect(color, const Color(0xFF00FF00));
416416
});
417417

418+
// For an explaination of the problem see https://github.com/flutter/flutter/issues/163302 .
419+
test('ImageFilter.shader equality checks consider uniform values', () async {
420+
if (!impellerEnabled) {
421+
print('Skipped for Skia');
422+
return;
423+
}
424+
final FragmentProgram program = await FragmentProgram.fromAsset('filter_shader.frag.iplr');
425+
final FragmentShader shader = program.fragmentShader();
426+
final ImageFilter filter = ImageFilter.shader(shader);
427+
428+
// The same shader is equal to itself.
429+
expect(filter, filter);
430+
expect(identical(filter, filter), true);
431+
432+
final ImageFilter filter_2 = ImageFilter.shader(shader);
433+
434+
// The different shader is equal as long as uniforms are identical.
435+
expect(filter, filter_2);
436+
expect(identical(filter, filter_2), false);
437+
438+
// Not equal if uniforms change.
439+
shader.setFloat(0, 1);
440+
final ImageFilter filter_3 = ImageFilter.shader(shader);
441+
442+
expect(filter, isNot(filter_3));
443+
expect(identical(filter, filter_3), false);
444+
});
445+
418446
if (impellerEnabled) {
419447
print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823');
420448
return;

0 commit comments

Comments
 (0)