Move BufferRequest request code from CompositorData into Compositor

Once we remove the integration with Servo's layer scaling, this will
make it easier pull requesting buffers into rust-layers.
This commit is contained in:
Martin Robinson 2014-07-25 08:21:27 -07:00
parent 32740b3012
commit fb51bc79ad
2 changed files with 49 additions and 42 deletions

View file

@ -26,7 +26,7 @@ use geom::point::{Point2D, TypedPoint2D};
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::TypedSize2D; use geom::size::TypedSize2D;
use geom::scale_factor::ScaleFactor; use geom::scale_factor::ScaleFactor;
use gfx::render_task::ReRenderMsg; use gfx::render_task::{RenderChan, ReRenderMsg, ReRenderRequest, UnusedBufferMsg};
use layers::layers::LayerBufferSet; use layers::layers::LayerBufferSet;
use layers::rendergl; use layers::rendergl;
use layers::rendergl::RenderContext; use layers::rendergl::RenderContext;
@ -791,17 +791,44 @@ impl IOCompositor {
match self.scene.root { match self.scene.root {
Some(ref layer) => { Some(ref layer) => {
let rect = Rect(Point2D(0f32, 0f32), page_window.to_untyped()); let rect = Rect(Point2D(0f32, 0f32), page_window.to_untyped());
let mut request_map = HashMap::new(); let mut layers_and_requests = Vec::new();
let recomposite = let mut unused_buffers = Vec::new();
CompositorData::get_buffer_requests_recursively(&mut request_map, CompositorData::get_buffer_requests_recursively(&mut layers_and_requests,
&mut unused_buffers,
layer.clone(), layer.clone(),
rect, rect,
scale.get()); scale.get());
for (_pipeline_id, (chan, requests)) in request_map.move_iter() {
// Return unused tiles first, so that they can be reused by any new BufferRequests.
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);
}
// We want to batch requests for each pipeline to avoid race conditions
// when handling the resulting BufferRequest responses.
let mut pipeline_requests:
HashMap<PipelineId, (RenderChan, Vec<ReRenderRequest>)> = HashMap::new();
for (layer, 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())
});
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; num_rerendermsgs_sent += 1;
let _ = chan.send_opt(ReRenderMsg(requests)); let _ = chan.send_opt(ReRenderMsg(requests));
} }
self.recomposite = self.recomposite || recomposite;
} }
None => { } None => { }
} }

View file

@ -10,14 +10,13 @@ use azure::azure_hl::Color;
use geom::point::TypedPoint2D; use geom::point::TypedPoint2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::{Size2D, TypedSize2D}; use geom::size::{Size2D, TypedSize2D};
use gfx::render_task::{ReRenderRequest, RenderChan, UnusedBufferMsg}; use gfx::render_task::{UnusedBufferMsg};
use layers::layers::{Layer, LayerBufferSet}; use layers::layers::{BufferRequest, Layer, LayerBuffer, LayerBufferSet};
use layers::platform::surface::NativeSurfaceMethods; use layers::platform::surface::NativeSurfaceMethods;
use servo_msg::compositor_msg::{Epoch, LayerId}; use servo_msg::compositor_msg::{Epoch, LayerId};
use servo_msg::compositor_msg::ScrollPolicy; use servo_msg::compositor_msg::ScrollPolicy;
use servo_msg::constellation_msg::PipelineId; use servo_msg::constellation_msg::PipelineId;
use servo_util::geometry::PagePx; use servo_util::geometry::PagePx;
use std::collections::hashmap::HashMap;
use std::rc::Rc; use std::rc::Rc;
pub struct CompositorData { pub struct CompositorData {
@ -83,36 +82,20 @@ impl CompositorData {
// Given the current window size, determine which tiles need to be (re-)rendered and sends them // 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. // off the the appropriate renderer. Returns true if and only if the scene should be repainted.
pub fn get_buffer_requests_recursively(requests: &mut HashMap<PipelineId, pub fn get_buffer_requests_recursively(requests: &mut Vec<(Rc<Layer<CompositorData>>,
(RenderChan, Vec<BufferRequest>)>,
Vec<ReRenderRequest>)>, unused_buffers: &mut Vec<Box<LayerBuffer>>,
layer: Rc<Layer<CompositorData>>, layer: Rc<Layer<CompositorData>>,
window_rect: Rect<f32>, window_rect: Rect<f32>,
scale: f32) scale: f32) {
-> bool {
let (request, unused) = layer.get_tile_rects_page(window_rect, scale); let (request, unused) = layer.get_tile_rects_page(window_rect, scale);
let redisplay = !unused.is_empty(); unused_buffers.push_all_move(unused);
if redisplay {
// Send back unused tiles.
let msg = UnusedBufferMsg(unused);
let _ = layer.extra_data.borrow().pipeline.render_chan.send_opt(msg);
}
if !request.is_empty() { if !request.is_empty() {
// Ask for tiles. requests.push((layer.clone(), request));
let pipeline_id = layer.extra_data.borrow().pipeline.id;
let msg = ReRenderRequest {
buffer_requests: request,
scale: scale,
layer_id: layer.extra_data.borrow().id,
epoch: layer.extra_data.borrow().epoch,
};
let &(_, ref mut vec) = requests.find_or_insert_with(pipeline_id, |_| {
(layer.extra_data.borrow().pipeline.render_chan.clone(), Vec::new())
});
vec.push(msg);
} }
let get_child_buffer_request = |kid: &Rc<Layer<CompositorData>>| -> bool { for kid in layer.children().iter() {
let mut new_rect = window_rect; let mut new_rect = window_rect;
let offset = kid.extra_data.borrow().scroll_offset.to_untyped(); let offset = kid.extra_data.borrow().scroll_offset.to_untyped();
new_rect.origin.x = new_rect.origin.x - offset.x; new_rect.origin.x = new_rect.origin.x - offset.x;
@ -125,17 +108,14 @@ impl CompositorData {
let child_rect = Rect(new_rect.origin.sub(&kid.bounds.borrow().origin), let child_rect = Rect(new_rect.origin.sub(&kid.bounds.borrow().origin),
new_rect.size); new_rect.size);
CompositorData::get_buffer_requests_recursively(requests, CompositorData::get_buffer_requests_recursively(requests,
unused_buffers,
kid.clone(), kid.clone(),
child_rect, child_rect,
scale) scale);
}
None => {
false // Layer is offscreen
} }
None => {}
} }
}; };
layer.children().iter().map(get_child_buffer_request).any(|b| b) || redisplay
} }
pub fn update_layer(layer: Rc<Layer<CompositorData>>, layer_properties: LayerProperties) { pub fn update_layer(layer: Rc<Layer<CompositorData>>, layer_properties: LayerProperties) {