diff options
Diffstat (limited to 'components/script/dom/paintworkletglobalscope.rs')
-rw-r--r-- | components/script/dom/paintworkletglobalscope.rs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs new file mode 100644 index 00000000000..6a4babe896d --- /dev/null +++ b/components/script/dom/paintworkletglobalscope.rs @@ -0,0 +1,97 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use app_units::Au; +use dom::bindings::cell::DOMRefCell; +use dom::bindings::codegen::Bindings::PaintWorkletGlobalScopeBinding; +use dom::bindings::codegen::Bindings::PaintWorkletGlobalScopeBinding::PaintWorkletGlobalScopeMethods; +use dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction; +use dom::bindings::js::Root; +use dom::bindings::str::DOMString; +use dom::workletglobalscope::WorkletGlobalScope; +use dom::workletglobalscope::WorkletGlobalScopeInit; +use dom_struct::dom_struct; +use euclid::Size2D; +use ipc_channel::ipc::IpcSharedMemory; +use js::rust::Runtime; +use msg::constellation_msg::PipelineId; +use net_traits::image::base::Image; +use net_traits::image::base::PixelFormat; +use script_traits::PaintWorkletError; +use servo_atoms::Atom; +use servo_url::ServoUrl; +use std::rc::Rc; +use std::sync::mpsc::Sender; + +#[dom_struct] +/// https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope +pub struct PaintWorkletGlobalScope { + /// The worklet global for this object + worklet_global: WorkletGlobalScope, + /// A buffer to draw into + buffer: DOMRefCell<Vec<u8>>, +} + +impl PaintWorkletGlobalScope { + #[allow(unsafe_code)] + pub fn new(runtime: &Runtime, + pipeline_id: PipelineId, + base_url: ServoUrl, + init: &WorkletGlobalScopeInit) + -> Root<PaintWorkletGlobalScope> { + debug!("Creating paint worklet global scope for pipeline {}.", pipeline_id); + let global = box PaintWorkletGlobalScope { + worklet_global: WorkletGlobalScope::new_inherited(pipeline_id, base_url, init), + buffer: Default::default(), + }; + unsafe { PaintWorkletGlobalScopeBinding::Wrap(runtime.cx(), global) } + } + + pub fn perform_a_worklet_task(&self, task: PaintWorkletTask) { + match task { + PaintWorkletTask::DrawAPaintImage(name, size, sender) => self.draw_a_paint_image(name, size, sender), + } + } + + fn draw_a_paint_image(&self, + name: Atom, + concrete_object_size: Size2D<Au>, + sender: Sender<Result<Image, PaintWorkletError>>) { + let width = concrete_object_size.width.to_px().abs() as u32; + let height = concrete_object_size.height.to_px().abs() as u32; + let area = (width as usize) * (height as usize); + let old_buffer_size = self.buffer.borrow().len(); + let new_buffer_size = area * 4; + debug!("Drawing a paint image {}({},{}).", name, width, height); + // TODO: call into script to create the image. + // For now, we just build a dummy. + if new_buffer_size > old_buffer_size { + let pixel = [0xFF, 0x00, 0x00, 0xFF]; + self.buffer.borrow_mut().extend(pixel.iter().cycle().take(new_buffer_size - old_buffer_size)); + } else { + self.buffer.borrow_mut().truncate(new_buffer_size); + } + let image = Image { + width: width, + height: height, + format: PixelFormat::RGBA8, + bytes: IpcSharedMemory::from_bytes(&*self.buffer.borrow()), + id: None, + }; + let _ = sender.send(Ok(image)); + } +} + +impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope { + /// https://drafts.css-houdini.org/css-paint-api/#dom-paintworkletglobalscope-registerpaint + fn RegisterPaint(&self, name: DOMString, _paintCtor: Rc<VoidFunction>) { + debug!("Registering paint image name {}.", name); + // TODO + } +} + +/// Tasks which can be peformed by a paint worklet +pub enum PaintWorkletTask { + DrawAPaintImage(Atom, Size2D<Au>, Sender<Result<Image, PaintWorkletError>>) +} |