New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 807406 link

Starred by 5 users

Issue metadata

Status: Started
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Feature



Sign in to add a comment

Add Better Support for Variable Refresh Rate (G-SYNC, FreeSync, etc)

Reported by blurbust...@gmail.com, Jan 30 2018

Issue description

UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36

Steps to reproduce the problem:
As an Invited Expert to W3C Web Platform Working Group, I submitted a change to HTML 5.2 to support high refresh rate monitors that is now accepted (section 7.1.4.2).  Chrome is already complaint.

I have brainstorms at Blur Busters on adding Variable Refresh Rate support to HTML 5.2:

https://www.blurbusters.com/blur-busters-working-on-changes-to-html-5-2/

However, you can kinda force a web browser to run at a variable refresh rate by doing this.

1. You need a G-SYNC monitor.  Enable G-SYNC windowed mode in NVIDIA Control Panel.

2. Launch a fluctuating-framerate game in windowed mode

3. Launch Chrome in an adjacent window.  Put it side by side, but give focus to the game instead.

4. The browser is forced with variable-times between VSYNC intervals.  (each refresh cycle has its own unique interval).   

----

However, this is not the primary reason I am reporting this: The browser should have direct native support for VRR sometime, e.g. being able to synchronize video/animations/WebGL/etc with a variable refresh rate monitor, especially when the browser is running in "Full Screen Mode" -- the browser should automatically sieze host VRR control.   

Every framebuffer delivery can then thus, initiate an immediate refresh cycle (for variable refresh monitors, software always initiates an immediate refresh cycle -- e.g. Direct3D Present() = instant refresh cycle begins displaying, rather than wait for an interval refresh cycle)

What is the expected behavior?
When in full screen mode, and VRR support is detected (at least for windowed full screen mode, like G-SYNC) the Chrome browser should automatically flip framebuffers immediately on readiness instead of waiting for a compositing interval. 

This allows the monitor to automatically synchronize its refresh rate to the frame rate of the dominant content (e.g. biggest <canvas> or <video> surface).   

e.g. 
- 48fps videos mean monitor is 48Hz
- 67.915 frames per second in a WebGL video means moitor is 67.915 Hz
- Each refresh cycle can have its own unique interval, so this is great for varying framerate games.
etc.

For people who have never seen a variable refresh rate, I have a software-based emulation (using interpolation) at www.testufo.com/vrr -- this animation is simply to educate people on how VRR displays can de-stutter motion despite varying frame rates.  Try the "Ramp" motion, "Random" motion and "Struggle At Max" motion.

What went wrong?
There is no variable refresh rate support in web browser or web browser standardization.

Did this work before? No 

Chrome version: 64.0.3282.119  Channel: stable
OS Version: 10.0
Flash Version: 

I can assist in W3C VRR standardization.  Comments welcome!
 
Labels: Needs-Triage-M64
Components: Internals>GPU
Labels: Triaged-ET M-66
Status: Untriaged (was: Unconfirmed)
The issue seems to be a feature request. Hence, marking it as untriaged for further inputs from dev team.

Thanks...!!

Comment 4 by piman@chromium.org, Feb 5 2018

Cc: danakj@chromium.org vmi...@chromium.org ccameron@chromium.org
Components: -Internals>GPU Internals>GPU>Internals
Status: Available (was: Untriaged)
It's not on our radar currently. cc-ing some folks who mentioned interest at various points.
Related thread on W3C standardization ideas for variable refresh rate: https://github.com/w3c/html/issues/375

However, initially, this could be implemented as simple support at the browser engine level instead:

(1) Activate VRR only in full screen mode;

(2) Sync to (varying, fixed) framerate of the dominant <video> or <canvas> element (WebGL, video, or requestAnimationFrame)
"Sync to framerate", meaning, either:

(A) Sync the compositor to the framerate of the dominant element; or
(B) Sync a framebuffer flip (e.g. Direct3D Present()) to the framerate of the dominant element; or

Basically, you run in VSYNC OFF mode at that given frame rate.  A variable refresh display converts that stuttery/teary motion into perfectly-smooth motion by synchronizing actual hardware display refresh cycles to the framebuffer.  

So now the software controls the refresh rate (e.g. Direct3D Present() triggers instant refresh cycle).  Which means, 24fps movies, 48fps movies, fluctuating-framerate games, etc.   It looks like "permanently perfectly synchronized VSYNC ON" at that frame rate, even for (somewhat) fluctuating framerates.

The principle is relatively simple: 

Metaphorically from a classical programming perspective you're simply forcing to VSYNC OFF (when VRR is detected) and then intentionally flushing the composited framebuffers out at the frame rate of the dominant element (full screen content).
So it means you're automatically enabling "--disable-gpu-vsync" (an existing feature in Chrome) whenever in full screen mode on a VRR display, and then automatically capping the frame rate to the full screen <video> or <canvas> element.  

Should be a (theoretically) easy initial change, I'd hope?
Note: That said, to prevent scrolling from varying in fluidity, you'd only intentionally disengage from traditional VSYNC whenever something is playing on a large-surface onscreen <video> or <canvas> when in full screen mode.  Basically, do the VRR automatic synchronization.

(Sorry, I keep adding multiple extra comments -- I don't have edit-comment priveleges.  Would love to fix some typing errors in my original report).

Comment 9 by vmi...@chromium.org, Mar 13 2018

Cc: zmo@chromium.org sunn...@chromium.org
Cc: skyos...@chromium.org
Blocking: 726842
Owner: sunn...@chromium.org
Status: Started (was: Available)
Cc: paul.bli...@amd.com
Prototype for using allow tearing flag with swap chains: crrev.com/c/1068032 

I haven't tried this with a GSYNC/FreeSync display yet, but curiously DXGI says tearing is supported on my Nvidia Quadro M2000 with a regular 60Hz display (Acer B326HK).

The documentation says sync interval 0 and allow tearing flag should be used when supported. Does that mean vsync is disabled when we pass this flag? Or is vsync magically handled by DWM? Of course actual "tearing" can never happen with DWM, but we can still drop frames due to sync interval 0, right?
Did more testing on a non-VRR monitor. Allow tearing and sync interval 0 cause tearing in fullscreen, but don't seem to affect windowed mode. The documentation recommends not using allow tearing when fullscreen, and the sample app detects this using GetFullscreenState. However, this doesn't seem to be supported for composition swap chains as it always returns false. Not surprising because SetFullscreenState documentation says its not supported for composition swap chains.

So the way to support it in Chrome would be to use non-composition swap chains, and detect fullscreen state changes to control sync interval and present flags.
I tested this on a 144 Hz GSYNC primary monitor with 60Hz secondary monitor. On the primary monitor it looks like this works as expected, but on the secondary monitor Chrome renders at 144 fps without vsync and tearing in fullscreen (on secondary only).

Unless we have a good way of detecting GSYNC/FreeSync programmatically, the best we can do is land this behind a flag.
Blocking: -726842

Comment 17 by pblin...@gmail.com, May 22 2018

For VESA standardized VRR (which is what FreeSync represents) the EDID information  of the display provides the range capabilities which could be queried by the application  as part of the device property discovery (sync range descriptor).

Comment 18 by marky...@gmail.com, May 22 2018

> The documentation recommends not using allow tearing when fullscreen, and the sample app detects this using GetFullscreenState.

> Unless we have a good way of detecting GSYNC/FreeSync programmatically, the best we can do is land this behind a flag

There are situations where we WANT tearing, because it's a low-lag mode.   The billon-dollar eSports industry tolerates tearing because it's lower lag than avoiding tearing.   

So it should be a app-adjustable flag API where any Javascript application can set ".VSYNC = false" (Equivalent to a --disable-gpu-vsync option of sorts).   Not a user configurable flag.   Basically true by default, unless browser app configures it otherwise for the specific app (or in the settings screen of such app).

So you hit two birds with one stone:

--> Satisfy the eSports industry who is upset at browsers hobbling them with assumptions

--> Satisfy GSYNC ability

Please see W3C VSYNC API: https://github.com/w3c/html/issues/375

And please see: https://www.blurbusters.com/blur-busters-working-on-changes-to-html-5-2/

We want Javascript access to tearing/tearlines for low-latency applications too!

Comment 19 by marky...@gmail.com, May 22 2018

Also, as founder of Blur Busters, we've invented a lot of input lag tests.  Also, I committed a change to HTML 5.2 (section 7.1.4.2), as an Invited Expert to W3C.

So a lot of us indeed want access to tearing via Javascript.  It's scientifically the lowest-latency mode available, for things like science applications, eSports applications, and other lag-critical applications where lag is more critical than tearing.   

A lot of game companies (Electronic Arts, DICE, Ubisoft, etc) who talk with me are screaming at me why the heck the browser standardizers don't let them do VSYNC OFF via javascript.  I tell them that they standardize to a lowest common denominator but that I'm trying to convince many people that we need Javascript API access to VSYNC OFF and access to tearlines.  Too many ingrained assumptions by browser standardizers (tearing is evil) without knowing the benefits behind, such as ~30ms less input lag.
Project Member

Comment 20 by bugdroid1@chromium.org, May 23 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/2c951c8f6de48c558783859c611f3dd04a6f46a8

commit 2c951c8f6de48c558783859c611f3dd04a6f46a8
Author: Sunny Sachanandani <sunnyps@chromium.org>
Date: Wed May 23 20:39:37 2018

Split --disable-gpu-vsync command line switch

Introduce new --disable-frame-rate-limit switch that disables begin
frame limiting and synchronization of presentation with vblank.

After this change --disable-gpu-vsync only controls synchronization of
presentation with vblank which allows using this mode independently of
frame rate limiting e.g. for minimizing latency.

Follow up CL will enable variable refresh rate support on Windows with
--disable-gpu-vsync.

Bug: 807406
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I18ce2df9218620e9ec3e86d926252e36246f7e89
Reviewed-on: https://chromium-review.googlesource.com/1069744
Reviewed-by: Antoine Labour <piman@chromium.org>
Reviewed-by: enne <enne@chromium.org>
Reviewed-by: Luke Halliwell <halliwell@chromium.org>
Reviewed-by: Fernando Serboncini <fserb@chromium.org>
Reviewed-by: Brian Anderson <brianderson@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561239}
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/chromecast/browser/DEPS
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/chromecast/browser/cast_browser_main_parts.cc
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/components/viz/common/switches.cc
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/components/viz/common/switches.h
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/content/browser/compositor/gpu_process_transport_factory.cc
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/content/browser/compositor/gpu_process_transport_factory.h
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/content/browser/gpu/gpu_process_host.cc
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/content/browser/renderer_host/render_process_host_impl.cc
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/content/browser/renderer_host/render_widget_host_view_mac.mm
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/content/renderer/render_thread_impl.cc
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/third_party/blink/manual_tests/canvas/README.md
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/third_party/blink/manual_tests/canvas/utils.js
[modify] https://crrev.com/2c951c8f6de48c558783859c611f3dd04a6f46a8/ui/gl/gl_switches.cc

Project Member

Comment 21 by bugdroid1@chromium.org, May 23 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/1d38ecd256add10635af8d2e9643ad7febd37b4e

commit 1d38ecd256add10635af8d2e9643ad7febd37b4e
Author: Sunny Sachanandani <sunnyps@chromium.org>
Date: Wed May 23 21:34:27 2018

Use swap chain tearing to enable variable refresh rate support

Swap chain tearing flag allows application to submit frames independent
of vblank. This allows supporting variable refresh rate displays.

However, there's no standard way of checking for variable refresh rate
displays across vendors so this is only enabled behind the existing
--disable-gpu-vsync flag.

Bug: 807406
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I4eb0a6db1bf96fc55154fc2d8a3c9c8921fd3bb5
Reviewed-on: https://chromium-review.googlesource.com/1068032
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561260}
[modify] https://crrev.com/1d38ecd256add10635af8d2e9643ad7febd37b4e/gpu/ipc/service/direct_composition_child_surface_win.cc
[modify] https://crrev.com/1d38ecd256add10635af8d2e9643ad7febd37b4e/gpu/ipc/service/direct_composition_child_surface_win.h
[modify] https://crrev.com/1d38ecd256add10635af8d2e9643ad7febd37b4e/gpu/ipc/service/direct_composition_surface_win.cc
[modify] https://crrev.com/1d38ecd256add10635af8d2e9643ad7febd37b4e/gpu/ipc/service/direct_composition_surface_win.h

I have some contacts at FireFox. Can I assist in standardizing a W3 JavaScript API that does two of the following:

-- JavaScript API Enable/disable frame rate limiter
-- JavaScript API Enable/disable VSYNC

Many applications need access to these options for other reasons, so this can be an unofficial method of accessing variable refresh rate.

I have some proposed web standardization documents, participating as a W3C Invited Expert, as I've got 20 gaming monitors to test on -- including an experimental Zisworks 480Hz display -- plus several GSYNC and FreeSync up to 240Hz.

Can we begin incubate this feature, under prefixed APIs, to begin to formalize something that we can bring to W3C for official standardization?

Let's talk and I can connect us to people for early incubation to a preliminary standardization path (prep for HTML 5.3).  I am also the writer of: https://www.blurbusters.com/blur-busters-working-on-changes-to-html-5-2/

Thank you -- From mark@blurbusters.com

Sign in to add a comment