I'm actually more concerned by how easy it is to peg the GPU. The operating system does a pretty good job in controlling errant processes in general, but with GPU stuff it's easy to get your computer completely unresponsive. My android phone rebooted while trying to load one of these demos. The GPU APIs and drivers are two raw to expose to the web directly,especially compared to the way threading, networking and storage have been abstracted. Hopefully vulkan will allow for a more web suitable api to be built on top of it.
I don't see how Vulkan will solve this. The problem has nothing to do with software. It has to do with the issue that GPUs are not preemptable. If you ask them to draw 100000000 fullscreen polygons they are stuck drawing 100000000 fullscreen polygons even if that will take it 30 minutes.
Most modern OSes monitor the GPU and if it doesn't return in a few seconds they reboot the GPU. Windows started doing that in Windows 7. OSX not until recently. Not sure if Linux does it.
The only real solution is someone making preemptable GPUs
I agree that to do it properly requires driver and hardware support.
However, it's already possible to have fairly granular control over compute resources with CUDA for example, and also to run streams of commands concurrently, so that would solve part of the problem.
The other part of the problem that could be solved by vulkan is the browser taking control of compilation, which allows for more static checking and refusal of possibly unterminated loops.
The ANGLE shader compiler used in most WebGL implementations already does enforce that loops terminate. The problem is that GPUs don't / didn't have HW interrupts to allow switching between tasks.
It's not easily solvable by a super-powered compiler either. Sure, you could write your own compute-driven preemptive graphics pipeline and break execution after every X billion simulated instructions & random memory accesses. You'd have to do reanalysis on every frame too, due to changing shader inputs.
The computation done is roughly (number of vertices * vertex shader compute time) + (number of pixels falling under the vertex primitives * fragment shader compute time). The shader compute times are the sums of instruction execution times + data fetch times. Then take into account early exits, data access patterns and cache sizes (otherwise the compiler'll think that e.g. a simple greyscaling fragment shader is going to cause a random memory access for every pixel and take forever to run, causing the compiler to spread the shader execution across multiple frames and kill performance dead.)