Auto merge of #10936 - pcwalton:wr-scroll-event-handling, r=glennw

compositor: When WebRender is in use, only composite on new WebRender frames.

Scheduling composition on scroll and so forth is unnecessary and can
cause us to miss frames if the code happens to start the composition
while the WebRender backend is still in the process of preparing the
frame. This is most easily seen when scrolling in full-screen mode in
release builds on Mac.

Closes #9879.

r? @glennw
cc @paulrouget
cc @tschneidereit

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10936)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-04-30 17:14:05 -07:00
commit a868bb2a90

View file

@ -633,7 +633,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
debug!("delayed composition timeout!");
if let CompositionRequest::DelayedComposite(this_timestamp) =
self.composition_request {
if timestamp == this_timestamp {
if timestamp == this_timestamp && !opts::get().use_webrender {
self.composition_request = CompositionRequest::CompositeNow(
CompositingReason::DelayedCompositeTimeout)
}
@ -752,7 +752,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
match animation_state {
AnimationState::AnimationsPresent => {
self.pipeline_details(pipeline_id).animations_running = true;
self.composite_if_necessary(CompositingReason::Animation);
self.composite_if_necessary_if_not_using_webrender(CompositingReason::Animation);
}
AnimationState::AnimationCallbacksPresent => {
if !self.pipeline_details(pipeline_id).animation_callbacks_running {
@ -837,7 +837,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.send_window_size(WindowSizeType::Initial);
self.frame_tree_id.next();
self.composite_if_necessary(CompositingReason::NewFrameTree);
self.composite_if_necessary_if_not_using_webrender(CompositingReason::NewFrameTree);
}
fn create_root_layer_for_pipeline_and_size(&mut self,
@ -1190,7 +1190,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
// FIXME(pcwalton): This is going to cause problems with inconsistent frames since
// we only composite one layer at a time.
layer.add_buffers(self, new_layer_buffer_set, epoch);
self.composite_if_necessary(CompositingReason::NewPaintedBuffers);
self.composite_if_necessary_if_not_using_webrender(CompositingReason::NewPaintedBuffers);
}
fn scroll_fragment_to_point(&mut self,
@ -1453,7 +1453,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
cursor: cursor,
phase: ScrollEventPhase::Move(true),
});
self.composite_if_necessary(CompositingReason::Zoom);
self.composite_if_necessary_if_not_using_webrender(CompositingReason::Zoom);
}
TouchAction::DispatchEvent => {
if let Some(result) = self.find_topmost_layer_at_point(point / self.scene.scale) {
@ -1507,7 +1507,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
cursor: cursor,
phase: ScrollEventPhase::Move(self.scroll_in_progress),
});
self.composite_if_necessary(CompositingReason::Scroll);
self.composite_if_necessary_if_not_using_webrender(CompositingReason::Scroll);
}
fn on_scroll_start_window_event(&mut self,
@ -1520,7 +1520,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
cursor: cursor,
phase: ScrollEventPhase::Start,
});
self.composite_if_necessary(CompositingReason::Scroll);
self.composite_if_necessary_if_not_using_webrender(CompositingReason::Scroll);
}
fn on_scroll_end_window_event(&mut self,
@ -1533,7 +1533,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
cursor: cursor,
phase: ScrollEventPhase::End,
});
self.composite_if_necessary(CompositingReason::Scroll);
self.composite_if_necessary_if_not_using_webrender(CompositingReason::Scroll);
}
fn process_pending_scroll_events(&mut self) {
@ -1664,7 +1664,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.send_updated_display_ports_to_layout();
if self.send_buffer_requests_for_all_layers() {
self.schedule_delayed_composite_if_necessary();
} else {
} else if !opts::get().use_webrender {
self.channel_to_self.send(Msg::Recomposite(CompositingReason::ContinueScroll));
}
}
@ -1756,7 +1756,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
cursor: Point2D::typed(-1, -1), // Make sure this hits the base layer.
phase: ScrollEventPhase::Move(true),
});
self.composite_if_necessary(CompositingReason::Zoom);
self.composite_if_necessary_if_not_using_webrender(CompositingReason::Zoom);
}
fn on_navigation_window_event(&self, direction: WindowNavigateMsg) {
@ -2182,7 +2182,11 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.last_composite_time = precise_time_ns();
self.composition_request = CompositionRequest::NoCompositingNecessary;
self.process_pending_scroll_events();
if !opts::get().use_webrender {
self.process_pending_scroll_events();
}
self.process_animations();
self.start_scrolling_bounce_if_necessary();
@ -2230,6 +2234,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
}
fn composite_if_necessary_if_not_using_webrender(&mut self, reason: CompositingReason) {
if !opts::get().use_webrender {
self.composite_if_necessary(reason)
}
}
fn initialize_compositing(&mut self) {
if self.webrender.is_none() {
let show_debug_borders = opts::get().show_debug_borders;
@ -2457,6 +2467,10 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
self.send_buffer_requests_for_all_layers();
}
if !self.pending_scroll_zoom_events.is_empty() && opts::get().use_webrender {
self.process_pending_scroll_events()
}
match self.composition_request {
CompositionRequest::NoCompositingNecessary |
CompositionRequest::DelayedComposite(_) => {}