diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index beb2abc5979..4a7959788fb 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -368,6 +368,7 @@ pub struct CanvasData<'a> { state: CanvasPaintState<'a>, saved_states: Vec>, webrender_api: webrender_api::RenderApi, + webrender_doc: webrender_api::DocumentId, image_key: Option, /// An old webrender image key that can be deleted when the next epoch ends. old_image_key: Option, @@ -384,6 +385,7 @@ impl<'a> CanvasData<'a> { pub fn new( size: Size2D, webrender_api_sender: webrender_api::RenderApiSender, + webrender_doc: webrender_api::DocumentId, antialias: AntialiasMode, canvas_id: CanvasId, ) -> CanvasData<'a> { @@ -397,6 +399,7 @@ impl<'a> CanvasData<'a> { state: CanvasPaintState::new(antialias), saved_states: vec![], webrender_api: webrender_api, + webrender_doc, image_key: None, old_image_key: None, very_old_image_key: None, @@ -996,7 +999,7 @@ impl<'a> CanvasData<'a> { txn.delete_image(image_key); } - self.webrender_api.update_resources(txn.resource_updates); + self.webrender_api.send_transaction(self.webrender_doc, txn); let data = CanvasImageData { image_key: self.image_key.unwrap(), @@ -1116,7 +1119,7 @@ impl<'a> Drop for CanvasData<'a> { txn.delete_image(image_key); } - self.webrender_api.update_resources(txn.resource_updates); + self.webrender_api.send_transaction(self.webrender_doc, txn); } } diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs index c68e11f745a..f73d8f7b9a8 100644 --- a/components/canvas/canvas_paint_thread.rs +++ b/components/canvas/canvas_paint_thread.rs @@ -75,11 +75,13 @@ impl<'a> CanvasPaintThread<'a> { 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, ); creator.send(canvas_id).unwrap(); @@ -103,6 +105,7 @@ impl<'a> CanvasPaintThread<'a> { &mut self, size: Size2D, webrender_api_sender: webrender_api::RenderApiSender, + webrender_doc: webrender_api::DocumentId, antialias: bool, ) -> CanvasId { let antialias = if antialias { @@ -114,7 +117,13 @@ impl<'a> CanvasPaintThread<'a> { let canvas_id = self.next_canvas_id.clone(); self.next_canvas_id.0 += 1; - let canvas_data = CanvasData::new(size, webrender_api_sender, antialias, canvas_id.clone()); + let canvas_data = CanvasData::new( + size, + webrender_api_sender, + webrender_doc, + antialias, + canvas_id.clone(), + ); self.canvases.insert(canvas_id.clone(), canvas_data); canvas_id diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs index ff744481770..97275dc19ab 100644 --- a/components/canvas/webgl_mode/inprocess.rs +++ b/components/canvas/webgl_mode/inprocess.rs @@ -40,6 +40,7 @@ impl WebGLComm { surfman: WebrenderSurfman, webrender_gl: Rc, webrender_api_sender: webrender_api::RenderApiSender, + webrender_doc: webrender_api::DocumentId, external_images: Arc>, api_type: GlType, ) -> WebGLComm { @@ -53,6 +54,7 @@ impl WebGLComm { // This implementation creates a single `WebGLThread` for all the pipelines. let init = WebGLThreadInit { webrender_api_sender, + webrender_doc, external_images, sender: sender.clone(), receiver, diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index a8abd36a3c9..9b7b4ed4683 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -221,6 +221,7 @@ pub(crate) struct WebGLThread { device: Device, /// Channel used to generate/update or delete `webrender_api::ImageKey`s. webrender_api: webrender_api::RenderApi, + webrender_doc: webrender_api::DocumentId, /// Map of live WebGLContexts. contexts: FnvHashMap, /// Cached information for WebGLContexts. @@ -257,6 +258,7 @@ pub type SurfaceProvider = Box + Sen pub(crate) struct WebGLThreadInit { pub webxr_surface_providers: SurfaceProviders, pub webrender_api_sender: webrender_api::RenderApiSender, + pub webrender_doc: webrender_api::DocumentId, pub external_images: Arc>, pub sender: WebGLSender, pub receiver: WebGLReceiver, @@ -276,6 +278,7 @@ impl WebGLThread { pub(crate) fn new( WebGLThreadInit { webrender_api_sender, + webrender_doc, external_images, sender, receiver, @@ -293,6 +296,7 @@ impl WebGLThread { .create_device(&adapter) .expect("Couldn't open WebGL device!"), webrender_api: webrender_api_sender.create_api(), + webrender_doc, contexts: Default::default(), cached_context_info: Default::default(), bound_context_id: None, @@ -652,6 +656,7 @@ impl WebGLThread { let image_key = Self::create_wr_external_image( &self.webrender_api, + self.webrender_doc, size.to_i32(), has_alpha, id, @@ -714,6 +719,7 @@ impl WebGLThread { let texture_target = current_wr_texture_target(&self.device); Self::update_wr_external_image( &self.webrender_api, + self.webrender_doc, size.to_i32(), has_alpha, context_id, @@ -732,7 +738,7 @@ impl WebGLThread { if let Some(info) = self.cached_context_info.remove(&context_id) { let mut txn = webrender_api::Transaction::new(); txn.delete_image(info.image_key); - self.webrender_api.update_resources(txn.resource_updates) + self.webrender_api.send_transaction(self.webrender_doc, txn) } // We need to make the context current so its resources can be disposed of. @@ -1016,6 +1022,7 @@ impl WebGLThread { /// Creates a `webrender_api::ImageKey` that uses shared textures. fn create_wr_external_image( webrender_api: &webrender_api::RenderApi, + webrender_doc: webrender_api::DocumentId, size: Size2D, alpha: bool, context_id: WebGLContextId, @@ -1027,7 +1034,7 @@ impl WebGLThread { let image_key = webrender_api.generate_image_key(); let mut txn = webrender_api::Transaction::new(); txn.add_image(image_key, descriptor, data, None); - webrender_api.update_resources(txn.resource_updates); + webrender_api.send_transaction(webrender_doc, txn); image_key } @@ -1035,6 +1042,7 @@ impl WebGLThread { /// Updates a `webrender_api::ImageKey` that uses shared textures. fn update_wr_external_image( webrender_api: &webrender_api::RenderApi, + webrender_doc: webrender_api::DocumentId, size: Size2D, alpha: bool, context_id: WebGLContextId, @@ -1046,7 +1054,7 @@ impl WebGLThread { let mut txn = webrender_api::Transaction::new(); txn.update_image(image_key, descriptor, data, &webrender_api::DirtyRect::All); - webrender_api.update_resources(txn.resource_updates); + webrender_api.send_transaction(webrender_doc, txn); } /// Helper function to create a `webrender_api::ImageDescriptor`. diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs index d7d893b2b32..ec510e6281d 100644 --- a/components/canvas_traits/lib.rs +++ b/components/canvas_traits/lib.rs @@ -27,6 +27,7 @@ pub enum ConstellationCanvasMsg { id_sender: Sender, size: Size2D, webrender_sender: webrender_api::RenderApiSender, + webrender_doc: webrender_api::DocumentId, antialias: bool, }, Exit, diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 00dcd2a4eb8..69af3482997 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -738,6 +738,7 @@ enum WebrenderMsg { fn handle_webrender_message( pending_wr_frame: &AtomicBool, webrender_api: &webrender_api::RenderApi, + webrender_doc: webrender_api::DocumentId, msg: WebrenderMsg, ) { match msg { @@ -810,9 +811,26 @@ fn handle_webrender_message( let _ = sender.send(webrender_api.generate_image_key()); }, - WebrenderMsg::Layout(script_traits::WebrenderMsg::UpdateResources(updates)) | - WebrenderMsg::Net(net_traits::WebrenderImageMsg::UpdateResources(updates)) => { - webrender_api.update_resources(updates); + 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); }, } } @@ -916,6 +934,7 @@ where 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(); ROUTER.add_route( webrender_ipc_receiver.to_opaque(), @@ -923,6 +942,7 @@ where handle_webrender_message( &pending_wr_frame_clone, &webrender_api, + webrender_doc, WebrenderMsg::Layout(message.to().expect("conversion failure")), ) }), @@ -936,6 +956,7 @@ where handle_webrender_message( &pending_wr_frame_clone, &webrender_api, + webrender_doc, WebrenderMsg::Net(message.to().expect("conversion failure")), ) }), @@ -4354,6 +4375,7 @@ where 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); diff --git a/components/gfx/font_cache_thread.rs b/components/gfx/font_cache_thread.rs index ecd11aa2146..48d4c9e2889 100644 --- a/components/gfx/font_cache_thread.rs +++ b/components/gfx/font_cache_thread.rs @@ -137,6 +137,7 @@ struct FontCache { core_resource_thread: CoreResourceThread, webrender_api: webrender_api::RenderApi, webrender_fonts: HashMap, + webrender_doc: webrender_api::DocumentId, font_instances: HashMap<(webrender_api::FontKey, Au), webrender_api::FontInstanceKey>, } @@ -180,6 +181,7 @@ impl FontCache { }, Command::GetFontInstance(font_key, size, result) => { let webrender_api = &self.webrender_api; + let doc = self.webrender_doc; let instance_key = *self @@ -189,7 +191,7 @@ impl FontCache { 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.update_resources(txn.resource_updates); + webrender_api.send_transaction(doc, txn); key }); @@ -389,6 +391,7 @@ impl FontCache { fn get_font_template_info(&mut self, template: Arc) -> FontTemplateInfo { let webrender_api = &self.webrender_api; + let doc = self.webrender_doc; let webrender_fonts = &mut self.webrender_fonts; let font_key = *webrender_fonts @@ -401,7 +404,7 @@ impl FontCache { (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.update_resources(txn.resource_updates); + webrender_api.send_transaction(doc, txn); font_key }); @@ -442,6 +445,7 @@ impl FontCacheThread { pub fn new( core_resource_thread: CoreResourceThread, webrender_api: webrender_api::RenderApi, + webrender_doc: webrender_api::DocumentId, ) -> FontCacheThread { let (chan, port) = ipc::channel().unwrap(); @@ -461,6 +465,7 @@ impl FontCacheThread { font_context: FontContextHandle::new(), core_resource_thread, webrender_api, + webrender_doc, webrender_fonts: HashMap::new(), font_instances: HashMap::new(), }; diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs index c39387fbdaf..3e0019ea42e 100644 --- a/components/layout_2020/display_list/mod.rs +++ b/components/layout_2020/display_list/mod.rs @@ -342,7 +342,9 @@ impl<'a> BuilderForBoxFragment<'a> { // value associated with the bottom-most background image layer.” let layer_index = b.background_image.0.len() - 1; let (bounds, common) = background::painting_area(self, builder, layer_index); - builder.wr.push_rect(&common, bounds, rgba(background_color)) + builder + .wr + .push_rect(&common, bounds, rgba(background_color)) } // Reverse because the property is top layer first, we want to paint bottom layer first. for (index, image) in b.background_image.0.iter().enumerate().rev() { diff --git a/components/net/image_cache.rs b/components/net/image_cache.rs index 8a5e6a53749..450653b341f 100644 --- a/components/net/image_cache.rs +++ b/components/net/image_cache.rs @@ -86,9 +86,7 @@ fn set_webrender_image_key(webrender_api: &WebrenderIpcSender, image: &mut Image }; let data = webrender_api::ImageData::new(bytes); let image_key = webrender_api.generate_image_key(); - let mut txn = webrender_api::Transaction::new(); - txn.add_image(image_key, descriptor, data, None); - webrender_api.update_resources(txn.resource_updates); + webrender_api.add_image(image_key, descriptor, data); image.id = Some(image_key); } diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 8bb1ad91cae..3222daceff0 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -32,7 +32,7 @@ use mime::Mime; use msg::constellation_msg::HistoryStateId; use servo_url::{ImmutableOrigin, ServoUrl}; use time::precise_time_ns; -use webrender_api::ImageKey; +use webrender_api::{ImageData, ImageDescriptor, ImageKey}; pub mod blob_url_store; pub mod filemanager_thread; @@ -777,7 +777,7 @@ pub fn http_percent_encode(bytes: &[u8]) -> String { #[derive(Deserialize, Serialize)] pub enum WebrenderImageMsg { - UpdateResources(Vec), + AddImage(ImageKey, ImageDescriptor, ImageData), GenerateImageKey(IpcSender), } @@ -797,8 +797,11 @@ impl WebrenderIpcSender { receiver.recv().expect("error receiving image key result") } - pub fn update_resources(&self, updates: Vec) { - if let Err(e) = self.0.send(WebrenderImageMsg::UpdateResources(updates)) { + pub fn add_image(&self, key: ImageKey, descriptor: ImageDescriptor, data: ImageData) { + if let Err(e) = self + .0 + .send(WebrenderImageMsg::AddImage(key, descriptor, data)) + { warn!("Error sending image update: {}", e); } } diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index a1a1d3204fb..0bcf2f45d0f 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -81,7 +81,7 @@ use net_traits::request::{Destination, Referrer}; use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, Metadata}; use net_traits::{NetworkError, ResourceFetchTiming, ResourceTimingType}; use script_layout_interface::HTMLMediaData; -use script_traits::WebrenderIpcSender; +use script_traits::{ImageUpdate, WebrenderIpcSender}; use servo_config::pref; use servo_media::player::audio::AudioRenderer; use servo_media::player::video::{VideoFrame, VideoFrameRenderer}; @@ -95,9 +95,9 @@ use std::mem; use std::rc::Rc; use std::sync::{Arc, Mutex}; use time::{self, Duration, Timespec}; +use webrender_api::ImageKey; use webrender_api::{ExternalImageData, ExternalImageId, ExternalImageType, TextureTarget}; use webrender_api::{ImageData, ImageDescriptor, ImageDescriptorFlags, ImageFormat}; -use webrender_api::{ImageKey, Transaction}; #[derive(PartialEq)] enum FrameStatus { @@ -177,10 +177,10 @@ impl MediaFrameRenderer { impl VideoFrameRenderer for MediaFrameRenderer { fn render(&mut self, frame: VideoFrame) { - let mut txn = Transaction::new(); + let mut updates = vec![]; if let Some(old_image_key) = mem::replace(&mut self.very_old_frame, self.old_frame.take()) { - txn.delete_image(old_image_key); + updates.push(ImageUpdate::DeleteImage(old_image_key)); } let descriptor = ImageDescriptor::new( @@ -195,12 +195,11 @@ impl VideoFrameRenderer for MediaFrameRenderer { if *width == frame.get_width() && *height == frame.get_height() => { if !frame.is_gl_texture() { - txn.update_image( + updates.push(ImageUpdate::UpdateImage( *image_key, descriptor, ImageData::Raw(frame.get_data()), - &webrender_api::DirtyRect::All, - ); + )); } self.current_frame_holder @@ -208,7 +207,7 @@ impl VideoFrameRenderer for MediaFrameRenderer { .set(frame); if let Some(old_image_key) = self.old_frame.take() { - txn.delete_image(old_image_key); + updates.push(ImageUpdate::DeleteImage(old_image_key)); } } Some((ref mut image_key, ref mut width, ref mut height)) => { @@ -241,7 +240,7 @@ impl VideoFrameRenderer for MediaFrameRenderer { .get_or_insert_with(|| FrameHolder::new(frame.clone())) .set(frame); - txn.add_image(new_image_key, descriptor, image_data, None); + updates.push(ImageUpdate::AddImage(new_image_key, descriptor, image_data)); }, None => { let image_key = self.api.generate_image_key(); @@ -265,10 +264,10 @@ impl VideoFrameRenderer for MediaFrameRenderer { self.current_frame_holder = Some(FrameHolder::new(frame)); - txn.add_image(image_key, descriptor, image_data, None); + updates.push(ImageUpdate::AddImage(image_key, descriptor, image_data)); }, } - self.api.update_resources(txn.resource_updates); + self.api.update_images(updates); } } diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index aeac1ff6087..b2a3de56796 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -69,8 +69,11 @@ use style_traits::SpeculativePainter; use webrender_api::units::{ DeviceIntSize, DevicePixel, LayoutPixel, LayoutPoint, LayoutSize, WorldPoint, }; -use webrender_api::{BuiltDisplayList, DocumentId, ExternalScrollId, ImageKey, ScrollClamping}; -use webrender_api::{BuiltDisplayListDescriptor, HitTestFlags, HitTestResult, ResourceUpdate}; +use webrender_api::{ + BuiltDisplayList, DocumentId, ExternalScrollId, ImageData, ImageDescriptor, ImageKey, + ScrollClamping, +}; +use webrender_api::{BuiltDisplayListDescriptor, HitTestFlags, HitTestResult}; pub use crate::script_msg::{ DOMMessage, HistoryEntryReplacement, SWManagerMsg, SWManagerSenders, ScopeThings, @@ -1173,7 +1176,7 @@ pub enum WebrenderMsg { /// provided channel sender. GenerateImageKey(IpcSender), /// Perform a resource update operation. - UpdateResources(Vec), + UpdateImages(Vec), } #[derive(Clone, Deserialize, Serialize)] @@ -1265,9 +1268,20 @@ impl WebrenderIpcSender { } /// Perform a resource update operation. - pub fn update_resources(&self, updates: Vec) { - if let Err(e) = self.0.send(WebrenderMsg::UpdateResources(updates)) { - warn!("error sending resource updates: {}", e); + pub fn update_images(&self, updates: Vec) { + if let Err(e) = self.0.send(WebrenderMsg::UpdateImages(updates)) { + warn!("error sending image updates: {}", e); } } } + +#[derive(Deserialize, Serialize)] +/// Serializable image updates that must be performed by WebRender. +pub enum ImageUpdate { + /// Register a new image. + AddImage(ImageKey, ImageDescriptor, ImageData), + /// Delete a previously registered image registration. + DeleteImage(ImageKey), + /// Update an existing image registration. + UpdateImage(ImageKey, ImageDescriptor, ImageData), +} diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 1d362fb2fa4..3da59234690 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -456,6 +456,7 @@ where webrender_gl.clone(), &mut webrender, webrender_api_sender.clone(), + webrender_document, &mut webxr_main_thread, &mut external_image_handlers, external_images.clone(), @@ -882,6 +883,7 @@ fn create_constellation( let font_cache_thread = FontCacheThread::new( public_resource_threads.sender(), webrender_api_sender.create_api(), + webrender_document, ); let initial_state = InitialConstellationState { @@ -1043,6 +1045,7 @@ fn create_webgl_threads( webrender_gl: Rc, webrender: &mut webrender::Renderer, webrender_api_sender: webrender_api::RenderApiSender, + webrender_doc: webrender_api::DocumentId, webxr_main_thread: &mut webxr::MainThreadRegistry, external_image_handlers: &mut WebrenderExternalImageHandlers, external_images: Arc>, @@ -1066,6 +1069,7 @@ fn create_webgl_threads( webrender_surfman, webrender_gl, webrender_api_sender, + webrender_doc, external_images, gl_type, ); diff --git a/tests/wpt/metadata/css/css-transforms/transform-input-012.html.ini b/tests/wpt/metadata/css/css-transforms/transform-input-012.html.ini index ed9389b2c24..4643ad53102 100644 --- a/tests/wpt/metadata/css/css-transforms/transform-input-012.html.ini +++ b/tests/wpt/metadata/css/css-transforms/transform-input-012.html.ini @@ -1,4 +1,3 @@ [transform-input-012.html] bug: https://github.com/servo/servo/issues/21092 - expected: - if os == "linux": FAIL + expected: FAIL diff --git a/tests/wpt/metadata/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html.ini b/tests/wpt/metadata/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html.ini index 068320fb597..8f2209ffd03 100644 --- a/tests/wpt/metadata/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html.ini +++ b/tests/wpt/metadata/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html.ini @@ -1,2 +1,3 @@ [fieldset-transform-translatez.html] - expected: FAIL + expected: + if os == "linux": FAIL