[ui] Fix ImageFilter.shader equality to consider uniform values. (#163348)
Fixes https://github.com/flutter/flutter/issues/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.
This commit is contained in:
parent
35eaaaa3d0
commit
1e2583eff2
@ -207,6 +207,7 @@ typedef CanvasPath Path;
|
||||
V(ImageFilter, initComposeFilter) \
|
||||
V(ImageFilter, initShader) \
|
||||
V(ImageFilter, initMatrix) \
|
||||
V(ImageFilter, equals) \
|
||||
V(ImageShader, dispose) \
|
||||
V(ImageShader, initWithImage) \
|
||||
V(ImmutableBuffer, dispose) \
|
||||
|
@ -4474,9 +4474,14 @@ class _FragmentShaderImageFilter implements ImageFilter {
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is _FragmentShaderImageFilter && other.shader == shader;
|
||||
return other is _FragmentShaderImageFilter &&
|
||||
other.shader == shader &&
|
||||
_equals(nativeFilter, other.nativeFilter);
|
||||
}
|
||||
|
||||
@Native<Bool Function(Handle, Handle)>(symbol: 'ImageFilter::equal')
|
||||
external static bool _equals(_ImageFilter a, _ImageFilter b);
|
||||
|
||||
@override
|
||||
int get hashCode => shader.hashCode;
|
||||
}
|
||||
|
@ -125,4 +125,8 @@ void ImageFilter::initShader(ReusableFragmentShader* shader) {
|
||||
filter_ = shader->as_image_filter();
|
||||
}
|
||||
|
||||
bool ImageFilter::equals(ImageFilter* a, ImageFilter* b) {
|
||||
return a->filter_ == b->filter_;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
@ -36,6 +36,7 @@ class ImageFilter : public RefCountedDartWrappable<ImageFilter> {
|
||||
void initColorFilter(ColorFilter* colorFilter);
|
||||
void initComposeFilter(ImageFilter* outer, ImageFilter* inner);
|
||||
void initShader(ReusableFragmentShader* shader);
|
||||
bool equals(ImageFilter* a, ImageFilter* b);
|
||||
|
||||
const std::shared_ptr<DlImageFilter> filter(DlTileMode mode) const;
|
||||
|
||||
|
@ -415,6 +415,34 @@ void main() async {
|
||||
expect(color, const Color(0xFF00FF00));
|
||||
});
|
||||
|
||||
// For an explaination of the problem see https://github.com/flutter/flutter/issues/163302 .
|
||||
test('ImageFilter.shader equality checks consider uniform values', () async {
|
||||
if (!impellerEnabled) {
|
||||
print('Skipped for Skia');
|
||||
return;
|
||||
}
|
||||
final FragmentProgram program = await FragmentProgram.fromAsset('filter_shader.frag.iplr');
|
||||
final FragmentShader shader = program.fragmentShader();
|
||||
final ImageFilter filter = ImageFilter.shader(shader);
|
||||
|
||||
// The same shader is equal to itself.
|
||||
expect(filter, filter);
|
||||
expect(identical(filter, filter), true);
|
||||
|
||||
final ImageFilter filter_2 = ImageFilter.shader(shader);
|
||||
|
||||
// The different shader is equal as long as uniforms are identical.
|
||||
expect(filter, filter_2);
|
||||
expect(identical(filter, filter_2), false);
|
||||
|
||||
// Not equal if uniforms change.
|
||||
shader.setFloat(0, 1);
|
||||
final ImageFilter filter_3 = ImageFilter.shader(shader);
|
||||
|
||||
expect(filter, isNot(filter_3));
|
||||
expect(identical(filter, filter_3), false);
|
||||
});
|
||||
|
||||
if (impellerEnabled) {
|
||||
print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823');
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user