mirror of
https://github.com/servo/servo.git
synced 2025-07-23 23:33:43 +01:00
Implemented paint worklet properties.
This commit is contained in:
parent
de331c6bc8
commit
ef033b8362
29 changed files with 353 additions and 118 deletions
|
@ -10,8 +10,6 @@
|
|||
//! thread pool implementation, which only performs GC or code loading on
|
||||
//! a backup thread, not on the primary worklet thread.
|
||||
|
||||
use app_units::Au;
|
||||
use canvas_traits::CanvasData;
|
||||
use dom::bindings::codegen::Bindings::RequestBinding::RequestCredentials;
|
||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
|
||||
use dom::bindings::codegen::Bindings::WorkletBinding::WorkletMethods;
|
||||
|
@ -29,7 +27,6 @@ use dom::bindings::str::USVString;
|
|||
use dom::bindings::trace::JSTraceable;
|
||||
use dom::bindings::trace::RootedTraceableBox;
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom::paintworkletglobalscope::PaintWorkletTask;
|
||||
use dom::promise::Promise;
|
||||
use dom::testworkletglobalscope::TestWorkletTask;
|
||||
use dom::window::Window;
|
||||
|
@ -38,8 +35,6 @@ use dom::workletglobalscope::WorkletGlobalScopeInit;
|
|||
use dom::workletglobalscope::WorkletGlobalScopeType;
|
||||
use dom::workletglobalscope::WorkletTask;
|
||||
use dom_struct::dom_struct;
|
||||
use euclid::Size2D;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use js::jsapi::JSGCParamKey;
|
||||
use js::jsapi::JSTracer;
|
||||
use js::jsapi::JS_GC;
|
||||
|
@ -59,8 +54,6 @@ use script_runtime::new_rt_and_cx;
|
|||
use script_thread::MainThreadScriptMsg;
|
||||
use script_thread::Runnable;
|
||||
use script_thread::ScriptThread;
|
||||
use script_traits::PaintWorkletExecutor;
|
||||
use servo_atoms::Atom;
|
||||
use servo_rand;
|
||||
use servo_url::ImmutableOrigin;
|
||||
use servo_url::ServoUrl;
|
||||
|
@ -69,7 +62,6 @@ use std::collections::HashMap;
|
|||
use std::collections::hash_map;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::atomic::AtomicIsize;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::mpsc;
|
||||
|
@ -117,13 +109,6 @@ impl Worklet {
|
|||
pub fn worklet_global_scope_type(&self) -> WorkletGlobalScopeType {
|
||||
self.global_type
|
||||
}
|
||||
|
||||
pub fn executor(&self) -> WorkletExecutor {
|
||||
WorkletExecutor {
|
||||
worklet_id: self.worklet_id,
|
||||
primary_sender: Mutex::new(ScriptThread::worklet_thread_pool().primary_sender.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WorkletMethods for Worklet {
|
||||
|
@ -268,7 +253,7 @@ impl Drop for WorkletThreadPool {
|
|||
impl WorkletThreadPool {
|
||||
/// Create a new thread pool and spawn the threads.
|
||||
/// When the thread pool is dropped, the threads will be asked to quit.
|
||||
pub fn spawn(script_sender: Sender<MainThreadScriptMsg>, global_init: WorkletGlobalScopeInit) -> WorkletThreadPool {
|
||||
pub fn spawn(global_init: WorkletGlobalScopeInit) -> WorkletThreadPool {
|
||||
let primary_role = WorkletThreadRole::new(false, false);
|
||||
let hot_backup_role = WorkletThreadRole::new(true, false);
|
||||
let cold_backup_role = WorkletThreadRole::new(false, true);
|
||||
|
@ -276,9 +261,9 @@ impl WorkletThreadPool {
|
|||
let hot_backup_sender = hot_backup_role.sender.clone();
|
||||
let cold_backup_sender = cold_backup_role.sender.clone();
|
||||
let init = WorkletThreadInit {
|
||||
primary_sender: primary_sender.clone(),
|
||||
hot_backup_sender: hot_backup_sender.clone(),
|
||||
cold_backup_sender: cold_backup_sender.clone(),
|
||||
script_sender: script_sender.clone(),
|
||||
global_init: global_init,
|
||||
};
|
||||
WorkletThreadPool {
|
||||
|
@ -388,9 +373,9 @@ impl WorkletThreadRole {
|
|||
#[derive(Clone)]
|
||||
struct WorkletThreadInit {
|
||||
/// Senders
|
||||
primary_sender: Sender<WorkletData>,
|
||||
hot_backup_sender: Sender<WorkletData>,
|
||||
cold_backup_sender: Sender<WorkletData>,
|
||||
script_sender: Sender<MainThreadScriptMsg>,
|
||||
|
||||
/// Data for initializing new worklet global scopes
|
||||
global_init: WorkletGlobalScopeInit,
|
||||
|
@ -406,9 +391,9 @@ struct WorkletThread {
|
|||
control_receiver: Receiver<WorkletControl>,
|
||||
|
||||
/// Senders
|
||||
primary_sender: Sender<WorkletData>,
|
||||
hot_backup_sender: Sender<WorkletData>,
|
||||
cold_backup_sender: Sender<WorkletData>,
|
||||
script_sender: Sender<MainThreadScriptMsg>,
|
||||
|
||||
/// Data for initializing new worklet global scopes
|
||||
global_init: WorkletGlobalScopeInit,
|
||||
|
@ -451,9 +436,9 @@ impl WorkletThread {
|
|||
let mut thread = RootedTraceableBox::new(WorkletThread {
|
||||
role: role,
|
||||
control_receiver: control_receiver,
|
||||
primary_sender: init.primary_sender,
|
||||
hot_backup_sender: init.hot_backup_sender,
|
||||
cold_backup_sender: init.cold_backup_sender,
|
||||
script_sender: init.script_sender,
|
||||
global_init: init.global_init,
|
||||
global_scopes: HashMap::new(),
|
||||
control_buffer: None,
|
||||
|
@ -562,7 +547,8 @@ impl WorkletThread {
|
|||
hash_map::Entry::Occupied(entry) => Root::from_ref(entry.get()),
|
||||
hash_map::Entry::Vacant(entry) => {
|
||||
debug!("Creating new worklet global scope.");
|
||||
let result = global_type.new(&self.runtime, pipeline_id, base_url, &self.global_init);
|
||||
let executor = WorkletExecutor::new(worklet_id, self.primary_sender.clone());
|
||||
let result = global_type.new(&self.runtime, pipeline_id, base_url, executor, &self.global_init);
|
||||
entry.insert(JS::from_ref(&*result));
|
||||
result
|
||||
},
|
||||
|
@ -626,7 +612,7 @@ impl WorkletThread {
|
|||
if old_counter == 1 {
|
||||
debug!("Resolving promise.");
|
||||
let msg = MainThreadScriptMsg::WorkletLoaded(pipeline_id);
|
||||
self.script_sender.send(msg).expect("Worklet thread outlived script thread.");
|
||||
self.global_init.script_sender.send(msg).expect("Worklet thread outlived script thread.");
|
||||
self.run_in_script_thread(promise.resolve_runnable(()));
|
||||
}
|
||||
}
|
||||
|
@ -668,35 +654,28 @@ impl WorkletThread {
|
|||
{
|
||||
let msg = CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::WorkletEvent, box runnable);
|
||||
let msg = MainThreadScriptMsg::Common(msg);
|
||||
self.script_sender.send(msg).expect("Worklet thread outlived script thread.");
|
||||
self.global_init.script_sender.send(msg).expect("Worklet thread outlived script thread.");
|
||||
}
|
||||
}
|
||||
|
||||
/// An executor of worklet tasks
|
||||
#[derive(Clone, JSTraceable, HeapSizeOf)]
|
||||
pub struct WorkletExecutor {
|
||||
worklet_id: WorkletId,
|
||||
// Rather annoyingly, we have to use a mutex here because
|
||||
// layout threads share their context rather than cloning it.
|
||||
primary_sender: Mutex<Sender<WorkletData>>,
|
||||
#[ignore_heap_size_of = "channels are hard"]
|
||||
primary_sender: Sender<WorkletData>,
|
||||
}
|
||||
|
||||
impl WorkletExecutor {
|
||||
/// Schedule a worklet task to be peformed by the worklet thread pool.
|
||||
fn schedule_a_worklet_task(&self, task: WorkletTask) {
|
||||
let _ = self.primary_sender.lock()
|
||||
.expect("Locking the worklet channel.")
|
||||
.send(WorkletData::Task(self.worklet_id, task));
|
||||
fn new(worklet_id: WorkletId, primary_sender: Sender<WorkletData>) -> WorkletExecutor {
|
||||
WorkletExecutor {
|
||||
worklet_id: worklet_id,
|
||||
primary_sender: primary_sender,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PaintWorkletExecutor for WorkletExecutor {
|
||||
/// https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image
|
||||
fn draw_a_paint_image(&self,
|
||||
name: Atom,
|
||||
concrete_object_size: Size2D<Au>,
|
||||
sender: IpcSender<CanvasData>)
|
||||
{
|
||||
let task = WorkletTask::Paint(PaintWorkletTask::DrawAPaintImage(name, concrete_object_size, sender));
|
||||
self.schedule_a_worklet_task(task);
|
||||
/// Schedule a worklet task to be peformed by the worklet thread pool.
|
||||
pub fn schedule_a_worklet_task(&self, task: WorkletTask) {
|
||||
let _ = self.primary_sender.send(WorkletData::Task(self.worklet_id, task));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue