mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
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.
This commit is contained in:
parent
da0fa6ae51
commit
c60c72fb15
3 changed files with 66 additions and 87 deletions
|
@ -27,7 +27,7 @@ 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::{RenderChan, ReRenderMsg, ReRenderRequest, UnusedBufferMsg};
|
use gfx::render_task::{RenderChan, ReRenderMsg, ReRenderRequest, UnusedBufferMsg};
|
||||||
use layers::layers::LayerBufferSet;
|
use layers::layers::{BufferRequest, Layer, LayerBufferSet};
|
||||||
use layers::rendergl;
|
use layers::rendergl;
|
||||||
use layers::rendergl::RenderContext;
|
use layers::rendergl::RenderContext;
|
||||||
use layers::scene::Scene;
|
use layers::scene::Scene;
|
||||||
|
@ -806,61 +806,78 @@ impl IOCompositor {
|
||||||
chan.send(NavigateMsg(direction))
|
chan.send(NavigateMsg(direction))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get BufferRequests from each layer.
|
fn convert_buffer_requests_to_pipeline_requests_map(&self,
|
||||||
fn ask_for_tiles(&mut self) {
|
requests: Vec<(Rc<Layer<CompositorData>>,
|
||||||
|
Vec<BufferRequest>)>) ->
|
||||||
|
HashMap<PipelineId, (RenderChan,
|
||||||
|
Vec<ReRenderRequest>)> {
|
||||||
let scale = self.device_pixels_per_page_px();
|
let scale = self.device_pixels_per_page_px();
|
||||||
let mut num_rerendermsgs_sent = 0;
|
let mut results:
|
||||||
let window_rect_in_device_pixels = Rect(Point2D(0f32, 0f32),
|
HashMap<PipelineId, (RenderChan, Vec<ReRenderRequest>)> = HashMap::new();
|
||||||
self.window_size.as_f32().to_untyped());
|
|
||||||
|
|
||||||
match self.scene.root {
|
for (layer, mut layer_requests) in requests.move_iter() {
|
||||||
Some(ref mut layer) => {
|
let pipeline_id = layer.extra_data.borrow().pipeline.id;
|
||||||
let mut layers_and_requests = Vec::new();
|
let &(_, ref mut vec) = results.find_or_insert_with(pipeline_id, |_| {
|
||||||
let mut unused_buffers = Vec::new();
|
(layer.extra_data.borrow().pipeline.render_chan.clone(), Vec::new())
|
||||||
CompositorData::get_buffer_requests_recursively(&mut layers_and_requests,
|
});
|
||||||
&mut unused_buffers,
|
|
||||||
layer.clone(),
|
|
||||||
window_rect_in_device_pixels);
|
|
||||||
|
|
||||||
// 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;
|
let have_unused_buffers = unused_buffers.len() > 0;
|
||||||
self.recomposite = self.recomposite || have_unused_buffers;
|
self.recomposite = self.recomposite || have_unused_buffers;
|
||||||
if have_unused_buffers {
|
if have_unused_buffers {
|
||||||
let message = UnusedBufferMsg(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
|
None => {}
|
||||||
// when handling the resulting BufferRequest responses.
|
|
||||||
let mut pipeline_requests:
|
|
||||||
HashMap<PipelineId, (RenderChan, Vec<ReRenderRequest>)> = 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 => { }
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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);
|
self.add_outstanding_rerendermsg(num_rerendermsgs_sent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,10 @@ use pipeline::CompositionPipeline;
|
||||||
|
|
||||||
use azure::azure_hl::Color;
|
use azure::azure_hl::Color;
|
||||||
use geom::point::TypedPoint2D;
|
use geom::point::TypedPoint2D;
|
||||||
use geom::rect::Rect;
|
|
||||||
use geom::scale_factor::ScaleFactor;
|
use geom::scale_factor::ScaleFactor;
|
||||||
use geom::size::{Size2D, TypedSize2D};
|
use geom::size::{Size2D, TypedSize2D};
|
||||||
use gfx::render_task::UnusedBufferMsg;
|
use gfx::render_task::UnusedBufferMsg;
|
||||||
use layers::layers::{BufferRequest, Layer, LayerBuffer, LayerBufferSet};
|
use layers::layers::{Layer, 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;
|
||||||
|
@ -81,43 +80,6 @@ impl CompositorData {
|
||||||
layer.add_child(new_kid.clone());
|
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<Layer<CompositorData>>,
|
|
||||||
Vec<BufferRequest>)>,
|
|
||||||
unused_buffers: &mut Vec<Box<LayerBuffer>>,
|
|
||||||
layer: Rc<Layer<CompositorData>>,
|
|
||||||
window_rect_in_device_pixels: Rect<f32>) {
|
|
||||||
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<CompositorData>>, layer_properties: LayerProperties) {
|
pub fn update_layer(layer: Rc<Layer<CompositorData>>, layer_properties: LayerProperties) {
|
||||||
layer.extra_data.borrow_mut().epoch = layer_properties.epoch;
|
layer.extra_data.borrow_mut().epoch = layer_properties.epoch;
|
||||||
layer.extra_data.borrow_mut().background_color = layer_properties.background_color;
|
layer.extra_data.borrow_mut().background_color = layer_properties.background_color;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit f5f5a8ba195921b2d786cbaf98c32087edafb0fe
|
Subproject commit b8a9223648fcd2b8f379eb6a29f2769e82dc7967
|
Loading…
Add table
Add a link
Reference in a new issue