HTML canvas won’t display asynchronously written ImageData

I recently learned about JavaScript async generators, and I though it might be fun to try to parallelize a simple JavaScript ray tracer that I built as an example for a class. Not specifically trying for any speedup, just seeing if I can make it work.

However, even though my generator function seems to fill the ImageData buffer correctly, and the CanvasRenderingContext2D has the right data after calling putImageData, the image doesn’t display on the screen. Even the background color doesn’t show up, which I think must be a good clue to the problem if only I could see it.

Here’s a snippet of the original version:

  for (let j = 0; j < viewport.height; j++)
    for (let i = 0; i < viewport.width; i++) {
      // <-- cast a ray, intersect, do shading here to generate color
      this.drawPixel(imgBuffer, { i: i, j: j, color: color });

  context.putImageData(imgBuffer, 0, 0);

And here’s my first attempt at the new version:

  let tracer = generateTracers(this, 0, viewport.width * viewport.height);
  for await (let fragment of tracer) {
    this.drawPixel(imgBuffer, fragment);

  context.putImageData(imgBuffer, 0, 0); // BREAKPOINT HERE

  const debuggery = context.getImageData(0, 0, viewport.width, viewport.height).data;

  async function* generateTracers(renderer, start, end) {
    const buffer = imgBuffer;
    for (let p = start; p < end; ++p) {
      const frag = await new Promise((resolve) => {
        const i = p % buffer.width, j = Math.floor(p / buffer.width);
        // <-- cast a ray, intersect, do shading here to generate color
        resolve({ i: i, j: j, color: color });

      yield frag;

In the Chrome debugger, with breakpoint set at the line indicated above, I can see that ImageData is correctly populated right before calling putImageData. I also grab a copy from the context itself afterward, and that also looks okay. But still no joy on screen. Here’s a screen grab from a low-res 64×36 pixel trace.

enter image description here

And here are before and after grabs of the page output.

enter image description here

enter image description here

Not sure if I’ve provided enough information to go on here, but if anyone has suggestions either for what might be wrong or how better to diagnose the problem, I’d greatly appreciate it. Thanks in advance!

Source: Ask Javascript Questions