imagebitmap: Resolve promise with ImageBitmap on bitmap task source (#37488)

Follow the ImageBitmap specification and use the global scope bitmap
task source
to fulfill resolved promise (asynchronously). 
https://html.spec.whatwg.org/multipage/#bitmap-task-source

Any promise rejection must be done synchronously.

Testing: Improvements in the following WPT test
-
html/canvas/element/manual/imagebitmap/createImageBitmap-resolves-in-task.any.js

Fixes (partially): #34112

Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
This commit is contained in:
Andrei Volykhin 2025-06-17 11:19:32 +03:00 committed by GitHub
parent ef5e9b5f4d
commit 1bd8f38810
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 38 additions and 30 deletions

View file

@ -3009,6 +3009,22 @@ impl GlobalScope {
return p;
}
// The promise with image bitmap should be fulfilled on the the bitmap task source.
let fullfill_promise_on_bitmap_task_source =
|promise: &Rc<Promise>, image_bitmap: &ImageBitmap| {
let trusted_promise = TrustedPromise::new(promise.clone());
let trusted_image_bitmap = Trusted::new(image_bitmap);
self.task_manager()
.bitmap_task_source()
.queue(task!(resolve_promise: move || {
let promise = trusted_promise.root();
let image_bitmap = trusted_image_bitmap.root();
promise.resolve_native(&image_bitmap, CanGc::note());
}));
};
// Step 3. Check the usability of the image argument. If this throws an exception or returns bad,
// then return a promise rejected with an "InvalidStateError" DOMException.
// Step 6. Switch on image:
@ -3065,7 +3081,9 @@ impl GlobalScope {
// of imageBitmap's bitmap to false.
image_bitmap.set_origin_clean(image.same_origin(GlobalScope::entry().origin()));
p.resolve_native(&image_bitmap, can_gc);
// Step 6.5. Queue a global task, using the bitmap task source,
// to resolve promise with imageBitmap.
fullfill_promise_on_bitmap_task_source(&p, &image_bitmap);
},
ImageBitmapSource::HTMLVideoElement(ref video) => {
// <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument>
@ -3103,7 +3121,9 @@ impl GlobalScope {
// of imageBitmap's bitmap to false.
image_bitmap.set_origin_clean(video.origin_is_clean());
p.resolve_native(&image_bitmap, can_gc);
// Step 6.4. Queue a global task, using the bitmap task source,
// to resolve promise with imageBitmap.
fullfill_promise_on_bitmap_task_source(&p, &image_bitmap);
},
ImageBitmapSource::HTMLCanvasElement(ref canvas) => {
// <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument>
@ -3132,7 +3152,9 @@ impl GlobalScope {
// as the origin-clean flag of image's bitmap.
image_bitmap.set_origin_clean(canvas.origin_is_clean());
p.resolve_native(&image_bitmap, can_gc);
// Step 6.3. Queue a global task, using the bitmap task source,
// to resolve promise with imageBitmap.
fullfill_promise_on_bitmap_task_source(&p, &image_bitmap);
},
ImageBitmapSource::ImageBitmap(ref bitmap) => {
// <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument>
@ -3161,7 +3183,9 @@ impl GlobalScope {
// as the origin-clean flag of image's bitmap.
image_bitmap.set_origin_clean(bitmap.origin_is_clean());
p.resolve_native(&image_bitmap, can_gc);
// Step 6.3. Queue a global task, using the bitmap task source,
// to resolve promise with imageBitmap.
fullfill_promise_on_bitmap_task_source(&p, &image_bitmap);
},
ImageBitmapSource::OffscreenCanvas(ref canvas) => {
// <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument>
@ -3190,7 +3214,9 @@ impl GlobalScope {
// as the origin-clean flag of image's bitmap.
image_bitmap.set_origin_clean(canvas.origin_is_clean());
p.resolve_native(&image_bitmap, can_gc);
// Step 6.3. Queue a global task, using the bitmap task source,
// to resolve promise with imageBitmap.
fullfill_promise_on_bitmap_task_source(&p, &image_bitmap);
},
ImageBitmapSource::Blob(_) => {
// TODO: implement support of Blob object as ImageBitmapSource
@ -3227,7 +3253,9 @@ impl GlobalScope {
let image_bitmap = ImageBitmap::new(self, bitmap_data, can_gc);
p.resolve_native(&image_bitmap, can_gc);
// Step 6.4. Queue a global task, using the bitmap task source,
// to resolve promise with imageBitmap.
fullfill_promise_on_bitmap_task_source(&p, &image_bitmap);
},
ImageBitmapSource::CSSStyleValue(_) => {
// TODO: CSSStyleValue is not part of ImageBitmapSource