Clip display list based on frame viewport

Instead of creating a display list for the entire page, only create one
for an area that expands around the viewport. On my machine this makes
incremental layout of http://timecube.com 50% faster.
This commit is contained in:
Martin Robinson 2014-10-22 14:00:09 -07:00
parent f4471f0602
commit c7327450ef
11 changed files with 130 additions and 34 deletions

View file

@ -37,10 +37,12 @@ use layers::scene::Scene;
use png;
use gleam::gl::types::{GLint, GLsizei};
use gleam::gl;
use script_traits::{ViewportMsg, ScriptControlChan};
use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading, IdleRenderState, LayerId};
use servo_msg::compositor_msg::{ReadyState, RenderingRenderState, RenderState, Scrollable};
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, LoadUrlMsg, NavigateMsg};
use servo_msg::constellation_msg::{LoadData, PipelineId, ResizedWindowMsg, WindowSizeData};
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, LoadUrlMsg};
use servo_msg::constellation_msg::{NavigateMsg, LoadData, PipelineId, ResizedWindowMsg};
use servo_msg::constellation_msg::{WindowSizeData};
use servo_msg::constellation_msg;
use servo_util::geometry::{PagePx, ScreenPx, ViewportPx};
use servo_util::memory::MemoryProfilerChan;
@ -265,6 +267,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.set_frame_tree(&frame_tree,
response_chan,
new_constellation_chan);
self.send_viewport_rects_for_all_layers();
}
(CreateOrUpdateRootLayer(layer_properties), NotShuttingDown) => {
@ -741,6 +744,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
fn process_pending_scroll_events(&mut self) {
let had_scroll_events = self.pending_scroll_events.len() > 0;
for scroll_event in mem::replace(&mut self.pending_scroll_events, Vec::new()).into_iter() {
let delta = scroll_event.delta / self.scene.scale;
let cursor = scroll_event.cursor.as_f32() / self.scene.scale;
@ -755,6 +759,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.start_scrolling_timer_if_necessary();
self.send_buffer_requests_for_all_layers();
}
if had_scroll_events {
self.send_viewport_rects_for_all_layers();
}
}
fn device_pixels_per_screen_px(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> {
@ -811,6 +819,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
None => { }
}
self.send_viewport_rects_for_all_layers();
self.composite_if_necessary();
}
@ -868,6 +877,27 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
}
fn send_viewport_rect_for_layer(&self, layer: Rc<Layer<CompositorData>>) {
if layer.extra_data.borrow().id == LayerId::null() {
let layer_rect = Rect(-layer.extra_data.borrow().scroll_offset.to_untyped(),
layer.bounds.borrow().size.to_untyped());
let pipeline = &layer.extra_data.borrow().pipeline;
let ScriptControlChan(ref chan) = pipeline.script_chan;
chan.send(ViewportMsg(pipeline.id.clone(), layer_rect));
}
for kid in layer.children().iter() {
self.send_viewport_rect_for_layer(kid.clone());
}
}
fn send_viewport_rects_for_all_layers(&self) {
match self.scene.root {
Some(ref root) => self.send_viewport_rect_for_layer(root.clone()),
None => {},
}
}
/// Returns true if any buffer requests were sent or false otherwise.
fn send_buffer_requests_for_all_layers(&mut self) -> bool {
let mut layers_and_requests = Vec::new();