Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit f55dfdf

Browse files
committed
Web
1 parent 1950e72 commit f55dfdf

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

lib/web_ui/lib/src/engine/initialization.dart

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,30 @@ void debugResetEngineInitializationState() {
102102
_initializationState = DebugEngineInitializationState.uninitialized;
103103
}
104104

105+
void renderFrame(int timeInMicroseconds) {
106+
frameTimingsOnVsync();
107+
108+
// In Flutter terminology "building a frame" consists of "beginning
109+
// frame" and "drawing frame".
110+
//
111+
// We do not call `frameTimingsOnBuildFinish` from here because
112+
// part of the rasterization process, particularly in the HTML
113+
// renderer, takes place in the `SceneBuilder.build()`.
114+
frameTimingsOnBuildStart();
115+
if (EnginePlatformDispatcher.instance.onBeginFrame != null) {
116+
EnginePlatformDispatcher.instance.invokeOnBeginFrame(
117+
Duration(microseconds: timeInMicroseconds));
118+
}
119+
120+
if (EnginePlatformDispatcher.instance.onDrawFrame != null) {
121+
// TODO(yjbanov): technically Flutter flushes microtasks between
122+
// onBeginFrame and onDrawFrame. We don't, which hasn't
123+
// been an issue yet, but eventually we'll have to
124+
// implement it properly.
125+
EnginePlatformDispatcher.instance.invokeOnDrawFrame();
126+
}
127+
}
128+
105129
/// Initializes non-UI engine services.
106130
///
107131
/// Does not put any UI onto the page. It is therefore safe to call this
@@ -158,8 +182,6 @@ Future<void> initializeEngineServices({
158182
if (!waitingForAnimation) {
159183
waitingForAnimation = true;
160184
domWindow.requestAnimationFrame((JSNumber highResTime) {
161-
frameTimingsOnVsync();
162-
163185
// Reset immediately, because `frameHandler` can schedule more frames.
164186
waitingForAnimation = false;
165187

@@ -170,29 +192,14 @@ Future<void> initializeEngineServices({
170192
// microsecond precision, and only then convert to `int`.
171193
final int highResTimeMicroseconds =
172194
(1000 * highResTime.toDartDouble).toInt();
173-
174-
// In Flutter terminology "building a frame" consists of "beginning
175-
// frame" and "drawing frame".
176-
//
177-
// We do not call `frameTimingsOnBuildFinish` from here because
178-
// part of the rasterization process, particularly in the HTML
179-
// renderer, takes place in the `SceneBuilder.build()`.
180-
frameTimingsOnBuildStart();
181-
if (EnginePlatformDispatcher.instance.onBeginFrame != null) {
182-
EnginePlatformDispatcher.instance.invokeOnBeginFrame(
183-
Duration(microseconds: highResTimeMicroseconds));
184-
}
185-
186-
if (EnginePlatformDispatcher.instance.onDrawFrame != null) {
187-
// TODO(yjbanov): technically Flutter flushes microtasks between
188-
// onBeginFrame and onDrawFrame. We don't, which hasn't
189-
// been an issue yet, but eventually we'll have to
190-
// implement it properly.
191-
EnginePlatformDispatcher.instance.invokeOnDrawFrame();
192-
}
195+
renderFrame(highResTimeMicroseconds);
193196
});
194197
}
195198
};
199+
warmUpFrameCallback = () {
200+
// TODO(dkwingsmt): Can we give it some time value?
201+
renderFrame(0);
202+
};
196203

197204
assetManager ??= ui_web.AssetManager(assetBase: configuration.assetBase);
198205
_setAssetManager(assetManager);

lib/web_ui/lib/src/engine/platform_dispatcher.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ import '../engine.dart';
1717
/// This may be overridden in tests, for example, to pump fake frames.
1818
ui.VoidCallback? scheduleFrameCallback;
1919

20+
/// Requests that the framework tries to render a frame immediately.
21+
///
22+
/// Since this will probably call [PlatformWindow.render] outside of an
23+
/// animation frame, the render will not be actually presented, but just to warm
24+
/// up the framework.
25+
ui.VoidCallback? warmUpFrameCallback;
26+
2027
/// Signature of functions added as a listener to high contrast changes
2128
typedef HighContrastListener = void Function(bool enabled);
2229
typedef _KeyDataResponseCallback = void Function(bool handled);
@@ -773,8 +780,10 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
773780

774781
@override
775782
void forceSyncFrame() {
776-
// TODO(dkwingsmt): Call beginFrame and drawFrame, since the framework
777-
// will no longer call them once it switches to forceSyncFrame.
783+
if (warmUpFrameCallback == null) {
784+
throw Exception('warmUpFrameCallback must be initialized first.');
785+
}
786+
warmUpFrameCallback!();
778787
}
779788

780789
/// Updates the application's rendering on the GPU with the newly provided

0 commit comments

Comments
 (0)