mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
97 lines
3.8 KiB
Rust
97 lines
3.8 KiB
Rust
/* 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>>)
|
|
}
|