diff --git a/sky/packages/sky/lib/rendering/sky_binding.dart b/sky/packages/sky/lib/rendering/sky_binding.dart index 42ce5cba373e3..f7f77cf594eb8 100644 --- a/sky/packages/sky/lib/rendering/sky_binding.dart +++ b/sky/packages/sky/lib/rendering/sky_binding.dart @@ -47,7 +47,7 @@ class SkyBinding { _renderView = renderViewOverride; } assert(_renderView != null); - scheduler.addPersistentFrameCallback(_beginFrame); + scheduler.addPersistentFrameCallback(beginFrame); assert(_instance == this); } @@ -69,7 +69,7 @@ class SkyBinding { void set root(RenderBox value) { _renderView.child = value; } - void _beginFrame(double timeStamp) { + void beginFrame(double timeStamp) { RenderObject.flushLayout(); RenderObject.flushPaint(); _renderView.paintFrame(); diff --git a/sky/packages/sky/lib/widgets/widget.dart b/sky/packages/sky/lib/widgets/widget.dart index 16ad4eaa8ba45..60efa0a24b521 100644 --- a/sky/packages/sky/lib/widgets/widget.dart +++ b/sky/packages/sky/lib/widgets/widget.dart @@ -7,6 +7,7 @@ import 'dart:collection'; import 'dart:sky' as sky; import 'package:sky/base/hit_test.dart'; +import 'package:sky/base/scheduler.dart' as scheduler; import 'package:sky/mojo/activity.dart' as activity; import 'package:sky/rendering/box.dart'; import 'package:sky/rendering/object.dart'; @@ -651,6 +652,11 @@ abstract class Component extends Widget { _scheduleComponentForRender(this); } + static void flushBuild() { + if (!_dirtyComponents.isEmpty) + _buildDirtyComponents(); + } + Widget build(); } @@ -759,13 +765,15 @@ void _absorbDirtyComponents(List list) { } void _buildDirtyComponents() { + assert(!_dirtyComponents.isEmpty); + Stopwatch sw; if (_shouldLogRenderDuration) sw = new Stopwatch()..start(); _inRenderDirtyComponents = true; try { - sky.tracing.begin('Widgets._buildDirtyComponents'); + sky.tracing.begin('Component.flushBuild'); List sortedDirtyComponents = new List(); _absorbDirtyComponents(sortedDirtyComponents); int index = 0; @@ -784,7 +792,7 @@ void _buildDirtyComponents() { } finally { _buildScheduled = false; _inRenderDirtyComponents = false; - sky.tracing.end('Widgets._buildDirtyComponents'); + sky.tracing.end('Component.flushBuild'); } Widget._notifyMountStatusChanged(); @@ -795,21 +803,20 @@ void _buildDirtyComponents() { if (_debugFrameTimes.length >= 1000) { _debugFrameTimes.sort(); const int i = 99; - print('_buildDirtyComponents: ${i+1}th fastest frame out of the last ${_debugFrameTimes.length}: ${_debugFrameTimes[i]} microseconds'); + print('Component.flushBuild: ${i+1}th fastest frame out of the last ${_debugFrameTimes.length}: ${_debugFrameTimes[i]} microseconds'); _debugFrameTimes.clear(); } } } -void _scheduleComponentForRender(Component c) { - _dirtyComponents.add(c); +void _scheduleComponentForRender(Component component) { + _dirtyComponents.add(component); if (!_buildScheduled) { _buildScheduled = true; - new Future.microtask(_buildDirtyComponents); + scheduler.ensureVisualUpdate(); } } - // RenderObjectWrappers correspond to a desired state of a RenderObject. // They are fully immutable, with one exception: A Widget which is a // Component which lives within an MultiChildRenderObjectWrapper's @@ -1178,6 +1185,11 @@ class WidgetSkyBinding extends SkyBinding { } } + void beginFrame(double timeStamp) { + Component.flushBuild(); + super.beginFrame(timeStamp); + } + } abstract class App extends StatefulComponent { diff --git a/sky/tests/resources/display_list.dart b/sky/tests/resources/display_list.dart index a22fe980a9d48..e3c2827325fa2 100644 --- a/sky/tests/resources/display_list.dart +++ b/sky/tests/resources/display_list.dart @@ -149,6 +149,7 @@ class TestRenderView extends RenderView { // TEST API: void syncCheckFrame() { + Component.flushBuild(); RenderObject.flushLayout(); paintFrame(); print(lastPaint); // TODO(ianh): figure out how to make this fit the unit testing framework better