diff options
Diffstat (limited to 'components/compositing')
-rw-r--r-- | components/compositing/Cargo.toml | 6 | ||||
-rw-r--r-- | components/compositing/compositor.rs | 321 | ||||
-rw-r--r-- | components/compositing/compositor_thread.rs | 15 | ||||
-rw-r--r-- | components/compositing/constellation.rs | 17 | ||||
-rw-r--r-- | components/compositing/lib.rs | 2 | ||||
-rw-r--r-- | components/compositing/pipeline.rs | 8 |
6 files changed, 313 insertions, 56 deletions
diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index a190ddb73f2..389b669d607 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -81,6 +81,12 @@ git = "https://github.com/servo/gaol" [target.aarch64-unknown-linux-gnu.dependencies.gaol] git = "https://github.com/servo/gaol" +[dependencies.webrender_traits] +git = "https://github.com/glennw/webrender_traits" + +[dependencies.webrender] +git = "https://github.com/glennw/webrender" + [dependencies] app_units = {version = "0.2.1", features = ["plugins"]} euclid = {version = "0.6.2", features = ["plugins"]} diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index f75126cab28..e8ac9a88c22 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -6,7 +6,7 @@ use CompositorMsg as ConstellationMsg; use app_units::Au; use compositor_layer::{CompositorData, CompositorLayer, RcCompositorLayer, WantsScrollEventsFlag}; use compositor_thread::{CompositorEventListener, CompositorProxy}; -use compositor_thread::{CompositorReceiver, InitialCompositorState, Msg}; +use compositor_thread::{CompositorReceiver, InitialCompositorState, Msg, RenderListener}; use constellation::SendableFrameTree; use euclid::point::TypedPoint2D; use euclid::rect::TypedRect; @@ -27,15 +27,15 @@ use layers::rendergl; use layers::rendergl::RenderContext; use layers::scene::Scene; use layout_traits::LayoutControlChan; -use msg::constellation_msg::{Image, PixelFormat}; +use msg::constellation_msg::{ConvertPipelineIdFromWebRender, ConvertPipelineIdToWebRender, Image, PixelFormat}; use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData}; use msg::constellation_msg::{NavigationDirection, PipelineId, WindowSizeData}; use pipeline::CompositionPipeline; use profile_traits::mem::{self, ReportKind, Reporter, ReporterRequest}; use profile_traits::time::{self, ProfilerCategory, profile}; -use script_traits::CompositorEvent::{MouseMoveEvent, TouchEvent}; +use script_traits::CompositorEvent::{MouseMoveEvent, MouseButtonEvent, TouchEvent}; use script_traits::{AnimationState, ConstellationControlMsg, LayoutControlMsg}; -use script_traits::{MouseButton, TouchEventType, TouchId}; +use script_traits::{MouseButton, MouseEventType, TouchEventType, TouchId}; use scrolling::ScrollingTimerProxy; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::{HashMap, HashSet}; @@ -51,6 +51,8 @@ use url::Url; use util::geometry::{PagePx, ScreenPx, ViewportPx}; use util::opts; use util::print_tree::PrintTree; +use webrender; +use webrender_traits; use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg}; #[derive(Debug, PartialEq)] @@ -192,6 +194,12 @@ pub struct IOCompositor<Window: WindowMethods> { /// The id of the pipeline that was last sent a mouse move event, if any. last_mouse_move_recipient: Option<PipelineId>, + + /// The webrender renderer, if enabled. + webrender: Option<webrender::Renderer>, + + /// The webrender interface, if enabled. + webrender_api: Option<webrender_traits::RenderApi>, } pub struct ScrollZoomEvent { @@ -261,7 +269,23 @@ pub enum CompositeTarget { PngFile } -fn initialize_png(width: usize, height: usize) -> (Vec<gl::GLuint>, Vec<gl::GLuint>) { +struct RenderTargetInfo { + framebuffer_ids: Vec<gl::GLuint>, + texture_ids: Vec<gl::GLuint>, + renderbuffer_ids: Vec<gl::GLuint>, +} + +impl RenderTargetInfo { + fn empty() -> RenderTargetInfo { + RenderTargetInfo { + framebuffer_ids: Vec::new(), + texture_ids: Vec::new(), + renderbuffer_ids: Vec::new() + } + } +} + +fn initialize_png(width: usize, height: usize) -> RenderTargetInfo { let framebuffer_ids = gl::gen_framebuffers(1); gl::bind_framebuffer(gl::FRAMEBUFFER, framebuffer_ids[0]); @@ -278,13 +302,64 @@ fn initialize_png(width: usize, height: usize) -> (Vec<gl::GLuint>, Vec<gl::GLui gl::bind_texture(gl::TEXTURE_2D, 0); - (framebuffer_ids, texture_ids) + let renderbuffer_ids = if opts::get().use_webrender { + let renderbuffer_ids = gl::gen_renderbuffers(1); + gl::bind_renderbuffer(gl::RENDERBUFFER, renderbuffer_ids[0]); + gl::renderbuffer_storage(gl::RENDERBUFFER, + gl::STENCIL_INDEX8, + width as GLsizei, + height as GLsizei); + gl::framebuffer_renderbuffer(gl::FRAMEBUFFER, + gl::STENCIL_ATTACHMENT, + gl::RENDERBUFFER, + renderbuffer_ids[0]); + renderbuffer_ids + } else { + Vec::new() + }; + + RenderTargetInfo { + framebuffer_ids: framebuffer_ids, + texture_ids: texture_ids, + renderbuffer_ids: renderbuffer_ids + } } pub fn reporter_name() -> String { "compositor-reporter".to_owned() } +struct RenderNotifier { + compositor_proxy: Box<CompositorProxy>, + constellation_chan: Sender<ConstellationMsg>, +} + +impl RenderNotifier { + fn new(compositor_proxy: Box<CompositorProxy>, + constellation_chan: Sender<ConstellationMsg>) -> RenderNotifier { + RenderNotifier { + compositor_proxy: compositor_proxy, + constellation_chan: constellation_chan, + } + } +} + +impl webrender_traits::RenderNotifier for RenderNotifier { + fn new_frame_ready(&mut self) { + self.compositor_proxy.recomposite(); + } + + fn pipeline_size_changed(&mut self, + pipeline_id: webrender_traits::PipelineId, + size: Option<Size2D<f32>>) { + let pipeline_id = pipeline_id.from_webrender(); + let size = size.unwrap_or(Size2D::zero()); + + self.constellation_chan.send(ConstellationMsg::FrameSize(pipeline_id, + size)).unwrap(); + } +} + impl<Window: WindowMethods> IOCompositor<Window> { fn new(window: Rc<Window>, state: InitialCompositorState) -> IOCompositor<Window> { @@ -306,6 +381,11 @@ impl<Window: WindowMethods> IOCompositor<Window> { Some(_) => CompositeTarget::PngFile, None => CompositeTarget::Window }; + + let webrender_api = state.webrender_api_sender.map(|sender| { + sender.create_api() + }); + let native_display = window.native_display(); IOCompositor { window: window, @@ -345,6 +425,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { surface_map: SurfaceMap::new(BUFFER_MAP_SIZE), pending_subpages: HashSet::new(), last_mouse_move_recipient: None, + webrender: state.webrender, + webrender_api: webrender_api, } } @@ -352,6 +434,14 @@ impl<Window: WindowMethods> IOCompositor<Window> { -> IOCompositor<Window> { let mut compositor = IOCompositor::new(window, state); + if let Some(ref mut webrender) = compositor.webrender { + let compositor_proxy_for_webrender = compositor.channel_to_self + .clone_compositor_proxy(); + let render_notifier = RenderNotifier::new(compositor_proxy_for_webrender, + compositor.constellation_chan.clone()); + webrender.set_render_notifier(Box::new(render_notifier)); + } + // Set the size of the root layer. compositor.update_zoom_transform(); @@ -674,6 +764,11 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.root_pipeline = Some(frame_tree.pipeline.clone()); + if let Some(ref webrender_api) = self.webrender_api { + let pipeline_id = frame_tree.pipeline.id.to_webrender(); + webrender_api.set_root_pipeline(pipeline_id); + } + // If we have an old root layer, release all old tiles before replacing it. let old_root_layer = self.scene.root.take(); if let Some(ref old_root_layer) = old_root_layer { @@ -1172,6 +1267,36 @@ impl<Window: WindowMethods> IOCompositor<Window> { MouseWindowEvent::MouseDown(_, p) => p, MouseWindowEvent::MouseUp(_, p) => p, }; + + if let Some(ref webrender_api) = self.webrender_api { + let root_pipeline_id = match self.get_root_pipeline_id() { + Some(root_pipeline_id) => root_pipeline_id, + None => return, + }; + let root_pipeline = match self.pipeline(root_pipeline_id) { + Some(root_pipeline) => root_pipeline, + None => return, + }; + + let translated_point = + webrender_api.translate_point_to_layer_space(&point.to_untyped()); + let event_to_send = match mouse_window_event { + MouseWindowEvent::Click(button, _) => { + MouseButtonEvent(MouseEventType::Click, button, translated_point) + } + MouseWindowEvent::MouseDown(button, _) => { + MouseButtonEvent(MouseEventType::MouseDown, button, translated_point) + } + MouseWindowEvent::MouseUp(button, _) => { + MouseButtonEvent(MouseEventType::MouseUp, button, translated_point) + } + }; + root_pipeline.script_chan + .send(ConstellationControlMsg::SendEvent(root_pipeline_id, + event_to_send)) + .unwrap(); + } + match self.find_topmost_layer_at_point(point / self.scene.scale) { Some(result) => result.layer.send_mouse_event(self, mouse_window_event, result.point), None => {}, @@ -1184,6 +1309,25 @@ impl<Window: WindowMethods> IOCompositor<Window> { return } + if let Some(ref webrender_api) = self.webrender_api { + let root_pipeline_id = match self.get_root_pipeline_id() { + Some(root_pipeline_id) => root_pipeline_id, + None => return, + }; + let root_pipeline = match self.pipeline(root_pipeline_id) { + Some(root_pipeline) => root_pipeline, + None => return, + }; + + let translated_point = + webrender_api.translate_point_to_layer_space(&cursor.to_untyped()); + let event_to_send = MouseMoveEvent(Some(translated_point)); + root_pipeline.script_chan + .send(ConstellationControlMsg::SendEvent(root_pipeline_id, + event_to_send)) + .unwrap(); + } + match self.find_topmost_layer_at_point(cursor / self.scene.scale) { Some(result) => { // In the case that the mouse was previously over a different layer, @@ -1285,30 +1429,52 @@ impl<Window: WindowMethods> IOCompositor<Window> { fn process_pending_scroll_events(&mut self) { let had_events = self.pending_scroll_zoom_events.len() > 0; - for event in std_mem::replace(&mut self.pending_scroll_zoom_events, - Vec::new()) { - let delta = event.delta / self.scene.scale; - let cursor = event.cursor.as_f32() / self.scene.scale; - if let Some(ref mut layer) = self.scene.root { - layer.handle_scroll_event(delta, cursor); + match self.webrender_api { + Some(ref webrender_api) => { + // Batch up all scroll events into one, or else we'll do way too much painting. + let mut total_delta = None; + let mut last_cursor = Point2D::zero(); + for scroll_event in self.pending_scroll_zoom_events.drain(..) { + let this_delta = scroll_event.delta / self.scene.scale; + last_cursor = scroll_event.cursor.as_f32() / self.scene.scale; + match total_delta { + None => total_delta = Some(this_delta), + Some(ref mut total_delta) => *total_delta = *total_delta + this_delta, + } + } + // TODO(gw): Support zoom (WR issue #28). + if let Some(total_delta) = total_delta { + webrender_api.scroll(total_delta.to_untyped(), last_cursor.to_untyped()); + } } + None => { + for event in std_mem::replace(&mut self.pending_scroll_zoom_events, + Vec::new()) { + let delta = event.delta / self.scene.scale; + let cursor = event.cursor.as_f32() / self.scene.scale; - if event.magnification != 1.0 { - self.zoom_action = true; - self.zoom_time = precise_time_s(); - self.viewport_zoom = ScaleFactor::new( - (self.viewport_zoom.get() * event.magnification) - .min(self.max_viewport_zoom.as_ref().map_or(MAX_ZOOM, ScaleFactor::get)) - .max(self.min_viewport_zoom.as_ref().map_or(MIN_ZOOM, ScaleFactor::get))); - self.update_zoom_transform(); - } + if let Some(ref mut layer) = self.scene.root { + layer.handle_scroll_event(delta, cursor); + } - self.perform_updates_after_scroll(); - } + if event.magnification != 1.0 { + self.zoom_action = true; + self.zoom_time = precise_time_s(); + self.viewport_zoom = ScaleFactor::new( + (self.viewport_zoom.get() * event.magnification) + .min(self.max_viewport_zoom.as_ref().map_or(MAX_ZOOM, ScaleFactor::get)) + .max(self.min_viewport_zoom.as_ref().map_or(MIN_ZOOM, ScaleFactor::get))); + self.update_zoom_transform(); + } + + self.perform_updates_after_scroll(); + } - if had_events { - self.send_viewport_rects_for_all_layers(); + if had_events { + self.send_viewport_rects_for_all_layers(); + } + } } } @@ -1542,6 +1708,10 @@ impl<Window: WindowMethods> IOCompositor<Window> { /// Returns true if any buffer requests were sent or false otherwise. fn send_buffer_requests_for_all_layers(&mut self) -> bool { + if self.webrender.is_some() { + return false; + } + if let Some(ref root_layer) = self.scene.root { root_layer.update_transform_state(&Matrix4::identity(), &Matrix4::identity(), @@ -1656,7 +1826,15 @@ impl<Window: WindowMethods> IOCompositor<Window> { // frame tree. let mut pipeline_epochs = HashMap::new(); for (id, details) in &self.pipeline_details { - pipeline_epochs.insert(*id, details.current_epoch); + if let Some(ref webrender) = self.webrender { + let webrender_pipeline_id = id.to_webrender(); + if let Some(webrender_traits::Epoch(epoch)) = webrender.current_epoch(webrender_pipeline_id) { + let epoch = Epoch(epoch); + pipeline_epochs.insert(*id, epoch); + } + } else { + pipeline_epochs.insert(*id, details.current_epoch); + } } // Pass the pipeline/epoch states to the constellation and check @@ -1707,7 +1885,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { /// is WindowAndPng Ok(Some(png::Image)) is returned. pub fn composite_specific_target(&mut self, target: CompositeTarget) -> Result<Option<Image>, UnableToComposite> { - if !self.context.is_some() { + if self.context.is_none() && self.webrender.is_none() { return Err(UnableToComposite::NoContext) } let (width, height) = @@ -1716,6 +1894,11 @@ impl<Window: WindowMethods> IOCompositor<Window> { return Err(UnableToComposite::WindowUnprepared) } + if let Some(ref mut webrender) = self.webrender { + assert!(self.context.is_none()); + webrender.update(); + } + let wait_for_stable_image = match target { CompositeTarget::WindowAndPng | CompositeTarget::PngFile => true, CompositeTarget::Window => opts::get().exit_after_load, @@ -1738,8 +1921,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { } } - let (framebuffer_ids, texture_ids) = match target { - CompositeTarget::Window => (vec!(), vec!()), + let render_target_info = match target { + CompositeTarget::Window => RenderTargetInfo::empty(), _ => initialize_png(width, height) }; @@ -1760,7 +1943,10 @@ impl<Window: WindowMethods> IOCompositor<Window> { }; // Paint the scene. - if let Some(ref layer) = self.scene.root { + if let Some(ref mut webrender) = self.webrender { + assert!(self.context.is_none()); + webrender.render(self.window_size.to_untyped()); + } else if let Some(ref layer) = self.scene.root { match self.context { Some(context) => { if let Some((point, size)) = self.viewport { @@ -1790,16 +1976,21 @@ impl<Window: WindowMethods> IOCompositor<Window> { let rv = match target { CompositeTarget::Window => None, CompositeTarget::WindowAndPng => { - let img = self.draw_img(framebuffer_ids, texture_ids, width, height); + let img = self.draw_img(render_target_info, + width, + height); Some(Image { width: img.width(), height: img.height(), format: PixelFormat::RGB8, bytes: IpcSharedMemory::from_bytes(&*img), + id: None, }) } CompositeTarget::PngFile => { - let img = self.draw_img(framebuffer_ids, texture_ids, width, height); + let img = self.draw_img(render_target_info, + width, + height); let path = opts::get().output_file.as_ref().unwrap(); let mut file = File::create(path).unwrap(); DynamicImage::ImageRgb8(img).save(&mut file, ImageFormat::PNG).unwrap(); @@ -1820,8 +2011,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { } fn draw_img(&self, - framebuffer_ids: Vec<gl::GLuint>, - texture_ids: Vec<gl::GLuint>, + render_target_info: RenderTargetInfo, width: usize, height: usize) -> RgbImage { @@ -1832,8 +2022,11 @@ impl<Window: WindowMethods> IOCompositor<Window> { gl::bind_framebuffer(gl::FRAMEBUFFER, 0); - gl::delete_buffers(&texture_ids); - gl::delete_frame_buffers(&framebuffer_ids); + gl::delete_buffers(&render_target_info.texture_ids); + gl::delete_frame_buffers(&render_target_info.framebuffer_ids); + if opts::get().use_webrender { + gl::delete_renderbuffers(&render_target_info.renderbuffer_ids); + } // flip image vertically (texture is upside down) let orig_pixels = pixels.clone(); @@ -1859,10 +2052,12 @@ impl<Window: WindowMethods> IOCompositor<Window> { } fn initialize_compositing(&mut self) { - let show_debug_borders = opts::get().show_debug_borders; - self.context = Some(rendergl::RenderContext::new(self.native_display.clone(), - show_debug_borders, - opts::get().output_file.is_some())) + if self.webrender.is_none() { + let show_debug_borders = opts::get().show_debug_borders; + self.context = Some(rendergl::RenderContext::new(self.native_display.clone(), + show_debug_borders, + opts::get().output_file.is_some())) + } } fn find_topmost_layer_at_point_for_layer(&self, @@ -1951,6 +2146,10 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.surface_map.insert_surfaces(&self.native_display, surfaces); } + fn get_root_pipeline_id(&self) -> Option<PipelineId> { + self.scene.root.as_ref().map(|root_layer| root_layer.extra_data.borrow().pipeline_id) + } + #[allow(dead_code)] fn dump_layer_tree(&self) { if !opts::get().dump_layer_tree { @@ -2076,19 +2275,37 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind /// /// This is used when resizing the window. fn repaint_synchronously(&mut self) { - while self.shutdown_state != ShutdownState::ShuttingDown { - let msg = self.port.recv_compositor_msg(); - let received_new_buffers = match msg { - Msg::AssignPaintedBuffers(..) => true, - _ => false, - }; - let keep_going = self.handle_browser_message(msg); - if received_new_buffers { - self.composite(); - break + if self.webrender.is_none() { + while self.shutdown_state != ShutdownState::ShuttingDown { + let msg = self.port.recv_compositor_msg(); + let received_new_buffers = match msg { + Msg::AssignPaintedBuffers(..) => true, + _ => false, + }; + let keep_going = self.handle_browser_message(msg); + if received_new_buffers { + self.composite(); + break + } + if !keep_going { + break + } } - if !keep_going { - break + } else { + while self.shutdown_state != ShutdownState::ShuttingDown { + let msg = self.port.recv_compositor_msg(); + let need_recomposite = match msg { + Msg::RecompositeAfterScroll => true, + _ => false, + }; + let keep_going = self.handle_browser_message(msg); + if need_recomposite { + self.composite(); + break + } + if !keep_going { + break + } } } } diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index 618bac9674b..f9f0c03d1e3 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -26,6 +26,8 @@ use url::Url; use windowing::{WindowEvent, WindowMethods}; pub use constellation::SendableFrameTree; pub use windowing; +use webrender; +use webrender_traits; /// Sends messages to the compositor. This is a trait supplied by the port because the method used /// to communicate with the compositor may have to kick OS event loops awake, communicate cross- @@ -100,6 +102,16 @@ pub fn run_script_listener_thread(compositor_proxy: Box<CompositorProxy + 'stati } } +pub trait RenderListener { + fn recomposite(&mut self); +} + +impl RenderListener for Box<CompositorProxy + 'static> { + fn recomposite(&mut self) { + self.send(Msg::RecompositeAfterScroll); + } +} + /// Implementation of the abstract `PaintListener` interface. impl PaintListener for Box<CompositorProxy + 'static + Send> { fn native_display(&mut self) -> Option<NativeDisplay> { @@ -301,4 +313,7 @@ pub struct InitialCompositorState { pub time_profiler_chan: time::ProfilerChan, /// A channel to the memory profiler thread. pub mem_profiler_chan: mem::ProfilerChan, + /// Instance of webrender API if enabled + pub webrender: Option<webrender::Renderer>, + pub webrender_api_sender: Option<webrender_traits::RenderApiSender>, } diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs index a08687bb680..b7a57f7069e 100644 --- a/components/compositing/constellation.rs +++ b/components/compositing/constellation.rs @@ -63,6 +63,7 @@ use url::Url; use util::geometry::PagePx; use util::thread::spawn_named; use util::{opts, prefs}; +use webrender_traits; #[derive(Debug, PartialEq)] enum ReadyToSave { @@ -181,6 +182,9 @@ pub struct Constellation<LTF, STF> { /// Document states for loaded pipelines (used only when writing screenshots). document_states: HashMap<PipelineId, DocumentState>, + + // Webrender interface, if enabled. + webrender_api_sender: Option<webrender_traits::RenderApiSender>, } /// State needed to construct a constellation. @@ -203,6 +207,8 @@ pub struct InitialConstellationState { pub mem_profiler_chan: mem::ProfilerChan, /// Whether the constellation supports the clipboard. pub supports_clipboard: bool, + /// Optional webrender API reference (if enabled). + pub webrender_api_sender: Option<webrender_traits::RenderApiSender>, } /// Stores the navigation context for a single frame in the frame tree. @@ -347,6 +353,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF> scheduler_chan: TimerScheduler::start(), child_processes: Vec::new(), document_states: HashMap::new(), + webrender_api_sender: state.webrender_api_sender, }; let namespace_id = constellation.next_pipeline_namespace_id(); PipelineNamespace::install(namespace_id); @@ -399,6 +406,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF> load_data: load_data, device_pixel_ratio: self.window_size.device_pixel_ratio, pipeline_namespace_id: self.next_pipeline_namespace_id(), + webrender_api_sender: self.webrender_api_sender.clone(), }); if spawning_paint_only { @@ -1196,7 +1204,9 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF> size: &Size2D<i32>, response_sender: IpcSender<(IpcSender<CanvasMsg>, usize)>) { let id = self.canvas_paint_threads.len(); - let (out_of_process_sender, in_process_sender) = CanvasPaintThread::start(*size); + let webrender_api = self.webrender_api_sender.clone(); + let (out_of_process_sender, in_process_sender) = CanvasPaintThread::start(*size, + webrender_api); self.canvas_paint_threads.push(in_process_sender); response_sender.send((out_of_process_sender, id)).unwrap() } @@ -1206,13 +1216,14 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF> size: &Size2D<i32>, attributes: GLContextAttributes, response_sender: IpcSender<Result<(IpcSender<CanvasMsg>, usize), String>>) { - let response = match WebGLPaintThread::start(*size, attributes) { + let webrender_api = self.webrender_api_sender.clone(); + let response = match WebGLPaintThread::start(*size, attributes, webrender_api) { Ok((out_of_process_sender, in_process_sender)) => { let id = self.webgl_paint_threads.len(); self.webgl_paint_threads.push(in_process_sender); Ok((out_of_process_sender, id)) }, - Err(msg) => Err(msg.to_owned()), + Err(msg) => Err(msg), }; response_sender.send(response).unwrap() diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index 6434c3a8939..410b007a3a6 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -48,6 +48,8 @@ extern crate time; extern crate url; #[macro_use] extern crate util; +extern crate webrender; +extern crate webrender_traits; pub use compositor_thread::{CompositorEventListener, CompositorProxy, CompositorThread}; pub use constellation::Constellation; diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs index 2a4e3b1999e..bbf892048c8 100644 --- a/components/compositing/pipeline.rs +++ b/components/compositing/pipeline.rs @@ -35,6 +35,7 @@ use util::geometry::{PagePx, ViewportPx}; use util::ipc::OptionalIpcSender; use util::opts::{self, Opts}; use util::prefs; +use webrender_traits; /// A uniquely-identifiable pipeline of script thread, layout thread, and paint thread. pub struct Pipeline { @@ -113,6 +114,8 @@ pub struct InitialPipelineState { pub load_data: LoadData, /// The ID of the pipeline namespace for this script thread. pub pipeline_namespace_id: PipelineNamespaceId, + /// Optional webrender api (if enabled). + pub webrender_api_sender: Option<webrender_traits::RenderApiSender>, } impl Pipeline { @@ -225,6 +228,7 @@ impl Pipeline { layout_content_process_shutdown_port: layout_content_process_shutdown_port, script_content_process_shutdown_chan: script_content_process_shutdown_chan, script_content_process_shutdown_port: script_content_process_shutdown_port, + webrender_api_sender: state.webrender_api_sender, }; let privileged_pipeline_content = PrivilegedPipelineContent { @@ -376,6 +380,7 @@ pub struct UnprivilegedPipelineContent { layout_content_process_shutdown_port: IpcReceiver<()>, script_content_process_shutdown_chan: IpcSender<()>, script_content_process_shutdown_port: IpcReceiver<()>, + webrender_api_sender: Option<webrender_traits::RenderApiSender>, } impl UnprivilegedPipelineContent { @@ -419,7 +424,8 @@ impl UnprivilegedPipelineContent { self.time_profiler_chan, self.mem_profiler_chan, self.layout_shutdown_chan, - self.layout_content_process_shutdown_chan.clone()); + self.layout_content_process_shutdown_chan.clone(), + self.webrender_api_sender); if wait_for_completion { self.script_content_process_shutdown_port.recv().unwrap(); |