diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 7fe578dea2..67d0d47a64 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -2113,6 +2113,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { if (!_needsCompositingBitsUpdate) return; final bool oldNeedsCompositing = _needsCompositing; + _needsCompositing = false; visitChildren((RenderObject child) { child._updateCompositingBits(); if (child.needsCompositing) diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index b4d3888365..90843e1160 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -1286,6 +1286,7 @@ class RenderPhysicalModel extends _RenderCustomClip { if (elevation == value) return; _elevation = value; + markNeedsCompositingBitsUpdate(); markNeedsPaint(); } @@ -1325,6 +1326,11 @@ class RenderPhysicalModel extends _RenderCustomClip { static final Paint _defaultPaint = new Paint(); static final Paint _transparentPaint = new Paint()..color = const Color(0x00000000); + // On Fuchsia, the system compositor is responsible for drawing shadows + // for physical model layers with non-zero elevation. + @override + bool get alwaysNeedsCompositing => _elevation != 0.0 && defaultTargetPlatform == TargetPlatform.fuchsia; + @override void paint(PaintingContext context, Offset offset) { if (child != null) { diff --git a/packages/flutter/test/rendering/proxy_box_test.dart b/packages/flutter/test/rendering/proxy_box_test.dart index 8e355a9498..ff0958d654 100644 --- a/packages/flutter/test/rendering/proxy_box_test.dart +++ b/packages/flutter/test/rendering/proxy_box_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:test/test.dart'; @@ -29,4 +30,43 @@ void main() { layout(makeFittedBox(), constraints: new BoxConstraints.tight(Size.zero), phase: EnginePhase.paint); expect(painted, equals(false)); }); + + test('RenderPhysicalModel compositing on Fuchsia', () { + debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; + + final root = new RenderPhysicalModel(color: new Color(0xffff00ff)); + layout(root, phase: EnginePhase.composite); + expect(root.needsCompositing, isFalse); + + // On Fuchsia, the system compositor is responsible for drawing shadows + // for physical model layers with non-zero elevation. + root.elevation = 1.0; + pumpFrame(phase: EnginePhase.composite); + expect(root.needsCompositing, isTrue); + + root.elevation = 0.0; + pumpFrame(phase: EnginePhase.composite); + expect(root.needsCompositing, isFalse); + + debugDefaultTargetPlatformOverride = null; + }); + + test('RenderPhysicalModel compositing on non-Fuchsia', () { + debugDefaultTargetPlatformOverride = TargetPlatform.iOS; + + final root = new RenderPhysicalModel(color: new Color(0xffff00ff)); + layout(root, phase: EnginePhase.composite); + expect(root.needsCompositing, isFalse); + + // On non-Fuchsia platforms, Flutter draws its own shadows. + root.elevation = 1.0; + pumpFrame(phase: EnginePhase.composite); + expect(root.needsCompositing, isFalse); + + root.elevation = 0.0; + pumpFrame(phase: EnginePhase.composite); + expect(root.needsCompositing, isFalse); + + debugDefaultTargetPlatformOverride = null; + }); }