Unverified Commit 1b441333 authored by Todd Volkert's avatar Todd Volkert Committed by GitHub

Move ensureVisualUpdate call to call sites in WidgetsBinding.attachRootWidget() (#75811)

This call is unnecessary and wasteful for callers that are building
parallel widget trees, since for those use cases, the caller is
generally going to build the tree synchronously immediately.
parent 235927d5
......@@ -926,12 +926,16 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
/// * [RenderObjectToWidgetAdapter.attachToRenderTree], which inflates a
/// widget and attaches it to the render tree.
void attachRootWidget(Widget rootWidget) {
final bool isBootstrapFrame = renderViewElement == null;
_readyToProduceFrames = true;
_renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
container: renderView,
debugShortDescription: '[root]',
child: rootWidget,
).attachToRenderTree(buildOwner!, renderViewElement as RenderObjectToWidgetElement<RenderBox>?);
if (isBootstrapFrame) {
SchedulerBinding.instance!.ensureVisualUpdate();
}
}
/// Whether the [renderViewElement] has been initialized.
......@@ -1094,9 +1098,6 @@ class RenderObjectToWidgetAdapter<T extends RenderObject> extends RenderObjectWi
owner.buildScope(element!, () {
element!.mount(null, null);
});
// This is most likely the first time the framework is ready to produce
// a frame. Ensure that we are asked for one.
SchedulerBinding.instance!.ensureVisualUpdate();
} else {
element._newWidget = this;
element.markNeedsBuild();
......
......@@ -2,12 +2,38 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui;
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
const Size _kTestViewSize = Size(800.0, 600.0);
class ScheduledFrameTrackingWindow extends TestWindow {
ScheduledFrameTrackingWindow() : super(window: ui.window);
int _scheduledFrameCount = 0;
int get scheduledFrameCount => _scheduledFrameCount;
void resetScheduledFrameCount() {
_scheduledFrameCount = 0;
}
@override
void scheduleFrame() {
_scheduledFrameCount++;
super.scheduleFrame();
}
}
class ScheduledFrameTrackingBindings extends AutomatedTestWidgetsFlutterBinding {
final ScheduledFrameTrackingWindow _window = ScheduledFrameTrackingWindow();
@override
ScheduledFrameTrackingWindow get window => _window;
}
class OffscreenRenderView extends RenderView {
OffscreenRenderView() : super(
configuration: const ViewConfiguration(size: _kTestViewSize),
......@@ -139,6 +165,20 @@ class TestFocusableState extends State<TestFocusable> {
}
void main() {
// Override the bindings for this test suite so that we can track the number
// of times a frame has been scheduled.
ScheduledFrameTrackingBindings();
testWidgets('RenderObjectToWidgetAdapter.attachToRenderTree does not schedule frame', (WidgetTester tester) async {
expect(WidgetsBinding.instance, isA<ScheduledFrameTrackingBindings>());
final ScheduledFrameTrackingWindow window = WidgetsBinding.instance!.window as ScheduledFrameTrackingWindow;
window.resetScheduledFrameCount();
expect(window.scheduledFrameCount, isZero);
final OffscreenWidgetTree tree = OffscreenWidgetTree();
tree.pumpWidget(const SizedBox.shrink());
expect(window.scheduledFrameCount, isZero);
});
testWidgets('no crosstalk between widget build owners', (WidgetTester tester) async {
final Trigger trigger1 = Trigger();
final Counter counter1 = Counter();
......
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