123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- // Copyright (c) 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/shelf/test/widget_animation_smoothness_inspector.h"
- #include "base/strings/stringprintf.h"
- #include "ui/compositor/layer.h"
- #include "ui/compositor/layer_animation_sequence.h"
- #include "ui/compositor/layer_animator.h"
- #include "ui/views/widget/widget.h"
- namespace ash {
- const char kErrorFormat[] =
- "Animation changes the widget's %s but stutters at value %d between steps "
- "%lu and %lu (on a total of %lu steps)";
- WidgetAnimationSmoothnessInspector::WidgetAnimationSmoothnessInspector(
- views::Widget* widget)
- : widget_(widget) {
- widget->GetLayer()->GetAnimator()->AddObserver(this);
- }
- WidgetAnimationSmoothnessInspector::~WidgetAnimationSmoothnessInspector() {
- widget_->GetLayer()->GetAnimator()->RemoveObserver(this);
- }
- bool WidgetAnimationSmoothnessInspector::CheckAnimation(
- unsigned int min_steps) const {
- DCHECK(min_steps > 2) << "An animation with 2 steps or less isn't "
- << "really an animation";
- if (bound_history_.size() < min_steps)
- return false;
- const unsigned long total_step_count = bound_history_.size();
- const unsigned long interval_between_steps_to_check =
- total_step_count / (min_steps - 1);
- const gfx::Rect initial_bounds = bound_history_.front();
- const gfx::Rect final_bounds = bound_history_.back();
- const bool x_changed = initial_bounds.x() != final_bounds.x();
- const bool y_changed = initial_bounds.y() != final_bounds.y();
- const bool w_changed = initial_bounds.width() != final_bounds.width();
- const bool h_changed = initial_bounds.height() != final_bounds.height();
- // An animation that changes nothing can't be considered smooth.
- if (!x_changed && !y_changed && !w_changed && !h_changed)
- return false;
- int last_x = initial_bounds.x();
- int last_y = initial_bounds.y();
- int last_w = initial_bounds.width();
- int last_h = initial_bounds.height();
- auto print_error = [=](const char* dimension, int value,
- unsigned long step) -> void {
- // Step numbers are 1-based in user-visible messages.
- DLOG(ERROR) << base::StringPrintf(
- kErrorFormat, dimension, value,
- 1 + step - interval_between_steps_to_check, 1 + step, total_step_count);
- };
- for (unsigned long i = interval_between_steps_to_check; i < total_step_count;
- i += interval_between_steps_to_check) {
- // Check the actual last step on the last loop iteration.
- if ((total_step_count - i) < interval_between_steps_to_check)
- i = total_step_count - 1;
- const gfx::Rect bounds = bound_history_[i];
- if (x_changed && bounds.x() == last_x) {
- print_error("x", last_x, i);
- return false;
- }
- if (y_changed && bounds.y() == last_y) {
- print_error("y", last_y, i);
- return false;
- }
- if (w_changed && bounds.width() == last_y) {
- print_error("width", last_w, i);
- return false;
- }
- if (h_changed && bounds.height() == last_h) {
- print_error("height", last_h, i);
- return false;
- }
- last_x = bounds.x();
- last_y = bounds.y();
- last_w = bounds.width();
- last_h = bounds.height();
- }
- return true;
- }
- void WidgetAnimationSmoothnessInspector::OnLayerAnimationEnded(
- ui::LayerAnimationSequence* sequence) {
- bound_history_.push_back(widget_->GetClientAreaBoundsInScreen());
- }
- void WidgetAnimationSmoothnessInspector::OnLayerAnimationAborted(
- ui::LayerAnimationSequence* sequence) {}
- void WidgetAnimationSmoothnessInspector::OnLayerAnimationScheduled(
- ui::LayerAnimationSequence* sequence) {
- bound_history_.push_back(widget_->GetClientAreaBoundsInScreen());
- }
- void WidgetAnimationSmoothnessInspector::OnLayerAnimationProgressed(
- const ui::LayerAnimationSequence* sequence) {
- bound_history_.push_back(widget_->GetClientAreaBoundsInScreen());
- }
- } // namespace ash
|