mirror of
https://github.com/servo/servo.git
synced 2025-08-15 02:15:33 +01:00
Improve decisions in compositor over when to draw a frame.
This patch fixes a couple of issues in the compositor: 1) Remove the delayed composition code. Previously, this would schedule a composite for 12ms in the future. This doesn't really make any sense with WR. There's no point in doing a composite unless WR has provided a new frame to be drawn. This fixes issues in several benchmarks where we were doing multiple composite / renders per rAF, which is a waste of CPU time. This *does* make the framerate slower in some cases (such as a slow rAF callback) but it's more correct - otherwise we were just compositing the same frame multiple times for no real benefit. 2) Inform the window of the current animation state of the compositor. Specifically, if an animation (or rAF) is currently active, the window system switches to use event polling, and does not block on the OS-level event loop. In the case of active animation, we just assume that we want to be running as the vsync interval and not blocking. This means the compositor thread only sleeps on vsync during animation, which reduces OS scheduling and results in much smoother animation.
This commit is contained in:
parent
5f10a25ead
commit
c8255922a9
6 changed files with 32 additions and 154 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
use NestedEventLoopListener;
|
||||
use compositing::compositor_thread::EventLoopWaker;
|
||||
use compositing::windowing::{MouseWindowEvent, WindowNavigateMsg};
|
||||
use compositing::windowing::{AnimationState, MouseWindowEvent, WindowNavigateMsg};
|
||||
use compositing::windowing::{WindowEvent, WindowMethods};
|
||||
use euclid::{Point2D, Size2D, TypedPoint2D, TypedVector2D, TypedRect, ScaleFactor, TypedSize2D};
|
||||
#[cfg(target_os = "windows")]
|
||||
|
@ -196,6 +196,8 @@ pub struct Window {
|
|||
#[cfg(not(target_os = "windows"))]
|
||||
pressed_key_map: RefCell<Vec<(ScanCode, char)>>,
|
||||
|
||||
animation_state: Cell<AnimationState>,
|
||||
|
||||
gl: Rc<gl::Gl>,
|
||||
}
|
||||
|
||||
|
@ -316,6 +318,7 @@ impl Window {
|
|||
#[cfg(target_os = "windows")]
|
||||
last_pressed_key: Cell::new(None),
|
||||
gl: gl.clone(),
|
||||
animation_state: Cell::new(AnimationState::Idle),
|
||||
};
|
||||
|
||||
window.present();
|
||||
|
@ -655,10 +658,14 @@ impl Window {
|
|||
let mut events = mem::replace(&mut *self.event_queue.borrow_mut(), Vec::new());
|
||||
let mut close_event = false;
|
||||
|
||||
let poll = self.animation_state.get() == AnimationState::Animating ||
|
||||
opts::get().output_file.is_some() ||
|
||||
opts::get().exit_after_load ||
|
||||
opts::get().headless;
|
||||
// When writing to a file then exiting, use event
|
||||
// polling so that we don't block on a GUI event
|
||||
// such as mouse click.
|
||||
if opts::get().output_file.is_some() || opts::get().exit_after_load || opts::get().headless {
|
||||
if poll {
|
||||
match self.kind {
|
||||
WindowKind::Window(ref window) => {
|
||||
while let Some(event) = window.poll_events().next() {
|
||||
|
@ -1005,6 +1012,10 @@ impl WindowMethods for Window {
|
|||
|
||||
}
|
||||
|
||||
fn set_animation_state(&self, state: AnimationState) {
|
||||
self.animation_state.set(state);
|
||||
}
|
||||
|
||||
fn set_inner_size(&self, size: Size2D<u32>) {
|
||||
match self.kind {
|
||||
WindowKind::Window(ref window) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue