mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Implemented paint worklet rendering context.
This commit is contained in:
parent
d47de6ccfc
commit
328fb25a65
15 changed files with 547 additions and 110 deletions
|
@ -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)?
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue