Fix violation of the render rule in Windows Startup Test (#134245)
This PR fixes yet another case in the windows startup test that violates the render rule, which caused https://github.com/flutter/engine/pull/45300 to be reverted. Although the `FlutterView.render` call is within `onBeginFrame`, there is an `await` before the call, causing the call to fall out of the synchronous scope. I've added this problem to the documentation of `FlutterView.render` in https://github.com/flutter/engine/pull/45555.
This commit is contained in:
parent
de44daf1f8
commit
203ec67c65
@ -31,6 +31,25 @@ void drawHelloWorld(ui.FlutterView view) {
|
|||||||
view.render(sceneBuilder.build());
|
view.render(sceneBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _waitUntilWindowVisible() async {
|
||||||
|
while (!await isWindowVisible()) {
|
||||||
|
await Future<void>.delayed(const Duration(milliseconds: 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _expectVisible(bool current, bool expect, Completer<String> completer, int frameCount) {
|
||||||
|
if (current != expect) {
|
||||||
|
try {
|
||||||
|
throw 'Window should be ${expect ? 'visible' : 'hidden'} on frame $frameCount';
|
||||||
|
} catch (e) {
|
||||||
|
if (!completer.isCompleted) {
|
||||||
|
completer.completeError(e);
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
// TODO(goderbauer): Create a window if embedder doesn't provide an implicit view to draw into.
|
// TODO(goderbauer): Create a window if embedder doesn't provide an implicit view to draw into.
|
||||||
assert(ui.PlatformDispatcher.instance.implicitView != null);
|
assert(ui.PlatformDispatcher.instance.implicitView != null);
|
||||||
@ -70,27 +89,39 @@ void main() async {
|
|||||||
throw 'Window should be hidden at startup';
|
throw 'Window should be hidden at startup';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool firstFrame = true;
|
int frameCount = 0;
|
||||||
ui.PlatformDispatcher.instance.onBeginFrame = (Duration duration) async {
|
ui.PlatformDispatcher.instance.onBeginFrame = (Duration duration) {
|
||||||
if (await isWindowVisible()) {
|
// Our goal is to verify that it's `drawHelloWorld` that makes the window
|
||||||
if (firstFrame) {
|
// appear, not anything else. This requires checking the visibility right
|
||||||
throw 'Window should be hidden on first frame';
|
// before drawing, but since `isWindowVisible` has to be async, and
|
||||||
}
|
// `FlutterView.render` (in `drawHelloWorld`) forbids async before it,
|
||||||
|
// this can not be done during a single onBeginFrame. However, we can
|
||||||
if (!visibilityCompleter.isCompleted) {
|
// verify in separate frames to indirectly prove it, by ensuring that
|
||||||
visibilityCompleter.complete('success');
|
// no other mechanism can affect isWindowVisible in the first frame at all.
|
||||||
}
|
frameCount += 1;
|
||||||
|
switch (frameCount) {
|
||||||
|
// The 1st frame: render nothing, just verify that the window is hidden.
|
||||||
|
case 1:
|
||||||
|
isWindowVisible().then((bool visible) {
|
||||||
|
_expectVisible(visible, false, visibilityCompleter, frameCount);
|
||||||
|
ui.PlatformDispatcher.instance.scheduleFrame();
|
||||||
|
});
|
||||||
|
// The 2nd frame: render, which makes the window appear.
|
||||||
|
case 2:
|
||||||
|
drawHelloWorld(view);
|
||||||
|
_waitUntilWindowVisible().then((_) {
|
||||||
|
if (!visibilityCompleter.isCompleted) {
|
||||||
|
visibilityCompleter.complete('success');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Others, in case requested to render.
|
||||||
|
default:
|
||||||
|
drawHelloWorld(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw something to trigger the first frame callback that displays the
|
|
||||||
// window.
|
|
||||||
drawHelloWorld(view);
|
|
||||||
firstFrame = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ui.PlatformDispatcher.instance.scheduleFrame();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
visibilityCompleter.completeError(e);
|
visibilityCompleter.completeError(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
ui.PlatformDispatcher.instance.scheduleFrame();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user