From c60c72fb15fe7ad81bdfb558c979306d488ec45e Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Mon, 28 Jul 2014 19:49:15 -0700 Subject: [PATCH] Push get_buffer_requests_recursively into rust-layers Also do some reorganization and abstraction in IOCompositor now that we do not have to borrow self.scene.root. --- src/components/compositing/compositor.rs | 111 ++++++++++-------- src/components/compositing/compositor_data.rs | 40 +------ src/support/layers/rust-layers | 2 +- 3 files changed, 66 insertions(+), 87 deletions(-) diff --git a/src/components/compositing/compositor.rs b/src/components/compositing/compositor.rs index 11173d140f8..445f9e83afc 100644 --- a/src/components/compositing/compositor.rs +++ b/src/components/compositing/compositor.rs @@ -27,7 +27,7 @@ use geom::rect::Rect; use geom::size::TypedSize2D; use geom::scale_factor::ScaleFactor; use gfx::render_task::{RenderChan, ReRenderMsg, ReRenderRequest, UnusedBufferMsg}; -use layers::layers::LayerBufferSet; +use layers::layers::{BufferRequest, Layer, LayerBufferSet}; use layers::rendergl; use layers::rendergl::RenderContext; use layers::scene::Scene; @@ -806,61 +806,78 @@ impl IOCompositor { chan.send(NavigateMsg(direction)) } - /// Get BufferRequests from each layer. - fn ask_for_tiles(&mut self) { + fn convert_buffer_requests_to_pipeline_requests_map(&self, + requests: Vec<(Rc>, + Vec)>) -> + HashMap)> { let scale = self.device_pixels_per_page_px(); - let mut num_rerendermsgs_sent = 0; - let window_rect_in_device_pixels = Rect(Point2D(0f32, 0f32), - self.window_size.as_f32().to_untyped()); + let mut results: + HashMap)> = HashMap::new(); - match self.scene.root { - Some(ref mut layer) => { - let mut layers_and_requests = Vec::new(); - let mut unused_buffers = Vec::new(); - CompositorData::get_buffer_requests_recursively(&mut layers_and_requests, - &mut unused_buffers, - layer.clone(), - window_rect_in_device_pixels); + for (layer, mut layer_requests) in requests.move_iter() { + let pipeline_id = layer.extra_data.borrow().pipeline.id; + let &(_, ref mut vec) = results.find_or_insert_with(pipeline_id, |_| { + (layer.extra_data.borrow().pipeline.render_chan.clone(), Vec::new()) + }); - // Return unused tiles first, so that they can be reused by any new BufferRequests. + // All the BufferRequests are in layer/device coordinates, but the render task + // wants to know the page coordinates. We scale them before sending them. + for request in layer_requests.mut_iter() { + request.page_rect = request.page_rect / scale.get(); + } + + vec.push(ReRenderRequest { + buffer_requests: layer_requests, + scale: scale.get(), + layer_id: layer.extra_data.borrow().id, + epoch: layer.extra_data.borrow().epoch, + }); + } + + return results; + } + + fn send_back_unused_buffers(&mut self) { + match self.root_pipeline { + Some(ref pipeline) => { + let unused_buffers = self.scene.collect_unused_buffers(); let have_unused_buffers = unused_buffers.len() > 0; self.recomposite = self.recomposite || have_unused_buffers; if have_unused_buffers { let message = UnusedBufferMsg(unused_buffers); - let _ = layer.extra_data.borrow().pipeline.render_chan.send_opt(message); + let _ = pipeline.render_chan.send_opt(message); } - - // We want to batch requests for each pipeline to avoid race conditions - // when handling the resulting BufferRequest responses. - let mut pipeline_requests: - HashMap)> = HashMap::new(); - for (layer, mut requests) in layers_and_requests.move_iter() { - let pipeline_id = layer.extra_data.borrow().pipeline.id; - let &(_, ref mut vec) = pipeline_requests.find_or_insert_with(pipeline_id, |_| { - (layer.extra_data.borrow().pipeline.render_chan.clone(), Vec::new()) - }); - - // All the BufferRequests are in layer/device coordinates, but the render task - // wants to know the page coordinates. We scale them before sending them. - for request in requests.mut_iter() { - request.page_rect = request.page_rect / scale.get(); - } - - vec.push(ReRenderRequest { - buffer_requests: requests, - scale: scale.get(), - layer_id: layer.extra_data.borrow().id, - epoch: layer.extra_data.borrow().epoch, - }); - } - - for (_pipeline_id, (chan, requests)) in pipeline_requests.move_iter() { - num_rerendermsgs_sent += 1; - let _ = chan.send_opt(ReRenderMsg(requests)); - } - } - None => { } + }, + None => {} } + } + + /// Get BufferRequests from each layer. + fn ask_for_tiles(&mut self) { + let mut layers_and_requests = Vec::new(); + self.scene.get_buffer_requests(&mut layers_and_requests, + Rect(Point2D(0f32, 0f32), + self.window_size.as_f32().to_untyped())); + + // Return unused tiles first, so that they can be reused by any new BufferRequests. + self.send_back_unused_buffers(); + + if layers_and_requests.len() == 0 { + return; + } + + // We want to batch requests for each pipeline to avoid race conditions + // when handling the resulting BufferRequest responses. + let pipeline_requests = + self.convert_buffer_requests_to_pipeline_requests_map(layers_and_requests); + + let mut num_rerendermsgs_sent = 0; + for (_pipeline_id, (chan, requests)) in pipeline_requests.move_iter() { + num_rerendermsgs_sent += 1; + let _ = chan.send_opt(ReRenderMsg(requests)); + } + self.add_outstanding_rerendermsg(num_rerendermsgs_sent); } diff --git a/src/components/compositing/compositor_data.rs b/src/components/compositing/compositor_data.rs index e08694443b9..801fcecc9e9 100644 --- a/src/components/compositing/compositor_data.rs +++ b/src/components/compositing/compositor_data.rs @@ -8,11 +8,10 @@ use pipeline::CompositionPipeline; use azure::azure_hl::Color; use geom::point::TypedPoint2D; -use geom::rect::Rect; use geom::scale_factor::ScaleFactor; use geom::size::{Size2D, TypedSize2D}; use gfx::render_task::UnusedBufferMsg; -use layers::layers::{BufferRequest, Layer, LayerBuffer, LayerBufferSet}; +use layers::layers::{Layer, LayerBufferSet}; use layers::platform::surface::NativeSurfaceMethods; use servo_msg::compositor_msg::{Epoch, LayerId}; use servo_msg::compositor_msg::ScrollPolicy; @@ -81,43 +80,6 @@ impl CompositorData { layer.add_child(new_kid.clone()); } - // Given the current window size, determine which tiles need to be (re-)rendered and sends them - // off the the appropriate renderer. Returns true if and only if the scene should be repainted. - pub fn get_buffer_requests_recursively(requests: &mut Vec<(Rc>, - Vec)>, - unused_buffers: &mut Vec>, - layer: Rc>, - window_rect_in_device_pixels: Rect) { - let (request, unused) = layer.get_tile_rects_page(window_rect_in_device_pixels); - unused_buffers.push_all_move(unused); - - if !request.is_empty() { - requests.push((layer.clone(), request)); - } - - for kid in layer.children().iter() { - let mut new_rect = window_rect_in_device_pixels; - let content_offset = kid.content_offset.borrow(); - new_rect.origin.x = new_rect.origin.x - content_offset.x; - new_rect.origin.y = new_rect.origin.y - content_offset.y; - - match new_rect.intersection(&*kid.bounds.borrow()) { - Some(new_rect) => { - // Child layers act as if they are rendered at (0,0), so we - // subtract the layer's (x,y) coords in its containing page - // to make the child_rect appear in coordinates local to it. - let child_rect = Rect(new_rect.origin.sub(&kid.bounds.borrow().origin), - new_rect.size); - CompositorData::get_buffer_requests_recursively(requests, - unused_buffers, - kid.clone(), - child_rect); - } - None => {} - } - }; - } - pub fn update_layer(layer: Rc>, layer_properties: LayerProperties) { layer.extra_data.borrow_mut().epoch = layer_properties.epoch; layer.extra_data.borrow_mut().background_color = layer_properties.background_color; diff --git a/src/support/layers/rust-layers b/src/support/layers/rust-layers index f5f5a8ba195..b8a9223648f 160000 --- a/src/support/layers/rust-layers +++ b/src/support/layers/rust-layers @@ -1 +1 @@ -Subproject commit f5f5a8ba195921b2d786cbaf98c32087edafb0fe +Subproject commit b8a9223648fcd2b8f379eb6a29f2769e82dc7967