From a3dacf50a27e4907ea4ce3396595b4da35341afd Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 1 Apr 2016 16:37:46 -0700 Subject: [PATCH] Brand each payload message with the stacking context ID and epoch to avoid races. Addresses servo/servo#10256. --- Cargo.toml | 1 + src/lib.rs | 1 + src/render_backend.rs | 38 +++++++++++++++++++++++++++++++++++--- src/renderer.rs | 2 ++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2e819f68a9..88ed5bfe95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ scoped_threadpool = "0.1.6" app_units = {version = "0.2.1", features = ["plugins"]} lazy_static = "0.1" log = "0.3" +byteorder = "0.5" [target.x86_64-apple-darwin.dependencies] core-graphics = ">=0.2, <0.4" diff --git a/src/lib.rs b/src/lib.rs index 0fe2e63efb..ec1f754060 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,5 +80,6 @@ extern crate scoped_threadpool; extern crate time; extern crate webrender_traits; extern crate offscreen_gl_context; +extern crate byteorder; pub use renderer::{Renderer, RendererOptions}; diff --git a/src/render_backend.rs b/src/render_backend.rs index bdff41a70b..7bc32da076 100644 --- a/src/render_backend.rs +++ b/src/render_backend.rs @@ -2,14 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use byteorder::{LittleEndian, ReadBytesExt}; use frame::Frame; use internal_types::{FontTemplate, ResultMsg, RendererFrame}; -use ipc_channel::ipc::{IpcBytesReceiver, IpcReceiver}; +use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender, IpcReceiver}; use profiler::BackendProfileCounters; use resource_cache::ResourceCache; use scene::Scene; use scoped_threadpool; use std::collections::HashMap; +use std::io::{Cursor, Read}; use std::sync::{Arc, Mutex}; use std::sync::mpsc::Sender; use texture_cache::{TextureCache, TextureCacheItemId}; @@ -22,6 +24,7 @@ use offscreen_gl_context::{NativeGLContext, GLContext, ColorAttachmentType, Nati pub struct RenderBackend { api_rx: IpcReceiver, payload_rx: IpcBytesReceiver, + payload_tx: IpcBytesSender, result_tx: Sender, device_pixel_ratio: f32, @@ -42,6 +45,7 @@ pub struct RenderBackend { impl RenderBackend { pub fn new(api_rx: IpcReceiver, payload_rx: IpcBytesReceiver, + payload_tx: IpcBytesSender, result_tx: Sender, device_pixel_ratio: f32, white_image_id: TextureCacheItemId, @@ -63,6 +67,7 @@ impl RenderBackend { thread_pool: thread_pool, api_rx: api_rx, payload_rx: payload_rx, + payload_tx: payload_tx, result_tx: result_tx, device_pixel_ratio: device_pixel_ratio, resource_cache: resource_cache, @@ -131,9 +136,34 @@ impl RenderBackend { stacking_context); } + let mut leftover_auxiliary_data = vec![]; + let mut auxiliary_data; + loop { + auxiliary_data = self.payload_rx.recv().unwrap(); + { + let mut payload_reader = Cursor::new(&auxiliary_data[..]); + let payload_stacking_context_id = + payload_reader.read_u32::().unwrap(); + let payload_epoch = + payload_reader.read_u32::().unwrap(); + if payload_epoch == epoch.0 && + payload_stacking_context_id == stacking_context_id.0 { + break + } + } + leftover_auxiliary_data.push(auxiliary_data) + } + for leftover_auxiliary_data in leftover_auxiliary_data { + self.payload_tx.send(&leftover_auxiliary_data[..]).unwrap() + } + + let mut auxiliary_data = Cursor::new(&mut auxiliary_data[8..]); for (display_list_id, display_list_descriptor) in display_lists.into_iter() { - let built_display_list_data = self.payload_rx.recv().unwrap(); + let mut built_display_list_data = + vec![0; display_list_descriptor.size()]; + auxiliary_data.read_exact(&mut built_display_list_data[..]) + .unwrap(); let built_display_list = BuiltDisplayList::from_data(built_display_list_data, display_list_descriptor); @@ -144,7 +174,9 @@ impl RenderBackend { &mut self.resource_cache); } - let auxiliary_lists_data = self.payload_rx.recv().unwrap(); + let mut auxiliary_lists_data = + vec![0; auxiliary_lists_descriptor.size()]; + auxiliary_data.read_exact(&mut auxiliary_lists_data[..]).unwrap(); let auxiliary_lists = AuxiliaryLists::from_data(auxiliary_lists_data, auxiliary_lists_descriptor); diff --git a/src/renderer.rs b/src/renderer.rs index 2ab22d327c..3355112da3 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -259,9 +259,11 @@ impl Renderer { let context_handle = NativeGLContext::current_handle(); let (device_pixel_ratio, enable_aa) = (options.device_pixel_ratio, options.enable_aa); + let payload_tx_for_backend = payload_tx.clone(); thread::spawn(move || { let mut backend = RenderBackend::new(api_rx, payload_rx, + payload_tx_for_backend, result_tx, device_pixel_ratio, white_image_id,