compositing: Support multiple events per frame.

Improves scrolling performance on Mac.
This commit is contained in:
Patrick Walton 2015-05-15 15:07:26 -07:00
parent e52197d126
commit 0098d9e9e8
12 changed files with 67 additions and 59 deletions

View file

@ -1003,7 +1003,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
if pipeline_details.animations_running ||
pipeline_details.animation_callbacks_running {
self.constellation_chan.0.send(ConstellationMsg::TickAnimation(*pipeline_id)).unwrap();
self.constellation_chan.0.send(ConstellationMsg::TickAnimation(*pipeline_id))
.unwrap();
}
}
}
@ -1064,7 +1065,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
if let Some(min_zoom) = self.min_viewport_zoom.as_ref() {
viewport_zoom = min_zoom.get().max(viewport_zoom)
}
let viewport_zoom = self.max_viewport_zoom.as_ref().map_or(1., |z| z.get()).min(viewport_zoom);
let viewport_zoom = self.max_viewport_zoom
.as_ref()
.map_or(1., |z| z.get())
.min(viewport_zoom);
let viewport_zoom = ScaleFactor::new(viewport_zoom);
self.viewport_zoom = viewport_zoom;
@ -1355,7 +1359,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
rv
}
fn draw_png(&self, framebuffer_ids: Vec<gl::GLuint>, texture_ids: Vec<gl::GLuint>, width: usize, height: usize) -> png::Image {
fn draw_png(&self,
framebuffer_ids: Vec<gl::GLuint>,
texture_ids: Vec<gl::GLuint>,
width: usize,
height: usize)
-> png::Image {
let mut pixels = gl::read_pixels(0, 0,
width as gl::GLsizei,
height as gl::GLsizei,
@ -1489,7 +1498,7 @@ fn find_layer_with_pipeline_and_layer_id_for_layer(layer: Rc<Layer<CompositorDat
}
impl<Window> CompositorEventListener for IOCompositor<Window> where Window: WindowMethods {
fn handle_event(&mut self, msg: WindowEvent) -> bool {
fn handle_events(&mut self, messages: Vec<WindowEvent>) -> bool {
// Check for new messages coming from the other tasks in the system.
loop {
match self.port.try_recv_compositor_msg() {
@ -1509,8 +1518,10 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
return false;
}
// Handle the message coming from the windowing system.
self.handle_window_message(msg);
// Handle any messages coming from the windowing system.
for message in messages.into_iter() {
self.handle_window_message(message);
}
// If a pinch-zoom happened recently, ask for tiles at the new resolution
if self.zoom_action && precise_time_s() - self.zoom_time > 0.3 {

View file

@ -87,7 +87,8 @@ pub trait CompositorLayer {
/// Destroys tiles for this layer and all descendent layers, sending the buffers back to the
/// painter to be destroyed or reused.
fn clear_all_tiles<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods;
fn clear_all_tiles<Window>(&self, compositor: &IOCompositor<Window>)
where Window: WindowMethods;
/// Removes the root layer (and any children) for a given pipeline from the
/// compositor. Buffers that the compositor is holding are returned to the

View file

@ -254,7 +254,7 @@ impl CompositorTask {
}
pub trait CompositorEventListener {
fn handle_event(&mut self, event: WindowEvent) -> bool;
fn handle_events(&mut self, events: Vec<WindowEvent>) -> bool;
fn repaint_synchronously(&mut self);
fn shutdown(&mut self);
fn pinch_zoom_level(&self) -> f32;

View file

@ -66,7 +66,7 @@ impl NullCompositor {
}
impl CompositorEventListener for NullCompositor {
fn handle_event(&mut self, _: WindowEvent) -> bool {
fn handle_events(&mut self, _: Vec<WindowEvent>) -> bool {
match self.port.recv_compositor_msg() {
Msg::Exit(chan) => {
debug!("shutting down the constellation");

View file

@ -45,12 +45,11 @@ pub use constellation::Constellation;
pub mod compositor_task;
mod compositor_layer;
mod scrolling;
mod compositor;
mod headless;
mod scrolling;
pub mod pipeline;
pub mod constellation;
pub mod windowing;

View file

@ -75,9 +75,9 @@ pub struct Browser {
/// application Servo is embedded in. Clients then create an event
/// loop to pump messages between the embedding application and
/// various browser components.
impl Browser {
impl Browser {
pub fn new<Window>(window: Option<Rc<Window>>) -> Browser
where Window: WindowMethods + 'static {
where Window: WindowMethods + 'static {
// Global configuration options, parsed from the command line.
let opts = opts::get();
@ -124,8 +124,8 @@ impl Browser {
}
}
pub fn handle_event(&mut self, event: WindowEvent) -> bool {
self.compositor.handle_event(event)
pub fn handle_events(&mut self, events: Vec<WindowEvent>) -> bool {
self.compositor.handle_events(events)
}
pub fn repaint_synchronously(&mut self) {

View file

@ -64,17 +64,14 @@ fn main() {
maybe_register_glutin_resize_handler(&window, &mut browser);
browser.browser.handle_event(WindowEvent::InitializeCompositing);
browser.browser.handle_events(vec![WindowEvent::InitializeCompositing]);
// Feed events from the window to the browser until the browser
// says to stop.
loop {
let should_continue = match window {
None => browser.browser.handle_event(WindowEvent::Idle),
Some(ref window) => {
let event = window.wait_events();
browser.browser.handle_event(event)
}
None => browser.browser.handle_events(Vec::new()),
Some(ref window) => browser.browser.handle_events(window.wait_events()),
};
if !should_continue {
break
@ -123,7 +120,7 @@ impl app::NestedEventLoopListener for BrowserWrapper {
WindowEvent::Resize(..) => true,
_ => false,
};
if !self.browser.handle_event(event) {
if !self.browser.handle_events(vec![event]) {
return false
}
if is_resize {