Proxy all WR interactions for layout/font/script/canvas threads to the compositor

thread. There is now a single RenderApi that is used, and all transactions are serialized
through the compositor.
This commit is contained in:
Josh Matthews 2020-06-08 13:53:33 -04:00
parent a6016b3a62
commit 75efaa95f5
16 changed files with 344 additions and 261 deletions

View file

@ -12,35 +12,52 @@ use ipc_channel::router::ROUTER;
use std::borrow::ToOwned;
use std::collections::HashMap;
use std::thread;
use webrender_api::{ImageData, ImageDescriptor, ImageKey};
pub enum AntialiasMode {
Default,
None,
}
pub enum ImageUpdate {
Add(ImageKey, ImageDescriptor, ImageData),
Update(ImageKey, ImageDescriptor, ImageData),
Delete(ImageKey),
}
pub trait WebrenderApi {
fn generate_key(&self) -> webrender_api::ImageKey;
fn update_images(&self, updates: Vec<ImageUpdate>);
fn clone(&self) -> Box<dyn WebrenderApi>;
}
pub struct CanvasPaintThread<'a> {
canvases: HashMap<CanvasId, CanvasData<'a>>,
next_canvas_id: CanvasId,
webrender_api: Box<dyn WebrenderApi>,
}
impl<'a> CanvasPaintThread<'a> {
fn new() -> CanvasPaintThread<'a> {
fn new(webrender_api: Box<dyn WebrenderApi>) -> CanvasPaintThread<'a> {
CanvasPaintThread {
canvases: HashMap::new(),
next_canvas_id: CanvasId(0),
webrender_api,
}
}
/// Creates a new `CanvasPaintThread` and returns an `IpcSender` to
/// communicate with it.
pub fn start() -> (Sender<ConstellationCanvasMsg>, IpcSender<CanvasMsg>) {
pub fn start(
webrender_api: Box<dyn WebrenderApi + Send>,
) -> (Sender<ConstellationCanvasMsg>, IpcSender<CanvasMsg>) {
let (ipc_sender, ipc_receiver) = ipc::channel::<CanvasMsg>().unwrap();
let msg_receiver = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(ipc_receiver);
let (create_sender, create_receiver) = unbounded();
thread::Builder::new()
.name("CanvasThread".to_owned())
.spawn(move || {
let mut canvas_paint_thread = CanvasPaintThread::new();
let mut canvas_paint_thread = CanvasPaintThread::new(webrender_api);
loop {
select! {
recv(msg_receiver) -> msg => {
@ -74,16 +91,9 @@ impl<'a> CanvasPaintThread<'a> {
Ok(ConstellationCanvasMsg::Create {
id_sender: creator,
size,
webrender_sender: webrenderer_api_sender,
webrender_doc,
antialias
}) => {
let canvas_id = canvas_paint_thread.create_canvas(
size,
webrenderer_api_sender,
webrender_doc,
antialias,
);
let canvas_id = canvas_paint_thread.create_canvas(size, antialias);
creator.send(canvas_id).unwrap();
},
Ok(ConstellationCanvasMsg::Exit) => break,
@ -101,13 +111,7 @@ impl<'a> CanvasPaintThread<'a> {
(create_sender, ipc_sender)
}
pub fn create_canvas(
&mut self,
size: Size2D<u64>,
webrender_api_sender: webrender_api::RenderApiSender,
webrender_doc: webrender_api::DocumentId,
antialias: bool,
) -> CanvasId {
pub fn create_canvas(&mut self, size: Size2D<u64>, antialias: bool) -> CanvasId {
let antialias = if antialias {
AntialiasMode::Default
} else {
@ -119,8 +123,7 @@ impl<'a> CanvasPaintThread<'a> {
let canvas_data = CanvasData::new(
size,
webrender_api_sender,
webrender_doc,
self.webrender_api.clone(),
antialias,
canvas_id.clone(),
);