aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/paintworkletglobalscope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/paintworkletglobalscope.rs')
-rw-r--r--components/script/dom/paintworkletglobalscope.rs97
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>>)
+}