proposals icon indicating copy to clipboard operation
proposals copied to clipboard

PROPOSAL: (VRR) Simplest Incubatation Path for Variable Refresh Rate (FreeSync / GSYNC / etc)

Open mdrejhon opened this issue 8 months ago • 21 comments

EDIT: More incubatory approach needed; see replies

As seen in the replies to this thread, instead of WICG standardization (phase 2), this is now my "proposed incubation" (Phase 1) towards future WICG-impacting standardization:

Goal: Seeking cross-browser-engine consensus. I welcome feedback here.

Introduction

Browsers generally don't support Variable Refresh Rate (VRR). Terms: FreeSync, G-SYNC, HDMI VRR, VESA Adaptive-Sync, Apple ProMotion, etc. EDIT: Eventual WICG involvement is needed, this is a first-step (chicken-egg solving proposal).

User Benefits of Variable Refresh Rate (VRR)

  • Smoother video playbacks (e.g. YouTube natural 24p, 48p, 50p, 60p!). No judder; Home theater quality.
  • Existing WebGL/WebGPU content & games often adapt to VRR with no mods. Fewer erratic stutters caused by fixed Hz.
  • Creators (including me at TestUFO) can finally add VRR support to their sites
  • Still compatible with any browser frame rate caps

Proposal of Simplest Universal Solution (VRR Agnostic)

Born deaf (and creator of TestUFO) I'm a fanatic about visuals and over the last few years I gained some new experience in VRR programming.

I have what I believe is the simplest possible solution that will work with maximum compatibility with the least changes in all 3 browser engines (Webkit, Chromium, Gecko) on all platforms thave modern VRR-compatible OS compositors (PC/Mac/Wayland/Android/iOS/Playstation/Xbox).

Currently, all browsers composite at max Hz, regardless of the frame rate of full screen content in a browser. The top-level browser engine compositor currently does not synchronize to content frame rate. Some engine programming tweaks are minor, but it requires recompiling Chromium / other workarounds / proprietary modified browers. It is thus, preferred, to standardize.

My proposed solution works on all of these platforms in all VRR technologies. While browser complexity varies, this is possibly the simplest possible solution; perhaps initially as a flag setting for testing/vetting it out, followed further TBD progress.

There is only a universal Best Practices for apps (e.g. games or video or browsers) to make them VRR universally compatible across all platforms in a generic VRR-agnostic way. There's no universal "JS/HTML" API solution technically possible for VRR, and no universally standardized way to detect VRR. Therefore, the generic VRR solution has to be done at the browser engine level to unlocks generic VRR compatibility. Thus, my proposal:

Proposed Setting or Proposed Flag

  • [x] VRR Compatible: Sync Browser To Content Frame Rate During Full Screen Mode

Note: This could be turned off by default initially to allow incubating and testing. Based on existing programming experience and precedents in other software, this setting is expected to be (normally) harmless if OS/display VRR setting is turned off. For more information, see FAQ at bottom.

Proposed Text:

"Whenever a browser is running in full screen mode, it is RECOMMENDED that the browser compositor synchronizes to the frame rate frequency of the dominant <CANVAS>/<VIDEO> element, to unlock variable refresh rate (VRR) without compromising non-VRR displays."

Pseudocode Equivalent:

IF (isBrowserFullscreen) THEN (sync main browser engine compositor to frame rate of biggest element.)

By gating it to fullscreen mode for a single dominant animation/video element, this greatly simplifies cross-platform VRR-agnostic implementation for the most common use cases (fullscreen mode). Browsers already contain code for frame rate capping. (See FAQ) Implementation complexity may vary, however, this is the "simplest possible VRR algorithm".

Short Programming-Technical Explanation of VRR

It automatically works behind the scenes thanks to the graphics driver. In other words, frame rate of application becomes the display's refresh rate. As frames are presented (e.g. application top level Present() or gl.Finish() type API), the graphics drivers transmits frame immediately and display refreshes immediately on the spot.

TL;DR: The display syncs to application's own framerate.

Currently, all browsers composite at max Hz, regardless of the frame rate of full screen content in a browser. The top-level browser engine compositor currently does not synchronize to content frame rate. Some engine programming tweaks are minor, but it requires recompiling Chromium / other workarounds / proprietary modified browers. It is thus, preferred, to standardize.

My proposal aims to standardize the recommended useful minimal-as-feasible engine modification in a browser-independent VRR-tech-independent multiplatform Best Practices way. (Windows, Mac, Android, iPhone/iPad, Linux Wayland, PlayStation 5, XBox SX, Switch 2, or any GPU-accelerated OS compositor capable of VRR to a display capable of VRR).


Long Explainer / FAQ

Keywords: Developer Test Methods / Workarounds / Valuable Due Diligence / Weird Bugs / Workarounds / Etc. You can expand/collapse these sections to read more:

What Happens At Framerates Above/Below Hz?

For certain parts of dev teams that might be new to VRR:

  • Framerates hitting maxHz = It behaves like normal VSYNC, like today. The drivers begin throttling/blocking frame presentations, just as today.
  • Frame rates below minHz = Drivers does best-effort doubling, called Low Frame Rate compensation. For apps presenting frames at 24fps (e.g. movies) a display with a 40-75Hz VRR range will automatically refresh at 48Hz.
  • Frame rates between MinHz and MaxHz = Framerate is the Hz, and Hz is the framerate. Same thing.

Therefore, it is not necessary to worry about the display's VRR range; the graphics drivers does it automatically. The "simplest possible solution" will still work.

At the application development level, details actually doesn't matter, it's an orchestra between graphics drivers & display.

What matters is the engine application developer (game engine, browser engine, or top-level application compositor) presents frames to the operating system at the same frame rate as its content. In the situation of an adjustable browser engine cap (flag setting), frame presentation should be framepaced as smoothly as feasibly possible (e.g. minimal jitter).

Is This Universal Even When Display VRR Is Turned Off? [Short Answer: Yes]

Non-VRR displays show no difference in stutter; it will just one-dimensionally snap-to-grid to the next VSYNC.

Full rate simply gets throttled by MaxHz (which is unchanged for VRR and non-VRR). So full-framerate animations look no different. They look equally smooth on both VRR and non-VRR displays with the same standards change.

Low frame rates generally show little difference in stutter; it will just one-dimensionally snap-to-grid to the next VSYNC. So 24fps will still look like it has 3:2 pulldown (i.e. more stuttery than non-VRR).

If there are concerns, there could be a setting to toggle on/off this proposed feature for compatibility / comparision testing.

This could be a DevFlag (Safari) or chrome://flags (Chromium) or about:config (FireFox) in order to incubate, and help further discussion. By enabling the ability to test VRR, we can determine if it looks production-ready or require further refinement.

Are There HTML/JS Syntax Chanes Needed? [Short Answer: No]

The chicken-vs-egg is who is responsible for VRR? There's no way to create a HTML or JS standard other than telling the compositor to sync to a target frame rate (e.g. https://github.com/whatwg/html/issues/5025 )... But the secondary problem is that doesn't automatically cause the top-level compositor (browser engine) to sync to the OS/display Hz.

There's no on/off switch for that. Just a Best Practices that is more easily universalified than a "javascript API" construct/concept for VRR. This PROPOSAL aims to create discussion that breaks a discussion confusion (department A refers to department B, and department B refers to department A).

So to simplify that confusion of who's responsible for VRR:

This is why we propose gating it to full screen mode only for cross-platform simplicity & best user experience. Most of the time when user uses full screen mode (without menus) on a desktop platform, it's due to consuming full screen content (videos, games).

However, even in the case of text scrolling during full screen, the browser will just run at its full MaxHz compositor rate or internal cap (e.g. 60fps cap or configured cap), since smooth scrolling is easy for modern GPUs to do at full frame rate. Thus, scrolling experiences are unaffected by this VRR standards change.

In other words, no Javascript changes are needed. It's just a browser decision to sync its app-wide compositor (presentation to OS) to the full screen content's own framerate.

What if a Page Has Multiple VIDEO or CANVAS elements? [Simple Solution]

Obviously, pages can have multiple <CANVAS> and/or <VIDEO> elements.

However, when a user does full screen mode, it is commonly occurs that a single CANVAS or VIDEO element matches the horizontal and vertical width of the browser engine's full-screen-permitted surface (avoiding notches and whatnots)

Doing an Inspect on fullscreen content shows that most of these elements match what was reported by windows.screen object (and similar). This is easy code to detect IF one content-consumption element (VIDEO or CANVAS, 2d/webgl/webgpu) covers the full screen.

So if all conditions are met:

  1. Browser is in full screen mode, often by tapping a fullscreen button in a video or game or 3d animation;
  2. The dominant CANVAS or VIDEO element matches (or overlaps) dimensions of the reported window.screen info;

Then it is RECOMMENDED that the browser engine temporarily modifies the engine compositor to present frames to the OS immediately. Upon the completion of a new frame for the CANVAS or VIDEO and its frame delivery to browser engine; the browser engine immediately executes its internal global compositor and sends the frame to the operating system on the spot. By doing this, the operating system and drivers can begin to deliver the frame immediately.

This preserves frame timestamp:photon time relativity, since screens begins emitting the photons of the delivered frame, at a fixed tape-delay relative to the application's final frame-presentation. There's obviously some minor jitter due to internal compositing overheads (e.g. browser engine-wide and operating system level).

There are tests show that less than 1-2ms elapse between the application's top-level Present(), and the first pixels (pixel row #1) beginning to be output of the GPU port (DisplayPort or HDMI). This allows the display refreshes to the software; rather than to an independent refresh rate. Obviously, displays have latency, but it's a fixed tape delay style latency; VRR is still preserved through that.

To more directly access, long term (optional) it may be ideal to have some kind of a javascript hinting feature (e.g. "PrefersVRR" or "PrefersNonVRR") for special use cases and/or target preferred frequencies (e.g. to unlock 120Hz Safari). The "Should Pages Have Control Over Compositor Rate?" discussion can go another day, and can be permissionwalled behind things like the Windows Management API; but right now -- this is simply about simple fullscreen content consumption.

The simplest use case for VRR. This proposal about the minimum possible user-friendly VRR-agnostic multiplatform change to all browser engines that is not too onerous by browser engine vendors. That's what we need to discuss and test-out;

Testing: Custom Frame Rate Caps In Existing Browsers

These are useful for accessibility situations or developer-testing situations; see next section for more info.

  • FireFox Capping: about:config -> layout.frame_rate (Would improve with oneliner VRR spec change)
  • Chromium Capping: --disable-frame-rate-limit --disable-gpu-vsync --max-gum-fps="24"
Fun Visual Developer Test Case

How to Framerate Cap A Browser (For Testing, or For Accessibility)

Also, capping using an in-app browser cap also lowers latency of VRR, for the latency sensitive browser users too (if they want), from the old gamer-trick of "cap-below-max-Hz-to-reduce-lag".

  • FireFox Capping: about:config -> layout.frame_rate (Would improve with oneliner VRR spec change)
  • Chromium Capping: --disable-frame-rate-limit --disable-gpu-vsync --max-gum-fps="24"
  • Safari: Change "Prefer Page Rendering Updates Near 60fps" setting (try a 144Hz FreeSync display; VRR ON makes 60fps-on-144Hz smoother).
  1. Configure browser cap (see above), at a very cap within VRR range (not near Hz or content fps).
    Example "77" on a 120Hz. Ideal easily-seen dev-testing numbers are usually roughly 3/5 of your MaxHz, but slightly off and non-integer-divisible. For common 75Hz DELL/HP office monitors with 40-75 VRR, try 55 or 65fps cap.
  2. Open www.testufo.com/animation-time-graph#indicator=1 with frameskip indicator
  3. Optional (Webkit engine developers): If you're on MacBook, open TestUFO Settings (gear icon) and enable High Precision Mode (gpu busyloop)
  4. Go to full screen mode.
  5. PASS: Make sure that frametime jitter stays glassfloor (no red spikes)
  6. PASS: Make sure that frameskipping indicator doesn't erratically flicker (that means VRR is framepacing good)
  7. If items 5 and 6 PASS, your browser engine is in proper VRR mode.

During visual QA, use an odd number for testing not divisible by content frame rates and monitor refresh rates. It's easy to see a 100% framedrop (e.g. 1 frame dropped at 120Hz still visually shows as jank), so help with visual debugging of a framerate cap, use www.testufo.com/animation-time-graph#indicator=1 in full screen mode for Capped VRR tests. If you add a cap to your browser, it should stay perfectly glassfloor flat and the frameskip indicator should not erratically flicker

Browser Engine implementers can override the existing maxHz compositor clock whenever running a dominant CANVAS/VIDEO element in full screen mode, and sync the compositor to that framerate, but only up to the caps configured by the end-user (e.g. 77fps cap = block until exactly 1/77sec later after previous frame presentation).

It's important to avoid using an averaging-based framerate-cap, or use a very low averaging-window, you don't want frametime jitter bad between adjacent refresh cycles; just present frames immediately as close as possible to the moment of the CANVAS/VIDEO frame delivery, e.g. execute immediately composite+present.

Even 4ms frametime jitter at 120fps VRR at 240Hz = very bad 120fps (half refresh cycle jitter), so framepace better than that. For best results, keep framepacing jitter during capped situations to less than 10%. e.g. Try not jitter the main browser engine compositor more than 10% (e.g. ~0.1/77sec during a 77fps cap) whenever the full screen content is blasting framerate fully against an in-browser frame rate cap. (Ideally 1% is better, but 10% allowance is OK)

Accessibility Use Cases

The ability to make existing internal browser-cap settings optionally more compatible with VRR, would help accessibility.

  • Low caps behave like Apple's "Reduce Motion" for motion sick people triggered by smooth motion.
  • High caps behave as ergonomic relief by people who get motionsick by motion blur or stutter.

In short, some people get less motionsick at 24fps 24Hz, while others get less motion sick at 240fps 240Hz.

Just like "Reduce Motion" accessibility settings, there are situations where 24fps reduce motion sickness, but also (more) situations where 240fps reduce motion sickness. In an ideal case, VRR will work normally for framerates up to the user-specified cap. But right now it does not: It stutters badly! The one-line spec change + some minor code changes to engine will fix this.

Many users with motion sickness like using low caps like a "Reduce Motion" setting. Right now, user benefit and accessibility benefit is somewhat more limited than it could be, due to bad stutters when using odd frame rates not divisible by Hz.

The double-edged sword cuts both ways. Too many companies assume only one option (Calling out Apple's "Prefer Page Rendering Updates Near 60fps" cc: @smfr also ergonomic testing is throttled by bad compositor jitter and slow LCD GtG, obscuring the "High" ergonomic benefits that works much better during 60-vs-240 OLED geometric-upgrade situation)

Workaround For Testing with Certain Windows NVIDIA Drivers

On some NVIDIA drivers, it blacklists chrome from VRR due to a paste chrome bug with VRR. Make a copy of chrome.exe to chrome-vrr.exe and run NVIDIA Control Panel to permit that executable to do VRR.

This is simply a temporary workaround (that affects some NVIDIA drivers that blacklist VRR from chrome.exe) -- this enables Chromium developers to update the Chrome compositor to test compositor-sync-behavior changes.

Sometimes this is a stalemate between two big companies (Google vs NVIDIA), so let's at least mention this workaround to give some flexibility to browser developers to test VRR properly, shall we....

Best Practices For Frame Pacing To Browser's Configured Frame Rate Cap

If you manually configure a frame rate cap into your browser, there are some important considerations:

For browser-framerate-cap mechanisms (like FireFox layout.frame_rate or Chrome --max-gum-fps option), make frametime jitter as low as possible if you use timer-based compositor loops during caps. Use a more precise timer loop or a mutex of some kind with a reasonable precision, when executing an in-browser framerate cap.

Fix VRR Stutters: Frame Pacing Error Margins for Fixed-Framerate Situations
  • A lot of content have fixed frame rates
  • Many browsers have configurable frame rate caps (some optional), see above

It is fine to let frame rates float with the frame presentation rate. That being said, it is ideal that when a frame rate is known (e.g. video frame rate, or a browser frame rate cap), that jitter of frame presentation (to OS) should be within 10% of a Hz (best effort).

Otherwise, stutters become visible again showing through VRR, in a progressively worse fashion. In other words, you don't want 4ms framepacing error for your 8ms frames (120fps 120Hz). Even those kinds of stutters are visible; at 1000 pixels/sec smooth scrolling, that's 4 pixeljump jitters (4ms out of 1000ms), which is still human visible. I simply include this extra information, since many office/desktop non-game developers are unaware how milliseconds can cascade/amplify to visible jank, especially with cyclics (e.g. 4ms jitters comes and goes in a cyclic fashion).

So instead of low-priority timers or jittery video codecs (e.g. erratic decode of video frames due to codec performance) to operate VRR compositor, an additional improvement may be RECOMMENDED:

IF (content frame rate is known) THEN (Best Practice to improve frame pacing precision to within 10% of a single refresh cycle or better)

Otherwise, just present as the frame comes in. This is not hard nor exact; simply a Best Practice during known-content-framerate situations. VSYNC ON (non-VRR) is often a shock-absorber for jittery frames, since the VSYNC is almost a perfect framepacer for divisibles (e.g. 30fps and 60fps at 60Hz).

With VRR, the software is responsible for refresh cycle jitter synchronized to frame pacing jitter, and thus it is the software's responsibility to frame pace smoothly for fixed-framerate content.

Fortunately (as of 2025), the Windows compositors seem to have fairly good precision; just an additional consideration for VRR developer education to reduces VRR jank caused by unsteady delivery of fixed-framerate frames. It improves user experience.

Potential Side Effects

Some displays have VRR issues that creates side effects that require mitigations, such as the ability to turn off this setting.

  • [x] Sync Browser Compositor To Full Screen Content Frame Rate

A flag could be proposed for now, followed by later a more easily-configured user preference setting in the main settings screen, that becomes enabled default once the ecosystem is more mature. We, thusly, initially propose to begin with a flag setting.

Recommended Test Display For Maximal VRR-Benefits Tests

Any display with VRR, however, stutters are more visible on OLED due to fast pixel response (less blur to hide small stutters).

  • Many office monitors (Dell/HP) have unadvertised freesync in the 40-60Hz range or 40-75Hz range
  • A laptop connected to a 120Hz OLED TV is a good demo for stutters.
  • Modern gaming monitors

For developer testing, use various frame rates about 60-90% of the max Hz that are not divisors or multiples, like 100fps at 120Hz, or 65fps at 75Hz, or PAL 50fps on a 60Hz-mode LCD, in order to be away from common display Hz multiples and framerate multiples. This maximizes visibility of VRR benefits, since framedrops near Hz are the most visible kind.

Note about Past LCD 120Hz Mainstreaming: MacBook 120Hz was pretty marginal in the past because of two factors (1) Bad compositing jitter; and (2) Extremely slow LCD GtG making 60-vs-120 only 1.1x difference. Slow pixel response is like a slowly moving camera shutter before/after your refresh cycle (that's actually accurate: LCD pixels are light valves), you don't want a 4ms slow shutter before/after your 8ms refresh cycles blending to 16ms of motion blur per 8ms refresh cycles!**

Note About The New Mainstreaming of OLED 120Hz And Up: Everybody at DisplayWeek 2025 at VESA's booth could tell 60 vs 120 vs 240 vs 480 on a 480Hz OLED, since zeroed-out GtG made Hz differences maximally visible. Also, during new blind-study scientific testing variables, focussing on 2D scrolling, unrelated to gaming, an early salmple public population could tell apart 120-vs-480 browser smooth scrolling more clearly than 60-vs-120 smooth scrolling. A study is upcoming.

One of my articles, with actual scientific pursuit photographs (moving camera = moving eyeball tracking scrolling motion = same blur = like 1/120sec shutter versus 1/480sec shutter if GtG pixel response is nigh perfect 0 like OLED):

[Image](https://blurbusters.com/120vs480]

Due to OLED amplifying ergonomic Hz benefits; many vendors are considering mainstreaming non-gaming 240Hz by 2030 in "Pro"/"Premium" product, while bringing 120Hz to low-end products. Browser engine programmers and standards groups should have at least one member who owns a 240Hz OLED, for canary testing of the future.

Note: Some of my collaborators prefer my long walls of text. For that version, go to https://github.com/blurbusters/testufo-public/issues/6 .... Also there is another item within the framerate-control sphere that is independent-but-related https://github.com/WICG/proposals/issues/208 .... Which may invite cross-discussion because both covers a framerate-related sphere, regardless of which is implemented first (or both).


Feedback

I am seeking cross-browser-engine consensus. I welcome feedback here.

mdrejhon avatar Apr 17 '25 08:04 mdrejhon

There's nothing in the spec preventing browsers from doing this today. As such, you may have more joy filing issues directly with browsers.

jakearchibald avatar Apr 17 '25 11:04 jakearchibald

There's nothing in the spec preventing browsers from doing this today. As such, you may have more joy filing issues directly with browsers.

I welcome suggestions. I already covered this conundrum, my post above says "department A refers to department B, and department B refers to department A". Even a browser vendor referred me back here, and vice-versa. This gotta go somewhere. So here I am.

mdrejhon avatar Apr 17 '25 12:04 mdrejhon

Can you link to the browser issues you already filed?

jakearchibald avatar Apr 17 '25 12:04 jakearchibald

Most recent Dept A-B vs B-A situation (the other two, I can't find now)

  • https://github.com/whatwg/html/issues/11232#issuecomment-2812013236 (Told me to go to WICG)

Some ancient history:

  • I did a successful W3C commit to HTML 5.2 long time ago, before WHATWG took the main baton
  • 2016: https://github.com/w3c/html/issues/785
  • 2016: https://github.com/w3c/html/issues/375
  • 2013: Tests on high Hz https://blurbusters.com/blur-busters-120hz-web-browser-tests/

Omitting the in-between's K.I.S.S. and giving just bookends to prevent excess verbosity -- And if you know my Wall of Text history and cites in research papers (Search term: Blur Busters Display Science, Engineering & Research) or other standards (e.g. authored XMPP XEP-0301)...

...Then in comparision to my other writings, this WICG PROPOSAL here is relatively tiny and simplified in comparison. Especially in the context of my blog thru research papers thru specs. I spent a while hiding the non-sessential parts in detail blocks too. I would like to see a consensus about where I should go; before I waste more keypresses packing up tent again... So, welcoming a multi-person discussion to figure out how to move forward...

mdrejhon avatar Apr 17 '25 12:04 mdrejhon

None of those are browser issues. I did a quick search on Chrome's tracker and found these two:

  • https://issues.chromium.org/issues/346931323
  • https://issues.chromium.org/issues/40143481

As you can see, they're not requiring a spec update to do this work.

The clue was in your proposal - if it's just adding a recommendation, and not removing anything preventing that recommendation already being followed, then there doesn't need to be a spec change before implementations are changed.

Aside from that, I don't think your recommendation is sufficient. A canvas doesn't have a frame rate, so what does it mean to match it? If you're drawing something to a canvas you're generally using requestAnimationFrame. A video would have a frame rate of zero if it was paused. There's no definition for 'dominant'. etc etc.

jakearchibald avatar Apr 17 '25 12:04 jakearchibald

Aside from that, I don't think your recommendation is sufficient. A canvas doesn't have a frame rate, so what does it mean to match it? If you're drawing something to a canvas you're generally using requestAnimationFrame. A video would have a frame rate of zero if it was paused. There's no definition for 'dominant'. etc etc.

Good question, and I'll answer: The OS automatically keeps refreshing the screen at MinHz refresh rate when framerates pause. At framerates half Hz, it's doubled automatically by the OS/graphics/gpu drivers. As framerates fall below, it keeps repeating refresh cycles of the previous (now-still) frame in an autorepeating fashion. All VRR tech does it -- implementations differ -- but we needn't be concerned).

So the universal automatic VRR guardrails are already in the OS/drivers, expanding the specific FAQ lineitem for quick context:

> What Happens At Framerates Above/Below Hz?

For certain parts of dev teams that might be new to VRR:

Framerates hitting maxHz = It behaves like normal VSYNC, like today. The drivers begin throttling/blocking frame presentations, just as today. Frame rates below minHz = Drivers does best-effort doubling, called Low Frame Rate compensation. For apps presenting frames at 24fps (e.g. movies) a display with a 40-75Hz VRR range will automatically refresh at 48Hz. Frame rates between MinHz and MaxHz = Framerate is the Hz, and Hz is the framerate. Same thing.

Also, addressing the ping-pong (who's responsible?) that often deadends such a simple recommendation (and happy to help familiarize developers about how all VRR works, in general, behind the scenes -- I work with display companies too).

There is only a universal Best Practices for apps (e.g. games or video or browsers) to make them VRR universally compatible across all platforms in a generic VRR-agnostic way. There's no universal "JS/HTML" API solution technically possible for VRR, and no universally standardized way to detect VRR. Therefore, the generic VRR solution has to be done at the browser engine level to unlocks generic VRR compatibility. Thus, my proposal:

Welcome your thoughts on approaches.

mdrejhon avatar Apr 17 '25 12:04 mdrejhon

Thinking of a developer-friendly explanation:

In other words, it doesn't matter what the framerate is, if it's unknown. No framerate? No problemo; the computer already autorepeats the last frame to prevent VRR going below MinHz. Just relay the frames as they come; let the system do the rest. It's already there. Whenever framerates are inside VRR range, the display Hz is the frame presentation rate.

Also, during fluctuating frame rates of a game, the VRR display has 100 different instantaneous refresh rates at 100fps VRR; they can have separate individual per-refresh-cycle refreshtime, as frametime=refreshtime.

  • If framerate is unknown, just relay frames as is (immediately on the spot)
  • If framerate is known, try to framepace it more precisely
  • Don't worry about the VRR range; let the drivers/OS subsystem work.

I keep getting the ping pong ball because few in the engine community (who I talked to) seems to knows how VRR work (nor how easy it is to add VRR)

mdrejhon avatar Apr 17 '25 12:04 mdrejhon

TL;DR: In other words, it doesn't matter what the framerate is, if it's unknown. Just relay the frames as they come; let the drivers do the rest.

Then your proposed spec change, which makes recommendations around that thing that you say doesn't matter, is therefore redundant.

If you want the existing event loop to take VRR into account, please file issues with browsers. I have already linked to a couple, so there are already interested parties looking at this.

jakearchibald avatar Apr 17 '25 12:04 jakearchibald

Yes. Thank you for linking to them! I'd like to find a proper venue for some central browser-agnostic discussion thread somewhere (whether WICG here, or otherwise) as a parallel front, since it helps decide how to approach this problem in a less chaotic way.

Keep in mind:

  • One submission is a WontFix.
  • The other submission is a submission by NVIDIA -- As much as I am a fan of powerful GPUs, my proposal to have a "Best Practices For All Browser Engine Vendors" is GPU-agnostic, multiplatform, OS-independent, VRR-agnostic, and provides a quicker win with a simpler introductory change -- which can still lead to that more complex proposal by NVIDIA.

That being said, I'll go participate in those discussions too.

And those proposed NVIDIA VRR proposed extensions beyond my basics may affect WICG: e.g. a Permission-based API to enable the setting, or reliable discovery of screen Hz or existence of VRR (at least on some platforms that allow it), or a framerate-range request by Javascript (as mentioned in one of the FAQ items) -- that hits the surface of the WICG sphere. Therefore, I think it's in-scope for ongoing discussion here. I do have friends at NVIDIA too, who love my work.

mdrejhon avatar Apr 17 '25 12:04 mdrejhon

Ok. Good luck!

jakearchibald avatar Apr 17 '25 13:04 jakearchibald

"Whenever a browser is running in full screen mode, it is RECOMMENDED that the browser compositor synchronizes to the frame rate frequency of the dominant <CANVAS>/<VIDEO> element, to unlock variable refresh rate (VRR) without compromising non-VRR displays."

This doesn't really make any sense.

A canvas does not have an inherent frame rate. Its frame rate is governed by the frequency with which it's updated. Most commonly, if canvas drawing is done from requestAnimationFrame, then we're back to talking about rAF frame rate . If a page use setInterval(..., 2) to draw every 2ms, the browser is going to coalesce updates, and probably again paint the results at something equivalent to requestAnimationFrame frequency.

For fullscreen video, if the video is the only thing on the screen, browsers/OSes already have fast paths ("detached" video) which will match the display refresh rate to the video's frame rate as much as possible (within 4ms quanta on modern hardware). If there's a video and some other animated web content (canvas/animated GIF/whatever), then we're back to updating at the engine's inherent update frequency.

BTW, "variable refresh rate" for a display is generally used to describe how a display may not be locked to a consistent update frequency, but can update as necessary. For example, some Apple displays might have 8ms, 12ms, 16ms, 32ms intervals between frames.

So I'm not really sure what you're proposing.

smfr avatar Apr 17 '25 16:04 smfr

Related?

  • https://github.com/w3c/csswg-drafts/issues/7196
  • https://github.com/whatwg/html/issues/5025 (I see this was already referenced in the FAQ...)

mmocny avatar Apr 17 '25 18:04 mmocny

Great comments! Thank you.

Related?

Only partially.

It does not cover the whole scope of VRR -- only those for apps controlling framerate;

  1. VRR benefits synchronous framerate situations (e.g. video files)
  2. VRR benefits random frame rate situations (e.g. games). 100 unique refresh rates during 100fps during one second.

To address both replies; there are multiple purposes of VRR. Some vendors mainly focus on subset of VRR usefulnesses, e.g. video priority over gaming priority, or vice versa (etc). This is legitimate -- not all video devices focus on gaming -- and not all gaming devices focus on video. For this reason, both sides of the team may be unaware of VRR benefits to the other team. I aim to commonalize;

Figures: How VRR benefits random-framerate situations

During non-VRR:

Image

During VRR:

Image

VRR also benefits also erratic framerates of games (e.g. Randomized framerates simulator via a blending simulation at www.testufo.com/vrr (if viewing on MacBook, enable TestUFO High Performance Mode in TestUFO Settings).

In other words, the game doesn't set its own framerate except by trying to finish frames as performance allows -- uncontrolled/uncapped. VRR benefits smoothing that too.

Many operating system VRR compositors keeps the coalescing/composition chain intact all the way from OS through GPU output. Here, in this Proposal, is a discussion of Best Practices at the main coalescing/compositing level -- aka the browser engine beyond control of web app level.

My Proposal aims to provide a universal simplified solution, since solving the VRR problem is typically easier than expected once the coalscing problem clicks in a game developer's mind (e.g. game HUD/overlays/mouse events/keyboard events), as there's identical parallels in a browser engine too (more below)

mdrejhon avatar Apr 18 '25 00:04 mdrejhon

Also, @smfr, great reply too

Addressing Coalscing Page Updates

Good point about the coalscing. I attempted covered this; but it may have gotten a bit confused due to different terminologies. For glossary of mine, "coaslscing updates" = "top level compositor" (browser engine level)

So I'm not really sure what you're proposing.

Before I started programming VRR, I started educating about VRR In year 2013:

Now, I have to say I don't know engine internals, but I do know (in tests, e.g. outside browser context, or casting a 2D frame to an external non-browser frame server) the simplest Best Practices of VRR is to present in sync. If the engine is not architecture as such, then possibly implementation is slightly more complex.

Fortunately, based on the link followed, it seems that the Chromium team seem to be closest to getting there, so that we could all do some more shaking-out of browser-level Best Practice -- which may influence a standardization of how VRR is designed into browser sengines.

So given the coalescing requirement, it already naturally falls in place with a PC gaming industry best practice (HUD panels, floating text, on top of a 3D game framebuffer) that corresponds to multiple browser elements that needs to be composited/coalsced. So excellent question. Here's my answer:

Details

EDIT: I have hidden Wall of Text excess into above expand/collapse -- click Details for more information

Recommended Frame Deliver Signals (That Works)

Possible deliver signals:

  • Examples of Non-JS controlled events
    • VIDEO; the frame delivery moment
  • Examples of JS controlled events
    • WebGL gl.fiinish
    • WebGPU GPUQueue.submit()
    • Canvas2D (none)
    • Then right after, the completion of the event loop (e.g. exit of all events, including rAF()
      • Then the browser should commit frame to the OS on the spot;

K.I.S.S. Version At Browser Engine Level

"Coalsce and composite the instant the moment the main browser loop is done."

Following the coalesceing done in non-browser pipelines -- we simply borrow the same workflow.

For most WebGL/WebGPU games, they already usually execute one frame-presentation per main browser event loop, so that's why the requirement is mergeable/simplifiable.

Apparently it works. In a minor modification of Chromium Embedded Framework a couple years ago. (I need to find the code). I wish I had reached out sooner about that; but my proposal is based on that.

Even OffscreenCanvas, Web Workers still usually have to deliver it to the main loop, and usually the main loop only presents one frame per main browser event loop cycle anyway (most of the time).

Therefore, upon the moment a the fullscreen visible canvas/video changes -- is the moment immediate coalscing (top level compositor) should execute on the spot.

Then on the spot, the browser SHOULD excute all final stuff (coalescing updates + composition) immediately upon exit of the main top-level browser loop, and deliver to OS immediately on the spot. And refrain from delivering another frame to OS until the next cycle of event loop executes (unless too much time has passed: Then execute the events anyway to prevent page unresponsiveness).

Now that said, I am not aware how specific engines tie keyboard/mouse frequencies to the page update frequency -- whether coupled or decouipled in which engine. But typically most content output either 0 or 1 frame per main browser event loop. You skip sending frame to OS if there's 0 for the fullscreen element, and you send to the OS right on the spot if the canvas/video element is 'dirty'. By doing this, we preserve a VRR workflow that is surprisingly similiar to non-browser VRR workflows!

Given knowledge of how VRR is programmed outside browser -- it works whether you run one main browser loop or multiple main browser loops per changed frame (CANVAS/VIDEO). There are multiple workflows possible inside a browser engine (A) You can still coalesce/composite internally offscreen (if it helps responsiveness for the NEXT visible paint-coaslce/top-evel compositor); just don't send the frame to the OS, or (B) You can run those at lower frequencies in sync with the framerate (dirty eventrate of CANVAS/VIDEO) or whatever mechanism you do -- the same generic principle applies. Whatever terminology you use -- I can try to glossary for you so we read the proposal from the same songsheet;

The solution works either way, with some tweaks to the workflow -- without knowing engine-level restrictions, if there's a tight tie on one keyboard/mouse eventloop run per one animation frame run -- then details will have to be discussed about how to proceed on preventing page unresponsiveness for a 0fps situation, but a MinFramerate setting could be incubated.

We need an "incubation path"

Nontheless, the proof of concept shows a minor change is at least theoretically possible that accomodates the problem in a universal cross-platform way --

Like the HTML overlay on top of the full screen video. Sure, the subelement overlays (e.g. HTML or tiny-CANVAS-driven play control overlays on top of a full screen CANVAS/VIDEO) will update at variable frequencies.

Industry Best Practices Precedent on Final Coalescing / Composition Updates

The non-browser VRR best practices is composite/coalsce the moment the game present frame. HUD/overlays/text/playcontrols, and latest mouse/keyboard loop, etc (metaphorical equivalent of other HTML elements and events)

So in a browser context, we simply use existing precedent used in non-browser software. VRR content does all its framebuffer final-compositing (HUD menus, overlays, floating text) at the delivery of the fullscreen frame. Likewise, browser compositors that enable VRR for fullscreened CANVAS/VIDEO should fololow VRR games does forcoalescing/composition.

Human Vision Priority - Benefiting Users

The frame rate of a play button, or the frame rate of an animated-gif-style HUD overlay, is less important than the frame rate of the biggest surface area that the human eyes are seeing (the fullscreened video element)

Coalsceing/Compositing (All the independent update frequencies...)

If this workflow is followed, VRR works where it matters for user experience (smoother content without stutters).

I've gained enough VRR programming experience to find a universal formula, I'm simply proposing how the browser engine workflow for improving user experience in VRR should be (in the easiest engine implementation way).

So, the coalescing pipeline works as usual, just that coalescing/merging/compositing the page updates inside the engine is now synchronized to the frequency of the "Recommended Deliver Signals" listed above.

The entire browser main loop (that runs the javascript event loop, keyboard, mouse, all the multiple rAF() of tiny player-button controls, etc) would thusly, then run at that frequency of the Recommended Finish Signals of the (A) sole fullscreened CANVAS/VIDEO element, (B) only during fullscreen, (C) only when the setting is enabled in the browser.

So following industry precedent is enough.

By doing this, and enabling in a dev flag, it makes it easier to optimize the browser engine to be more compatible with VRR.

Obviously there's hinting available in some venues (e.g. video framerate) but in the abscence of hinting, the browesr compositor shall withhold commits of unchanged frames to the OS (unless excess time elapsed) until the "deliver signals" occur.

Offer

Simon -- with my now-improved VRR programming experience -- I offer humanpower on professional spec writing. I now put money where it counts -- I'm a monthly Mozilla Foundation donator too. How can I help?

If you want me to move this to a Coalescing-Explainer.md, I will honor your request and create a Coalscing Specification, and help your team. Bonus is, spec-writing forces me to do repeat-rewrite passes (refactoring my Walls of Text) into a more professional spec...

But, it is only worthwhile, if I'm asked by a major standards/engine stakeholder (like you) to do so, and be instructed on the correct venue (to avoid DeptA DeptB ping pong) to submit a lovely proposed spec to Webkit for iteration/improvements.

Or even to address other workflow-painpoints or workflow-confusion points that needs to be addressed before the Coalsceing Problem. I realize some platforms have difficulty (e.g. my new javascript-controlled TestUFO High Performance Mode targets those platforms).

I am prepared to assist in improving collab between OS-level, app-level, and webapp-level, using prevailing industry-wide best practices compositor/coalsceing sync. One weak link does cause problems. It's important that it's possible to shake things out (e.g. OS team will find it easier, if the browser is capable of it). Meetings between departments is hard, and a good spec can help...

I will move the text of my reply to that spec and hide this comment in a DETAILS collapse. How can I help? Please let me know. I realize things are complicated behind the scenes, NDAs, etc, but I can help with humanpower on a spec -- if you honestly think I'd do useful contribution.

Discussion Welcome

Whether WICG or pre-WICG. Currently, since there's a browser engine minimum-feature showstopper preventing the community from incubating minimum-VRR-capability tests. In other words, Phase 1 changes that don't require HTML/JS changes yet.

To circle back to the important point of minimum possible change that enables incubating VRR.

There are multiple fronts involved that interact:

  • The proposed "VRR Compatibility" (browser setting or flag)
  • The "Framerate Cap" setting (browser setting or flag, and/or future theoretical HTML/JS feature)
  • Webapp "Framerate Target" setting (webapp control, aka WICG attack surface)
  • Browser event loop (typically 0 frame or 1 frame per animation loop) and using [x] VRR Compatibility to optimize its workflow for VRR, as I've proposed above

In order to shake out VRR interactions and practicalities in browser quicker and sooner and lead to VRR-improvement proposals (e.g. future potential extensions to framerate control that accomodates VRR) that affect WICG.

This is a chicken and egg (browser engine and web standards) that apparently clearly requires engine-first "minimum possible" VRR incubation so that furhter progress can be made on any front somehow -- if you have a better generic alternative that has parallels in non-browser contexts, I'm all ears.

To better approach individual engine vendors (Stage 1 pre-WICG step), I now feel there needs to be at least a reasonably cohesive "minimum possible" incubation route (that has parallels to non-browser world, and also shows great promise in quick tests). One that preserves existing standards, adds a broad developer incubation route, and adds VRR gracefully, which may (Stage 2) require WICG involvement, including tie-in with those relateds.

Further discussion welcome!

mdrejhon avatar Apr 18 '25 00:04 mdrejhon

Note that for <canvas>, there is already a desynchronized settings; even though its support is limited to some configs only.

Kaiido avatar Apr 25 '25 00:04 Kaiido

Note that for <canvas>, there is already a desynchronized settings; even though its support is limited to some configs only.

Good comment! However, VRR applies to both desynchronized and synchronized.

  • VRR can be desynchronized during framerates below Hz, unless it's ticking to some predictable external rate (e.g. a film framerate or an OS-preferred compositor framerate like ProMotions' 80fps mode)
  • VRR is usually synchronized again during framerates hitting Hz. It then automatically switches back to normal max Hz behavior, aka as if VRR is not turned off.

My simplified proposal is apparently found to be universal regardless. Everything 'clicks' into place surprisingly automagically; when a full screen canvas/video element immediately triggers compositing (coalsce+merge+master-composite+present IMMEDIATELY on the spot) after refraining from presenting until canvas/video frame is ready -- then the next chain is now responsible. That's why my proposal is so beautifully rudimentary and simple; it unexpectedly works (CEF test).

VRR works to the next layers' specs. Fix the weak link in the browser top-level coalscer/compositor, and finally VRR can incubate.

mdrejhon avatar Apr 25 '25 20:04 mdrejhon

Any other "simple-but-works" incubation proposals that can unblock VRR progress?

Having an untoggleable weak link in multiple layers (issue in OS, issue in browser engine) makes it hard to debug the VRR ecosystem. One has to metaphorically ask oneself; why doesn't browsers support VRR after all these years, despite it being fundamentally fairly easy; and how can we help move things along;

A flag setting unlocks incubation that can then unlock progress (including finding flaws and best-paths-forward) that steers next level of progress / standardization steps. Remove all the squirrels/red herrings, focus on the easiest unlock for incubation.

It at least helps other stakeholders focus on fixing other weak links (e.g. driver issues, driver blacklists, OS compositor quirks during power maangement, etc) once a web browser gains incubation-VRR capability as proposed. Work our way on VRR flaws outwards logically; flag-then-engine-then-OS-then-driver. OS and drivers can't fix flawed-VRR-apps, so we have to layer up -- beginning with the app. Standardization can't begin without that incubation.

New Discussion Angle

  • From an Apple/Safari perspective -- it's metaphorically the rough equivalent of "Prefer Page Updates Near 60fps" instead becoming "Prefer Pages Updates Near Fullscreen Canvas Update Rate" (including all smaller elements, which now synchronously tick to the dominant fullscreen element, whenever fullscreened -- from the coalsced top level compositor now tick-tocking to the rate of the big fullscreened element -- it works in CEF mods! A fullscreened element primary framerate BECOMES the new primary compositor clock (graphics-updates-coalescer). Just like a game's HUD (metaphorical equiv of HTML overlays) is also forced to update to the fullscreen frame rate of whatever is fullscreened; it is UX stndard practice of VRR anyway; and it's just an incubation flag that I think should exist;

  • From a Chromium perspective -- which already supports the necessary command line options, but has some stutter problems caused by compositing stationary frames more frequently than the actual framerate. Hopefully it is just a few minor changes, that I will attempt to assist Chromium team on incubating this (And maybe I'll even fund a commit later this year). It's currently at the "It's almost but not quite VRR-incubation compatible yet, until more surgical minor changes are needed to codebase once a developer understands VRR better" status right now.

Ideally, before WICG Phase 2 (impacting JS surface) I would like a common front from Mozilla and Webkit sides so I am not going down the wrong path on a possible incubation step. I've added a comment to that thread. I'm trying to simplify this with what works in a high-impact incubation modifications (with my new improved software-developer knowledge). I definitely want to make sure that this is a "future-WICG-compatible" generic path that makes most sense for shaking out the VRR ecosystem before official WICG standardization.

Top-Level Updates Compositor/Coalscer Standardization Progress

Past: Existing browser engine top level compositor (updates-coalscer) in essence, already can sync to multiple primary clocks:

  • Refresh rate
  • Power-managed rate (e.g. 30fps during low battery)
  • Cap (e.g. Prefer Page Updates Near 60fps)

Today: My proposal simply adds a flag or setting to have a new updates-coalscer frequency:

  • VRR Incubation flag to allow sync to framerate of fullscreened CANVAS or VIDEO element ✅ --> WE ARE HERE <-- Aim of simple proposal

Future: Phase 2 & post-incubation impacting WICG surface for adjustable root-level compositor-coalscer clock:

  • Later, talk JS/HTML hinting feature for websites to flag a main element as primary framerate clock;
  • Or extensions to fullscreen mode or display management APIs;
  • Or other acceptable proposals (after futher incubation) that replaces the flagged incubation;
  • Related Talk
    • Compatibility with power management (e.g. use lower of (hinted cap) vs (engine/OS-mandated cap)
    • Compatibility with other future standards (e.g. framerate-requesting APIs)
    • Discussion of UX factors (e.g. VRR checkbox in Settings required for the hinting feature to work)
    • Discussion of other gating factors (e.g. permission only? fullscreen only? Etc.);
    • Vet compatibility with VRR systems without VRR discovery APIs
    • Vet compatibility with VRR systems with VRR discovery APIs
    • Vet compatibility with future non-traditional-framerate workflows (e.g. framegen, framerate-changing filters, etc)
    • Etc.

In all the above -- same status quo of a changeable primary compositor frequency -- Any small or secondary elements that updates more frequently is all just existing defacto offscreen updates (e.g. high framerates in a WebGL canvas doesn't visibly show more than 30fps during low-power mode, as an example), until the primary coalscer ticks, composites, and presents to the operating system. Same principle!

Existing precedent in other non-browser apps (e.g. game HUD, overlays, player controls, smaller elements) tick to a single primary framerate clock of the main fullscreen content (e.g. game or video). In such fullscreen apps, framerates of overlayed elements doesn't matter as much as the VRR best-practices of the primary item of fullscreen immersion.

My proposal has field precedent; are there other proposals, for generic platform-independent VRR-tech-independent VRR incubation? That bulletproofs everybody's future without shooting feet architecturally, and with all cooks in the kitchen in harmony?

Discussion welcome!

mdrejhon avatar Apr 28 '25 00:04 mdrejhon

One has to metaphorically ask oneself; why doesn't browsers support VRR after all these years, despite it being fundamentally fairly easy; and how can we help move things along;

I think this needs to be answered more than metaphorically. Any proposal needs to show why it will result in a different outcome than the status quo. For example, I cannot see how a "RECOMMENDED" line in a spec changes things. Putting an equivalent of "please try harder here" into the spec doesn't suddenly change the development priority of browsers.

The spec doesn't mandate painting at any particular frequency, or even a steady frequency. We already have declarative animations (via CSS and web animations), and a way to request an animation frame (requestAnimationFrame). The browser can already choose when to schedule those frames. Doing that in the most visually pleasing way is a quality-of-implementation issue.

There's also a way to schedule work to run at the frame delivery rate of a video, requestVideoFrameCallback.

If you can show that this is insufficient, and that a spec change, or API change is needed, then that's a good start. "Browsers haven't done it yet, therefore a spec change is needed" is not good logic, as there's no solid link between the problem and the proposed solution, other than simply 'doing something'.

jakearchibald avatar Apr 28 '25 09:04 jakearchibald

One has to metaphorically ask oneself; why doesn't browsers support VRR after all these years, despite it being fundamentally fairly easy; and how can we help move things along;

I think this needs to be answered more than metaphorically. Any proposal needs to show why it will result in a different outcome than the status quo. For example, I cannot see how a "RECOMMENDED" line in a spec changes things. Putting an equivalent of "please try harder here" into the spec doesn't suddenly change the development priority of browsers.

Excellent question!

Firstly, I admit that my original post needs to be slightly changed a bit actually because the intent of this discussion has steered slightly to a more incubatory approach. I've edited my original post to highlight this explicitly. However, there's no consensus yet on which direction that takes that is congruent to long-term WICG standardization.

1. Competing Goal Problem & Cancelled VRR Support

We are faced with lots of problems and many cooks in the kitchen:

  • Compromise VRR tweaks often created UX problems (e.g. tried to sync to the framerate in a very chaotic way).
  • ❌ FLAG REMOVAL: Earlier, chrome tried and cancelled/removed a different (more complex) path to enabling VRR support: e.g. VRR flag removal https://issues.chromium.org/issues/394308610 and have since removed this flag -- Chromium team deleted an earlier (more code-complex) VRR flag. I had no involvement in this flag, and I was unaware of it until too late in its development. Mine is simple, and hits the UX benefits more directly while staying generic.
  • Several parties prioritize VRR mainly for video consumption (24fps, 30fps, 59.94fps, 60fps) like Apple's ProMotion
  • Other parties prioritize VRR mainly for video games, like NVIDIA's G-SYNC
  • Others, like generic HDMI VRR, targets both games and video.
  • All work on each other's tech (e.g. SMPlayer/MPV player in fullscreen for Windows supports NVIDIA's G-SYNC when video playing, and many Apple Games will activate ProMotion modes) even if it's not the vendors' primary target of VRR-ability. Generic behaviors of VRR is commonal to all that it still benefits.
  • Standardization discussion don't want to play to a specific vendor's playbook (AMD FreeSync, NVIDIA G-SYNC, HDMI VRR, VESA Adaptive-Sync, etc)
  • Some parties are advocating a VRR-platform-specific path (e.g. NVIDIA and hooks into NVIDIA APIs), e.g. https://issues.chromium.org/issues/346931323#comment1
  • VRR documentation is not always as generic as they should be. Vendors that add VRR often add vendor-specific sugar to the generic principles of VRR.
  • VRR is often a "see for oneself" technology to understand its benefits better.
  • There is disagreement whether or not VRR impacts HTML/JS surface. The true answer is "Yes, but not yet". So here we are, Phase 1 (no WICG) + Phase 2 (WICG). It's a major chicken-and-egg situation.
  • Several programmers still don't fully understand VRR, and would appreciate a demonstration. Related/corollary: The venn diagram overlap of skills tend to get poor when you try to overlap (non-game/non-video application developers) with display technologies like VRR or HDR. For example, a Google Docs developer who works on the Chromium browser source code would not really know much about VRR or HDR, nor need to. This limits number of programmers who can work on browser engines who also intimately understands a specific display technology line item (e.g. VRR). This is where roles of people like us can help assist (to an extent).
  • Many platforms support VRR but have no VRR discovery APIs, stalling standardization progress
  • Demand signals from end users and developers are weak (e.g. end users who gave up waiting for good VRR in browsers) because no VRR incubation approaches in browsers successfully fixed enough weak links, in a simple way, to be more universal usable/testable by a wider number of people.
  • Framerate-control APIs have lots of commonalties with VRR benefits too
  • There is an unusually inordinate numbers of chicken-and-egg factors involving VRR deployment (app level, OS level, driver level, and display level). Any weak link inhibits debugging. Two weak links is surprisingly common, it often causes the other link to revert itself (give up implementing VRR). A simpler less code-intrusive flagged incubation step is a very helpful unlock.
  • Etc.

So, simplifying focus to distill to the minimums:

2. "What Is The Minimum UX-Benefitting VRR-Agnostic Situation?"

  • That's fullscreen content (e.g. games or video).
    • Years of industry-wide best practices show that it works in all VRR technologies as long as "frames presented on the spot" as precisely as the app itself can (best-effort precision "present now on spot" when framerate is unknown)
    • That's to keep refresh cycle photontime (hits eyeballs) as close to sync of the frame presentation timing
  • Don't enable "VRR mode" (modified frame presentation timing) if it only benefits specific VRR platforms <-- BIGGIE ✅
    • Side effects such as stutters that get worse when VRR enabled in a not-best-practices way <-- BIGGIE ✅
    • Side effects such as VRR-benefits incompatibilities (e.g. improves one VRR but worsens another VRR)
    • VRR is a global refresh rate, you can't have multiple refresh rates at the same time for multiple elements/windows.
    • Windowed VRR is very platform-specific and not as generic, sometimes buggy when primary framerate signals change.
  • Therefore for generic VRR benefit:
    • Fullscreen content only, and present-frequency sync'd to framerate.
    • Underrated advice; this advice has been gold timesavers to brand new VRR programmers.
  • User experience is much better when VRR experience is gated properly
  • And next; how to standardized a browser engine based Best Practices with minimum code changes;

3. How to Reconcile Steps Forward?

The problem is we're trying to reconcile the competing goals that has stalled browser VRR progress for 10 years. Simplification, genericization, and reducing code changes, required for a minimum-incubation path, to unlock the VRR deadlock.

  • VRR is often a "see for oneself" technology to understand its benefits better.

Expanding on this bullet: With some planning (e.g. targetting a very specific convention), I would be happy to arrange to do a free visual VRR presentation at some future convention, in order to teach a team of software developers (on my dime) of all the visual (see-for-yourself) benefits of VRR. I teach classrooms now (image of one of my classes) despite my deafness (I use clever visual techniques and a caption board to communicate my words, as seen in the photo) -- is there a role here for me to attend some future convention and do something similar? I'd arrange something on my own dime in 2026, if it produced helpful progress;

If you can show that this is insufficient, and that a spec change, or API change is needed, then that's a good start. "Browsers haven't done it yet, therefore a spec change is needed" is not good logic, as there's no solid link between the problem and the proposed solution, other than simply 'doing something'.

A lot of my Wall of Text's covers it, but without fantastic classroom demos, it doesn't help much;

Any better suggestion forward of the minimum possible incubation step going forward to enable multiplatform experiments, that can enable good WICG next-steps? Everything is on the table -- even multiple concurrent incubation paths. The large amount of VRR direction-pulls inhibits progress.

As displays become more complicated (Hz / HDR / VRR / Non-rectangular / notches / etc), implementation can lag further behind display capabilities. If you think my incubation path is bad, consider the size of the testing surface (number of platforms + number of GPUs + number of displays testable) unlocked by my simplified incubation proposal. Even unlocking this simple "giant-testability-surface-hitting" incubation path allows us to discover better incubation paths more easily.

The first-step falls in the netherland between engine-specific incubation and non-engine-specific standardization, which creates a "What Venue?" challenge. Not quite webkit.org/chromium.org/mozilla.org, but not quite WICG/WHATWG. Whether we ditch the RFC2119 nomenclature while temporarily in the netherland, but how do we standardize this netherland? (Real non-rheoretical question...)

I think by now, many realize we need at least a faint consensus on early moves since some dominoes (eventually) hits WICG surface. We don't want another VRR flag removal situation, so we need at least a modicum of faint cross-browser consensus before convincing one of the vendors to re-flag a new simpler incubatory VRR implementation that hits UX better, reduces code changes, and increases testability surface.

Discusion Welcome: What Is The Next Logical Step Forward?

Among other people outside this WICG arena; there is currently confusion whose court the ball is currently in. (...Funny aside on xkcd 927 on 14 standards: Standarize the location of the ball before standarding the scoreboard...) ...

Suggestions? More Walls of Text? Custom specs I can write? In-person classroom demo show, all-expenses paid by me?

At the minimum, let's keep discussing at least!

Edited my original post at top too

mdrejhon avatar Apr 28 '25 19:04 mdrejhon

To help guide commentary;

If you can only comment on one thing -- this part is key in this standardization crossroads:

2. "What Is The Minimum UX-Benefitting VRR-Agnostic Situation?"

  • That's fullscreen content (e.g. games or video).

    • Years of industry-wide best practices show that it works in all VRR technologies as long as "frames presented on the spot" as precisely as the app itself can (best-effort precision "present now on spot" when framerate is unknown)
    • That's to keep refresh cycle photontime (hits eyeballs) as close to sync of the frame presentation timing
  • Don't enable "VRR mode" (modified frame presentation timing) if it only benefits specific VRR platforms <-- BIGGIE ✅

    • Side effects such as stutters that get worse when VRR enabled in a not-best-practices way <-- BIGGIE ✅
    • Side effects such as VRR-benefits incompatibilities (e.g. improves one VRR but worsens another VRR)
    • VRR is a global refresh rate, you can't have multiple refresh rates at the same time for multiple elements/windows.
    • Windowed VRR is very platform-specific and not as generic, sometimes buggy when primary framerate signals change.
  • Therefore for generic VRR benefit:

    • Fullscreen content only, and present-frequency sync'd to framerate.
    • Underrated advice; this advice has been gold timesavers to brand new VRR programmers.
  • User experience is much better when VRR experience is gated properly

  • And next; how to standardized a browser engine based Best Practices with minimum code changes;

Refining this will help multiple parties decide the specific long term step-by-step standardization paths (WICG-level, pre-WICG-level, and mozilla.org/webkit.org/chromium.org-level) or even potential funded open source pull request(s) (~2026) of possible generic flagged implementation(s) if nothing happens prior;

A reasonable browser-engine-POV consensus about item 2 will help these cross-engine cross-VRR considerations massively to avoid time wasted on a flag-pull situation on a poorly-UX-impacting or too-VRR-specific standardization approach.

Further commentary / agreements / disagreements is welcome in item 2 of this decision fork.

mdrejhon avatar May 03 '25 02:05 mdrejhon

I'm running under the assumption that the new revised plan is a nominally acceptable way forward; beginning with the browser that is closest to being able to implement VRR support (in this case, incubate via Chromium).

I also have Plan B too; since the beta version of TestUFO now has gained essentially a js-based hardware abstraction layer -- Internally. I recently successfully got WebGL version of TestUFO running on development server -- and will have interfaces for eventual external native rendering helper app (e.g. Direct3D/Metal/OpenGL/any native render tech) that has access to all native sync technologies.

So I've come up with two paths forward in this pre-standardization incubation.

But -- long term, I'd prefer a fully in-browser plug and play solution without helper apps.

So I have two possible paths forward. Either will also follow the best-known best-practices principles of "What Is The Minimum UX-Benefitting VRR-Agnostic Situation?".

I welcome comments on refining that Best Practices, in case it leads to future standardization at the HTML/JS level.

mdrejhon avatar May 26 '25 01:05 mdrejhon