Auto merge of #26296 - ramyananth:master, r=jdm

Implementing createImageBitmap

<!-- Please describe your changes on the following line: -->
Implementing createImageBitmap method for canvas image source.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #20650 (GitHub issue number if applicable)

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
bors-servo 2020-04-30 12:05:21 -04:00 committed by GitHub
commit 39e4eb43c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
73 changed files with 340 additions and 46 deletions

View file

@ -5,6 +5,9 @@
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::BroadcastChannelBinding::BroadcastChannelMethods;
use crate::dom::bindings::codegen::Bindings::EventSourceBinding::EventSourceBinding::EventSourceMethods;
use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{
ImageBitmapOptions, ImageBitmapSource,
};
use crate::dom::bindings::codegen::Bindings::PermissionStatusBinding::PermissionState;
use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
@ -31,6 +34,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::file::File;
use crate::dom::htmlscriptelement::ScriptId;
use crate::dom::identityhub::Identities;
use crate::dom::imagebitmap::ImageBitmap;
use crate::dom::messageevent::MessageEvent;
use crate::dom::messageport::MessagePort;
use crate::dom::paintworkletglobalscope::PaintWorkletGlobalScope;
@ -41,7 +45,7 @@ use crate::dom::window::Window;
use crate::dom::workerglobalscope::WorkerGlobalScope;
use crate::dom::workletglobalscope::WorkletGlobalScope;
use crate::microtask::{Microtask, MicrotaskQueue, UserMicrotask};
use crate::realms::{enter_realm, InRealm};
use crate::realms::{enter_realm, AlreadyInRealm, InRealm};
use crate::script_module::ModuleTree;
use crate::script_runtime::{CommonScriptMsg, JSContext as SafeJSContext, ScriptChan, ScriptPort};
use crate::script_thread::{MainThreadScriptChan, ScriptThread};
@ -2227,6 +2231,71 @@ impl GlobalScope {
}))
}
pub fn create_image_bitmap(
&self,
image: ImageBitmapSource,
options: &ImageBitmapOptions,
) -> Rc<Promise> {
let in_realm_proof = AlreadyInRealm::assert(&self);
let p = Promise::new_in_current_realm(&self, InRealm::Already(&in_realm_proof));
if options.resizeWidth.map_or(false, |w| w == 0) {
p.reject_error(Error::InvalidState);
return p;
}
if options.resizeHeight.map_or(false, |w| w == 0) {
p.reject_error(Error::InvalidState);
return p;
}
let promise = match image {
ImageBitmapSource::HTMLCanvasElement(ref canvas) => {
// https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument
if !canvas.is_valid() {
p.reject_error(Error::InvalidState);
return p;
}
if let Some((data, size)) = canvas.fetch_all_data() {
let data = data
.map(|data| data.to_vec())
.unwrap_or_else(|| vec![0; size.area() as usize * 4]);
let image_bitmap = ImageBitmap::new(&self, size.width, size.height).unwrap();
image_bitmap.set_bitmap_data(data);
image_bitmap.set_origin_clean(canvas.origin_is_clean());
p.resolve_native(&(image_bitmap));
}
p
},
ImageBitmapSource::OffscreenCanvas(ref canvas) => {
// https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument
if !canvas.is_valid() {
p.reject_error(Error::InvalidState);
return p;
}
if let Some((data, size)) = canvas.fetch_all_data() {
let data = data
.map(|data| data.to_vec())
.unwrap_or_else(|| vec![0; size.area() as usize * 4]);
let image_bitmap = ImageBitmap::new(&self, size.width, size.height).unwrap();
image_bitmap.set_bitmap_data(data);
image_bitmap.set_origin_clean(canvas.origin_is_clean());
p.resolve_native(&(image_bitmap));
}
p
},
_ => {
p.reject_error(Error::NotSupported);
return p;
},
};
promise
}
pub fn fire_timer(&self, handle: TimerEventId) {
self.timers.fire_timer(handle, self);
}

View file

@ -12,6 +12,7 @@ use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use dom_struct::dom_struct;
use std::cell::Cell;
use std::vec::Vec;
#[dom_struct]
@ -20,6 +21,7 @@ pub struct ImageBitmap {
width: u32,
height: u32,
bitmap_data: DomRefCell<Vec<u8>>,
origin_clean: Cell<bool>,
}
impl ImageBitmap {
@ -29,6 +31,7 @@ impl ImageBitmap {
width: width_arg,
height: height_arg,
bitmap_data: DomRefCell::new(vec![]),
origin_clean: Cell::new(true),
}
}
@ -39,6 +42,14 @@ impl ImageBitmap {
Ok(reflect_dom_object(imagebitmap, global))
}
pub fn set_bitmap_data(&self, data: Vec<u8>) {
*self.bitmap_data.borrow_mut() = data;
}
pub fn set_origin_clean(&self, origin_is_clean: bool) {
self.origin_clean.set(origin_is_clean);
}
}
impl ImageBitmapMethods for ImageBitmap {

View file

@ -24,7 +24,7 @@ interface mixin WindowOrWorkerGlobalScope {
void queueMicrotask(VoidFunction callback);
// ImageBitmap
// Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options);
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options = {});
// Promise<ImageBitmap> createImageBitmap(
// ImageBitmapSource image, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options);
};

View file

@ -7,6 +7,9 @@ use crate::dom::bindings::codegen::Bindings::DocumentBinding::{
DocumentMethods, DocumentReadyState,
};
use crate::dom::bindings::codegen::Bindings::HistoryBinding::HistoryBinding::HistoryMethods;
use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{
ImageBitmapOptions, ImageBitmapSource,
};
use crate::dom::bindings::codegen::Bindings::MediaQueryListBinding::MediaQueryListBinding::MediaQueryListMethods;
use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
@ -889,6 +892,18 @@ impl WindowMethods for Window {
.queue_function_as_microtask(callback);
}
// https://html.spec.whatwg.org/multipage/#dom-createimagebitmap
fn CreateImageBitmap(
&self,
image: ImageBitmapSource,
options: &ImageBitmapOptions,
) -> Rc<Promise> {
let p = self
.upcast::<GlobalScope>()
.create_image_bitmap(image, options);
p
}
// https://html.spec.whatwg.org/multipage/#dom-window
fn Window(&self) -> DomRoot<WindowProxy> {
self.window_proxy()

View file

@ -3,6 +3,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{
ImageBitmapOptions, ImageBitmapSource,
};
use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
use crate::dom::bindings::codegen::Bindings::WorkerBinding::WorkerType;
@ -348,6 +351,18 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
.queue_function_as_microtask(callback);
}
// https://html.spec.whatwg.org/multipage/#dom-createimagebitmap
fn CreateImageBitmap(
&self,
image: ImageBitmapSource,
options: &ImageBitmapOptions,
) -> Rc<Promise> {
let p = self
.upcast::<GlobalScope>()
.create_image_bitmap(image, options);
p
}
#[allow(unrooted_must_root)]
// https://fetch.spec.whatwg.org/#fetch-method
fn Fetch(

View file

@ -1,4 +0,0 @@
[hit-test-floats-001.html]
[hit-test-floats-001]
expected: FAIL

View file

@ -1,2 +0,0 @@
[trailing-other-space-separators-break-spaces-004.html]
expected: FAIL

View file

@ -8,3 +8,6 @@
[throws if handleEvent is thruthy and not callable]
expected: FAIL
[looks up handleEvent method on every event dispatch]
expected: FAIL

View file

@ -14,3 +14,6 @@
[<li>Outside 3</li>]
expected: FAIL
[<li>Image Inside 2</li>]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -59,3 +59,6 @@
[separate text/javascript;charset=windows-1252 error text/javascript]
expected: FAIL
[separate text/javascript;charset=windows-1252 text/javascript]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_5.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -41,6 +41,3 @@
[Window replaceable attribute: screenLeft]
expected: FAIL
[Window method: createImageBitmap]
expected: FAIL

View file

@ -1819,9 +1819,6 @@
[Window interface: operation createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions)]
expected: FAIL
[Window interface: window must inherit property "createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions)" with the proper type]
expected: FAIL
[Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on new Document() with too few arguments must throw TypeError]
expected: FAIL
@ -1831,9 +1828,6 @@
[Document interface: new Document() must inherit property "execCommand(DOMString, optional boolean, optional DOMString)" with the proper type]
expected: FAIL
[Window interface: window must inherit property "createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions)" with the proper type]
expected: FAIL
[Document interface: calling execCommand(DOMString, optional boolean, optional DOMString) on iframe.contentDocument with too few arguments must throw TypeError]
expected: FAIL

View file

@ -494,9 +494,6 @@
[OffscreenCanvasRenderingContext2D interface: operation fill(optional CanvasFillRule)]
expected: FAIL
[WorkerGlobalScope interface: self must inherit property "createImageBitmap(ImageBitmapSource, long, long, long, long, optional ImageBitmapOptions)" with the proper type]
expected: FAIL
[OffscreenCanvasRenderingContext2D interface: operation isPointInPath(unrestricted double, unrestricted double, optional CanvasFillRule)]
expected: FAIL
@ -551,9 +548,6 @@
[Path2D interface: operation addPath(Path2D, optional DOMMatrix2DInit)]
expected: FAIL
[WorkerGlobalScope interface: self must inherit property "createImageBitmap(ImageBitmapSource, optional ImageBitmapOptions)" with the proper type]
expected: FAIL
[OffscreenCanvasRenderingContext2D interface: operation clip(optional CanvasFillRule)]
expected: FAIL

View file

@ -11,9 +11,6 @@
[Serialize should throw before a detached MessagePort is found]
expected: FAIL
[Cannot transfer the same ImageBitmap twice]
expected: FAIL
[Serialize should make the ImageBitmap detached, so it cannot be transferred again]
expected: FAIL

View file

@ -1,4 +0,0 @@
[DOMContentLoaded-defer.html]
[The end: DOMContentLoaded and defer scripts]
expected: FAIL

View file

@ -1,9 +1,10 @@
[promise-job-entry-different-function-realm.html]
expected: TIMEOUT
[Fulfillment handler on fulfilled promise]
expected: FAIL
[Rejection handler on pending-then-rejected promise]
expected: FAIL
expected: TIMEOUT
[Thenable resolution]
expected: FAIL
@ -12,5 +13,5 @@
expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise]
expected: FAIL
expected: TIMEOUT

View file

@ -21,6 +21,3 @@
[unhandledrejection: from createImageBitmap which is UA triggered]
expected: FAIL
[no unhandledrejection/rejectionhandled: rejection handler attached synchronously to a promise created from createImageBitmap]
expected: FAIL

View file

@ -5,6 +5,3 @@
[unhandledrejection: from createImageBitmap which is UA triggered]
expected: FAIL
[no unhandledrejection/rejectionhandled: rejection handler attached synchronously to a promise created from createImageBitmap]
expected: FAIL

View file

@ -42,6 +42,3 @@
[Test that convertToBlob with default arguments produces correct result in a worker]
expected: FAIL
[Test that call convertToBlob on a OffscreenCanvas with tainted origin throws exception in a worker]
expected: FAIL

View file

@ -1,5 +1,4 @@
[offscreencanvas.filter.w.html]
expected: ERROR
[offscreencanvas]
expected: FAIL

View file

@ -1,4 +1,5 @@
[realtimeanalyser-fft-scaling.html]
expected: TIMEOUT
[X 2048-point FFT peak position is not equal to 64. Got 0.]
expected: FAIL

View file

@ -1,4 +1,5 @@
[audiocontextoptions.html]
expected: CRASH
[X context = new AudioContext({sampleRate: 1}) did not throw an exception.]
expected: FAIL

View file

@ -0,0 +1,2 @@
[Worker-constructor.html]
expected: ERROR

View file

@ -0,0 +1,4 @@
[tex-2d-alpha-alpha-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-luminance-luminance-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgb-rgb-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgb-rgb-unsigned_short_5_6_5.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,5 @@
[tex-2d-alpha-alpha-unsigned_byte.html]
expected: ERROR
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-luminance-luminance-unsigned_byte.html]
expected: ERROR
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html]
expected: ERROR
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgb-rgb-unsigned_byte.html]
expected: ERROR
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgb-rgb-unsigned_short_5_6_5.html]
expected: ERROR
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgba-rgba-unsigned_byte.html]
expected: ERROR
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html]
expected: ERROR
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html]
expected: ERROR
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,4 @@
[tex-2d-alpha-alpha-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-luminance-luminance-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgb-rgb-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgb-rgb-unsigned_short_5_6_5.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-alpha-alpha-unsigned_byte.html]
[WebGL test #1: createImageBitmap(imageData) should succeed.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-luminance-luminance-unsigned_byte.html]
[WebGL test #1: createImageBitmap(imageData) should succeed.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html]
[WebGL test #1: createImageBitmap(imageData) should succeed.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgb-rgb-unsigned_byte.html]
[WebGL test #1: createImageBitmap(imageData) should succeed.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgb-rgb-unsigned_short_5_6_5.html]
[WebGL test #1: createImageBitmap(imageData) should succeed.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_byte.html]
[WebGL test #1: createImageBitmap(imageData) should succeed.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html]
[WebGL test #1: createImageBitmap(imageData) should succeed.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html]
[WebGL test #1: createImageBitmap(imageData) should succeed.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-alpha-alpha-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-luminance-luminance-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgb-rgb-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgb-rgb-unsigned_short_5_6_5.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_byte.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,4 @@
[tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html]
[WebGL test #1: createImageBitmap(source) failed: "The operation is not supported."]
expected: FAIL

View file

@ -0,0 +1,5 @@
[tex-2d-alpha-alpha-unsigned_byte.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-luminance-luminance-unsigned_byte.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgb-rgb-unsigned_byte.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgb-rgb-unsigned_short_5_6_5.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgba-rgba-unsigned_byte.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN