Passing an offscreen canvas to an offscreen document for rendering

173 views
Skip to first unread message

Bob Numan

unread,
Jun 1, 2025, 6:11:39 PMJun 1
to Chromium Extensions
My extension's content script needs to use a Worker to perform some drawing operations on a canvas but creation of the worker might be blocked by CSP on the containing site.

I've tried using postMessage to create a message channel from the content script to an offscreen document spawned from the extension's service worker (with the help of an iframe).

Then I transferred the offscreen canvas from that canvas to a worker in the offscreen document.
In the worker, I tried calling a simple fillRect on the offscreen canvas but that results in my extension crashing without the ability to see any logs (all inspector windows related to the extension close immediately upon the drawing call).

Is this flow supported or is there something I'm doing wrong?

woxxom

unread,
Jun 1, 2025, 9:33:51 PMJun 1
to Chromium Extensions, Bob Numan
Assuming you've used the web platform MessageChannel as shown in https://stackoverflow.com/a/68689866 correctly, I guess the OffscreenCanvas must be transferred i.e. port.postMessage(canvas, [canvas]). BTW, consider not using an offscreen document and instead create a Worker inside the web_accessible_resources iframe directly, which is simpler in case its initialization is fast, otherwise it would make more sense to have such workers be kept in a long running offscreen document and reused/terminated as necessary.

Bob Numan

unread,
Jun 2, 2025, 12:36:04 PMJun 2
to Chromium Extensions, woxxom, Bob Numan
Thanks for the suggestion. I was transferring the OffscreenCanvas through postMessage the way you mentioned.
I've also tried your recommendation of creating an iframe in the page that loads a web_accessible_resource instead of using an offscreen document. 

So the transfer of the offscreen canvas goes like this: content script --> iframe with extension's bundled page --> Worker spawned from iframe.

When I tried to call a drawing function in the worker, the iframe unloaded itself (presumably crashes) without any error messages (inspecting the iframe shows).

Chrome's console did log this:

[16548:21132:0602/221839.401:ERROR:content\browser\renderer_host\render_process_host_impl.cc:5707] Terminating render process for bad Mojo message: Received bad user message: Invalid client ID
[16548:21132:0602/221839.401:ERROR:content\browser\bad_message.cc:29] Terminating renderer for bad IPC message, reason 123

Could this be because drawing on OffscreenCanvases across origins is not allowed? (I'm not sure if that's an actual restriction, pretty new to offscreen canvases)


woxxom

unread,
Jun 2, 2025, 1:34:36 PMJun 2
to Chromium Extensions, Bob Numan, woxxom
Indeed, a canvas is locked to an origin, judging by that dreaded "tainted canvas" error. Try passing the blob obtained via canvas.convertToBlob(), then recreate the canvas in a worker from this blob via createImageBitmap. Note that blobs don't need to be listed in the second parameter of postMessage as they are just tiny handles to the actual data and thus sent instantly.

Bob Numan

unread,
Jun 3, 2025, 9:46:22 AMJun 3
to Chromium Extensions, woxxom, Bob Numan
Thanks, looks like that approach is the way to go
Reply all
Reply to author
Forward
0 new messages