From ed90011fa34871a5b7b6f028ab818d4cb0cb69c9 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 29 Apr 2016 14:45:35 -0700 Subject: [PATCH] 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. --- components/compositing/compositor.rs | 36 +++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 36688456333..2a5b5b403c4 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -631,7 +631,7 @@ impl IOCompositor { 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) } @@ -750,7 +750,7 @@ impl IOCompositor { 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 { @@ -832,7 +832,7 @@ impl IOCompositor { 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, @@ -1184,7 +1184,7 @@ impl IOCompositor { // 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, @@ -1447,7 +1447,7 @@ impl IOCompositor { 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) { @@ -1501,7 +1501,7 @@ impl IOCompositor { 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, @@ -1514,7 +1514,7 @@ impl IOCompositor { 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, @@ -1527,7 +1527,7 @@ impl IOCompositor { 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) { @@ -1658,7 +1658,7 @@ impl IOCompositor { 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)); } } @@ -1750,7 +1750,7 @@ impl IOCompositor { 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) { @@ -2176,7 +2176,11 @@ impl IOCompositor { 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(); @@ -2224,6 +2228,12 @@ impl IOCompositor { } } + 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; @@ -2451,6 +2461,10 @@ impl CompositorEventListener for IOCompositor 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(_) => {}