mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #6077 - pcwalton:multiple-events-per-frame, r=glennw
Improves scrolling performance significantly on Mac. r? @glennw <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6077) <!-- Reviewable:end -->
This commit is contained in:
commit
071f89aa5f
12 changed files with 67 additions and 59 deletions
|
@ -1003,7 +1003,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
if pipeline_details.animations_running ||
|
if pipeline_details.animations_running ||
|
||||||
pipeline_details.animation_callbacks_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() {
|
if let Some(min_zoom) = self.min_viewport_zoom.as_ref() {
|
||||||
viewport_zoom = min_zoom.get().max(viewport_zoom)
|
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);
|
let viewport_zoom = ScaleFactor::new(viewport_zoom);
|
||||||
self.viewport_zoom = viewport_zoom;
|
self.viewport_zoom = viewport_zoom;
|
||||||
|
|
||||||
|
@ -1355,7 +1359,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
rv
|
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,
|
let mut pixels = gl::read_pixels(0, 0,
|
||||||
width as gl::GLsizei,
|
width as gl::GLsizei,
|
||||||
height 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 {
|
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.
|
// Check for new messages coming from the other tasks in the system.
|
||||||
loop {
|
loop {
|
||||||
match self.port.try_recv_compositor_msg() {
|
match self.port.try_recv_compositor_msg() {
|
||||||
|
@ -1509,8 +1518,10 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the message coming from the windowing system.
|
// Handle any messages coming from the windowing system.
|
||||||
self.handle_window_message(msg);
|
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 a pinch-zoom happened recently, ask for tiles at the new resolution
|
||||||
if self.zoom_action && precise_time_s() - self.zoom_time > 0.3 {
|
if self.zoom_action && precise_time_s() - self.zoom_time > 0.3 {
|
||||||
|
|
|
@ -87,7 +87,8 @@ pub trait CompositorLayer {
|
||||||
|
|
||||||
/// Destroys tiles for this layer and all descendent layers, sending the buffers back to the
|
/// Destroys tiles for this layer and all descendent layers, sending the buffers back to the
|
||||||
/// painter to be destroyed or reused.
|
/// 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
|
/// Removes the root layer (and any children) for a given pipeline from the
|
||||||
/// compositor. Buffers that the compositor is holding are returned to the
|
/// compositor. Buffers that the compositor is holding are returned to the
|
||||||
|
|
|
@ -254,7 +254,7 @@ impl CompositorTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CompositorEventListener {
|
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 repaint_synchronously(&mut self);
|
||||||
fn shutdown(&mut self);
|
fn shutdown(&mut self);
|
||||||
fn pinch_zoom_level(&self) -> f32;
|
fn pinch_zoom_level(&self) -> f32;
|
||||||
|
|
|
@ -66,7 +66,7 @@ impl NullCompositor {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompositorEventListener for 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() {
|
match self.port.recv_compositor_msg() {
|
||||||
Msg::Exit(chan) => {
|
Msg::Exit(chan) => {
|
||||||
debug!("shutting down the constellation");
|
debug!("shutting down the constellation");
|
||||||
|
|
|
@ -45,12 +45,11 @@ pub use constellation::Constellation;
|
||||||
pub mod compositor_task;
|
pub mod compositor_task;
|
||||||
|
|
||||||
mod compositor_layer;
|
mod compositor_layer;
|
||||||
mod scrolling;
|
|
||||||
|
|
||||||
mod compositor;
|
mod compositor;
|
||||||
mod headless;
|
mod headless;
|
||||||
|
mod scrolling;
|
||||||
|
|
||||||
pub mod pipeline;
|
pub mod pipeline;
|
||||||
pub mod constellation;
|
pub mod constellation;
|
||||||
|
|
||||||
pub mod windowing;
|
pub mod windowing;
|
||||||
|
|
||||||
|
|
|
@ -75,9 +75,9 @@ pub struct Browser {
|
||||||
/// application Servo is embedded in. Clients then create an event
|
/// application Servo is embedded in. Clients then create an event
|
||||||
/// loop to pump messages between the embedding application and
|
/// loop to pump messages between the embedding application and
|
||||||
/// various browser components.
|
/// various browser components.
|
||||||
impl Browser {
|
impl Browser {
|
||||||
pub fn new<Window>(window: Option<Rc<Window>>) -> 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.
|
// Global configuration options, parsed from the command line.
|
||||||
let opts = opts::get();
|
let opts = opts::get();
|
||||||
|
|
||||||
|
@ -124,8 +124,8 @@ impl Browser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_event(&mut self, event: WindowEvent) -> bool {
|
pub fn handle_events(&mut self, events: Vec<WindowEvent>) -> bool {
|
||||||
self.compositor.handle_event(event)
|
self.compositor.handle_events(events)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn repaint_synchronously(&mut self) {
|
pub fn repaint_synchronously(&mut self) {
|
||||||
|
|
|
@ -64,17 +64,14 @@ fn main() {
|
||||||
|
|
||||||
maybe_register_glutin_resize_handler(&window, &mut browser);
|
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
|
// Feed events from the window to the browser until the browser
|
||||||
// says to stop.
|
// says to stop.
|
||||||
loop {
|
loop {
|
||||||
let should_continue = match window {
|
let should_continue = match window {
|
||||||
None => browser.browser.handle_event(WindowEvent::Idle),
|
None => browser.browser.handle_events(Vec::new()),
|
||||||
Some(ref window) => {
|
Some(ref window) => browser.browser.handle_events(window.wait_events()),
|
||||||
let event = window.wait_events();
|
|
||||||
browser.browser.handle_event(event)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if !should_continue {
|
if !should_continue {
|
||||||
break
|
break
|
||||||
|
@ -123,7 +120,7 @@ impl app::NestedEventLoopListener for BrowserWrapper {
|
||||||
WindowEvent::Resize(..) => true,
|
WindowEvent::Resize(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if !self.browser.handle_event(event) {
|
if !self.browser.handle_events(vec![event]) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if is_resize {
|
if is_resize {
|
||||||
|
|
|
@ -32,8 +32,8 @@ pub enum ServoBrowser {
|
||||||
impl ServoBrowser {
|
impl ServoBrowser {
|
||||||
fn handle_event(&mut self, event: WindowEvent) {
|
fn handle_event(&mut self, event: WindowEvent) {
|
||||||
match *self {
|
match *self {
|
||||||
ServoBrowser::OnScreen(ref mut browser) => { browser.handle_event(event); }
|
ServoBrowser::OnScreen(ref mut browser) => { browser.handle_events(vec![event]); }
|
||||||
ServoBrowser::OffScreen(ref mut browser) => { browser.handle_event(event); }
|
ServoBrowser::OffScreen(ref mut browser) => { browser.handle_events(vec![event]); }
|
||||||
ServoBrowser::Invalid => {}
|
ServoBrowser::Invalid => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,8 +100,8 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Currently unimplemented.
|
/// Currently unimplemented.
|
||||||
pub fn wait_events(&self) -> WindowEvent {
|
pub fn wait_events(&self) -> Vec<WindowEvent> {
|
||||||
WindowEvent::Idle
|
vec![WindowEvent::Idle]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cursor_type_for_cursor(&self, cursor: Cursor) -> cef_cursor_type_t {
|
fn cursor_type_for_cursor(&self, cursor: Cursor) -> cef_cursor_type_t {
|
||||||
|
|
|
@ -14,13 +14,15 @@ use layers::geometry::DevicePixel;
|
||||||
use layers::platform::surface::NativeGraphicsMetadata;
|
use layers::platform::surface::NativeGraphicsMetadata;
|
||||||
use msg::constellation_msg;
|
use msg::constellation_msg;
|
||||||
use msg::constellation_msg::Key;
|
use msg::constellation_msg::Key;
|
||||||
use NestedEventLoopListener;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::{channel, Sender};
|
use std::sync::mpsc::{channel, Sender};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::cursor::Cursor;
|
use util::cursor::Cursor;
|
||||||
use util::geometry::ScreenPx;
|
use util::geometry::ScreenPx;
|
||||||
|
|
||||||
|
use NestedEventLoopListener;
|
||||||
|
|
||||||
#[cfg(feature = "window")]
|
#[cfg(feature = "window")]
|
||||||
use compositing::windowing::{MouseWindowEvent, WindowNavigateMsg};
|
use compositing::windowing::{MouseWindowEvent, WindowNavigateMsg};
|
||||||
#[cfg(feature = "window")]
|
#[cfg(feature = "window")]
|
||||||
|
@ -259,7 +261,16 @@ impl Window {
|
||||||
#[cfg(target_os="macos")]
|
#[cfg(target_os="macos")]
|
||||||
fn handle_next_event(&self) -> bool {
|
fn handle_next_event(&self) -> bool {
|
||||||
let event = self.window.wait_events().next().unwrap();
|
let event = self.window.wait_events().next().unwrap();
|
||||||
self.handle_window_event(event)
|
let mut close = self.handle_window_event(event);
|
||||||
|
if !close {
|
||||||
|
while let Some(event) = self.window.poll_events().next() {
|
||||||
|
if self.handle_window_event(event) {
|
||||||
|
close = true;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os="linux", target_os="android"))]
|
#[cfg(any(target_os="linux", target_os="android"))]
|
||||||
|
@ -283,7 +294,9 @@ impl Window {
|
||||||
//
|
//
|
||||||
// See https://github.com/servo/servo/issues/5780
|
// See https://github.com/servo/servo/issues/5780
|
||||||
//
|
//
|
||||||
match self.window.poll_events().next() {
|
let first_event = self.window.poll_events().next();
|
||||||
|
|
||||||
|
match first_event {
|
||||||
Some(event) => {
|
Some(event) => {
|
||||||
self.handle_window_event(event)
|
self.handle_window_event(event)
|
||||||
}
|
}
|
||||||
|
@ -294,40 +307,27 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait_events(&self) -> WindowEvent {
|
pub fn wait_events(&self) -> Vec<WindowEvent> {
|
||||||
{
|
let mut events = mem::replace(&mut *self.event_queue.borrow_mut(), Vec::new());
|
||||||
let mut event_queue = self.event_queue.borrow_mut();
|
|
||||||
if !event_queue.is_empty() {
|
|
||||||
return event_queue.remove(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut close_event = false;
|
let mut close_event = false;
|
||||||
|
|
||||||
// When writing to a file then exiting, use event
|
// When writing to a file then exiting, use event
|
||||||
// polling so that we don't block on a GUI event
|
// polling so that we don't block on a GUI event
|
||||||
// such as mouse click.
|
// such as mouse click.
|
||||||
if opts::get().output_file.is_some() {
|
if opts::get().output_file.is_some() {
|
||||||
for event in self.window.poll_events() {
|
while let Some(event) = self.window.poll_events().next() {
|
||||||
close_event = self.handle_window_event(event);
|
close_event = self.handle_window_event(event) || close_event;
|
||||||
if close_event {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
close_event = self.handle_next_event();
|
close_event = self.handle_next_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
if close_event || self.window.is_closed() {
|
if close_event || self.window.is_closed() {
|
||||||
WindowEvent::Quit
|
events.push(WindowEvent::Quit)
|
||||||
} else {
|
|
||||||
let mut event_queue = self.event_queue.borrow_mut();
|
|
||||||
if event_queue.is_empty() {
|
|
||||||
WindowEvent::Idle
|
|
||||||
} else {
|
|
||||||
event_queue.remove(0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
events.extend(mem::replace(&mut *self.event_queue.borrow_mut(), Vec::new()).into_iter());
|
||||||
|
events
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn set_nested_event_loop_listener(
|
pub unsafe fn set_nested_event_loop_listener(
|
||||||
|
@ -634,8 +634,8 @@ impl Window {
|
||||||
Rc::new(window)
|
Rc::new(window)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait_events(&self) -> WindowEvent {
|
pub fn wait_events(&self) -> Vec<WindowEvent> {
|
||||||
WindowEvent::Idle
|
vec![WindowEvent::Idle]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn set_nested_event_loop_listener(
|
pub unsafe fn set_nested_event_loop_listener(
|
||||||
|
|
|
@ -76,16 +76,16 @@ fn main() {
|
||||||
Some(ref window) => input::run_input_loop(&window.event_send)
|
Some(ref window) => input::run_input_loop(&window.event_send)
|
||||||
}
|
}
|
||||||
|
|
||||||
browser.browser.handle_event(WindowEvent::InitializeCompositing);
|
browser.browser.handle_events(vec![WindowEvent::InitializeCompositing]);
|
||||||
|
|
||||||
// Feed events from the window to the browser until the browser
|
// Feed events from the window to the browser until the browser
|
||||||
// says to stop.
|
// says to stop.
|
||||||
loop {
|
loop {
|
||||||
let should_continue = match window {
|
let should_continue = match window {
|
||||||
None => browser.browser.handle_event(WindowEvent::Idle),
|
None => browser.browser.handle_events(vec![WindowEvent::Idle]),
|
||||||
Some(ref window) => {
|
Some(ref window) => {
|
||||||
let event = window.wait_events();
|
let events = window.wait_events();
|
||||||
browser.browser.handle_event(event)
|
browser.browser.handle_events(events)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if !should_continue {
|
if !should_continue {
|
||||||
|
|
|
@ -754,8 +754,8 @@ impl Window {
|
||||||
Rc::new(window)
|
Rc::new(window)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait_events(&self) -> WindowEvent {
|
pub fn wait_events(&self) -> Vec<WindowEvent> {
|
||||||
self.event_recv.recv().unwrap()
|
vec![self.event_recv.recv().unwrap()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue