[framework] revert removal of opacity (#111202) (#111207)

Co-authored-by: Kevin Chisholm <kevinjchisholm@google.com>
diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart
index a5107bb..2917266 100644
--- a/packages/flutter/lib/src/rendering/proxy_box.dart
+++ b/packages/flutter/lib/src/rendering/proxy_box.dart
@@ -883,7 +883,7 @@
        super(child);
 
   @override
-  bool get alwaysNeedsCompositing => child != null && (_alpha > 0 && _alpha < 255);
+  bool get alwaysNeedsCompositing => child != null && _alpha > 0;
 
   int _alpha;
 
@@ -949,11 +949,6 @@
       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?);
@@ -1060,7 +1055,7 @@
     _alpha = ui.Color.getAlphaFromOpacity(opacity.value);
     if (oldAlpha != _alpha) {
       final bool? wasRepaintBoundary = _currentlyIsRepaintBoundary;
-      _currentlyIsRepaintBoundary = _alpha! > 0 && _alpha! < 255;
+      _currentlyIsRepaintBoundary = _alpha! > 0;
       if (child != null && wasRepaintBoundary != _currentlyIsRepaintBoundary) {
         markNeedsCompositingBitsUpdate();
       }
diff --git a/packages/flutter/test/rendering/proxy_box_test.dart b/packages/flutter/test/rendering/proxy_box_test.dart
index 78c426e..d29d2d5 100644
--- a/packages/flutter/test/rendering/proxy_box_test.dart
+++ b/packages/flutter/test/rendering/proxy_box_test.dart
@@ -240,13 +240,13 @@
     expect(renderOpacity.needsCompositing, false);
   });
 
-  test('RenderOpacity does not composite if it is opaque', () {
+  test('RenderOpacity does 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);
+    expect(renderOpacity.needsCompositing, true);
   });
 
   test('RenderOpacity does composite if it is partially opaque', () {
@@ -282,7 +282,7 @@
     expect(renderAnimatedOpacity.needsCompositing, false);
   });
 
-  test('RenderAnimatedOpacity does not composite if it is opaque', () {
+  test('RenderAnimatedOpacity does composite if it is opaque', () {
     final Animation<double> opacityAnimation = AnimationController(
       vsync: FakeTickerProvider(),
     )..value = 1.0;
@@ -293,7 +293,7 @@
     );
 
     layout(renderAnimatedOpacity, phase: EnginePhase.composite);
-    expect(renderAnimatedOpacity.needsCompositing, false);
+    expect(renderAnimatedOpacity.needsCompositing, true);
   });
 
   test('RenderAnimatedOpacity does composite if it is partially opaque', () {
diff --git a/packages/flutter/test/rendering/proxy_sliver_test.dart b/packages/flutter/test/rendering/proxy_sliver_test.dart
index c4c7e1d..bb83fd8 100644
--- a/packages/flutter/test/rendering/proxy_sliver_test.dart
+++ b/packages/flutter/test/rendering/proxy_sliver_test.dart
@@ -47,6 +47,7 @@
     layout(root, phase: EnginePhase.composite);
     expect(renderSliverOpacity.needsCompositing, true);
   });
+
   test('RenderSliverOpacity reuses its layer', () {
     final RenderSliverOpacity renderSliverOpacity = RenderSliverOpacity(
       opacity: 0.5,
@@ -121,7 +122,7 @@
     expect(renderSliverAnimatedOpacity.needsCompositing, true);
   });
 
-  test('RenderSliverAnimatedOpacity does not composite if it is opaque', () {
+  test('RenderSliverAnimatedOpacity does composite if it is opaque', () {
     final Animation<double> opacityAnimation = AnimationController(
       vsync: FakeTickerProvider(),
     )..value = 1.0;
@@ -141,7 +142,7 @@
     );
 
     layout(root, phase: EnginePhase.composite);
-    expect(renderSliverAnimatedOpacity.needsCompositing, false);
+    expect(renderSliverAnimatedOpacity.needsCompositing, true);
   });
 
   test('RenderSliverAnimatedOpacity reuses its layer', () {
diff --git a/packages/flutter/test/widgets/animated_opacity_repaint_test.dart b/packages/flutter/test/widgets/animated_opacity_repaint_test.dart
index 555ee52..425ab6b 100644
--- a/packages/flutter/test/widgets/animated_opacity_repaint_test.dart
+++ b/packages/flutter/test/widgets/animated_opacity_repaint_test.dart
@@ -7,7 +7,7 @@
 import 'package:flutter_test/flutter_test.dart';
 
 void main() {
-  testWidgets('RenderAnimatedOpacityMixin drops layer when animating to 1', (WidgetTester tester) async {
+  testWidgets('RenderAnimatedOpacityMixin does not drop layer when animating to 1', (WidgetTester tester) async {
     RenderTestObject.paintCount = 0;
     final AnimationController controller = AnimationController(vsync: const TestVSync(), duration: const Duration(seconds: 1));
     final Tween<double> opacityTween = Tween<double>(begin: 0, end: 1);
@@ -32,12 +32,12 @@
     await tester.pump();
     await tester.pump(const Duration(milliseconds: 500));
 
-    expect(RenderTestObject.paintCount, 2);
+    expect(RenderTestObject.paintCount, 1);
 
     controller.stop();
     await tester.pump();
 
-    expect(RenderTestObject.paintCount, 2);
+    expect(RenderTestObject.paintCount, 1);
   });
 
   testWidgets('RenderAnimatedOpacityMixin avoids repainting child as it animates', (WidgetTester tester) async {