Commit 660a4775 authored by Matt Reynolds's avatar Matt Reynolds Committed by Commit Bot

Add a flag to configure the gamepad polling interval

Adds --gamepad-polling-interval [INTERVAL], where INTERVAL is the delay
in milliseconds between successive polls of gamepad button and axis
inputs. Decreasing the interval improves latency, but may cause a loss
in performance due to more CPU time spent in the input polling thread.
The interval must be between 4 and 16 ms, inclusive. If no interval is
specified the max value (16ms) is used.

Also adds chrome://flags#gamepad-polling-rate to allow selection of the
target polling rate from the flags page.

BUG=855188

Change-Id: I9ec58c7320eff952c46bce263da8526459ad8a9b
Reviewed-on: https://chromium-review.googlesource.com/1110742
Commit-Queue: Matt Reynolds <mattreynolds@chromium.org>
Reviewed-by: default avatarNico Weber <thakis@chromium.org>
Reviewed-by: default avatarBrandon Jones <bajones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#571227}
parent f0fb42f5
......@@ -1819,6 +1819,7 @@ jumbo_split_static_library("browser") {
"//crypto:platform",
"//device/base",
"//device/fido",
"//device/gamepad/public/cpp:switches",
"//device/usb/mojo",
"//device/usb/public/mojom",
"//device/vr/buildflags",
......
......@@ -26,6 +26,7 @@ include_rules = [
"+device/bluetooth",
"+device/fido",
"+device/geolocation/public/cpp",
"+device/gamepad/public/cpp",
"+device/usb",
"+device/vr/buildflags/buildflags.h",
"+extensions/browser",
......
......@@ -105,6 +105,7 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/feature_h264_with_openh264_ffmpeg.h"
#include "device/base/features.h"
#include "device/gamepad/public/cpp/gamepad_switches.h"
#include "device/vr/buildflags/buildflags.h"
#include "extensions/buildflags/buildflags.h"
#include "google_apis/drive/drive_switches.h"
......@@ -1155,6 +1156,14 @@ const FeatureEntry::FeatureVariation kProactiveTabFreezeAndDiscardVariations[] =
base::size(kProactiveTabFreezeAndDiscard_FreezeAndDiscard), nullptr}};
#endif
const FeatureEntry::Choice kGamepadPollingRateChoices[] = {
{"60 Hz (Default)", "", ""}, // 16 ms, technically 62.5 Hz
{"100 Hz", switches::kGamepadPollingInterval, "10"},
{"125 Hz", switches::kGamepadPollingInterval, "8"},
{"200 Hz", switches::kGamepadPollingInterval, "5"},
{"250 Hz", switches::kGamepadPollingInterval, "4"},
};
// RECORDING USER METRICS FOR FLAGS:
// -----------------------------------------------------------------------------
// The first line of the entry is the internal name.
......@@ -3996,6 +4005,10 @@ const FeatureEntry kFeatureEntries[] = {
FEATURE_VALUE_TYPE(features::kArcCupsApi)},
#endif // OS_CHROMEOS
{"gamepad-polling-rate", flag_descriptions::kGamepadPollingRateName,
flag_descriptions::kGamepadPollingRateDescription, kOsDesktop,
MULTI_VALUE_TYPE(kGamepadPollingRateChoices)},
// NOTE: Adding a new flag requires adding a corresponding entry to enum
// "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
// Histograms" in tools/metrics/histograms/README.md (run the
......
......@@ -880,6 +880,11 @@ const char kFramebustingDescription[] =
const char kGamepadExtensionsName[] = "Gamepad Extensions";
const char kGamepadExtensionsDescription[] =
"Enables experimental extensions to the Gamepad APIs.";
const char kGamepadPollingRateName[] = "Gamepad Polling Rate";
const char kGamepadPollingRateDescription[] =
"Changes the rate at which gamepad input devices are polled. Increasing "
"the polling rate improves the average latency of button and axis inputs "
"but may negatively affect performance.";
const char kGamepadVibrationName[] = "Gamepad Vibration";
const char kGamepadVibrationDescription[] =
"Enables haptic vibration effects on supported gamepads.";
......
......@@ -550,6 +550,8 @@ extern const char kFramebustingDescription[];
extern const char kGamepadExtensionsName[];
extern const char kGamepadExtensionsDescription[];
extern const char kGamepadPollingRateName[];
extern const char kGamepadPollingRateDescription[];
extern const char kGamepadVibrationName[];
extern const char kGamepadVibrationDescription[];
......
......@@ -89,6 +89,7 @@ component("gamepad") {
"//base/third_party/dynamic_annotations",
"//device/base/synchronization",
"//device/gamepad/public/cpp:shared_with_blink",
"//device/gamepad/public/cpp:switches",
"//device/gamepad/public/mojom",
"//mojo/public/cpp/system",
"//third_party/blink/public:blink_headers",
......
......@@ -11,10 +11,12 @@
#include <vector>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
......@@ -23,10 +25,18 @@
#include "device/gamepad/gamepad_data_fetcher.h"
#include "device/gamepad/gamepad_data_fetcher_manager.h"
#include "device/gamepad/gamepad_user_gesture.h"
#include "device/gamepad/public/cpp/gamepad_switches.h"
#include "mojo/public/cpp/system/platform_handle.h"
namespace device {
namespace {
const size_t kPollingIntervalMillisecondsMin = 4; // ~250 Hz
const size_t kPollingIntervalMillisecondsMax = 16; // ~62.5 Hz
} // namespace
GamepadProvider::ClosureAndThread::ClosureAndThread(
const base::Closure& c,
const scoped_refptr<base::SingleThreadTaskRunner>& m)
......@@ -185,6 +195,22 @@ void GamepadProvider::OnDevicesChanged(base::SystemMonitor::DeviceType type) {
}
void GamepadProvider::Initialize(std::unique_ptr<GamepadDataFetcher> fetcher) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
size_t interval_millis = kPollingIntervalMillisecondsMax;
if (command_line &&
command_line->HasSwitch(switches::kGamepadPollingInterval)) {
std::string string_value =
command_line->GetSwitchValueASCII(switches::kGamepadPollingInterval);
size_t int_value;
if (base::StringToSizeT(string_value, &int_value)) {
// Clamp interval duration to valid range.
int_value = std::max(int_value, kPollingIntervalMillisecondsMin);
int_value = std::min(int_value, kPollingIntervalMillisecondsMax);
interval_millis = int_value;
}
}
sampling_interval_delta_ = base::TimeDelta::FromMilliseconds(interval_millis);
base::SystemMonitor* monitor = base::SystemMonitor::Get();
if (monitor)
monitor->AddDevicesChangedObserver(this);
......@@ -372,7 +398,7 @@ void GamepadProvider::ScheduleDoPoll() {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::BindOnce(&GamepadProvider::DoPoll, Unretained(this)),
base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs));
sampling_interval_delta_);
have_scheduled_do_poll_ = true;
}
......
......@@ -15,6 +15,7 @@
#include "base/memory/shared_memory.h"
#include "base/synchronization/lock.h"
#include "base/system_monitor/system_monitor.h"
#include "base/time/time.h"
#include "device/gamepad/gamepad_export.h"
#include "device/gamepad/gamepad_pad_state_provider.h"
#include "device/gamepad/gamepad_shared_buffer.h"
......@@ -114,7 +115,8 @@ class DEVICE_GAMEPAD_EXPORT GamepadProvider
// true if any user gesture observers were notified.
bool CheckForUserGesture();
enum { kDesiredSamplingIntervalMs = 16 };
// The duration of the delay between iterations of DoPoll.
base::TimeDelta sampling_interval_delta_;
// Keeps track of when the background thread is paused. Access to is_paused_
// must be guarded by is_paused_lock_.
......
......@@ -41,3 +41,10 @@ component("shared_typemap_traits") {
"//device/gamepad/public/mojom:mojom_shared",
]
}
static_library("switches") {
sources = [
"gamepad_switches.cc",
"gamepad_switches.h",
]
}
// Copyright 2018 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 "device/gamepad/public/cpp/gamepad_switches.h"
namespace switches {
// Overrides the gamepad polling interval. Decreasing the interval improves
// input latency of buttons and axes but may negatively affect performance due
// to more CPU time spent in the input polling thread.
const char kGamepadPollingInterval[] = "gamepad-polling-interval";
} // namespace switches
// Copyright 2018 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 DEVICE_GAMEPAD_PUBLIC_CPP_GAMEPAD_SWITCHES_H_
#define DEVICE_GAMEPAD_PUBLIC_CPP_GAMEPAD_SWITCHES_H_
namespace switches {
// All switches in alphabetical order. The switches should be documented
// alongside the definition of their values in the .cc file.
extern const char kGamepadPollingInterval[];
} // namespace switches
#endif // DEVICE_GAMEPAD_PUBLIC_CPP_GAMEPAD_SWITCHES_H_
......@@ -28460,6 +28460,7 @@ from previous Chrome versions.
<int value="1209221384" label="enable-experimental-accessibility-features"/>
<int value="1210343926" label="enable-drop-sync-credential"/>
<int value="1211284676" label="V8NoTurbo:enabled"/>
<int value="1214219155" label="gamepad-polling-interval"/>
<int value="1214455758" label="VideoRotateToFullscreen:disabled"/>
<int value="1215531732" label="OmniboxUIExperiments:disabled"/>
<int value="1217907443" label="spurious-power-button-keyboard-accel"/>
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