From bcd0d8fe9bc95bc0211a4fc0e5117e3cd429b700 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Fri, 7 Aug 2015 17:06:41 -0700 Subject: [PATCH] Remove the flicker from MimicOverlay There were two problems: 1) When starting the mimic, we put up a bad frame because although we set the `begin` value of the animation, we were building using the current `value`, which hadn't been updated. 2) When stoping the mimic, we'd dirty a component during didUnmount, which wouldn't get cleaned until the next frame. Now we're sure to clean all the components before leaving flushBuild. --- packages/flutter/lib/widgets/framework.dart | 52 ++++++++++--------- .../flutter/lib/widgets/mimic_overlay.dart | 3 +- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/packages/flutter/lib/widgets/framework.dart b/packages/flutter/lib/widgets/framework.dart index c3f1643047..2300736941 100644 --- a/packages/flutter/lib/widgets/framework.dart +++ b/packages/flutter/lib/widgets/framework.dart @@ -116,7 +116,7 @@ abstract class GlobalKey extends Key { } static void _notifyListeners() { - assert(!_inRenderDirtyComponents); + assert(!_inBuildDirtyComponents); assert(!Widget._notifyingMountStatus); assert(_debugDuplicates.isEmpty); _notifyingListeners = true; @@ -161,7 +161,7 @@ abstract class Widget { } // you should not build the UI tree ahead of time, build it only during build() - bool _isConstructedDuringBuild() => this is AbstractWidgetRoot || this is App || _inRenderDirtyComponents || _inLayoutCallbackBuilder > 0; + bool _isConstructedDuringBuild() => this is AbstractWidgetRoot || this is App || _inBuildDirtyComponents || _inLayoutCallbackBuilder > 0; Key _key; @@ -755,7 +755,7 @@ abstract class StatefulComponent extends Component { Set _dirtyComponents = new Set(); bool _buildScheduled = false; -bool _inRenderDirtyComponents = false; +bool _inBuildDirtyComponents = false; int _inLayoutCallbackBuilder = 0; class LayoutCallbackBuilderHandle { bool _active = true; } @@ -793,31 +793,33 @@ void _buildDirtyComponents() { if (_shouldLogRenderDuration) sw = new Stopwatch()..start(); - _inRenderDirtyComponents = true; - try { - sky.tracing.begin('Component.flushBuild'); - List sortedDirtyComponents = new List(); - _absorbDirtyComponents(sortedDirtyComponents); - int index = 0; - while (index < sortedDirtyComponents.length) { - Component component = sortedDirtyComponents[index]; - component._buildIfDirty(); - if (_dirtyComponents.length > 0) { - // the following assert verifies that we're not rebuilding anyone twice in one frame - assert(_dirtyComponents.every((Component component) => !sortedDirtyComponents.contains(component))); - _absorbDirtyComponents(sortedDirtyComponents); - index = 0; - } else { - index += 1; + while (!_dirtyComponents.isEmpty) { + _inBuildDirtyComponents = true; + try { + sky.tracing.begin('Component.flushBuild'); + List sortedDirtyComponents = new List(); + _absorbDirtyComponents(sortedDirtyComponents); + int index = 0; + while (index < sortedDirtyComponents.length) { + Component component = sortedDirtyComponents[index]; + component._buildIfDirty(); + if (_dirtyComponents.length > 0) { + // the following assert verifies that we're not rebuilding anyone twice in one frame + assert(_dirtyComponents.every((Component component) => !sortedDirtyComponents.contains(component))); + _absorbDirtyComponents(sortedDirtyComponents); + index = 0; + } else { + index += 1; + } } + } finally { + _buildScheduled = false; + _inBuildDirtyComponents = false; + sky.tracing.end('Component.flushBuild'); } - } finally { - _buildScheduled = false; - _inRenderDirtyComponents = false; - sky.tracing.end('Component.flushBuild'); - } - Widget._notifyMountStatusChanged(); + Widget._notifyMountStatusChanged(); + } if (_shouldLogRenderDuration) { sw.stop(); diff --git a/packages/flutter/lib/widgets/mimic_overlay.dart b/packages/flutter/lib/widgets/mimic_overlay.dart index 4d80e79b94..36f8c44d40 100644 --- a/packages/flutter/lib/widgets/mimic_overlay.dart +++ b/packages/flutter/lib/widgets/mimic_overlay.dart @@ -70,8 +70,9 @@ class MimicOverlay extends AnimatedComponent { setState(() { // TODO(abarth): We need to convert global bounds into local coordinates. _mimicBounds.begin = globalToLocal(globalBounds.topLeft) & globalBounds.size; - _expandPerformance.forward(); + _mimicBounds.value = _mimicBounds.begin; }); + _expandPerformance.forward(); } Widget build() {