Auto merge of #26823 - jdm:single-renderapi, r=asajeffrey

Update webrender

These changes reflect changes in webrender's API that make RenderApiSender and RenderApi objects more challenging to share. This PR moves us to a model where:
* the compositor owns the main RenderApi object
* other threads that need to create transactions or manipulate fonts proxy those operations to the compositor (script/layout use IPC, while other threads use non-IPC channels)
* the webgl thread owns its own independent RenderApi
This commit is contained in:
bors-servo 2020-06-09 19:34:08 -04:00 committed by GitHub
commit 7eacfa4f0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
51 changed files with 421 additions and 331 deletions

30
Cargo.lock generated
View file

@ -755,6 +755,7 @@ dependencies = [
name = "compositing"
version = "0.0.1"
dependencies = [
"app_units",
"canvas",
"crossbeam-channel",
"embedder_traits",
@ -1895,10 +1896,12 @@ dependencies = [
name = "gfx_traits"
version = "0.0.1"
dependencies = [
"app_units",
"malloc_size_of",
"malloc_size_of_derive",
"range",
"serde",
"webrender_api",
]
[[package]]
@ -3021,6 +3024,7 @@ dependencies = [
name = "libservo"
version = "0.0.1"
dependencies = [
"app_units",
"background_hang_monitor",
"bluetooth",
"bluetooth_traits",
@ -3037,6 +3041,7 @@ dependencies = [
"euclid",
"gaol",
"gfx",
"gfx_traits",
"gleam 0.11.0",
"gstreamer",
"ipc-channel",
@ -3934,7 +3939,7 @@ dependencies = [
[[package]]
name = "peek-poke"
version = "0.2.0"
source = "git+https://github.com/servo/webrender#01082a9091ab98c392af8934d04271eb1dd546df"
source = "git+https://github.com/servo/webrender#de3999583ab20aad7c57ea35a3e0394ed45be627"
dependencies = [
"euclid",
"peek-poke-derive 0.2.1 (git+https://github.com/servo/webrender)",
@ -3952,7 +3957,7 @@ dependencies = [
[[package]]
name = "peek-poke-derive"
version = "0.2.1"
source = "git+https://github.com/servo/webrender#01082a9091ab98c392af8934d04271eb1dd546df"
source = "git+https://github.com/servo/webrender#de3999583ab20aad7c57ea35a3e0394ed45be627"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.2",
@ -4417,15 +4422,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
[[package]]
name = "ron"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da06feaa07f69125ab9ddc769b11de29090122170b402547f64b86fe16ebc399"
dependencies = [
"serde",
]
[[package]]
name = "ron"
version = "0.5.1"
@ -6407,7 +6403,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.61.0"
source = "git+https://github.com/servo/webrender#01082a9091ab98c392af8934d04271eb1dd546df"
source = "git+https://github.com/servo/webrender#de3999583ab20aad7c57ea35a3e0394ed45be627"
dependencies = [
"base64 0.10.1",
"bincode",
@ -6433,7 +6429,7 @@ dependencies = [
"num-traits",
"plane-split",
"rayon",
"ron 0.1.7",
"ron",
"serde",
"serde_json",
"smallvec 1.3.0",
@ -6449,7 +6445,7 @@ dependencies = [
[[package]]
name = "webrender_api"
version = "0.61.0"
source = "git+https://github.com/servo/webrender#01082a9091ab98c392af8934d04271eb1dd546df"
source = "git+https://github.com/servo/webrender#de3999583ab20aad7c57ea35a3e0394ed45be627"
dependencies = [
"app_units",
"bitflags",
@ -6470,7 +6466,7 @@ dependencies = [
[[package]]
name = "webrender_build"
version = "0.0.1"
source = "git+https://github.com/servo/webrender#01082a9091ab98c392af8934d04271eb1dd546df"
source = "git+https://github.com/servo/webrender#de3999583ab20aad7c57ea35a3e0394ed45be627"
dependencies = [
"bitflags",
"lazy_static",
@ -6550,7 +6546,7 @@ dependencies = [
"naga",
"parking_lot 0.10.2",
"peek-poke 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ron 0.5.1",
"ron",
"serde",
"smallvec 1.3.0",
"spirv_headers",
@ -6650,7 +6646,7 @@ dependencies = [
[[package]]
name = "wr_malloc_size_of"
version = "0.0.1"
source = "git+https://github.com/servo/webrender#01082a9091ab98c392af8934d04271eb1dd546df"
source = "git+https://github.com/servo/webrender#de3999583ab20aad7c57ea35a3e0394ed45be627"
dependencies = [
"app_units",
"euclid",

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::canvas_paint_thread::AntialiasMode;
use crate::canvas_paint_thread::{AntialiasMode, ImageUpdate, WebrenderApi};
use crate::raqote_backend::Repetition;
use canvas_traits::canvas::*;
use cssparser::RGBA;
@ -13,7 +13,6 @@ use num_traits::ToPrimitive;
use std::marker::PhantomData;
use std::mem;
use std::sync::Arc;
use webrender::api::DirtyRect;
use webrender_api::units::RectExt as RectExt_;
/// The canvas data stores a state machine for the current status of
@ -367,8 +366,7 @@ pub struct CanvasData<'a> {
path_state: Option<PathState>,
state: CanvasPaintState<'a>,
saved_states: Vec<CanvasPaintState<'a>>,
webrender_api: webrender_api::RenderApi,
webrender_doc: webrender_api::DocumentId,
webrender_api: Box<dyn WebrenderApi>,
image_key: Option<webrender_api::ImageKey>,
/// An old webrender image key that can be deleted when the next epoch ends.
old_image_key: Option<webrender_api::ImageKey>,
@ -384,22 +382,19 @@ fn create_backend() -> Box<dyn Backend> {
impl<'a> CanvasData<'a> {
pub fn new(
size: Size2D<u64>,
webrender_api_sender: webrender_api::RenderApiSender,
webrender_doc: webrender_api::DocumentId,
webrender_api: Box<dyn WebrenderApi>,
antialias: AntialiasMode,
canvas_id: CanvasId,
) -> CanvasData<'a> {
let backend = create_backend();
let draw_target = backend.create_drawtarget(size);
let webrender_api = webrender_api_sender.create_api();
CanvasData {
backend,
drawtarget: draw_target,
path_state: None,
state: CanvasPaintState::new(antialias),
saved_states: vec![],
webrender_api: webrender_api,
webrender_doc,
webrender_api,
image_key: None,
old_image_key: None,
very_old_image_key: None,
@ -979,27 +974,28 @@ impl<'a> CanvasData<'a> {
let data = self.drawtarget.snapshot_data_owned();
let data = webrender_api::ImageData::Raw(Arc::new(data));
let mut txn = webrender_api::Transaction::new();
let mut updates = vec![];
match self.image_key {
Some(image_key) => {
debug!("Updating image {:?}.", image_key);
txn.update_image(image_key, descriptor, data, &DirtyRect::All);
updates.push(ImageUpdate::Update(image_key, descriptor, data));
},
None => {
self.image_key = Some(self.webrender_api.generate_image_key());
let key = self.webrender_api.generate_key();
updates.push(ImageUpdate::Add(key, descriptor, data));
self.image_key = Some(key);
debug!("New image {:?}.", self.image_key);
txn.add_image(self.image_key.unwrap(), descriptor, data, None);
},
}
if let Some(image_key) =
mem::replace(&mut self.very_old_image_key, self.old_image_key.take())
{
txn.delete_image(image_key);
updates.push(ImageUpdate::Delete(image_key));
}
self.webrender_api.send_transaction(self.webrender_doc, txn);
self.webrender_api.update_images(updates);
let data = CanvasImageData {
image_key: self.image_key.unwrap(),
@ -1110,16 +1106,15 @@ impl<'a> CanvasData<'a> {
impl<'a> Drop for CanvasData<'a> {
fn drop(&mut self) {
let mut txn = webrender_api::Transaction::new();
let mut updates = vec![];
if let Some(image_key) = self.old_image_key.take() {
txn.delete_image(image_key);
updates.push(ImageUpdate::Delete(image_key));
}
if let Some(image_key) = self.very_old_image_key.take() {
txn.delete_image(image_key);
updates.push(ImageUpdate::Delete(image_key));
}
self.webrender_api.send_transaction(self.webrender_doc, txn);
self.webrender_api.update_images(updates);
}
}

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(),
);

View file

@ -655,7 +655,7 @@ impl WebGLThread {
);
let image_key = Self::create_wr_external_image(
&self.webrender_api,
&mut self.webrender_api,
self.webrender_doc,
size.to_i32(),
has_alpha,
@ -718,7 +718,7 @@ impl WebGLThread {
.contains(ContextAttributeFlags::ALPHA);
let texture_target = current_wr_texture_target(&self.device);
Self::update_wr_external_image(
&self.webrender_api,
&mut self.webrender_api,
self.webrender_doc,
size.to_i32(),
has_alpha,
@ -1021,7 +1021,7 @@ impl WebGLThread {
/// Creates a `webrender_api::ImageKey` that uses shared textures.
fn create_wr_external_image(
webrender_api: &webrender_api::RenderApi,
webrender_api: &mut webrender_api::RenderApi,
webrender_doc: webrender_api::DocumentId,
size: Size2D<i32>,
alpha: bool,
@ -1041,7 +1041,7 @@ impl WebGLThread {
/// Updates a `webrender_api::ImageKey` that uses shared textures.
fn update_wr_external_image(
webrender_api: &webrender_api::RenderApi,
webrender_api: &mut webrender_api::RenderApi,
webrender_doc: webrender_api::DocumentId,
size: Size2D<i32>,
alpha: bool,

View file

@ -26,8 +26,6 @@ pub enum ConstellationCanvasMsg {
Create {
id_sender: Sender<CanvasId>,
size: Size2D<u64>,
webrender_sender: webrender_api::RenderApiSender,
webrender_doc: webrender_api::DocumentId,
antialias: bool,
},
Exit,

View file

@ -16,6 +16,7 @@ default = []
gl = ["gleam", "pixels"]
[dependencies]
app_units = "0.7"
canvas = { path = "../canvas" }
crossbeam-channel = "0.4"
embedder_traits = { path = "../embedder_traits" }

View file

@ -3,7 +3,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::compositor_thread::CompositorReceiver;
use crate::compositor_thread::{InitialCompositorState, Msg};
use crate::compositor_thread::{
InitialCompositorState, Msg, WebrenderCanvasMsg, WebrenderFontMsg, WebrenderMsg,
};
#[cfg(feature = "gl")]
use crate::gl;
use crate::touch::{TouchAction, TouchHandler};
@ -11,10 +13,11 @@ use crate::windowing::{
self, EmbedderCoordinates, MouseWindowEvent, WebRenderDebugOption, WindowMethods,
};
use crate::{CompositionPipeline, ConstellationMsg, SendableFrameTree};
use canvas::canvas_paint_thread::ImageUpdate;
use crossbeam_channel::Sender;
use embedder_traits::Cursor;
use euclid::{Point2D, Rect, Scale, Vector2D};
use gfx_traits::Epoch;
use gfx_traits::{Epoch, FontData};
#[cfg(feature = "gl")]
use image::{DynamicImage, ImageFormat};
use ipc_channel::ipc;
@ -40,8 +43,6 @@ use std::fs::{create_dir_all, File};
use std::io::Write;
use std::num::NonZeroU32;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use style_traits::viewport::ViewportConstraints;
use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor};
use time::{now, precise_time_ns, precise_time_s};
@ -218,7 +219,7 @@ pub struct IOCompositor<Window: WindowMethods + ?Sized> {
/// True if a WR frame render has been requested. Screenshots
/// taken before the render is complete will not reflect the
/// most up to date rendering.
waiting_on_pending_frame: Arc<AtomicBool>,
waiting_on_pending_frame: bool,
}
#[derive(Clone, Copy)]
@ -334,7 +335,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
is_running_problem_test,
exit_after_load,
convert_mouse_to_touch,
waiting_on_pending_frame: state.pending_wr_frame,
waiting_on_pending_frame: false,
}
}
@ -443,7 +444,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
},
(Msg::Recomposite(reason), ShutdownState::NotShuttingDown) => {
self.waiting_on_pending_frame.store(false, Ordering::SeqCst);
self.waiting_on_pending_frame = false;
self.composition_request = CompositionRequest::CompositeNow(reason)
},
@ -474,7 +475,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
self.ready_to_save_state,
ReadyState::WaitingForConstellationReply
);
if is_ready && !self.waiting_on_pending_frame.load(Ordering::SeqCst) {
if is_ready && !self.waiting_on_pending_frame {
self.ready_to_save_state = ReadyState::ReadyToSaveImage;
if self.is_running_problem_test {
println!("ready to save image!");
@ -569,6 +570,10 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}
},
(Msg::Webrender(msg), ShutdownState::NotShuttingDown) => {
self.handle_webrender_message(msg);
},
// When we are shutting_down, we need to avoid performing operations
// such as Paint that may crash because we have begun tearing down
// the rest of our resources.
@ -578,6 +583,146 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
true
}
/// Accept messages from content processes that need to be relayed to the WebRender
/// instance in the parent process.
fn handle_webrender_message(&mut self, msg: WebrenderMsg) {
match msg {
WebrenderMsg::Layout(script_traits::WebrenderMsg::SendInitialTransaction(pipeline)) => {
self.waiting_on_pending_frame = true;
let mut txn = webrender_api::Transaction::new();
txn.set_display_list(
webrender_api::Epoch(0),
None,
Default::default(),
(pipeline, Default::default(), Default::default()),
false,
);
self.webrender_api
.send_transaction(self.webrender_document, txn);
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::SendScrollNode(
point,
scroll_id,
clamping,
)) => {
let mut txn = webrender_api::Transaction::new();
txn.scroll_node_with_id(point, scroll_id, clamping);
self.webrender_api
.send_transaction(self.webrender_document, txn);
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::SendDisplayList(
epoch,
size,
pipeline,
size2,
data,
descriptor,
)) => {
self.waiting_on_pending_frame = true;
let mut txn = webrender_api::Transaction::new();
txn.set_display_list(
epoch,
None,
size,
(
pipeline,
size2,
webrender_api::BuiltDisplayList::from_data(data, descriptor),
),
true,
);
txn.generate_frame();
self.webrender_api
.send_transaction(self.webrender_document, txn);
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::HitTest(
pipeline,
point,
flags,
sender,
)) => {
let result =
self.webrender_api
.hit_test(self.webrender_document, pipeline, point, flags);
let _ = sender.send(result);
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::GenerateImageKey(sender)) |
WebrenderMsg::Net(net_traits::WebrenderImageMsg::GenerateImageKey(sender)) => {
let _ = sender.send(self.webrender_api.generate_image_key());
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::UpdateImages(updates)) => {
let mut txn = webrender_api::Transaction::new();
for update in updates {
match update {
script_traits::ImageUpdate::AddImage(key, desc, data) => {
txn.add_image(key, desc, data, None)
},
script_traits::ImageUpdate::DeleteImage(key) => txn.delete_image(key),
script_traits::ImageUpdate::UpdateImage(key, desc, data) => {
txn.update_image(key, desc, data, &webrender_api::DirtyRect::All)
},
}
}
self.webrender_api
.send_transaction(self.webrender_document, txn);
},
WebrenderMsg::Net(net_traits::WebrenderImageMsg::AddImage(key, desc, data)) => {
let mut txn = webrender_api::Transaction::new();
txn.add_image(key, desc, data, None);
self.webrender_api
.send_transaction(self.webrender_document, txn);
},
WebrenderMsg::Font(WebrenderFontMsg::AddFontInstance(font_key, size, sender)) => {
let key = self.webrender_api.generate_font_instance_key();
let mut txn = webrender_api::Transaction::new();
txn.add_font_instance(key, font_key, size, None, None, Vec::new());
self.webrender_api
.send_transaction(self.webrender_document, txn);
let _ = sender.send(key);
},
WebrenderMsg::Font(WebrenderFontMsg::AddFont(data, sender)) => {
let font_key = self.webrender_api.generate_font_key();
let mut txn = webrender_api::Transaction::new();
match data {
FontData::Raw(bytes) => txn.add_raw_font(font_key, bytes, 0),
FontData::Native(native_font) => txn.add_native_font(font_key, native_font),
}
self.webrender_api
.send_transaction(self.webrender_document, txn);
let _ = sender.send(font_key);
},
WebrenderMsg::Canvas(WebrenderCanvasMsg::GenerateKey(sender)) => {
let _ = sender.send(self.webrender_api.generate_image_key());
},
WebrenderMsg::Canvas(WebrenderCanvasMsg::UpdateImages(updates)) => {
let mut txn = webrender_api::Transaction::new();
for update in updates {
match update {
ImageUpdate::Add(key, descriptor, data) => {
txn.add_image(key, descriptor, data, None)
},
ImageUpdate::Update(key, descriptor, data) => {
txn.update_image(key, descriptor, data, &webrender_api::DirtyRect::All)
},
ImageUpdate::Delete(key) => txn.delete_image(key),
}
}
self.webrender_api
.send_transaction(self.webrender_document, txn);
},
}
}
/// Sets or unsets the animations-running flag for the given pipeline, and schedules a
/// recomposite if necessary.
fn change_running_animations_state(

View file

@ -6,6 +6,7 @@
use crate::compositor::CompositingReason;
use crate::{ConstellationMsg, SendableFrameTree};
use canvas::canvas_paint_thread::ImageUpdate;
use crossbeam_channel::{Receiver, Sender};
use embedder_traits::EventLoopWaker;
use euclid::Rect;
@ -18,8 +19,6 @@ use profile_traits::time;
use script_traits::{AnimationState, EventResult, MouseButton, MouseEventType};
use std::fmt::{Debug, Error, Formatter};
use std::rc::Rc;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use style_traits::viewport::ViewportConstraints;
use style_traits::CSSPixel;
use webrender_api;
@ -122,6 +121,30 @@ pub enum Msg {
GetScreenSize(IpcSender<DeviceIntSize>),
/// Get screen available size.
GetScreenAvailSize(IpcSender<DeviceIntSize>),
/// Webrender operations requested from non-compositor threads.
Webrender(WebrenderMsg),
}
pub enum WebrenderFontMsg {
AddFontInstance(
webrender_api::FontKey,
app_units::Au,
Sender<webrender_api::FontInstanceKey>,
),
AddFont(gfx_traits::FontData, Sender<webrender_api::FontKey>),
}
pub enum WebrenderCanvasMsg {
GenerateKey(Sender<webrender_api::ImageKey>),
UpdateImages(Vec<ImageUpdate>),
}
pub enum WebrenderMsg {
Layout(script_traits::WebrenderMsg),
Net(net_traits::WebrenderImageMsg),
Font(WebrenderFontMsg),
Canvas(WebrenderCanvasMsg),
}
impl Debug for Msg {
@ -148,6 +171,7 @@ impl Debug for Msg {
Msg::GetClientWindow(..) => write!(f, "GetClientWindow"),
Msg::GetScreenSize(..) => write!(f, "GetScreenSize"),
Msg::GetScreenAvailSize(..) => write!(f, "GetScreenAvailSize"),
Msg::Webrender(..) => write!(f, "Webrender"),
}
}
}
@ -171,5 +195,4 @@ pub struct InitialCompositorState {
pub webrender_surfman: WebrenderSurfman,
pub webrender_gl: Rc<dyn gleam::gl::Gl>,
pub webxr_main_thread: webxr::MainThreadRegistry,
pub pending_wr_frame: Arc<AtomicBool>,
}

View file

@ -109,6 +109,7 @@ use canvas_traits::webgl::WebGLThreads;
use canvas_traits::ConstellationCanvasMsg;
use compositing::compositor_thread::CompositorProxy;
use compositing::compositor_thread::Msg as ToCompositorMsg;
use compositing::compositor_thread::WebrenderMsg;
use compositing::{ConstellationMsg as FromCompositorMsg, SendableFrameTree};
use crossbeam_channel::{after, never, unbounded, Receiver, Sender};
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg};
@ -171,7 +172,6 @@ use std::marker::PhantomData;
use std::mem::replace;
use std::process;
use std::rc::{Rc, Weak};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use style_traits::viewport::ViewportConstraints;
@ -384,10 +384,6 @@ pub struct Constellation<Message, LTF, STF, SWF> {
/// A single WebRender document the constellation operates on.
webrender_document: webrender_api::DocumentId,
/// A channel for the constellation to send messages to the
/// WebRender thread.
webrender_api_sender: webrender_api::RenderApiSender,
/// A channel for content processes to send messages that will
/// be relayed to the WebRender thread.
webrender_api_ipc_sender: script_traits::WebrenderIpcSender,
@ -537,9 +533,6 @@ pub struct InitialConstellationState {
/// Webrender document ID.
pub webrender_document: webrender_api::DocumentId,
/// Webrender API.
pub webrender_api_sender: webrender_api::RenderApiSender,
/// Entry point to create and get channels to a WebGLThread.
pub webgl_threads: Option<WebGLThreads>,
@ -554,9 +547,6 @@ pub struct InitialConstellationState {
/// Mechanism to force the compositor to process events.
pub event_loop_waker: Option<Box<dyn EventLoopWaker>>,
/// A flag share with the compositor to indicate that a WR frame is in progress.
pub pending_wr_frame: Arc<AtomicBool>,
/// User agent string to report in network requests.
pub user_agent: Cow<'static, str>,
}
@ -726,113 +716,6 @@ where
mpsc_receiver
}
enum WebrenderMsg {
Layout(script_traits::WebrenderMsg),
Net(net_traits::WebrenderImageMsg),
}
/// Accept messages from content processes that need to be relayed to the WebRender
/// instance in the parent process.
fn handle_webrender_message(
pending_wr_frame: &AtomicBool,
webrender_api: &webrender_api::RenderApi,
webrender_doc: webrender_api::DocumentId,
msg: WebrenderMsg,
) {
match msg {
WebrenderMsg::Layout(script_traits::WebrenderMsg::SendInitialTransaction(
doc,
pipeline,
)) => {
pending_wr_frame.store(true, Ordering::SeqCst);
let mut txn = webrender_api::Transaction::new();
txn.set_display_list(
webrender_api::Epoch(0),
None,
Default::default(),
(pipeline, Default::default(), Default::default()),
false,
);
webrender_api.send_transaction(doc, txn);
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::SendScrollNode(
doc,
point,
scroll_id,
clamping,
)) => {
let mut txn = webrender_api::Transaction::new();
txn.scroll_node_with_id(point, scroll_id, clamping);
webrender_api.send_transaction(doc, txn);
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::SendDisplayList(
doc,
epoch,
size,
pipeline,
size2,
data,
descriptor,
)) => {
pending_wr_frame.store(true, Ordering::SeqCst);
let mut txn = webrender_api::Transaction::new();
txn.set_display_list(
epoch,
None,
size,
(
pipeline,
size2,
webrender_api::BuiltDisplayList::from_data(data, descriptor),
),
true,
);
txn.generate_frame();
webrender_api.send_transaction(doc, txn);
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::HitTest(
doc,
pipeline,
point,
flags,
sender,
)) => {
let result = webrender_api.hit_test(doc, pipeline, point, flags);
let _ = sender.send(result);
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::GenerateImageKey(sender)) |
WebrenderMsg::Net(net_traits::WebrenderImageMsg::GenerateImageKey(sender)) => {
let _ = sender.send(webrender_api.generate_image_key());
},
WebrenderMsg::Layout(script_traits::WebrenderMsg::UpdateImages(updates)) => {
let mut txn = webrender_api::Transaction::new();
for update in updates {
match update {
script_traits::ImageUpdate::AddImage(key, desc, data) => {
txn.add_image(key, desc, data, None)
},
script_traits::ImageUpdate::DeleteImage(key) => txn.delete_image(key),
script_traits::ImageUpdate::UpdateImage(key, desc, data) => {
txn.update_image(key, desc, data, &webrender_api::DirtyRect::All)
},
}
}
webrender_api.send_transaction(webrender_doc, txn);
},
WebrenderMsg::Net(net_traits::WebrenderImageMsg::AddImage(key, desc, data)) => {
let mut txn = webrender_api::Transaction::new();
txn.add_image(key, desc, data, None);
webrender_api.send_transaction(webrender_doc, txn);
},
}
}
impl<Message, LTF, STF, SWF> Constellation<Message, LTF, STF, SWF>
where
LTF: LayoutThreadFactory<Message = Message>,
@ -931,32 +814,23 @@ where
let (webrender_image_ipc_sender, webrender_image_ipc_receiver) =
ipc::channel().expect("ipc channel failure");
let webrender_api = state.webrender_api_sender.create_api();
let webrender_doc = state.webrender_document;
let pending_wr_frame_clone = state.pending_wr_frame.clone();
let compositor_proxy = state.compositor_proxy.clone();
ROUTER.add_route(
webrender_ipc_receiver.to_opaque(),
Box::new(move |message| {
handle_webrender_message(
&pending_wr_frame_clone,
&webrender_api,
webrender_doc,
let _ = compositor_proxy.send(ToCompositorMsg::Webrender(
WebrenderMsg::Layout(message.to().expect("conversion failure")),
)
));
}),
);
let webrender_api = state.webrender_api_sender.create_api();
let pending_wr_frame_clone = state.pending_wr_frame.clone();
let compositor_proxy = state.compositor_proxy.clone();
ROUTER.add_route(
webrender_image_ipc_receiver.to_opaque(),
Box::new(move |message| {
handle_webrender_message(
&pending_wr_frame_clone,
&webrender_api,
webrender_doc,
let _ = compositor_proxy.send(ToCompositorMsg::Webrender(
WebrenderMsg::Net(message.to().expect("conversion failure")),
)
));
}),
);
@ -1009,7 +883,6 @@ where
scheduler_receiver,
document_states: HashMap::new(),
webrender_document: state.webrender_document,
webrender_api_sender: state.webrender_api_sender,
webrender_api_ipc_sender: script_traits::WebrenderIpcSender::new(
webrender_ipc_sender,
),
@ -1474,10 +1347,10 @@ where
))
}
recv(self.swmanager_receiver) -> msg => {
msg.expect("Unexpected panic channel panic in constellation").map(Request::FromSWManager)
msg.expect("Unexpected SW channel panic in constellation").map(Request::FromSWManager)
}
recv(self.scheduler_receiver) -> msg => {
msg.expect("Unexpected panic channel panic in constellation").map(Request::Timer)
msg.expect("Unexpected schedule channel panic in constellation").map(Request::Timer)
}
recv(scheduler_timeout) -> _ => {
// Note: by returning, we go back to the top,
@ -4386,14 +4259,11 @@ where
size: UntypedSize2D<u64>,
response_sender: IpcSender<(IpcSender<CanvasMsg>, CanvasId)>,
) {
let webrender_api = self.webrender_api_sender.clone();
let (canvas_id_sender, canvas_id_receiver) = unbounded();
if let Err(e) = self.canvas_chan.send(ConstellationCanvasMsg::Create {
id_sender: canvas_id_sender,
size,
webrender_sender: webrender_api,
webrender_doc: self.webrender_document,
antialias: self.enable_canvas_antialiasing,
}) {
return warn!("Create canvas paint thread failed ({})", e);

View file

@ -606,7 +606,6 @@ impl UnprivilegedPipelineContent {
self.time_profiler_chan,
self.mem_profiler_chan,
self.webrender_api_sender,
self.webrender_document,
paint_time_metrics,
layout_thread_busy_flag.clone(),
self.opts.load_webfonts_synchronously,

View file

@ -12,6 +12,7 @@ use crate::platform::font_list::system_default_family;
use crate::platform::font_list::SANS_SERIF_FONT_FAMILY;
use crate::platform::font_template::FontTemplateData;
use app_units::Au;
use gfx_traits::{FontData, WebrenderApi};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use net_traits::request::{Destination, RequestBuilder};
use net_traits::{fetch_async, CoreResourceThread, FetchResponseMsg};
@ -135,9 +136,8 @@ struct FontCache {
web_families: HashMap<LowercaseString, FontTemplates>,
font_context: FontContextHandle,
core_resource_thread: CoreResourceThread,
webrender_api: webrender_api::RenderApi,
webrender_api: Box<dyn WebrenderApi>,
webrender_fonts: HashMap<Atom, webrender_api::FontKey>,
webrender_doc: webrender_api::DocumentId,
font_instances: HashMap<(webrender_api::FontKey, Au), webrender_api::FontInstanceKey>,
}
@ -181,19 +181,11 @@ impl FontCache {
},
Command::GetFontInstance(font_key, size, result) => {
let webrender_api = &self.webrender_api;
let doc = self.webrender_doc;
let instance_key =
*self
let instance_key = *self
.font_instances
.entry((font_key, size))
.or_insert_with(|| {
let key = webrender_api.generate_font_instance_key();
let mut txn = webrender_api::Transaction::new();
txn.add_font_instance(key, font_key, size, None, None, Vec::new());
webrender_api.send_transaction(doc, txn);
key
});
.or_insert_with(|| webrender_api.add_font_instance(font_key, size));
let _ = result.send(instance_key);
},
@ -391,21 +383,17 @@ impl FontCache {
fn get_font_template_info(&mut self, template: Arc<FontTemplateData>) -> FontTemplateInfo {
let webrender_api = &self.webrender_api;
let doc = self.webrender_doc;
let webrender_fonts = &mut self.webrender_fonts;
let font_key = *webrender_fonts
.entry(template.identifier.clone())
.or_insert_with(|| {
let font_key = webrender_api.generate_font_key();
let mut txn = webrender_api::Transaction::new();
match (template.bytes_if_in_memory(), template.native_font()) {
(Some(bytes), _) => txn.add_raw_font(font_key, bytes, 0),
(None, Some(native_font)) => txn.add_native_font(font_key, native_font),
(None, None) => txn.add_raw_font(font_key, template.bytes(), 0),
}
webrender_api.send_transaction(doc, txn);
font_key
let font = match (template.bytes_if_in_memory(), template.native_font()) {
(Some(bytes), _) => FontData::Raw(bytes),
(None, Some(native_font)) => FontData::Native(native_font),
(None, None) => FontData::Raw(template.bytes()),
};
webrender_api.add_font(font)
});
FontTemplateInfo {
@ -444,8 +432,7 @@ pub struct FontCacheThread {
impl FontCacheThread {
pub fn new(
core_resource_thread: CoreResourceThread,
webrender_api: webrender_api::RenderApi,
webrender_doc: webrender_api::DocumentId,
webrender_api: Box<dyn WebrenderApi + Send>,
) -> FontCacheThread {
let (chan, port) = ipc::channel().unwrap();
@ -465,7 +452,6 @@ impl FontCacheThread {
font_context: FontContextHandle::new(),
core_resource_thread,
webrender_api,
webrender_doc,
webrender_fonts: HashMap::new(),
font_instances: HashMap::new(),
};

View file

@ -11,7 +11,9 @@ name = "gfx_traits"
path = "lib.rs"
[dependencies]
app_units = "0.7"
malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = "0.1"
range = { path = "../range" }
serde = "1.0"
webrender_api = { git = "https://github.com/servo/webrender" }

View file

@ -103,3 +103,17 @@ pub fn node_id_from_scroll_id(id: usize) -> Option<usize> {
}
None
}
pub enum FontData {
Raw(Vec<u8>),
Native(webrender_api::NativeFontHandle),
}
pub trait WebrenderApi {
fn add_font_instance(
&self,
font_key: webrender_api::FontKey,
size: app_units::Au,
) -> webrender_api::FontInstanceKey;
fn add_font(&self, data: FontData) -> webrender_api::FontKey;
}

View file

@ -234,6 +234,12 @@ impl DisplayItem {
builder.push_iter(&stacking_context.filters);
}
// TODO(jdm): WebRender now requires us to create stacking context items
// with the IS_BLEND_CONTAINER flag enabled if any children
// of the stacking context have a blend mode applied.
// This will require additional tracking during layout
// before we start collecting stacking contexts so that
// information will be available when we reach this point.
let wr_item = PushStackingContextDisplayItem {
origin: bounds.origin,
spatial_id,
@ -243,9 +249,7 @@ impl DisplayItem {
mix_blend_mode: stacking_context.mix_blend_mode,
clip_id: None,
raster_space: RasterSpace::Screen,
// TODO(pcwalton): Enable picture caching?
cache_tiles: false,
is_backdrop_root: false,
flags: Default::default(),
},
};

View file

@ -234,6 +234,12 @@ impl StackingContext {
));
}
// TODO(jdm): WebRender now requires us to create stacking context items
// with the IS_BLEND_CONTAINER flag enabled if any children
// of the stacking context have a blend mode applied.
// This will require additional tracking during layout
// before we start collecting stacking contexts so that
// information will be available when we reach this point.
builder.wr.push_stacking_context(
LayoutPoint::zero(), // origin
self.spatial_id,
@ -245,8 +251,7 @@ impl StackingContext {
&vec![], // filter_datas
&vec![], // filter_primitives
wr::RasterSpace::Screen,
false, // cache_tiles,
false, // false
wr::StackingContextFlags::empty(),
);
true

View file

@ -212,9 +212,6 @@ pub struct LayoutThread {
/// Webrender interface.
webrender_api: WebrenderIpcSender,
/// Webrender document.
webrender_document: webrender_api::DocumentId,
/// Paint time metrics.
paint_time_metrics: PaintTimeMetrics,
@ -276,7 +273,6 @@ impl LayoutThreadFactory for LayoutThread {
time_profiler_chan: profile_time::ProfilerChan,
mem_profiler_chan: profile_mem::ProfilerChan,
webrender_api_sender: WebrenderIpcSender,
webrender_document: webrender_api::DocumentId,
paint_time_metrics: PaintTimeMetrics,
busy: Arc<AtomicBool>,
load_webfonts_synchronously: bool,
@ -325,7 +321,6 @@ impl LayoutThreadFactory for LayoutThread {
time_profiler_chan,
mem_profiler_chan.clone(),
webrender_api_sender,
webrender_document,
paint_time_metrics,
busy,
load_webfonts_synchronously,
@ -495,7 +490,6 @@ impl LayoutThread {
time_profiler_chan: profile_time::ProfilerChan,
mem_profiler_chan: profile_mem::ProfilerChan,
webrender_api: WebrenderIpcSender,
webrender_document: webrender_api::DocumentId,
paint_time_metrics: PaintTimeMetrics,
busy: Arc<AtomicBool>,
load_webfonts_synchronously: bool,
@ -510,7 +504,7 @@ impl LayoutThread {
dump_flow_tree: bool,
) -> LayoutThread {
// Let webrender know about this pipeline by sending an empty display list.
webrender_api.send_initial_transaction(webrender_document, id.to_webrender());
webrender_api.send_initial_transaction(id.to_webrender());
let device = Device::new(
MediaType::screen(),
@ -553,7 +547,6 @@ impl LayoutThread {
epoch: Cell::new(Epoch(1)),
viewport_size: Size2D::new(Au(0), Au(0)),
webrender_api,
webrender_document,
stylist: Stylist::new(device, QuirksMode::NoQuirks),
rw_data: Arc::new(Mutex::new(LayoutThreadData {
constellation_chan: constellation_chan,
@ -773,7 +766,6 @@ impl LayoutThread {
let point = Point2D::new(-state.scroll_offset.x, -state.scroll_offset.y);
self.webrender_api.send_scroll_node(
self.webrender_document,
webrender_api::units::LayoutPoint::from_untyped(point),
state.scroll_id,
webrender_api::ScrollClamping::ToContentBounds,
@ -882,7 +874,6 @@ impl LayoutThread {
self.time_profiler_chan.clone(),
self.mem_profiler_chan.clone(),
self.webrender_api.clone(),
self.webrender_document,
info.paint_time_metrics,
info.layout_is_busy,
self.load_webfonts_synchronously,
@ -1171,12 +1162,8 @@ impl LayoutThread {
self.paint_time_metrics
.maybe_observe_paint_time(self, epoch, is_contentful.0);
self.webrender_api.send_display_list(
self.webrender_document,
epoch,
viewport_size,
builder.finalize(),
);
self.webrender_api
.send_display_list(epoch, viewport_size, builder.finalize());
},
);
}
@ -1578,7 +1565,6 @@ impl LayoutThread {
let client_point = webrender_api::units::WorldPoint::from_untyped(client_point);
let results = self.webrender_api.hit_test(
self.webrender_document,
Some(self.id.to_webrender()),
client_point,
flags,

View file

@ -191,9 +191,6 @@ pub struct LayoutThread {
/// Webrender interface.
webrender_api: WebrenderIpcSender,
/// Webrender document.
webrender_document: webrender_api::DocumentId,
/// Paint time metrics.
paint_time_metrics: PaintTimeMetrics,
@ -245,7 +242,6 @@ impl LayoutThreadFactory for LayoutThread {
time_profiler_chan: profile_time::ProfilerChan,
mem_profiler_chan: profile_mem::ProfilerChan,
webrender_api_sender: WebrenderIpcSender,
webrender_document: webrender_api::DocumentId,
paint_time_metrics: PaintTimeMetrics,
busy: Arc<AtomicBool>,
load_webfonts_synchronously: bool,
@ -294,7 +290,6 @@ impl LayoutThreadFactory for LayoutThread {
time_profiler_chan,
mem_profiler_chan.clone(),
webrender_api_sender,
webrender_document,
paint_time_metrics,
busy,
load_webfonts_synchronously,
@ -463,7 +458,6 @@ impl LayoutThread {
time_profiler_chan: profile_time::ProfilerChan,
mem_profiler_chan: profile_mem::ProfilerChan,
webrender_api_sender: WebrenderIpcSender,
webrender_document: webrender_api::DocumentId,
paint_time_metrics: PaintTimeMetrics,
busy: Arc<AtomicBool>,
load_webfonts_synchronously: bool,
@ -477,7 +471,7 @@ impl LayoutThread {
trace_layout: bool,
) -> LayoutThread {
// Let webrender know about this pipeline by sending an empty display list.
webrender_api_sender.send_initial_transaction(webrender_document, id.to_webrender());
webrender_api_sender.send_initial_transaction(id.to_webrender());
// The device pixel ratio is incorrect (it does not have the hidpi value),
// but it will be set correctly when the initial reflow takes place.
@ -521,7 +515,6 @@ impl LayoutThread {
epoch: Cell::new(Epoch(1)),
viewport_size: Size2D::new(Au(0), Au(0)),
webrender_api: webrender_api_sender,
webrender_document,
stylist: Stylist::new(device, QuirksMode::NoQuirks),
rw_data: Arc::new(Mutex::new(LayoutThreadData {
constellation_chan: constellation_chan,
@ -737,7 +730,6 @@ impl LayoutThread {
let point = Point2D::new(-state.scroll_offset.x, -state.scroll_offset.y);
self.webrender_api.send_scroll_node(
self.webrender_document,
webrender_api::units::LayoutPoint::from_untyped(point),
state.scroll_id,
webrender_api::ScrollClamping::ToContentBounds,
@ -823,7 +815,6 @@ impl LayoutThread {
self.time_profiler_chan.clone(),
self.mem_profiler_chan.clone(),
self.webrender_api.clone(),
self.webrender_document,
info.paint_time_metrics,
info.layout_is_busy,
self.load_webfonts_synchronously,
@ -1231,7 +1222,6 @@ impl LayoutThread {
let client_point = webrender_api::units::WorldPoint::from_untyped(client_point);
let results = self.webrender_api.hit_test(
self.webrender_document,
Some(self.id.to_webrender()),
client_point,
flags,
@ -1349,12 +1339,8 @@ impl LayoutThread {
self.viewport_size.width.to_f32_px(),
self.viewport_size.height.to_f32_px(),
));
self.webrender_api.send_display_list(
self.webrender_document,
epoch,
viewport_size,
display_list.wr.finalize(),
);
self.webrender_api
.send_display_list(epoch, viewport_size, display_list.wr.finalize());
if self.trace_layout {
layout_debug::end_trace(self.generation.get());

View file

@ -44,7 +44,6 @@ pub trait LayoutThreadFactory {
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan,
webrender_api_sender: WebrenderIpcSender,
webrender_document: webrender_api::DocumentId,
paint_time_metrics: PaintTimeMetrics,
busy: Arc<AtomicBool>,
load_webfonts_synchronously: bool,

View file

@ -213,7 +213,10 @@ impl VideoFrameRenderer for MediaFrameRenderer {
Some((ref mut image_key, ref mut width, ref mut height)) => {
self.old_frame = Some(*image_key);
let new_image_key = self.api.generate_image_key();
let new_image_key = match self.api.generate_image_key() {
Ok(key) => key,
Err(()) => return,
};
/* update current_frame */
*image_key = new_image_key;
@ -243,7 +246,10 @@ impl VideoFrameRenderer for MediaFrameRenderer {
updates.push(ImageUpdate::AddImage(new_image_key, descriptor, image_data));
},
None => {
let image_key = self.api.generate_image_key();
let image_key = match self.api.generate_image_key() {
Ok(key) => key,
Err(()) => return,
};
self.current_frame = Some((image_key, frame.get_width(), frame.get_height()));
let image_data = if frame.is_gl_texture() && self.player_id.is_some() {

View file

@ -1100,12 +1100,11 @@ impl From<i32> for MediaSessionActionType {
#[derive(Deserialize, Serialize)]
pub enum WebrenderMsg {
/// Inform WebRender of the existence of this pipeline.
SendInitialTransaction(DocumentId, webrender_api::PipelineId),
SendInitialTransaction(webrender_api::PipelineId),
/// Perform a scroll operation.
SendScrollNode(DocumentId, LayoutPoint, ExternalScrollId, ScrollClamping),
SendScrollNode(LayoutPoint, ExternalScrollId, ScrollClamping),
/// Inform WebRender of a new display list for the given pipeline.
SendDisplayList(
DocumentId,
webrender_api::Epoch,
LayoutSize,
webrender_api::PipelineId,
@ -1116,7 +1115,6 @@ pub enum WebrenderMsg {
/// Perform a hit test operation. The result will be returned via
/// the provided channel sender.
HitTest(
DocumentId,
Option<webrender_api::PipelineId>,
WorldPoint,
HitTestFlags,
@ -1140,15 +1138,8 @@ impl WebrenderIpcSender {
}
/// Inform WebRender of the existence of this pipeline.
pub fn send_initial_transaction(
&self,
document: DocumentId,
pipeline: webrender_api::PipelineId,
) {
if let Err(e) = self
.0
.send(WebrenderMsg::SendInitialTransaction(document, pipeline))
{
pub fn send_initial_transaction(&self, pipeline: webrender_api::PipelineId) {
if let Err(e) = self.0.send(WebrenderMsg::SendInitialTransaction(pipeline)) {
warn!("Error sending initial transaction: {}", e);
}
}
@ -1156,14 +1147,14 @@ impl WebrenderIpcSender {
/// Perform a scroll operation.
pub fn send_scroll_node(
&self,
document: DocumentId,
point: LayoutPoint,
scroll_id: ExternalScrollId,
clamping: ScrollClamping,
) {
if let Err(e) = self.0.send(WebrenderMsg::SendScrollNode(
document, point, scroll_id, clamping,
)) {
if let Err(e) = self
.0
.send(WebrenderMsg::SendScrollNode(point, scroll_id, clamping))
{
warn!("Error sending scroll node: {}", e);
}
}
@ -1171,14 +1162,12 @@ impl WebrenderIpcSender {
/// Inform WebRender of a new display list for the given pipeline.
pub fn send_display_list(
&self,
document: DocumentId,
epoch: Epoch,
size: LayoutSize,
(pipeline, size2, list): (webrender_api::PipelineId, LayoutSize, BuiltDisplayList),
) {
let (data, descriptor) = list.into_data();
if let Err(e) = self.0.send(WebrenderMsg::SendDisplayList(
document,
webrender_api::Epoch(epoch.0),
size,
pipeline,
@ -1194,27 +1183,24 @@ impl WebrenderIpcSender {
/// and a result is available.
pub fn hit_test(
&self,
document: DocumentId,
pipeline: Option<webrender_api::PipelineId>,
point: WorldPoint,
flags: HitTestFlags,
) -> HitTestResult {
let (sender, receiver) = ipc::channel().unwrap();
self.0
.send(WebrenderMsg::HitTest(
document, pipeline, point, flags, sender,
))
.send(WebrenderMsg::HitTest(pipeline, point, flags, sender))
.expect("error sending hit test");
receiver.recv().expect("error receiving hit test result")
}
/// Create a new image key. Blocks until the key is available.
pub fn generate_image_key(&self) -> ImageKey {
pub fn generate_image_key(&self) -> Result<ImageKey, ()> {
let (sender, receiver) = ipc::channel().unwrap();
self.0
.send(WebrenderMsg::GenerateImageKey(sender))
.expect("error sending image key generation");
receiver.recv().expect("error receiving image key result")
.map_err(|_| ())?;
receiver.recv().map_err(|_| ())
}
/// Perform a resource update operation.

View file

@ -38,6 +38,7 @@ webrender_debugger = ["webrender/debugger"]
xr-profile = ["canvas/xr-profile", "canvas_traits/xr-profile", "script/xr-profile", "webxr/profile"]
[dependencies]
app_units = "0.7"
background_hang_monitor = { path = "../background_hang_monitor" }
bluetooth = { path = "../bluetooth" }
bluetooth_traits = { path = "../bluetooth_traits" }
@ -53,6 +54,7 @@ embedder_traits = { path = "../embedder_traits" }
env_logger = "0.7"
euclid = "0.20"
gfx = { path = "../gfx" }
gfx_traits = { path = "../gfx_traits" }
gleam = "0.11"
gstreamer = { version = "0.15", optional = true }
ipc-channel = "0.14"

View file

@ -64,10 +64,12 @@ fn webdriver(_port: u16, _constellation: Sender<ConstellationMsg>) {}
use bluetooth::BluetoothThreadFactory;
use bluetooth_traits::BluetoothRequest;
use canvas::canvas_paint_thread::{self, CanvasPaintThread};
use canvas::{SurfaceProviders, WebGLComm, WebGlExecutor};
use canvas_traits::webgl::WebGLThreads;
use compositing::compositor_thread::{
CompositorProxy, CompositorReceiver, InitialCompositorState, Msg,
CompositorProxy, CompositorReceiver, InitialCompositorState, Msg, WebrenderCanvasMsg,
WebrenderFontMsg, WebrenderMsg,
};
use compositing::windowing::{EmbedderMethods, WindowEvent, WindowMethods};
use compositing::{CompositingReason, ConstellationMsg, IOCompositor, ShutdownState};
@ -115,7 +117,6 @@ use std::borrow::Cow;
use std::cmp::max;
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Mutex};
use surfman::GLApi;
use webrender::ShaderPrecacheFlags;
@ -454,7 +455,7 @@ where
webrender_surfman.clone(),
webrender_gl.clone(),
&mut webrender,
webrender_api_sender.clone(),
webrender_api.create_sender(),
webrender_document,
&mut webxr_main_thread,
&mut external_image_handlers,
@ -500,8 +501,6 @@ where
device_pixel_ratio: Scale::new(device_pixel_ratio),
};
let pending_wr_frame = Arc::new(AtomicBool::new(false));
// Create the constellation, which maintains the engine
// pipelines, including the script and layout threads, as well
// as the navigation context.
@ -515,14 +514,12 @@ where
debugger_chan,
devtools_chan,
webrender_document,
webrender_api_sender,
webxr_main_thread.registry(),
player_context,
webgl_threads,
glplayer_threads,
event_loop_waker,
window_size,
pending_wr_frame.clone(),
);
if cfg!(feature = "webdriver") {
@ -547,7 +544,6 @@ where
webrender_surfman,
webrender_gl,
webxr_main_thread,
pending_wr_frame,
},
opts.output_file.clone(),
opts.is_running_problem_test,
@ -855,14 +851,12 @@ fn create_constellation(
debugger_chan: Option<debugger::Sender>,
devtools_chan: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
webrender_document: webrender_api::DocumentId,
webrender_api_sender: webrender_api::RenderApiSender,
webxr_registry: webxr_api::Registry,
player_context: WindowGLContext,
webgl_threads: Option<WebGLThreads>,
glplayer_threads: Option<GLPlayerThreads>,
event_loop_waker: Option<Box<dyn EventLoopWaker>>,
initial_window_size: WindowSizeData,
pending_wr_frame: Arc<AtomicBool>,
) -> Sender<ConstellationMsg> {
// Global configuration options, parsed from the command line.
let opts = opts::get();
@ -879,14 +873,14 @@ fn create_constellation(
config_dir,
opts.certificate_path.clone(),
);
let font_cache_thread = FontCacheThread::new(
public_resource_threads.sender(),
webrender_api_sender.create_api(),
webrender_document,
Box::new(FontCacheWR(compositor_proxy.clone())),
);
let initial_state = InitialConstellationState {
compositor_proxy,
compositor_proxy: compositor_proxy.clone(),
embedder_proxy,
debugger_chan,
devtools_chan,
@ -897,17 +891,16 @@ fn create_constellation(
time_profiler_chan,
mem_profiler_chan,
webrender_document,
webrender_api_sender,
webxr_registry,
webgl_threads,
glplayer_threads,
player_context,
event_loop_waker,
pending_wr_frame,
user_agent,
};
let (canvas_chan, ipc_canvas_chan) = canvas::canvas_paint_thread::CanvasPaintThread::start();
let (canvas_chan, ipc_canvas_chan) =
CanvasPaintThread::start(Box::new(CanvasWebrenderApi(compositor_proxy)));
let constellation_chan = Constellation::<
script_layout_interface::message::Msg,
@ -929,6 +922,50 @@ fn create_constellation(
constellation_chan
}
struct FontCacheWR(CompositorProxy);
impl gfx_traits::WebrenderApi for FontCacheWR {
fn add_font_instance(
&self,
font_key: webrender_api::FontKey,
size: app_units::Au,
) -> webrender_api::FontInstanceKey {
let (sender, receiver) = unbounded();
let _ = self.0.send(Msg::Webrender(WebrenderMsg::Font(
WebrenderFontMsg::AddFontInstance(font_key, size, sender),
)));
receiver.recv().unwrap()
}
fn add_font(&self, data: gfx_traits::FontData) -> webrender_api::FontKey {
let (sender, receiver) = unbounded();
let _ = self.0.send(Msg::Webrender(WebrenderMsg::Font(
WebrenderFontMsg::AddFont(data, sender),
)));
receiver.recv().unwrap()
}
}
#[derive(Clone)]
struct CanvasWebrenderApi(CompositorProxy);
impl canvas_paint_thread::WebrenderApi for CanvasWebrenderApi {
fn generate_key(&self) -> webrender_api::ImageKey {
let (sender, receiver) = unbounded();
let _ = self.0.send(Msg::Webrender(WebrenderMsg::Canvas(
WebrenderCanvasMsg::GenerateKey(sender),
)));
receiver.recv().unwrap()
}
fn update_images(&self, updates: Vec<canvas_paint_thread::ImageUpdate>) {
let _ = self.0.send(Msg::Webrender(WebrenderMsg::Canvas(
WebrenderCanvasMsg::UpdateImages(updates),
)));
}
fn clone(&self) -> Box<dyn canvas_paint_thread::WebrenderApi> {
Box::new(<Self as Clone>::clone(self))
}
}
// A logger that logs to two downstream loggers.
// This should probably be in the log crate.
struct BothLogger<Log1, Log2>(Log1, Log2);

View file

@ -37,7 +37,6 @@ packages = [
"wayland-sys",
"parking_lot",
"parking_lot_core",
"ron",
# https://github.com/servo/servo/pull/23288#issuecomment-494687746
"gl_generator",

View file

@ -0,0 +1,2 @@
[mix-blend-mode-animation.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-blended-element-interposed.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-blended-element-overflow-hidden-and-border-radius.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-blended-element-overflow-scroll.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-blended-element-with-transparent-pixels.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-blending-with-sibling.html]
expected: FAIL

View file

@ -1,3 +1,2 @@
[mix-blend-mode-both-parent-and-blended-with-3D-transform.html]
expected:
if os == "linux": FAIL
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-canvas-parent.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-canvas-sibling.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-iframe-parent.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-iframe-sibling.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-image.html]
expected: FAIL

View file

@ -1,2 +1,3 @@
[mix-blend-mode-intermediate-element-overflow-hidden-and-border-radius.html]
fuzzy: /css/compositing/mix-blend-mode/reference/mix-blend-mode-intermediate-element-overflow-hidden-and-border-radius-ref.html:9;8
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-mask.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-overflowing-child-of-blended-element.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-overflowing-child.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-parent-element-overflow-scroll-blended-position-fixed.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-parent-element-overflow-scroll.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-parent-with-3D-transform.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-parent-with-border-radius.html]
expected: FAIL

View file

@ -1,3 +1,2 @@
[mix-blend-mode-parent-with-text.html]
expected:
if os == "linux": FAIL
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-script.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-sibling-with-3D-transform.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-simple.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-stacking-context-creates-isolation.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[mix-blend-mode-with-transform-and-preserve-3D.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[root-element-blend-mode.html]
expected: FAIL

View file

@ -1,3 +1,4 @@
[inline_block_baseline_a.html]
expected:
if os == "mac": FAIL
if os == "linux": FAIL
fuzzy: /_mozilla/css/inline_block_baseline_ref.html:49;2097