Skip to content

Commit

Permalink
Merge Compositor's ScrollbarAnimationControllers into single class
Browse files Browse the repository at this point in the history
This patch is for merge ScrollbarAnimationControllerLinearFade and
ScrollbarAnimationControllerThinning into ScrollbarAnimationController.

BUG=656606
CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel

Review-Url: https://codereview.chromium.org/2692243005
Cr-Commit-Position: refs/heads/master@{#451397}
  • Loading branch information
chaopeng authored and Commit bot committed Feb 17, 2017
1 parent 76f8191 commit 59e6fc0
Show file tree
Hide file tree
Showing 17 changed files with 807 additions and 1,029 deletions.
7 changes: 1 addition & 6 deletions cc/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,6 @@ cc_component("cc") {
"input/scroll_state_data.h",
"input/scrollbar_animation_controller.cc",
"input/scrollbar_animation_controller.h",
"input/scrollbar_animation_controller_linear_fade.cc",
"input/scrollbar_animation_controller_linear_fade.h",
"input/scrollbar_animation_controller_thinning.cc",
"input/scrollbar_animation_controller_thinning.h",
"input/selection.h",
"input/single_scrollbar_animation_controller_thinning.cc",
"input/single_scrollbar_animation_controller_thinning.h",
Expand Down Expand Up @@ -755,8 +751,7 @@ cc_test("cc_unittests") {
"debug/rendering_stats_unittest.cc",
"input/browser_controls_offset_manager_unittest.cc",
"input/scroll_state_unittest.cc",
"input/scrollbar_animation_controller_linear_fade_unittest.cc",
"input/scrollbar_animation_controller_thinning_unittest.cc",
"input/scrollbar_animation_controller_unittest.cc",
"input/single_scrollbar_animation_controller_thinning_unittest.cc",
"ipc/cc_param_traits_unittest.cc",
"ipc/struct_traits_unittest.cc",
Expand Down
214 changes: 159 additions & 55 deletions cc/input/scrollbar_animation_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,116 @@

namespace cc {

std::unique_ptr<ScrollbarAnimationController>
ScrollbarAnimationController::CreateScrollbarAnimationControllerAndroid(
int scroll_layer_id,
ScrollbarAnimationControllerClient* client,
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting,
base::TimeDelta fade_duration) {
return base::WrapUnique(new ScrollbarAnimationController(
scroll_layer_id, client, delay_before_starting,
resize_delay_before_starting, fade_duration));
}

std::unique_ptr<ScrollbarAnimationController>
ScrollbarAnimationController::CreateScrollbarAnimationControllerAuraOverlay(
int scroll_layer_id,
ScrollbarAnimationControllerClient* client,
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting,
base::TimeDelta fade_duration,
base::TimeDelta thinning_duration) {
return base::WrapUnique(new ScrollbarAnimationController(
scroll_layer_id, client, delay_before_starting,
resize_delay_before_starting, fade_duration, thinning_duration));
}

ScrollbarAnimationController::ScrollbarAnimationController(
int scroll_layer_id,
ScrollbarAnimationControllerClient* client,
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting)
base::TimeDelta resize_delay_before_starting,
base::TimeDelta fade_duration)
: client_(client),
delay_before_starting_(delay_before_starting),
resize_delay_before_starting_(resize_delay_before_starting),
is_animating_(false),
scroll_layer_id_(scroll_layer_id),
currently_scrolling_(false),
scroll_gesture_has_scrolled_(false),
opacity_(0.0f),
fade_duration_(fade_duration),
need_thinning_animation_(false),
weak_factory_(this) {
ApplyOpacityToScrollbars(0.0f);
}

ScrollbarAnimationController::ScrollbarAnimationController(
int scroll_layer_id,
ScrollbarAnimationControllerClient* client,
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting,
base::TimeDelta fade_duration,
base::TimeDelta thinning_duration)
: client_(client),
delay_before_starting_(delay_before_starting),
resize_delay_before_starting_(resize_delay_before_starting),
is_animating_(false),
scroll_layer_id_(scroll_layer_id),
currently_scrolling_(false),
scroll_gesture_has_scrolled_(false),
opacity_(0.0f),
fade_duration_(fade_duration),
need_thinning_animation_(true),
weak_factory_(this) {
vertical_controller_ = SingleScrollbarAnimationControllerThinning::Create(
scroll_layer_id, ScrollbarOrientation::VERTICAL, client,
thinning_duration);
horizontal_controller_ = SingleScrollbarAnimationControllerThinning::Create(
scroll_layer_id, ScrollbarOrientation::HORIZONTAL, client,
thinning_duration);
ApplyOpacityToScrollbars(0.0f);
}

ScrollbarAnimationController::~ScrollbarAnimationController() {}

ScrollbarSet ScrollbarAnimationController::Scrollbars() const {
return client_->ScrollbarsFor(scroll_layer_id_);
}

SingleScrollbarAnimationControllerThinning&
ScrollbarAnimationController::GetScrollbarAnimationController(
ScrollbarOrientation orientation) const {
DCHECK(NeedThinningAnimation());
DCHECK(need_thinning_animation_);
if (orientation == ScrollbarOrientation::VERTICAL)
return *(vertical_controller_.get());
else
return *(horizontal_controller_.get());
}

void ScrollbarAnimationController::StartAnimation() {
delayed_scrollbar_fade_.Cancel();
is_animating_ = true;
last_awaken_time_ = base::TimeTicks();
client_->SetNeedsAnimateForScrollbarAnimation();
}

void ScrollbarAnimationController::StopAnimation() {
delayed_scrollbar_fade_.Cancel();
is_animating_ = false;
}

void ScrollbarAnimationController::PostDelayedAnimationTask(bool on_resize) {
base::TimeDelta delay =
on_resize ? resize_delay_before_starting_ : delay_before_starting_;
delayed_scrollbar_fade_.Reset(
base::Bind(&ScrollbarAnimationController::StartAnimation,
weak_factory_.GetWeakPtr()));
client_->PostDelayedScrollbarAnimationTask(delayed_scrollbar_fade_.callback(),
delay);
}

bool ScrollbarAnimationController::Animate(base::TimeTicks now) {
bool animated = false;

Expand All @@ -53,63 +136,82 @@ bool ScrollbarAnimationController::Animate(base::TimeTicks now) {
animated = true;
}

if (NeedThinningAnimation()) {
if (need_thinning_animation_) {
animated |= vertical_controller_->Animate(now);
animated |= horizontal_controller_->Animate(now);
}

return animated;
}

bool ScrollbarAnimationController::ScrollbarsHidden() const {
return false;
}

bool ScrollbarAnimationController::NeedThinningAnimation() const {
return false;
}

float ScrollbarAnimationController::AnimationProgressAtTime(
base::TimeTicks now) {
base::TimeDelta delta = now - last_awaken_time_;
float progress = delta.InSecondsF() / Duration().InSecondsF();
float progress = delta.InSecondsF() / fade_duration_.InSecondsF();
return std::max(std::min(progress, 1.f), 0.f);
}

void ScrollbarAnimationController::DidScrollBegin() {
currently_scrolling_ = true;
}

void ScrollbarAnimationController::RunAnimationFrame(float progress) {
ApplyOpacityToScrollbars(1.f - progress);
client_->SetNeedsRedrawForScrollbarAnimation();
if (progress == 1.f)
StopAnimation();
}

void ScrollbarAnimationController::DidScrollUpdate(bool on_resize) {
if (need_thinning_animation_ && Captured())
return;

StopAnimation();

// As an optimization, we avoid spamming fade delay tasks during active fast
// scrolls. But if we're not within one, we need to post every scroll update.
if (!currently_scrolling_)
PostDelayedAnimationTask(on_resize);
else
if (!currently_scrolling_) {
// We don't fade out scrollbar if they need thinning animation and mouse is
// near.
if (!need_thinning_animation_ || !mouse_is_near_any_scrollbar())
PostDelayedAnimationTask(on_resize);
} else {
scroll_gesture_has_scrolled_ = true;
}

ApplyOpacityToScrollbars(1);

if (need_thinning_animation_) {
vertical_controller_->UpdateThumbThicknessScale();
horizontal_controller_->UpdateThumbThicknessScale();
}
}

void ScrollbarAnimationController::DidScrollEnd() {
if (scroll_gesture_has_scrolled_) {
PostDelayedAnimationTask(false);
scroll_gesture_has_scrolled_ = false;
}
bool has_scrolled = scroll_gesture_has_scrolled_;
scroll_gesture_has_scrolled_ = false;

currently_scrolling_ = false;

// We don't fade out scrollbar if they need thinning animation and mouse is
// near.
if (need_thinning_animation_ && mouse_is_near_any_scrollbar())
return;

if (has_scrolled)
PostDelayedAnimationTask(false);
}

void ScrollbarAnimationController::DidMouseDown() {
if (!NeedThinningAnimation() || ScrollbarsHidden())
if (!need_thinning_animation_ || ScrollbarsHidden())
return;

vertical_controller_->DidMouseDown();
horizontal_controller_->DidMouseDown();
}

void ScrollbarAnimationController::DidMouseUp() {
if (!NeedThinningAnimation())
if (!need_thinning_animation_)
return;

vertical_controller_->DidMouseUp();
Expand All @@ -120,7 +222,7 @@ void ScrollbarAnimationController::DidMouseUp() {
}

void ScrollbarAnimationController::DidMouseLeave() {
if (!NeedThinningAnimation())
if (!need_thinning_animation_)
return;

vertical_controller_->DidMouseLeave();
Expand All @@ -135,7 +237,7 @@ void ScrollbarAnimationController::DidMouseLeave() {
void ScrollbarAnimationController::DidMouseMoveNear(
ScrollbarOrientation orientation,
float distance) {
if (!NeedThinningAnimation())
if (!need_thinning_animation_)
return;

GetScrollbarAnimationController(orientation).DidMouseMoveNear(distance);
Expand All @@ -146,64 +248,66 @@ void ScrollbarAnimationController::DidMouseMoveNear(
if (mouse_is_near_any_scrollbar()) {
ApplyOpacityToScrollbars(1);
StopAnimation();
} else if (!animating_fade()) {
} else if (!is_animating_) {
PostDelayedAnimationTask(false);
}
}

bool ScrollbarAnimationController::mouse_is_over_scrollbar(
ScrollbarOrientation orientation) const {
DCHECK(NeedThinningAnimation());
DCHECK(need_thinning_animation_);
return GetScrollbarAnimationController(orientation).mouse_is_over_scrollbar();
}

bool ScrollbarAnimationController::mouse_is_near_scrollbar(
ScrollbarOrientation orientation) const {
DCHECK(NeedThinningAnimation());
DCHECK(need_thinning_animation_);
return GetScrollbarAnimationController(orientation).mouse_is_near_scrollbar();
}

bool ScrollbarAnimationController::mouse_is_near_any_scrollbar() const {
DCHECK(NeedThinningAnimation());
DCHECK(need_thinning_animation_);
return vertical_controller_->mouse_is_near_scrollbar() ||
horizontal_controller_->mouse_is_near_scrollbar();
}

bool ScrollbarAnimationController::Captured() const {
DCHECK(NeedThinningAnimation());
return vertical_controller_->captured() || horizontal_controller_->captured();
bool ScrollbarAnimationController::ScrollbarsHidden() const {
return opacity_ == 0.0f;
}

void ScrollbarAnimationController::PostDelayedAnimationTask(bool on_resize) {
base::TimeDelta delay =
on_resize ? resize_delay_before_starting_ : delay_before_starting_;
delayed_scrollbar_fade_.Reset(
base::Bind(&ScrollbarAnimationController::StartAnimation,
weak_factory_.GetWeakPtr()));
client_->PostDelayedScrollbarAnimationTask(delayed_scrollbar_fade_.callback(),
delay);
bool ScrollbarAnimationController::Captured() const {
DCHECK(need_thinning_animation_);
return vertical_controller_->captured() || horizontal_controller_->captured();
}

void ScrollbarAnimationController::StartAnimation() {
delayed_scrollbar_fade_.Cancel();
is_animating_ = true;
last_awaken_time_ = base::TimeTicks();
client_->SetNeedsAnimateForScrollbarAnimation();
}
void ScrollbarAnimationController::ApplyOpacityToScrollbars(float opacity) {
for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) {
if (!scrollbar->is_overlay_scrollbar())
continue;
float effective_opacity = scrollbar->CanScrollOrientation() ? opacity : 0;
PropertyTrees* property_trees =
scrollbar->layer_tree_impl()->property_trees();
// If this method is called during LayerImpl::PushPropertiesTo, we may not
// yet have valid layer_id_to_effect_node_index entries as property trees
// are pushed after layers during activation. We can skip updating opacity
// in that case as we are only registering a scrollbar and because opacity
// will be overwritten anyway when property trees are pushed.
if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT,
scrollbar->id())) {
property_trees->effect_tree.OnOpacityAnimated(
effective_opacity,
property_trees->layer_id_to_effect_node_index[scrollbar->id()],
scrollbar->layer_tree_impl());
}
}

void ScrollbarAnimationController::StopAnimation() {
delayed_scrollbar_fade_.Cancel();
is_animating_ = false;
}
bool previouslyVisible = opacity_ > 0.0f;
bool currentlyVisible = opacity > 0.0f;

ScrollbarSet ScrollbarAnimationController::Scrollbars() const {
return client_->ScrollbarsFor(scroll_layer_id_);
}
opacity_ = opacity;

void ScrollbarAnimationController::set_mouse_move_distance_for_test(
float distance) {
vertical_controller_->set_mouse_move_distance_for_test(distance);
horizontal_controller_->set_mouse_move_distance_for_test(distance);
if (previouslyVisible != currentlyVisible)
client_->DidChangeScrollbarVisibility();
}

} // namespace cc
Loading

0 comments on commit 59e6fc0

Please sign in to comment.