Commit c486fc4a authored by Adam Barth's avatar Adam Barth

Revert "A blinking cursor should push only one frame (#3445)"

This reverts commit 161f945e.

This patch caused a number of regressions.

Fixes #3497
parent e968d91c
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'colors.dart'; import 'colors.dart';
...@@ -170,6 +171,7 @@ class DrawerControllerState extends State<DrawerController> { ...@@ -170,6 +171,7 @@ class DrawerControllerState extends State<DrawerController> {
} }
double get _width { double get _width {
assert(!Scheduler.debugInFrame); // we should never try to read the tree state while building or laying out
RenderBox drawerBox = _drawerKey.currentContext?.findRenderObject(); RenderBox drawerBox = _drawerKey.currentContext?.findRenderObject();
if (drawerBox != null) if (drawerBox != null)
return drawerBox.size.width; return drawerBox.size.width;
......
...@@ -86,7 +86,7 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -86,7 +86,7 @@ abstract class SchedulerBinding extends BindingBase {
void initServiceExtensions() { void initServiceExtensions() {
super.initServiceExtensions(); super.initServiceExtensions();
registerNumericServiceExtension( registerNumericServiceExtension(
name: 'timeDilation', name: 'timeDilation',
getter: () => timeDilation, getter: () => timeDilation,
setter: (double value) { setter: (double value) {
timeDilation = value; timeDilation = value;
...@@ -94,8 +94,9 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -94,8 +94,9 @@ abstract class SchedulerBinding extends BindingBase {
); );
} }
/// The strategy to use when deciding whether to run a task or not. /// The strategy to use when deciding whether to run a task or not.
/// ///
/// Defaults to [defaultSchedulingStrategy]. /// Defaults to [defaultSchedulingStrategy].
SchedulingStrategy schedulingStrategy = defaultSchedulingStrategy; SchedulingStrategy schedulingStrategy = defaultSchedulingStrategy;
...@@ -118,6 +119,7 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -118,6 +119,7 @@ abstract class SchedulerBinding extends BindingBase {
_ensureEventLoopCallback(); _ensureEventLoopCallback();
} }
// Whether this scheduler already requested to be called from the event loop. // Whether this scheduler already requested to be called from the event loop.
bool _hasRequestedAnEventLoopCallback = false; bool _hasRequestedAnEventLoopCallback = false;
...@@ -153,10 +155,11 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -153,10 +155,11 @@ abstract class SchedulerBinding extends BindingBase {
} else { } else {
// TODO(floitsch): we shouldn't need to request a frame. Just schedule // TODO(floitsch): we shouldn't need to request a frame. Just schedule
// an event-loop callback. // an event-loop callback.
_scheduleFrame(); ensureVisualUpdate();
} }
} }
int _nextFrameCallbackId = 0; // positive int _nextFrameCallbackId = 0; // positive
Map<int, _FrameCallbackEntry> _transientCallbacks = <int, _FrameCallbackEntry>{}; Map<int, _FrameCallbackEntry> _transientCallbacks = <int, _FrameCallbackEntry>{};
final Set<int> _removedIds = new HashSet<int>(); final Set<int> _removedIds = new HashSet<int>();
...@@ -184,7 +187,7 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -184,7 +187,7 @@ abstract class SchedulerBinding extends BindingBase {
/// Callbacks registered with this method can be canceled using /// Callbacks registered with this method can be canceled using
/// [cancelFrameCallbackWithId]. /// [cancelFrameCallbackWithId].
int scheduleFrameCallback(FrameCallback callback, { bool rescheduling: false }) { int scheduleFrameCallback(FrameCallback callback, { bool rescheduling: false }) {
_scheduleFrame(); ensureVisualUpdate();
return addFrameCallback(callback, rescheduling: rescheduling); return addFrameCallback(callback, rescheduling: rescheduling);
} }
...@@ -267,6 +270,7 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -267,6 +270,7 @@ abstract class SchedulerBinding extends BindingBase {
return true; return true;
} }
final List<FrameCallback> _persistentCallbacks = new List<FrameCallback>(); final List<FrameCallback> _persistentCallbacks = new List<FrameCallback>();
/// Adds a persistent frame callback. /// Adds a persistent frame callback.
...@@ -282,6 +286,7 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -282,6 +286,7 @@ abstract class SchedulerBinding extends BindingBase {
_persistentCallbacks.add(callback); _persistentCallbacks.add(callback);
} }
final List<FrameCallback> _postFrameCallbacks = new List<FrameCallback>(); final List<FrameCallback> _postFrameCallbacks = new List<FrameCallback>();
/// Schedule a callback for the end of this frame. /// Schedule a callback for the end of this frame.
...@@ -301,11 +306,10 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -301,11 +306,10 @@ abstract class SchedulerBinding extends BindingBase {
_postFrameCallbacks.add(callback); _postFrameCallbacks.add(callback);
} }
// Whether this scheduler as requested that handleBeginFrame be called soon.
bool _hasScheduledFrame = false;
// Whether this scheduler is currently producing a frame in handleBeginFrame. // Whether this scheduler already requested to be called at the beginning of
bool _isProducingFrame = false; // the next frame.
bool _hasRequestedABeginFrameCallback = false;
/// If necessary, schedules a new frame by calling /// If necessary, schedules a new frame by calling
/// [ui.window.scheduleFrame]. /// [ui.window.scheduleFrame].
...@@ -315,18 +319,20 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -315,18 +319,20 @@ abstract class SchedulerBinding extends BindingBase {
/// device's screen is turned off it will typically be delayed until /// device's screen is turned off it will typically be delayed until
/// the screen is on and the application is visible.) /// the screen is on and the application is visible.)
void ensureVisualUpdate() { void ensureVisualUpdate() {
if (_hasScheduledFrame || _isProducingFrame) if (_hasRequestedABeginFrameCallback)
return;
_scheduleFrame();
}
void _scheduleFrame() {
if (_hasScheduledFrame)
return; return;
ui.window.scheduleFrame(); ui.window.scheduleFrame();
_hasScheduledFrame = true; _hasRequestedABeginFrameCallback = true;
} }
/// Whether the scheduler is currently handling a "begin frame"
/// callback.
///
/// True while [handleBeginFrame] is running in checked mode. False
/// otherwise.
static bool get debugInFrame => _debugInFrame;
static bool _debugInFrame = false;
/// Called by the engine to produce a new frame. /// Called by the engine to produce a new frame.
/// ///
/// This function first calls all the callbacks registered by /// This function first calls all the callbacks registered by
...@@ -336,11 +342,11 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -336,11 +342,11 @@ abstract class SchedulerBinding extends BindingBase {
/// callbacks registered by [addPostFrameCallback]. /// callbacks registered by [addPostFrameCallback].
void handleBeginFrame(Duration rawTimeStamp) { void handleBeginFrame(Duration rawTimeStamp) {
Timeline.startSync('Begin frame'); Timeline.startSync('Begin frame');
assert(!_isProducingFrame); assert(!_debugInFrame);
_isProducingFrame = true; assert(() { _debugInFrame = true; return true; });
_hasScheduledFrame = false;
Duration timeStamp = new Duration( Duration timeStamp = new Duration(
microseconds: (rawTimeStamp.inMicroseconds / timeDilation).round()); microseconds: (rawTimeStamp.inMicroseconds / timeDilation).round());
_hasRequestedABeginFrameCallback = false;
_invokeTransientFrameCallbacks(timeStamp); _invokeTransientFrameCallbacks(timeStamp);
for (FrameCallback callback in _persistentCallbacks) for (FrameCallback callback in _persistentCallbacks)
...@@ -352,7 +358,7 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -352,7 +358,7 @@ abstract class SchedulerBinding extends BindingBase {
for (FrameCallback callback in localPostFrameCallbacks) for (FrameCallback callback in localPostFrameCallbacks)
_invokeFrameCallback(callback, timeStamp); _invokeFrameCallback(callback, timeStamp);
_isProducingFrame = false; assert(() { _debugInFrame = false; return true; });
Timeline.finishSync(); Timeline.finishSync();
// All frame-related callbacks have been executed. Run lower-priority tasks. // All frame-related callbacks have been executed. Run lower-priority tasks.
...@@ -361,7 +367,7 @@ abstract class SchedulerBinding extends BindingBase { ...@@ -361,7 +367,7 @@ abstract class SchedulerBinding extends BindingBase {
void _invokeTransientFrameCallbacks(Duration timeStamp) { void _invokeTransientFrameCallbacks(Duration timeStamp) {
Timeline.startSync('Animate'); Timeline.startSync('Animate');
assert(_isProducingFrame); assert(_debugInFrame);
Map<int, _FrameCallbackEntry> callbacks = _transientCallbacks; Map<int, _FrameCallbackEntry> callbacks = _transientCallbacks;
_transientCallbacks = new Map<int, _FrameCallbackEntry>(); _transientCallbacks = new Map<int, _FrameCallbackEntry>();
callbacks.forEach((int id, _FrameCallbackEntry callbackEntry) { callbacks.forEach((int id, _FrameCallbackEntry callbackEntry) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment