Commit 30f405cd authored by Xiyuan Xia's avatar Xiyuan Xia Committed by Commit Bot

ash: Use ThroughputTracker for tablet transition smoothness

Bug: 1021774
Change-Id: Ie782cf0c74e51f04fab379983ecffe9e21ae4750
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2268499Reviewed-by: default avatarSammie Quon <sammiequon@chromium.org>
Commit-Queue: Xiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#783020}
parent 76334159
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <utility> #include <utility>
#include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/ash_switches.h"
#include "ash/public/cpp/fps_counter.h" #include "ash/public/cpp/metrics_util.h"
#include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/shelf_config.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/tablet_mode.h" #include "ash/public/cpp/tablet_mode.h"
...@@ -292,34 +292,14 @@ const char* ToString(TabletMode tablet_mode) { ...@@ -292,34 +292,14 @@ const char* ToString(TabletMode tablet_mode) {
return ""; return "";
} }
} // namespace void ReportTrasitionSmoothness(bool enter_tablet_mode, int smoothness) {
if (enter_tablet_mode)
// Class which records animation smoothness when entering or exiting tablet UMA_HISTOGRAM_PERCENTAGE(kTabletModeEnterHistogram, smoothness);
// mode. No stats should be recorded if no windows are animated. else
class TabletModeController::TabletModeTransitionFpsCounter : public FpsCounter { UMA_HISTOGRAM_PERCENTAGE(kTabletModeExitHistogram, smoothness);
public: }
TabletModeTransitionFpsCounter(ui::Compositor* compositor,
bool enter_tablet_mode)
: FpsCounter(compositor), enter_tablet_mode_(enter_tablet_mode) {}
~TabletModeTransitionFpsCounter() override = default;
void LogUma() {
int smoothness = ComputeSmoothness();
if (smoothness < 0)
return;
if (enter_tablet_mode_)
UMA_HISTOGRAM_PERCENTAGE(kTabletModeEnterHistogram, smoothness);
else
UMA_HISTOGRAM_PERCENTAGE(kTabletModeExitHistogram, smoothness);
}
bool enter_tablet_mode() const { return enter_tablet_mode_; }
private: } // namespace
bool enter_tablet_mode_;
DISALLOW_COPY_AND_ASSIGN(TabletModeTransitionFpsCounter);
};
// An observer that observes the destruction of the |window_| and executes the // An observer that observes the destruction of the |window_| and executes the
// callback. Used to run cleanup when the window is destroyed in the middle of // callback. Used to run cleanup when the window is destroyed in the middle of
...@@ -523,9 +503,9 @@ void TabletModeController::StopObservingAnimation(bool record_stats, ...@@ -523,9 +503,9 @@ void TabletModeController::StopObservingAnimation(bool record_stats,
} }
} }
if (record_stats && fps_counter_) if (record_stats && transition_tracker_)
fps_counter_->LogUma(); transition_tracker_->Stop();
fps_counter_.reset(); transition_tracker_.reset();
// Stop other animations (STEP_END), then update the tablet mode ui. // Stop other animations (STEP_END), then update the tablet mode ui.
if (tablet_mode_window_manager_ && delete_screenshot) if (tablet_mode_window_manager_ && delete_screenshot)
...@@ -757,7 +737,7 @@ void TabletModeController::OnLayerAnimationStarted( ...@@ -757,7 +737,7 @@ void TabletModeController::OnLayerAnimationStarted(
void TabletModeController::OnLayerAnimationAborted( void TabletModeController::OnLayerAnimationAborted(
ui::LayerAnimationSequence* sequence) { ui::LayerAnimationSequence* sequence) {
if (!fps_counter_ || !ShouldObserveSequence(sequence)) if (!transition_tracker_ || !ShouldObserveSequence(sequence))
return; return;
StopObservingAnimation(/*record_stats=*/false, /*delete_screenshot=*/true); StopObservingAnimation(/*record_stats=*/false, /*delete_screenshot=*/true);
...@@ -768,9 +748,9 @@ void TabletModeController::OnLayerAnimationEnded( ...@@ -768,9 +748,9 @@ void TabletModeController::OnLayerAnimationEnded(
// This may be called before |OnLayerAnimationScheduled()| if tablet is // This may be called before |OnLayerAnimationScheduled()| if tablet is
// entered/exited while an animation is in progress, so we won't get // entered/exited while an animation is in progress, so we won't get
// stats/screenshot in those cases. // stats/screenshot in those cases.
// TODO(sammiequon): We may want to remove the |fps_counter_| check and // TODO(sammiequon): We may want to remove the |transition_tracker_| check and
// simplify things since those are edge cases. // simplify things since those are edge cases.
if (!fps_counter_ || !ShouldObserveSequence(sequence)) if (!transition_tracker_ || !ShouldObserveSequence(sequence))
return; return;
StopObservingAnimation(/*record_stats=*/true, /*delete_screenshot=*/true); StopObservingAnimation(/*record_stats=*/true, /*delete_screenshot=*/true);
...@@ -781,10 +761,11 @@ void TabletModeController::OnLayerAnimationScheduled( ...@@ -781,10 +761,11 @@ void TabletModeController::OnLayerAnimationScheduled(
if (!ShouldObserveSequence(sequence)) if (!ShouldObserveSequence(sequence))
return; return;
if (!fps_counter_) { if (!transition_tracker_) {
fps_counter_ = std::make_unique<TabletModeTransitionFpsCounter>( transition_tracker_ =
animating_layer_->GetCompositor(), animating_layer_->GetCompositor()->RequestNewThroughputTracker();
state_ == State::kEnteringTabletMode); transition_tracker_->Start(metrics_util::ForSmoothness(base::BindRepeating(
&ReportTrasitionSmoothness, state_ == State::kEnteringTabletMode)));
return; return;
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_observer.h" #include "ui/compositor/layer_observer.h"
#include "ui/compositor/layer_tree_owner.h" #include "ui/compositor/layer_tree_owner.h"
#include "ui/compositor/throughput_tracker.h"
#include "ui/events/devices/input_device_event_observer.h" #include "ui/events/devices/input_device_event_observer.h"
#include "ui/gfx/geometry/vector3d_f.h" #include "ui/gfx/geometry/vector3d_f.h"
...@@ -205,7 +206,6 @@ class ASH_EXPORT TabletModeController ...@@ -205,7 +206,6 @@ class ASH_EXPORT TabletModeController
private: private:
class DestroyObserver; class DestroyObserver;
class TabletModeTransitionFpsCounter;
class ScopedShelfHider; class ScopedShelfHider;
friend class TabletModeControllerTestApi; friend class TabletModeControllerTestApi;
...@@ -449,7 +449,8 @@ class ASH_EXPORT TabletModeController ...@@ -449,7 +449,8 @@ class ASH_EXPORT TabletModeController
// does not show the old version of shelf in the background). // does not show the old version of shelf in the background).
std::unique_ptr<ScopedShelfHider> shelf_hider_; std::unique_ptr<ScopedShelfHider> shelf_hider_;
std::unique_ptr<TabletModeTransitionFpsCounter> fps_counter_; // Tracks and record transition smoothness.
base::Optional<ui::ThroughputTracker> transition_tracker_;
base::CancelableOnceCallback<void(std::unique_ptr<viz::CopyOutputResult>)> base::CancelableOnceCallback<void(std::unique_ptr<viz::CopyOutputResult>)>
screenshot_taken_callback_; screenshot_taken_callback_;
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "ash/public/cpp/app_types.h" #include "ash/public/cpp/app_types.h"
#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/ash_switches.h"
#include "ash/public/cpp/fps_counter.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/tablet_mode.h" #include "ash/public/cpp/tablet_mode.h"
#include "ash/public/cpp/test/shell_test_api.h" #include "ash/public/cpp/test/shell_test_api.h"
...@@ -49,6 +48,7 @@ ...@@ -49,6 +48,7 @@
#include "ui/base/hit_test.h" #include "ui/base/hit_test.h"
#include "ui/compositor/layer_animator.h" #include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/compositor/test/test_utils.h"
#include "ui/display/manager/display_manager.h" #include "ui/display/manager/display_manager.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "ui/display/test/display_manager_test_api.h" #include "ui/display/test/display_manager_test_api.h"
...@@ -111,7 +111,6 @@ class TabletModeControllerTest : public MultiDisplayOverviewAndSplitViewTest { ...@@ -111,7 +111,6 @@ class TabletModeControllerTest : public MultiDisplayOverviewAndSplitViewTest {
MultiDisplayOverviewAndSplitViewTest::SetUp(); MultiDisplayOverviewAndSplitViewTest::SetUp();
AccelerometerReader::GetInstance()->RemoveObserver( AccelerometerReader::GetInstance()->RemoveObserver(
tablet_mode_controller()); tablet_mode_controller());
FpsCounter::SetForceReportZeroAnimationForTest(true);
// Set the first display to be the internal display for the accelerometer // Set the first display to be the internal display for the accelerometer
// screen rotation tests. // screen rotation tests.
...@@ -129,7 +128,6 @@ class TabletModeControllerTest : public MultiDisplayOverviewAndSplitViewTest { ...@@ -129,7 +128,6 @@ class TabletModeControllerTest : public MultiDisplayOverviewAndSplitViewTest {
} }
void TearDown() override { void TearDown() override {
FpsCounter::SetForceReportZeroAnimationForTest(false);
AccelerometerReader::GetInstance()->AddObserver(tablet_mode_controller()); AccelerometerReader::GetInstance()->AddObserver(tablet_mode_controller());
MultiDisplayOverviewAndSplitViewTest::TearDown(); MultiDisplayOverviewAndSplitViewTest::TearDown();
} }
...@@ -214,6 +212,23 @@ class TabletModeControllerTest : public MultiDisplayOverviewAndSplitViewTest { ...@@ -214,6 +212,23 @@ class TabletModeControllerTest : public MultiDisplayOverviewAndSplitViewTest {
return window; return window;
} }
// Waits for |window|'s animation to finish.
void WaitForWindowAnimation(aura::Window* window) {
auto* compositor = window->layer()->GetCompositor();
while (window->layer()->GetAnimator()->is_animating())
EXPECT_TRUE(ui::WaitForNextFrameToBePresented(compositor));
}
// Wait one more frame presented for the metrics to get recorded.
// ignore_result() and timeout is because the frame could already be
// presented.
void WaitForSmoothnessMetrics() {
ignore_result(ui::WaitForNextFrameToBePresented(
Shell::GetPrimaryRootWindow()->layer()->GetCompositor(),
base::TimeDelta::FromMilliseconds(100)));
}
private: private:
std::unique_ptr<TabletModeControllerTestApi> test_api_; std::unique_ptr<TabletModeControllerTestApi> test_api_;
...@@ -1530,6 +1545,7 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsNotLogged) { ...@@ -1530,6 +1545,7 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsNotLogged) {
histogram_tester.ExpectTotalCount(kExitHistogram, 0); histogram_tester.ExpectTotalCount(kExitHistogram, 0);
tablet_mode_controller()->SetEnabledForTest(true); tablet_mode_controller()->SetEnabledForTest(true);
tablet_mode_controller()->SetEnabledForTest(false); tablet_mode_controller()->SetEnabledForTest(false);
WaitForSmoothnessMetrics();
histogram_tester.ExpectTotalCount(kEnterHistogram, 0); histogram_tester.ExpectTotalCount(kEnterHistogram, 0);
histogram_tester.ExpectTotalCount(kExitHistogram, 0); histogram_tester.ExpectTotalCount(kExitHistogram, 0);
} }
...@@ -1549,10 +1565,12 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsNotLogged) { ...@@ -1549,10 +1565,12 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsNotLogged) {
window->layer()->GetAnimator()->StopAnimating(); window->layer()->GetAnimator()->StopAnimating();
tablet_mode_controller()->SetEnabledForTest(true); tablet_mode_controller()->SetEnabledForTest(true);
EXPECT_FALSE(window->layer()->GetAnimator()->is_animating()); EXPECT_FALSE(window->layer()->GetAnimator()->is_animating());
WaitForSmoothnessMetrics();
histogram_tester.ExpectTotalCount(kEnterHistogram, 0); histogram_tester.ExpectTotalCount(kEnterHistogram, 0);
histogram_tester.ExpectTotalCount(kExitHistogram, 0); histogram_tester.ExpectTotalCount(kExitHistogram, 0);
tablet_mode_controller()->SetEnabledForTest(false); tablet_mode_controller()->SetEnabledForTest(false);
EXPECT_FALSE(window->layer()->GetAnimator()->is_animating()); EXPECT_FALSE(window->layer()->GetAnimator()->is_animating());
WaitForSmoothnessMetrics();
histogram_tester.ExpectTotalCount(kEnterHistogram, 0); histogram_tester.ExpectTotalCount(kEnterHistogram, 0);
histogram_tester.ExpectTotalCount(kExitHistogram, 0); histogram_tester.ExpectTotalCount(kExitHistogram, 0);
} }
...@@ -1573,8 +1591,9 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsLogged) { ...@@ -1573,8 +1591,9 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsLogged) {
tablet_mode_controller()->SetEnabledForTest(true); tablet_mode_controller()->SetEnabledForTest(true);
EXPECT_TRUE(window->layer()->GetAnimator()->is_animating()); EXPECT_TRUE(window->layer()->GetAnimator()->is_animating());
EXPECT_TRUE(window2->layer()->GetAnimator()->is_animating()); EXPECT_TRUE(window2->layer()->GetAnimator()->is_animating());
layer->GetAnimator()->StopAnimating(); WaitForWindowAnimation(window.get());
layer2->GetAnimator()->StopAnimating(); WaitForWindowAnimation(window2.get());
WaitForSmoothnessMetrics();
histogram_tester.ExpectTotalCount(kEnterHistogram, 1); histogram_tester.ExpectTotalCount(kEnterHistogram, 1);
histogram_tester.ExpectTotalCount(kExitHistogram, 0); histogram_tester.ExpectTotalCount(kExitHistogram, 0);
...@@ -1583,8 +1602,8 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsLogged) { ...@@ -1583,8 +1602,8 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsLogged) {
tablet_mode_controller()->SetEnabledForTest(false); tablet_mode_controller()->SetEnabledForTest(false);
EXPECT_FALSE(layer->GetAnimator()->is_animating()); EXPECT_FALSE(layer->GetAnimator()->is_animating());
EXPECT_TRUE(layer2->GetAnimator()->is_animating()); EXPECT_TRUE(layer2->GetAnimator()->is_animating());
layer->GetAnimator()->StopAnimating(); WaitForWindowAnimation(window2.get());
layer2->GetAnimator()->StopAnimating(); WaitForSmoothnessMetrics();
histogram_tester.ExpectTotalCount(kEnterHistogram, 1); histogram_tester.ExpectTotalCount(kEnterHistogram, 1);
histogram_tester.ExpectTotalCount(kExitHistogram, 1); histogram_tester.ExpectTotalCount(kExitHistogram, 1);
} }
...@@ -1604,6 +1623,7 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsSnappedWindows) { ...@@ -1604,6 +1623,7 @@ TEST_P(TabletModeControllerTest, TabletModeTransitionHistogramsSnappedWindows) {
tablet_mode_controller()->SetEnabledForTest(true); tablet_mode_controller()->SetEnabledForTest(true);
EXPECT_FALSE(window->layer()->GetAnimator()->is_animating()); EXPECT_FALSE(window->layer()->GetAnimator()->is_animating());
EXPECT_FALSE(window2->layer()->GetAnimator()->is_animating()); EXPECT_FALSE(window2->layer()->GetAnimator()->is_animating());
WaitForSmoothnessMetrics();
histogram_tester.ExpectTotalCount(kEnterHistogram, 0); histogram_tester.ExpectTotalCount(kEnterHistogram, 0);
histogram_tester.ExpectTotalCount(kExitHistogram, 0); histogram_tester.ExpectTotalCount(kExitHistogram, 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment