diff options
Diffstat (limited to 'components/script/dom/worklet.rs')
-rw-r--r-- | components/script/dom/worklet.rs | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index e5e55b97453..bbcc777ab11 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -11,6 +11,7 @@ //! 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; @@ -38,6 +39,7 @@ 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; @@ -45,7 +47,6 @@ 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; @@ -58,7 +59,6 @@ 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; @@ -76,7 +76,6 @@ 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; @@ -85,7 +84,6 @@ 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 @@ -163,6 +161,7 @@ impl WorkletMethods for Worklet { &promise); // Step 5. + debug!("Returning promise."); promise } } @@ -234,6 +233,17 @@ impl PendingTasksStruct { /// The thread pool lives in the script thread, and is initialized /// when a worklet adds a module. It is dropped when the script thread /// is dropped, and asks each of the worklet threads to quit. +/// +/// The layout thread can end up blocking on the primary worklet thread +/// (e.g. when invoking a paint callback), so it is important to avoid +/// deadlock by making sure the primary worklet thread doesn't end up +/// blocking waiting on layout. In particular, since the constellation +/// can block waiting on layout, this means the primary worklet thread +/// can't block waiting on the constellation. In general, the primary +/// worklet thread shouldn't perform any blocking operations. If a worklet +/// thread needs to do anything blocking, it should send a control +/// message, to make sure that the blocking operation is performed +/// by a backup thread, not by the primary thread. #[derive(Clone, JSTraceable)] pub struct WorkletThreadPool { @@ -551,6 +561,7 @@ impl WorkletThread { match self.global_scopes.entry(worklet_id) { 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); entry.insert(JS::from_ref(&*result)); result @@ -562,6 +573,7 @@ impl WorkletThread { /// https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script fn fetch_and_invoke_a_worklet_script(&self, global_scope: &WorkletGlobalScope, + pipeline_id: PipelineId, origin: ImmutableOrigin, script_url: ServoUrl, credentials: RequestCredentials, @@ -612,7 +624,9 @@ impl WorkletThread { debug!("Finished adding script."); let old_counter = pending_tasks_struct.decrement_counter_by(1); if old_counter == 1 { - // TODO: trigger a reflow? + debug!("Resolving promise."); + let msg = MainThreadScriptMsg::WorkletLoaded(pipeline_id); + self.script_sender.send(msg).expect("Worklet thread outlived script thread."); self.run_in_script_thread(promise.resolve_runnable(())); } } @@ -638,6 +652,7 @@ impl WorkletThread { global_type, base_url); self.fetch_and_invoke_a_worklet_script(&*global, + pipeline_id, origin, script_url, credentials, @@ -678,13 +693,10 @@ 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> + concrete_object_size: Size2D<Au>, + sender: IpcSender<CanvasData>) { - 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)? } } |