diff options
author | Alan Jeffrey <ajeffrey@mozilla.com> | 2017-04-03 14:35:57 -0500 |
---|---|---|
committer | Alan Jeffrey <ajeffrey@mozilla.com> | 2017-06-07 13:49:30 -0500 |
commit | fd17dcd60442e71f75010a34c6bcfe1c04aca3e5 (patch) | |
tree | e367aa4202f2da0e6e0dac33fbdcd9ca48e2f92f /components/script/dom/worklet.rs | |
parent | 7e273d6c9b86d6ffbf216e84ae7326976888e5ef (diff) | |
download | servo-fd17dcd60442e71f75010a34c6bcfe1c04aca3e5.tar.gz servo-fd17dcd60442e71f75010a34c6bcfe1c04aca3e5.zip |
Implemented the plumbing for paint worklets.
Diffstat (limited to 'components/script/dom/worklet.rs')
-rw-r--r-- | components/script/dom/worklet.rs | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index fa5b3950b51..da74215f752 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -10,6 +10,7 @@ //! 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 dom::bindings::codegen::Bindings::RequestBinding::RequestCredentials; use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods; use dom::bindings::codegen::Bindings::WorkletBinding::WorkletMethods; @@ -27,6 +28,7 @@ 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; @@ -35,6 +37,7 @@ use dom::workletglobalscope::WorkletGlobalScopeInit; use dom::workletglobalscope::WorkletGlobalScopeType; use dom::workletglobalscope::WorkletTask; use dom_struct::dom_struct; +use euclid::Size2D; use js::jsapi::JSGCParamKey; use js::jsapi::JSTracer; use js::jsapi::JS_GC; @@ -42,6 +45,7 @@ use js::jsapi::JS_GetGCParameter; use js::rust::Runtime; use msg::constellation_msg::PipelineId; use net_traits::IpcSend; +use net_traits::image::base::Image; use net_traits::load_whole_resource; use net_traits::request::Destination; use net_traits::request::RequestInit; @@ -54,6 +58,9 @@ use script_runtime::new_rt_and_cx; use script_thread::MainThreadScriptMsg; use script_thread::Runnable; use script_thread::ScriptThread; +use script_traits::PaintWorkletError; +use script_traits::PaintWorkletExecutor; +use servo_atoms::Atom; use servo_rand; use servo_url::ImmutableOrigin; use servo_url::ServoUrl; @@ -62,12 +69,14 @@ 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; use std::sync::mpsc::Receiver; use std::sync::mpsc::Sender; use std::thread; +use std::time::Duration; use style::thread_state; use swapper::Swapper; use swapper::swapper; @@ -76,6 +85,7 @@ use uuid::Uuid; // Magic numbers const WORKLET_THREAD_POOL_SIZE: u32 = 3; const MIN_GC_THRESHOLD: u32 = 1_000_000; +const PAINT_TIMEOUT_MILLISECONDS: u64 = 10; #[dom_struct] /// https://drafts.css-houdini.org/worklets/#worklet @@ -109,6 +119,13 @@ 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 { @@ -561,7 +578,8 @@ impl WorkletThread { // TODO: Caching. // TODO: Avoid re-parsing the origin as a URL. let resource_fetcher = self.global_init.resource_threads.sender(); - let origin_url = ServoUrl::parse(&*origin.unicode_serialization()).expect("Failed to parse origin as URL."); + let origin_url = ServoUrl::parse(&*origin.unicode_serialization()) + .unwrap_or_else(|_| ServoUrl::parse("about:blank").unwrap()); let request = RequestInit { url: script_url, type_: RequestType::Script, @@ -635,3 +653,35 @@ impl WorkletThread { self.script_sender.send(msg).expect("Worklet thread outlived script thread."); } } + +/// An executor of worklet tasks +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>>, +} + +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)); + } +} + +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>) + -> Result<Image, PaintWorkletError> + { + let (sender, receiver) = mpsc::channel(); + let task = WorkletTask::Paint(PaintWorkletTask::DrawAPaintImage(name, concrete_object_size, sender)); + let timeout = Duration::from_millis(PAINT_TIMEOUT_MILLISECONDS); + self.schedule_a_worklet_task(task); + receiver.recv_timeout(timeout)? + } +} |