Skip to content

Commit

Permalink
Only send new scroll frames to the compositor if a scroll event actually
Browse files Browse the repository at this point in the history
resulted in motion.

Requires servo/webrender_traits#64.
  • Loading branch information
pcwalton committed Jun 29, 2016
1 parent 6e9d1e3 commit 3aec09d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
15 changes: 11 additions & 4 deletions src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,23 +710,25 @@ impl Frame {
result
}

/// Returns true if any layers actually changed position or false otherwise.
pub fn scroll(&mut self,
mut delta: Point2D<f32>,
cursor: Point2D<f32>,
phase: ScrollEventPhase) {
phase: ScrollEventPhase)
-> bool {
let root_scroll_layer_id = match self.root_scroll_layer_id {
Some(root_scroll_layer_id) => root_scroll_layer_id,
None => return,
None => return false,
};

let scroll_layer_id = match self.get_scroll_layer(&cursor, root_scroll_layer_id) {
Some(scroll_layer_id) => scroll_layer_id,
None => return,
None => return false,
};

let layer = self.layers.get_mut(&scroll_layer_id).unwrap();
if layer.scrolling.started_bouncing_back && phase == ScrollEventPhase::Move(false) {
return
return false
}

let overscroll_amount = layer.overscroll_amount();
Expand All @@ -744,6 +746,8 @@ impl Frame {
let is_unscrollable = layer.layer_size.width <= layer.viewport_rect.size.width &&
layer.layer_size.height <= layer.viewport_rect.size.height;

let original_layer_scroll_offset = layer.scrolling.offset;

if layer.layer_size.width > layer.viewport_rect.size.width {
layer.scrolling.offset.x = layer.scrolling.offset.x + delta.x;
if is_unscrollable || !CAN_OVERSCROLL {
Expand Down Expand Up @@ -778,6 +782,9 @@ impl Frame {
if CAN_OVERSCROLL {
layer.stretch_overscroll_spring();
}

layer.scrolling.offset != original_layer_scroll_offset || layer.scrolling
.started_bouncing_back
}

pub fn tick_scrolling_bounce_animations(&mut self) {
Expand Down
34 changes: 29 additions & 5 deletions src/render_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl RenderBackend {
self.render()
});

self.publish_frame(frame, &mut profile_counters);
self.publish_frame_and_notify_compositor(frame, &mut profile_counters);
}
ApiMsg::SetRootPipeline(pipeline_id) => {
let frame = profile_counters.total_time.profile(|| {
Expand All @@ -243,19 +243,28 @@ impl RenderBackend {
}
ApiMsg::Scroll(delta, cursor, move_phase) => {
let frame = profile_counters.total_time.profile(|| {
self.frame.scroll(delta, cursor, move_phase);
self.render()
if self.frame.scroll(delta, cursor, move_phase) {
Some(self.render())
} else {
None
}
});

self.publish_frame(frame, &mut profile_counters);
match frame {
Some(frame) => {
self.publish_frame(frame, &mut profile_counters);
self.notify_compositor_of_new_scroll_frame(true)
}
None => self.notify_compositor_of_new_scroll_frame(false),
}
}
ApiMsg::TickScrollingBounce => {
let frame = profile_counters.total_time.profile(|| {
self.frame.tick_scrolling_bounce_animations();
self.render()
});

self.publish_frame(frame, &mut profile_counters);
self.publish_frame_and_notify_compositor(frame, &mut profile_counters);
}
ApiMsg::TranslatePointToLayerSpace(point, tx) => {
// First, find the specific layer that contains the point.
Expand Down Expand Up @@ -425,6 +434,12 @@ impl RenderBackend {
let msg = ResultMsg::NewFrame(frame, pending_updates, profile_counters.clone());
self.result_tx.send(msg).unwrap();
profile_counters.reset();
}

fn publish_frame_and_notify_compositor(&mut self,
frame: RendererFrame,
profile_counters: &mut BackendProfileCounters) {
self.publish_frame(frame, profile_counters);

// TODO(gw): This is kindof bogus to have to lock the notifier
// each time it's used. This is due to some nastiness
Expand All @@ -433,5 +448,14 @@ impl RenderBackend {
let mut notifier = self.notifier.lock();
notifier.as_mut().unwrap().as_mut().unwrap().new_frame_ready();
}

fn notify_compositor_of_new_scroll_frame(&mut self, composite_needed: bool) {
// TODO(gw): This is kindof bogus to have to lock the notifier
// each time it's used. This is due to some nastiness
// in initialization order for Servo. Perhaps find a
// cleaner way to do this, or use the OnceMutex on crates.io?
let mut notifier = self.notifier.lock();
notifier.as_mut().unwrap().as_mut().unwrap().new_scroll_frame_ready(composite_needed);
}
}

0 comments on commit 3aec09d

Please sign in to comment.