Commit 1797b858 authored by yjliu's avatar yjliu Committed by Commit Bot

Added frame throttling for window cycling.

Frame throttling starts and ends accordingly when window cycling starts
and ends.
Added test helper and unittests.

Bug: 1107201
Change-Id: I98d9ac1675ca8fd6d2eb7bb178c5c8961166dae4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2308131
Auto-Submit: Jun Liu <yjliu@chromium.org>
Commit-Queue: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarJun Mukai <mukai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790209}
parent 636d3427
......@@ -2302,6 +2302,8 @@ static_library("test_support") {
"drag_drop/drag_drop_controller_test_api.h",
"fast_ink/laser/laser_pointer_controller_test_api.cc",
"fast_ink/laser/laser_pointer_controller_test_api.h",
"frame_throttler/mock_frame_throttling_observer.cc",
"frame_throttler/mock_frame_throttling_observer.h",
"highlighter/highlighter_controller_test_api.cc",
"highlighter/highlighter_controller_test_api.h",
"ime/test_ime_controller_client.cc",
......
......@@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "ash/frame_throttler/frame_throttling_controller.h"
#include <utility>
#include "ash/public/cpp/app_types.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/host/host_frame_sink_manager.h"
......@@ -45,13 +48,16 @@ FrameThrottlingController::~FrameThrottlingController() {
}
void FrameThrottlingController::StartThrottling(
const std::vector<aura::Window*>& windows,
uint8_t fps) {
const std::vector<aura::Window*>& windows) {
std::vector<viz::FrameSinkId> frame_sink_ids;
frame_sink_ids.reserve(windows.size());
CollectBrowserFrameSinkIds(windows, &frame_sink_ids);
StartThrottling(frame_sink_ids, fps);
StartThrottling(frame_sink_ids, fps_);
for (auto& observer : observers_) {
observer.OnThrottlingStarted(windows);
}
}
void FrameThrottlingController::StartThrottling(
......@@ -67,6 +73,18 @@ void FrameThrottlingController::StartThrottling(
void FrameThrottlingController::EndThrottling() {
if (context_factory_)
context_factory_->GetHostFrameSinkManager()->EndThrottling();
for (auto& observer : observers_) {
observer.OnThrottlingEnded();
}
}
void FrameThrottlingController::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void FrameThrottlingController::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
} // namespace ash
......@@ -7,8 +7,11 @@
#include <stdint.h>
#include <vector>
#include "ash/ash_export.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
namespace aura {
......@@ -25,23 +28,35 @@ constexpr uint8_t kDefaultThrottleFps = 20;
class ASH_EXPORT FrameThrottlingController {
public:
class Observer : public base::CheckedObserver {
public:
virtual void OnThrottlingStarted(
const std::vector<aura::Window*>& windows) {}
virtual void OnThrottlingEnded() {}
};
explicit FrameThrottlingController(ui::ContextFactory* context_factory);
FrameThrottlingController(const FrameThrottlingController&) = delete;
FrameThrottlingController& operator=(const FrameThrottlingController&) =
delete;
~FrameThrottlingController();
// Starts to throttle the framerate of |windows|.
void StartThrottling(const std::vector<aura::Window*>& windows,
uint8_t fps = kDefaultThrottleFps);
void StartThrottling(const std::vector<aura::Window*>& windows);
// Ends throttling of all throttled windows.
void EndThrottling();
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
private:
void StartThrottling(const std::vector<viz::FrameSinkId>& frame_sink_ids,
uint8_t fps);
ui::ContextFactory* context_factory_;
friend class FrameThrottlingControllerTest;
DISALLOW_COPY_AND_ASSIGN(FrameThrottlingController);
ui::ContextFactory* context_factory_ = nullptr;
base::ObserverList<Observer> observers_;
// The fps used for throttling.
uint8_t fps_ = kDefaultThrottleFps;
};
} // namespace ash
......
// Copyright 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/frame_throttler/mock_frame_throttling_observer.h"
namespace ash {
MockFrameThrottlingObserver::MockFrameThrottlingObserver() = default;
MockFrameThrottlingObserver::~MockFrameThrottlingObserver() = default;
} // namespace ash
// Copyright 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.
#ifndef ASH_FRAME_THROTTLER_MOCK_FRAME_THROTTLING_OBSERVER_H_
#define ASH_FRAME_THROTTLER_MOCK_FRAME_THROTTLING_OBSERVER_H_
#include <vector>
#include "ash/frame_throttler/frame_throttling_controller.h"
#include "base/memory/weak_ptr.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace ash {
class MockFrameThrottlingObserver : public FrameThrottlingController::Observer {
public:
MockFrameThrottlingObserver();
~MockFrameThrottlingObserver() override;
MOCK_METHOD(void,
OnThrottlingStarted,
(const std::vector<aura::Window*>& windows),
(override));
MOCK_METHOD(void, OnThrottlingEnded, (), (override));
};
} // namespace ash
#endif // ASH_FRAME_THROTTLER_MOCK_FRAME_THROTTLING_OBSERVER_H_
......@@ -7,6 +7,7 @@
#include <memory>
#include "ash/app_list/test/app_list_test_helper.h"
#include "ash/frame_throttler/mock_frame_throttling_observer.h"
#include "ash/keyboard/ui/keyboard_ui_controller.h"
#include "ash/keyboard/ui/keyboard_util.h"
#include "ash/keyboard/ui/test/keyboard_test_util.h"
......@@ -705,4 +706,28 @@ TEST_F(OverviewVirtualKeyboardTest,
EXPECT_FALSE(keyboard::IsKeyboardHiding());
}
// Tests that frame throttling starts and ends accordingly when overview starts
// and ends.
TEST_F(OverviewControllerTest, FrameThrottling) {
MockFrameThrottlingObserver observer;
FrameThrottlingController* frame_throttling_controller =
Shell::Get()->frame_throttling_controller();
frame_throttling_controller->AddObserver(&observer);
const int window_count = 5;
std::unique_ptr<aura::Window> created_windows[window_count];
std::vector<aura::Window*> windows(window_count, nullptr);
for (int i = 0; i < window_count; ++i) {
created_windows[i] = CreateTestWindow();
windows[i] = created_windows[i].get();
}
auto* controller = Shell::Get()->overview_controller();
EXPECT_CALL(observer,
OnThrottlingStarted(testing::UnorderedElementsAreArray(windows)));
controller->StartOverview();
EXPECT_CALL(observer, OnThrottlingEnded());
controller->EndOverview();
frame_throttling_controller->RemoveObserver(&observer);
}
} // namespace ash
......@@ -9,6 +9,7 @@
#include "ash/app_list/test/app_list_test_helper.h"
#include "ash/focus_cycler.h"
#include "ash/frame_throttler/mock_frame_throttling_observer.h"
#include "ash/home_screen/home_screen_controller.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/shell_window_ids.h"
......@@ -827,4 +828,38 @@ TEST_F(LimitedWindowCycleControllerTest, CycleShowsActiveDeskWindows) {
EXPECT_EQ(win0.get(), window_util::GetActiveWindow());
}
// Tests that frame throttling starts and ends accordingly when window cycling
// starts and ends.
TEST_F(WindowCycleControllerTest, FrameThrottling) {
MockFrameThrottlingObserver observer;
FrameThrottlingController* frame_throttling_controller =
Shell::Get()->frame_throttling_controller();
frame_throttling_controller->AddObserver(&observer);
const int window_count = 5;
std::unique_ptr<aura::Window> created_windows[window_count];
std::vector<aura::Window*> windows(window_count, nullptr);
for (int i = 0; i < window_count; ++i) {
created_windows[i] = CreateTestWindow();
windows[i] = created_windows[i].get();
}
WindowCycleController* controller = Shell::Get()->window_cycle_controller();
EXPECT_CALL(observer,
OnThrottlingStarted(testing::UnorderedElementsAreArray(windows)));
controller->HandleCycleWindow(WindowCycleController::FORWARD);
EXPECT_CALL(observer,
OnThrottlingStarted(testing::UnorderedElementsAreArray(windows)))
.Times(0);
controller->HandleCycleWindow(WindowCycleController::FORWARD);
EXPECT_CALL(observer, OnThrottlingEnded());
controller->CompleteCycling();
EXPECT_CALL(observer,
OnThrottlingStarted(testing::UnorderedElementsAreArray(windows)));
controller->HandleCycleWindow(WindowCycleController::FORWARD);
EXPECT_CALL(observer, OnThrottlingEnded());
controller->CancelCycling();
frame_throttling_controller->RemoveObserver(&observer);
}
} // namespace ash
......@@ -10,6 +10,7 @@
#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/app_list/app_list_controller_impl.h"
#include "ash/frame_throttler/frame_throttling_controller.h"
#include "ash/public/cpp/metrics_util.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
......@@ -477,6 +478,7 @@ WindowCycleList::~WindowCycleList() {
auto* target_window = windows_[current_index_];
SelectWindow(target_window);
}
Shell::Get()->frame_throttling_controller()->EndThrottling();
}
void WindowCycleList::Step(WindowCycleController::Direction direction) {
......@@ -621,6 +623,8 @@ void WindowCycleList::InitWindowCycleView() {
// Close the app list, if it's open in clamshell mode.
if (!Shell::Get()->tablet_mode_controller()->InTabletMode())
Shell::Get()->app_list_controller()->DismissAppList();
Shell::Get()->frame_throttling_controller()->StartThrottling(windows_);
}
void WindowCycleList::SelectWindow(aura::Window* window) {
......
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