KhronosGroup / WebGL

The Official Khronos WebGL Repository
Other
2.63k stars 667 forks source link

Improve WebGL's power handling #2282

Open kenrussell opened 7 years ago

kenrussell commented 7 years ago

Use of the WebGL API currently implies use of the high-power discrete GPU on dual-GPU systems. A "preferLowPowerToHighPerformance" context creation attribute was specified some time ago, but it hasn't been widely implemented, nor used by web pages.

After discussion in the working group, the following decisions were made:

1) replace preferLowPowerToHighPerformance with an enumerant: powerPreference = "low_power", "high_performance", "default"

2) getContextCreationAttributes should return the user's powerPreference request unless the system had to override it for some reason.

3) Advertise to WebGL developers that the WEBGL_lose_context is a way to forcibly terminate their context.

4) Advertise to WebGL developers that their context may be lost at any time -- for example, if a tab using WebGL has been in the background for a long time.

The working group notes that it's very difficult to handle this automatically. On macOS, it appears to be possible to dynamically switch between the integrated and discrete GPU for running WebGL content without losing the context ( https://codereview.chromium.org/2627323007/ ). The same is not possible on Windows; it is not possible to seamlessly migrate multisampled renderbuffers between GPUs, for example.

Edge attempted to dynamically switch between the integrated and discrete GPUs based on how much GPU load the WebGL application induced. (Multisampled renderbuffers were resolved to single-sample textures before migration, and other corner cases were handled as well.) The result was flaky; developers could not reliably use either GPU, so the mechanism was removed from Edge. Other browser implementers should learn from this experience.

grorg commented 7 years ago

Oops. I didn't notice this when I started my work :(

RafaelCintron commented 7 years ago

@kenrussell , the section in the issue about Edge is not quite correct.

In previous versions of Microsoft's WebGL implementation, there was a feature that monitored WebGL performance of the system using disjoint timer queries. To avoid runaway WebGL pages from adversely interfering with the responsiveness of the desktop, the feature kicked the website into software mode if it encountered too many long frames. The rationale is that CPUs are generally much better able to preemptively schedule workloads than GPUs.

The feature was ultimately removed from the product because CPU workloads were easy to become entangled with GPU measurements using disjoint timer queries. This led to pages getting pushed into software mode unintentionally, which caused developer frustration. We decided to instead rely on the system being able to let the user close runaway browser tabs when they are not satisfied with performance.

Since we developed the feature, newer GPUs have improved in their ability to provide graphics preemption. Applications running on Windows can query the graphics preemption granularity by calling GetDesc2 on the DXGI adapter.

kenrussell commented 7 years ago

@RafaelCintron thank you for the correction and clarification!

grorg commented 7 years ago

@kenrussell

getContextCreationAttributes should return the user's powerPreference request unless the system had to override it for some reason.

Does this mean that if the user requests high-performance on a single GPU system, they'll see high-performance in the return attributes? Similarly for low-power and default. I think that makes sense.

kenrussell commented 7 years ago

@grorg that was the intent, yes.

I was wondering whether "default" should be translated to "high-performance" or "low-power", perhaps on the fly if the GPU switches dynamically -- but that sounds complicated.