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

[Windows] Don't block raster thread until v-blank #41231

Merged
merged 1 commit into from
Apr 21, 2023

Conversation

loic-sharma
Copy link
Member

@loic-sharma loic-sharma commented Apr 15, 2023

Currently the Windows raster thread blocks until the v-blank. As a result, on Windows a frame can spend 17ms on the raster thread even if rasterization completes in under 1ms. This behavior prevents us from rendering multiple views on the same raster thread on Windows.

This change does not make rasterization faster. Instead, it allows the raster thread to do more work.

Addresses flutter/flutter#124903

Results

Here are the performance graphs if I hover on and off the counter app's button repeatedly.

Before

The raster thread spends ~17ms per frame consistently:

Pasted image 20230414180144

After

After this change, the raster thread spends less than 1ms per frame consistently:
Pasted image 20230414180011

Background

Blocking until the v-blank prevents screen tearing if the OS does not synchronize to the vsync. Windows does synchronize if the Desktop Windows Manager composition is enabled, which is required on Windows 8 and newer. In other words, this blocking behavior is unnecessary for Windows 8 and newer.

For Windows 7, screen tearing is possible if DWM composition is disabled (either by the user or by an app). In this scenario, the Flutter app should block until the v-blank to synchronize with the vsync and prevent screen tearing. We can detect if DWM composition is disabled using DwmIsCompositionEnabled. We can detect changes to DWM composition using the top-level WM_DWMCOMPOSITIONCHANGED Windows message.

Useful resources:

  1. https://learn.microsoft.com/en-us/windows/win32/dwm/composition-ovw
  2. https://www.khronos.org/opengl/wiki/Swap_Interval
  3. https://forums.imgtec.com/t/eglswapinterval-0-tearing-problem/2356/5
  4. https://stackoverflow.com/questions/32282252/can-eglswapinterval0-cause-screen-tearing
  5. https://bugs.chromium.org/p/chromium/issues/detail?id=480361

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides].
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See [testing the engine] for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the [CLA].
  • All existing and new tests are passing.

@loic-sharma loic-sharma marked this pull request as ready for review April 15, 2023 01:37
@@ -81,8 +81,8 @@ uint32_t FlutterWindowsView::GetFrameBufferId(size_t width, size_t height) {
if (resize_target_width_ == width && resize_target_height_ == height) {
// Platform thread is blocked for the entire duration until the
// resize_status_ is set to kDone.
engine_->surface_manager()->ResizeSurface(GetRenderTarget(), width, height);
engine_->surface_manager()->MakeCurrent();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is now unneeded as resizing the window makes the surface current to update the wait interval.

@@ -48,7 +48,7 @@ bool WindowsLifecycleManager::WindowProc(HWND hwnd,
// send a request to the framework to see if the app should exit. If it
// is, we re-dispatch a new WM_CLOSE message. In order to allow the new
// message to reach other delegates, we ignore it here.
case WM_CLOSE:
case WM_CLOSE: {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The braces were added as the C++ compiler complained about potential jumping to uninitialized values

}

// OpenGL swap intervals can be used to prevent screen tearing.
// If enabled, the raster thread blocks until the v-blank.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that we will still block until the v-blank when this parameter is true, i.e. when composition is not enabled? And if so, is that what we intend?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and yes. Screen tearing is possible if a Windows 7 user does not have DWM composition enabled. The app should synchronize with the vsync to prevent screen tearing.

Copy link
Contributor

@yaakovschectman yaakovschectman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM then

@loic-sharma
Copy link
Member Author

This change is blocked on this Dart bug: dart-lang/sdk#52071

@loic-sharma loic-sharma added the autosubmit Merge PR when tree becomes green via auto submit App label Apr 21, 2023
@auto-submit auto-submit bot merged commit 122c3b3 into flutter:main Apr 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 21, 2023
zanderso pushed a commit to flutter/flutter that referenced this pull request Apr 21, 2023
…125271)

flutter/engine@2db85cb...122c3b3

2023-04-21 737941+loic-sharma@users.noreply.github.com [Windows] Don't
block raster thread until v-blank (flutter/engine#41231)
2023-04-21 chillers@google.com Manual roll skia to d5b4acfb4
(flutter/engine#41378)
2023-04-21 magder@google.com Run mac unopt arm builds with arm toolchain
(flutter/engine#41353)
2023-04-20 zanderso@users.noreply.github.com Revert "re-land "Migrate
mac_host_engine to engine v2 builds." (#41233)"" (flutter/engine#41380)
2023-04-20 skia-flutter-autoroll@skia.org Roll Dart SDK from
df05e451b79a to 50b96abe9f6f (1 revision) (flutter/engine#41379)
2023-04-20 109111084+yaakovschectman@users.noreply.github.com Move
ownership of `AccessibilityBridgeWindows` to `FlutterWindowsView`
(flutter/engine#41308)
2023-04-20 skia-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from
AoPEjX8Xfq1v0h4kx... to PqBDstaESE_l77k1e... (flutter/engine#41373)
2023-04-20 godofredoc@google.com Revert "Upload windows arm artifacts to
production bucket." (flutter/engine#41372)
2023-04-20 godofredoc@google.com re-land "Migrate mac_host_engine to
engine v2 builds." (#41233)" (flutter/engine#41323)
2023-04-20 godofredoc@google.com Upload windows arm artifacts to
production bucket. (flutter/engine#41324)
2023-04-20 jason-simmons@users.noreply.github.com [Impeller] Change the
default color format for the GLES backend to RGBA (flutter/engine#41342)
2023-04-20 maRci002@users.noreply.github.com [web] change status bar
color based on SystemUiOverlayStyle (flutter/engine#40599)
2023-04-20 skia-flutter-autoroll@skia.org Roll Fuchsia Mac SDK from
OcPCdaE17MAihaCrD... to 4OrPF9lzqCKGwBLRh... (flutter/engine#41367)
2023-04-20 skia-flutter-autoroll@skia.org Roll Skia from fc09f9b2fb27 to
f4609aa2eaba (1 revision) (flutter/engine#41366)
2023-04-20 skia-flutter-autoroll@skia.org Roll Dart SDK from
7d165bd0bb5e to df05e451b79a (2 revisions) (flutter/engine#41365)
2023-04-20 skia-flutter-autoroll@skia.org Roll Skia from 80c38970791e to
fc09f9b2fb27 (1 revision) (flutter/engine#41362)
2023-04-20 skia-flutter-autoroll@skia.org Roll Skia from c50081c62219 to
80c38970791e (2 revisions) (flutter/engine#41360)
2023-04-20 skia-flutter-autoroll@skia.org Roll Skia from c21e7df194c3 to
c50081c62219 (11 revisions) (flutter/engine#41358)
2023-04-20 skia-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from
Tun7i4VLz6ncx8JJJ... to AoPEjX8Xfq1v0h4kx... (flutter/engine#41357)
2023-04-20 skia-flutter-autoroll@skia.org Roll Dart SDK from
88a3b66b50d6 to 7d165bd0bb5e (1 revision) (flutter/engine#41356)
2023-04-20 jason-simmons@users.noreply.github.com Manual Skia roll from
ad90b6bd4760 to c21e7df194c3 (flutter/engine#41341)
2023-04-20 jonahwilliams@google.com [impeller] convert src over to src
for solid color (flutter/engine#41351)

Also rolling transitive DEPS:
  fuchsia/sdk/core/linux-amd64 from Tun7i4VLz6nc to PqBDstaESE_l
  fuchsia/sdk/core/mac-amd64 from OcPCdaE17MAi to 4OrPF9lzqCKG

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC chinmaygarde@google.com,rmistry@google.com,zra@google.com on
the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
@MiinoY
Copy link

MiinoY commented Dec 12, 2024

@loic-sharma
Hello! This commit is very helpful to my issue! Thanks!
We have met the similar problem and this commit fix it. But i'm wondering that why Android doesn't have the same issue? On Android, I have forcibly set the eglSwapInterval to 1, but the SwapBuffers operation on the raster thread is still very fast(1~3ms), and the same case on Windows without this commit, the SwapBuffers time will reach 16ms.
Do you know any reasons for this difference? looking forward to your reply! Thank you!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
autosubmit Merge PR when tree becomes green via auto submit App platform-windows
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants