Commit 00982d27 authored by yjliu's avatar yjliu Committed by Commit Bot

Frame throttling for Android apps in ChromeOS.

Throttling Android apps from ash through wayland protocol. This is done
by manipulating the vsync updates intervals in exo. Because vsync is
global for all android apps, we don't apply throttle if at least one
android app shouldn't be throttled.

Bug: 1107201
Change-Id: I39f761f9460120928687058732942739bb26c88b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2389326Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Commit-Queue: Jun Liu <yjliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816831}
parent 91b5b55a
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "ash/public/cpp/app_types.h" #include "ash/public/cpp/app_types.h"
#include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/ash_switches.h"
#include "ash/shell.h"
#include "ash/wm/mru_window_tracker.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/frame_sink_id.h"
...@@ -64,32 +66,90 @@ void FrameThrottlingController::StartThrottling( ...@@ -64,32 +66,90 @@ void FrameThrottlingController::StartThrottling(
if (windows_throttled_) if (windows_throttled_)
EndThrottling(); EndThrottling();
windows_throttled_ = true; auto all_windows =
Shell::Get()->mru_window_tracker()->BuildMruWindowList(kActiveDesk);
std::vector<aura::Window*> all_arc_windows;
std::copy_if(all_windows.begin(), all_windows.end(),
std::back_inserter(all_arc_windows), [](aura::Window* window) {
return ash::AppType::ARC_APP ==
static_cast<ash::AppType>(
window->GetProperty(aura::client::kAppType));
});
std::vector<aura::Window*> browser_windows;
browser_windows.reserve(windows.size());
std::vector<aura::Window*> arc_windows;
arc_windows.reserve(windows.size());
for (auto* window : windows) {
ash::AppType type =
static_cast<ash::AppType>(window->GetProperty(aura::client::kAppType));
switch (type) {
case ash::AppType::BROWSER:
browser_windows.push_back(window);
break;
case ash::AppType::ARC_APP:
arc_windows.push_back(window);
break;
default:
break;
}
}
if (!browser_windows.empty()) {
std::vector<viz::FrameSinkId> frame_sink_ids; std::vector<viz::FrameSinkId> frame_sink_ids;
frame_sink_ids.reserve(windows.size()); frame_sink_ids.reserve(browser_windows.size());
CollectBrowserFrameSinkIds(windows, &frame_sink_ids); CollectBrowserFrameSinkIds(browser_windows, &frame_sink_ids);
if (!frame_sink_ids.empty()) if (!frame_sink_ids.empty())
StartThrottling(frame_sink_ids, throttled_fps_); StartThrottlingFrameSinks(frame_sink_ids);
}
for (auto& observer : observers_) { std::vector<aura::Window*> all_windows_to_throttle(browser_windows);
observer.OnThrottlingStarted(windows, throttled_fps_);
// Do not throttle arc if at least one arc window should not be throttled.
if (!arc_windows.empty() && (arc_windows.size() == all_arc_windows.size())) {
StartThrottlingArc(arc_windows);
all_windows_to_throttle.insert(all_windows_to_throttle.end(),
arc_windows.begin(), arc_windows.end());
}
if (!all_windows_to_throttle.empty()) {
windows_throttled_ = true;
for (auto& observer : observers_)
observer.OnThrottlingStarted(all_windows_to_throttle, throttled_fps_);
} }
} }
void FrameThrottlingController::StartThrottling( void FrameThrottlingController::StartThrottlingFrameSinks(
const std::vector<viz::FrameSinkId>& frame_sink_ids, const std::vector<viz::FrameSinkId>& frame_sink_ids) {
uint8_t fps) {
DCHECK_GT(fps, 0);
DCHECK(!frame_sink_ids.empty()); DCHECK(!frame_sink_ids.empty());
if (context_factory_) { if (context_factory_) {
context_factory_->GetHostFrameSinkManager()->StartThrottling( context_factory_->GetHostFrameSinkManager()->StartThrottling(
frame_sink_ids, base::TimeDelta::FromSeconds(1) / fps); frame_sink_ids, base::TimeDelta::FromSeconds(1) / throttled_fps_);
} }
} }
void FrameThrottlingController::EndThrottling() { void FrameThrottlingController::StartThrottlingArc(
const std::vector<aura::Window*>& arc_windows) {
for (auto& arc_observer : arc_observers_) {
arc_observer.OnThrottlingStarted(arc_windows, throttled_fps_);
}
}
void FrameThrottlingController::EndThrottlingFrameSinks() {
if (context_factory_) if (context_factory_)
context_factory_->GetHostFrameSinkManager()->EndThrottling(); context_factory_->GetHostFrameSinkManager()->EndThrottling();
}
void FrameThrottlingController::EndThrottlingArc() {
for (auto& arc_observer : arc_observers_) {
arc_observer.OnThrottlingEnded();
}
}
void FrameThrottlingController::EndThrottling() {
EndThrottlingFrameSinks();
EndThrottlingArc();
for (auto& observer : observers_) { for (auto& observer : observers_) {
observer.OnThrottlingEnded(); observer.OnThrottlingEnded();
...@@ -106,4 +166,14 @@ void FrameThrottlingController::RemoveObserver( ...@@ -106,4 +166,14 @@ void FrameThrottlingController::RemoveObserver(
observers_.RemoveObserver(observer); observers_.RemoveObserver(observer);
} }
void FrameThrottlingController::AddArcObserver(
FrameThrottlingObserver* observer) {
arc_observers_.AddObserver(observer);
}
void FrameThrottlingController::RemoveArcObserver(
FrameThrottlingObserver* observer) {
arc_observers_.RemoveObserver(observer);
}
} // namespace ash } // namespace ash
...@@ -43,14 +43,22 @@ class ASH_EXPORT FrameThrottlingController { ...@@ -43,14 +43,22 @@ class ASH_EXPORT FrameThrottlingController {
void AddObserver(FrameThrottlingObserver* observer); void AddObserver(FrameThrottlingObserver* observer);
void RemoveObserver(FrameThrottlingObserver* observer); void RemoveObserver(FrameThrottlingObserver* observer);
void AddArcObserver(FrameThrottlingObserver* observer);
void RemoveArcObserver(FrameThrottlingObserver* observer);
uint8_t throttled_fps() const { return throttled_fps_; } uint8_t throttled_fps() const { return throttled_fps_; }
private: private:
void StartThrottling(const std::vector<viz::FrameSinkId>& frame_sink_ids, void StartThrottlingFrameSinks(
uint8_t fps); const std::vector<viz::FrameSinkId>& frame_sink_ids);
void StartThrottlingArc(const std::vector<aura::Window*>& windows);
void EndThrottlingFrameSinks();
void EndThrottlingArc();
ui::ContextFactory* context_factory_ = nullptr; ui::ContextFactory* context_factory_ = nullptr;
base::ObserverList<FrameThrottlingObserver> observers_; base::ObserverList<FrameThrottlingObserver> observers_;
base::ObserverList<FrameThrottlingObserver> arc_observers_;
// The fps used for throttling. // The fps used for throttling.
uint8_t throttled_fps_ = kDefaultThrottleFps; uint8_t throttled_fps_ = kDefaultThrottleFps;
bool windows_throttled_ = false; bool windows_throttled_ = false;
......
...@@ -686,11 +686,15 @@ TEST_F(OverviewControllerTest, FrameThrottling) { ...@@ -686,11 +686,15 @@ TEST_F(OverviewControllerTest, FrameThrottling) {
FrameThrottlingController* frame_throttling_controller = FrameThrottlingController* frame_throttling_controller =
Shell::Get()->frame_throttling_controller(); Shell::Get()->frame_throttling_controller();
frame_throttling_controller->AddObserver(&observer); frame_throttling_controller->AddObserver(&observer);
const int window_count = 5; const int browser_window_count = 3;
std::unique_ptr<aura::Window> created_windows[window_count]; const int arc_window_count = 2;
std::vector<aura::Window*> windows(window_count, nullptr); const int total_window_count = browser_window_count + arc_window_count;
for (int i = 0; i < window_count; ++i) { std::unique_ptr<aura::Window> created_windows[total_window_count];
created_windows[i] = CreateAppWindow(gfx::Rect(), AppType::BROWSER); std::vector<aura::Window*> windows(total_window_count, nullptr);
for (int i = 0; i < total_window_count; ++i) {
created_windows[i] = CreateAppWindow(gfx::Rect(), i < browser_window_count
? AppType::BROWSER
: AppType::ARC_APP);
windows[i] = created_windows[i].get(); windows[i] = created_windows[i].get();
} }
......
...@@ -324,9 +324,52 @@ TEST_F(OverviewGridTest, FrameThrottling) { ...@@ -324,9 +324,52 @@ TEST_F(OverviewGridTest, FrameThrottling) {
aura::Window* window = windows[0]; aura::Window* window = windows[0];
windows.erase(windows.begin()); windows.erase(windows.begin());
EXPECT_CALL(observer, OnThrottlingEnded()); EXPECT_CALL(observer, OnThrottlingEnded());
if (!windows.empty()) {
EXPECT_CALL(observer, OnThrottlingStarted(
testing::UnorderedElementsAreArray(windows),
throttled_fps));
}
OverviewItem* item = grid()->GetOverviewItemContaining(window);
grid()->RemoveItem(item, /*item_destroying=*/false, /*reposition=*/false);
}
frame_throttling_controller->RemoveObserver(&observer);
}
TEST_F(OverviewGridTest, FrameThrottlingArc) {
testing::NiceMock<MockFrameThrottlingObserver> observer;
FrameThrottlingController* frame_throttling_controller =
Shell::Get()->frame_throttling_controller();
uint8_t throttled_fps = frame_throttling_controller->throttled_fps();
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] = CreateAppWindow(gfx::Rect(), AppType::ARC_APP);
windows[i] = created_windows[i].get();
}
InitializeGrid(windows);
frame_throttling_controller->StartThrottling(windows);
// Add a new window to overview.
std::unique_ptr<aura::Window> new_window(
CreateAppWindow(gfx::Rect(), AppType::ARC_APP));
windows.push_back(new_window.get());
EXPECT_CALL(observer, OnThrottlingEnded());
EXPECT_CALL(observer, EXPECT_CALL(observer,
OnThrottlingStarted(testing::UnorderedElementsAreArray(windows), OnThrottlingStarted(testing::UnorderedElementsAreArray(windows),
throttled_fps)); throttled_fps));
grid()->AppendItem(new_window.get(), /*reposition=*/false, /*animate=*/false,
/*use_spawn_animation=*/false);
// Remove windows one by one. Once one window is out of the overview grid, no
// more windows will be throttled.
for (int i = 0; i < window_count; ++i) {
aura::Window* window = windows[0];
windows.erase(windows.begin());
if (i == 0)
EXPECT_CALL(observer, OnThrottlingEnded());
EXPECT_CALL(observer, OnThrottlingStarted(testing::_, testing::_)).Times(0);
OverviewItem* item = grid()->GetOverviewItemContaining(window); OverviewItem* item = grid()->GetOverviewItemContaining(window);
grid()->RemoveItem(item, /*item_destroying=*/false, /*reposition=*/false); grid()->RemoveItem(item, /*item_destroying=*/false, /*reposition=*/false);
} }
......
...@@ -189,6 +189,8 @@ source_set("test_support") { ...@@ -189,6 +189,8 @@ source_set("test_support") {
testonly = true testonly = true
sources = [ sources = [
"mock_vsync_timing_observer.cc",
"mock_vsync_timing_observer.h",
"test/exo_test_base_views.cc", "test/exo_test_base_views.cc",
"test/exo_test_base_views.h", "test/exo_test_base_views.h",
"test/exo_test_suite_aura.cc", "test/exo_test_suite_aura.cc",
...@@ -294,6 +296,7 @@ source_set("unit_tests") { ...@@ -294,6 +296,7 @@ source_set("unit_tests") {
"toast_surface_unittest.cc", "toast_surface_unittest.cc",
"touch_unittest.cc", "touch_unittest.cc",
"ui_lock_controller_unittest.cc", "ui_lock_controller_unittest.cc",
"wm_helper_chromeos_unittest.cc",
"xdg_shell_surface_unittest.cc", "xdg_shell_surface_unittest.cc",
] ]
......
// 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 "components/exo/mock_vsync_timing_observer.h"
namespace exo {
MockVSyncTimingObserver::MockVSyncTimingObserver() = default;
MockVSyncTimingObserver::~MockVSyncTimingObserver() = default;
} // namespace exo
// 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 COMPONENTS_EXO_MOCK_VSYNC_TIMING_OBSERVER_H_
#define COMPONENTS_EXO_MOCK_VSYNC_TIMING_OBSERVER_H_
#include "components/exo/vsync_timing_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace exo {
class MockVSyncTimingObserver : public VSyncTimingManager::Observer {
public:
MockVSyncTimingObserver();
~MockVSyncTimingObserver() override;
MOCK_METHOD(void,
OnUpdateVSyncParameters,
(base::TimeTicks timebase, base::TimeDelta interval),
(override));
};
} // namespace exo
#endif // COMPONENTS_EXO_MOCK_VSYNC_TIMING_OBSERVER_H_
...@@ -63,6 +63,7 @@ class ExoTestBase : public ash::AshTestBase { ...@@ -63,6 +63,7 @@ class ExoTestBase : public ash::AshTestBase {
ShellSurface* parent); ShellSurface* parent);
ExoTestHelper* exo_test_helper() { return &exo_test_helper_; } ExoTestHelper* exo_test_helper() { return &exo_test_helper_; }
WMHelper* wm_helper() { return wm_helper_.get(); }
private: private:
ExoTestHelper exo_test_helper_; ExoTestHelper exo_test_helper_;
......
...@@ -6,11 +6,13 @@ ...@@ -6,11 +6,13 @@
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
namespace exo { namespace exo {
VSyncTimingManager::VSyncTimingManager(Delegate* delegate) VSyncTimingManager::VSyncTimingManager(Delegate* delegate)
: delegate_(delegate) {} : last_interval_(viz::BeginFrameArgs::DefaultInterval()),
delegate_(delegate) {}
VSyncTimingManager::~VSyncTimingManager() = default; VSyncTimingManager::~VSyncTimingManager() = default;
...@@ -36,8 +38,25 @@ void VSyncTimingManager::RemoveObserver(Observer* obs) { ...@@ -36,8 +38,25 @@ void VSyncTimingManager::RemoveObserver(Observer* obs) {
void VSyncTimingManager::OnUpdateVSyncParameters(base::TimeTicks timebase, void VSyncTimingManager::OnUpdateVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) { base::TimeDelta interval) {
for (auto* observer : observers_) for (auto* observer : observers_) {
observer->OnUpdateVSyncParameters(timebase, interval); observer->OnUpdateVSyncParameters(timebase, throttled_interval_.is_zero()
? interval
: throttled_interval_);
}
last_timebase_ = timebase;
last_interval_ = interval;
}
void VSyncTimingManager::OnThrottlingStarted(
const std::vector<aura::Window*>& windows,
uint8_t fps) {
throttled_interval_ = base::TimeDelta::FromSeconds(1) / fps;
OnUpdateVSyncParameters(last_timebase_, last_interval_);
}
void VSyncTimingManager::OnThrottlingEnded() {
throttled_interval_ = base::TimeDelta();
OnUpdateVSyncParameters(last_timebase_, last_interval_);
} }
void VSyncTimingManager::InitializeConnection() { void VSyncTimingManager::InitializeConnection() {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <vector> #include <vector>
#include "ash/frame_throttler/frame_throttling_observer.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h"
...@@ -18,7 +19,8 @@ namespace exo { ...@@ -18,7 +19,8 @@ namespace exo {
// Multiplexes vsync parameter updates from the display compositor to exo // Multiplexes vsync parameter updates from the display compositor to exo
// clients using the zcr_vsync_feedback_v1 protocol. Will maintain an IPC // clients using the zcr_vsync_feedback_v1 protocol. Will maintain an IPC
// connection to the display compositor only when necessary. // connection to the display compositor only when necessary.
class VSyncTimingManager : public viz::mojom::VSyncParameterObserver { class VSyncTimingManager : public viz::mojom::VSyncParameterObserver,
public ash::FrameThrottlingObserver {
public: public:
// Will be notified about changes in vsync parameters. // Will be notified about changes in vsync parameters.
class Observer { class Observer {
...@@ -44,15 +46,26 @@ class VSyncTimingManager : public viz::mojom::VSyncParameterObserver { ...@@ -44,15 +46,26 @@ class VSyncTimingManager : public viz::mojom::VSyncParameterObserver {
void AddObserver(Observer* obs); void AddObserver(Observer* obs);
void RemoveObserver(Observer* obs); void RemoveObserver(Observer* obs);
base::TimeDelta throttled_interval() const { return throttled_interval_; }
private: private:
// Overridden from viz::mojom::VSyncParameterObserver: // Overridden from viz::mojom::VSyncParameterObserver:
void OnUpdateVSyncParameters(base::TimeTicks timebase, void OnUpdateVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) override; base::TimeDelta interval) override;
// Overridden from ash::FrameThrottlingObserver
void OnThrottlingStarted(const std::vector<aura::Window*>& windows,
uint8_t fps) override;
void OnThrottlingEnded() override;
void InitializeConnection(); void InitializeConnection();
void MaybeInitializeConnection(); void MaybeInitializeConnection();
void OnConnectionError(); void OnConnectionError();
base::TimeDelta throttled_interval_;
base::TimeDelta last_interval_;
base::TimeTicks last_timebase_;
Delegate* const delegate_; Delegate* const delegate_;
std::vector<Observer*> observers_; std::vector<Observer*> observers_;
......
...@@ -839,6 +839,7 @@ class WaylandRemoteShell : public ash::TabletModeObserver, ...@@ -839,6 +839,7 @@ class WaylandRemoteShell : public ash::TabletModeObserver,
helper->AddTabletModeObserver(this); helper->AddTabletModeObserver(this);
helper->AddActivationObserver(this); helper->AddActivationObserver(this);
display::Screen::GetScreen()->AddObserver(this); display::Screen::GetScreen()->AddObserver(this);
helper->AddFrameThrottlingObserver();
layout_mode_ = helper->InTabletMode() layout_mode_ = helper->InTabletMode()
? ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_TABLET ? ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_TABLET
...@@ -864,6 +865,7 @@ class WaylandRemoteShell : public ash::TabletModeObserver, ...@@ -864,6 +865,7 @@ class WaylandRemoteShell : public ash::TabletModeObserver,
helper->RemoveTabletModeObserver(this); helper->RemoveTabletModeObserver(this);
helper->RemoveActivationObserver(this); helper->RemoveActivationObserver(this);
display::Screen::GetScreen()->RemoveObserver(this); display::Screen::GetScreen()->RemoveObserver(this);
helper->RemoveFrameThrottlingObserver();
} }
std::unique_ptr<ClientControlledShellSurface> CreateShellSurface( std::unique_ptr<ClientControlledShellSurface> CreateShellSurface(
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "components/exo/wm_helper_chromeos.h" #include "components/exo/wm_helper_chromeos.h"
#include "components/exo/wm_helper.h" #include "components/exo/wm_helper.h"
#include "ash/frame_throttler/frame_throttling_controller.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h"
...@@ -61,6 +62,16 @@ void WMHelperChromeOS::RemoveDisplayConfigurationObserver( ...@@ -61,6 +62,16 @@ void WMHelperChromeOS::RemoveDisplayConfigurationObserver(
ash::Shell::Get()->window_tree_host_manager()->RemoveObserver(observer); ash::Shell::Get()->window_tree_host_manager()->RemoveObserver(observer);
} }
void WMHelperChromeOS::AddFrameThrottlingObserver() {
ash::Shell::Get()->frame_throttling_controller()->AddArcObserver(
&vsync_timing_manager_);
}
void WMHelperChromeOS::RemoveFrameThrottlingObserver() {
ash::Shell::Get()->frame_throttling_controller()->RemoveArcObserver(
&vsync_timing_manager_);
}
void WMHelperChromeOS::AddActivationObserver( void WMHelperChromeOS::AddActivationObserver(
wm::ActivationChangeObserver* observer) { wm::ActivationChangeObserver* observer) {
ash::Shell::Get()->activation_client()->AddObserver(observer); ash::Shell::Get()->activation_client()->AddObserver(observer);
......
...@@ -60,6 +60,8 @@ class WMHelperChromeOS : public WMHelper, public VSyncTimingManager::Delegate { ...@@ -60,6 +60,8 @@ class WMHelperChromeOS : public WMHelper, public VSyncTimingManager::Delegate {
ash::WindowTreeHostManager::Observer* observer); ash::WindowTreeHostManager::Observer* observer);
void RemoveDisplayConfigurationObserver( void RemoveDisplayConfigurationObserver(
ash::WindowTreeHostManager::Observer* observer); ash::WindowTreeHostManager::Observer* observer);
void AddFrameThrottlingObserver();
void RemoveFrameThrottlingObserver();
// Overridden from WMHelper // Overridden from WMHelper
void AddActivationObserver(wm::ActivationChangeObserver* observer) override; void AddActivationObserver(wm::ActivationChangeObserver* observer) override;
......
// 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 "components/exo/wm_helper_chromeos.h"
#include "ash/frame_throttler/frame_throttling_controller.h"
#include "ash/shell.h"
#include "components/exo/mock_vsync_timing_observer.h"
#include "components/exo/test/exo_test_base.h"
namespace exo {
using WMHelperChromeOSTest = test::ExoTestBase;
TEST_F(WMHelperChromeOSTest, FrameThrottling) {
WMHelperChromeOS* wm_helper_chromeos =
static_cast<WMHelperChromeOS*>(wm_helper());
wm_helper_chromeos->AddFrameThrottlingObserver();
VSyncTimingManager& vsync_timing_manager =
wm_helper_chromeos->GetVSyncTimingManager();
MockVSyncTimingObserver observer;
vsync_timing_manager.AddObserver(&observer);
ash::FrameThrottlingController* ftc =
ash::Shell::Get()->frame_throttling_controller();
// Throttling should be off by default.
EXPECT_EQ(vsync_timing_manager.throttled_interval(), base::TimeDelta());
// Create two arc windows.
std::unique_ptr<aura::Window> arc_window_1 =
CreateAppWindow(gfx::Rect(), ash::AppType::ARC_APP);
std::unique_ptr<aura::Window> arc_window_2 =
CreateAppWindow(gfx::Rect(), ash::AppType::ARC_APP);
// Starting throttling on one of the two arc windows will have no effect on
// vsync time.
EXPECT_CALL(observer, OnUpdateVSyncParameters(testing::_, testing::_))
.Times(0);
ftc->StartThrottling({arc_window_1.get()});
EXPECT_EQ(vsync_timing_manager.throttled_interval(), base::TimeDelta());
// Both windows are to be throttled, vsync timing will be adjusted.
base::TimeDelta throttled_interval =
base::TimeDelta::FromSeconds(1) / ftc->throttled_fps();
EXPECT_CALL(observer,
OnUpdateVSyncParameters(testing::_, throttled_interval));
ftc->StartThrottling({arc_window_1.get(), arc_window_2.get()});
EXPECT_EQ(vsync_timing_manager.throttled_interval(), throttled_interval);
EXPECT_CALL(observer,
OnUpdateVSyncParameters(testing::_,
viz::BeginFrameArgs::DefaultInterval()));
ftc->EndThrottling();
EXPECT_EQ(vsync_timing_manager.throttled_interval(), base::TimeDelta());
vsync_timing_manager.RemoveObserver(&observer);
wm_helper_chromeos->RemoveFrameThrottlingObserver();
}
} // namespace exo
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