[framework] partial removal of forced compositing from opacity (#106989)
diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index 2af1c06..1d95a75 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart
@@ -883,15 +883,7 @@ super(child); @override - bool get alwaysNeedsCompositing => child != null && (_alpha > 0); - - @override - OffsetLayer updateCompositedLayer({required covariant OpacityLayer? oldLayer}) { - assert(_alpha != 255); - final OpacityLayer updatedLayer = oldLayer ?? OpacityLayer(); - updatedLayer.alpha = _alpha; - return updatedLayer; - } + bool get alwaysNeedsCompositing => child != null && (_alpha > 0 && _alpha < 255); int _alpha; @@ -949,19 +941,26 @@ @override void paint(PaintingContext context, Offset offset) { - if (child != null) { - if (_alpha == 0) { - // No need to keep the layer. We'll create a new one if necessary. - layer = null; - return; - } - assert(needsCompositing); - layer = context.pushOpacity(offset, _alpha, super.paint, oldLayer: layer as OpacityLayer?); - assert(() { - layer!.debugCreator = debugCreator; - return true; - }()); + if (child == null) { + return; } + if (_alpha == 0) { + // No need to keep the layer. We'll create a new one if necessary. + layer = null; + return; + } + if (_alpha == 255) { + // No need to keep the layer. We'll create a new one if necessary. + layer = null; + return super.paint(context, offset); + } + + assert(needsCompositing); + layer = context.pushOpacity(offset, _alpha, super.paint, oldLayer: layer as OpacityLayer?); + assert(() { + layer!.debugCreator = debugCreator; + return true; + }()); } @override
diff --git a/packages/flutter/test/rendering/proxy_box_test.dart b/packages/flutter/test/rendering/proxy_box_test.dart index 3077057..78c426e 100644 --- a/packages/flutter/test/rendering/proxy_box_test.dart +++ b/packages/flutter/test/rendering/proxy_box_test.dart
@@ -240,12 +240,22 @@ expect(renderOpacity.needsCompositing, false); }); - test('RenderOpacity does composite if it is opaque', () { + test('RenderOpacity does not composite if it is opaque', () { final RenderOpacity renderOpacity = RenderOpacity( child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter ); layout(renderOpacity, phase: EnginePhase.composite); + expect(renderOpacity.needsCompositing, false); + }); + + test('RenderOpacity does composite if it is partially opaque', () { + final RenderOpacity renderOpacity = RenderOpacity( + opacity: 0.1, + child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter + ); + + layout(renderOpacity, phase: EnginePhase.composite); expect(renderOpacity.needsCompositing, true); });
diff --git a/packages/flutter/test/widgets/debug_test.dart b/packages/flutter/test/widgets/debug_test.dart index ce1eabb..0ddcf3c 100644 --- a/packages/flutter/test/widgets/debug_test.dart +++ b/packages/flutter/test/widgets/debug_test.dart
@@ -285,7 +285,7 @@ child: Placeholder(), ), const Opacity( - opacity: 1.0, + opacity: 0.9, child: Placeholder(), ), ImageFiltered(