mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-10-12 03:24:00 +00:00
Reduce gamepad CPU usage on Steam Link
- Gamepad sensors are now disabled by default - Added a small deadzone to limit excess gamepad input reports
This commit is contained in:
@@ -9,6 +9,11 @@ HOME=/usr/local/moonlight
|
|||||||
# https://github.com/moonlight-stream/moonlight-qt/issues/697
|
# https://github.com/moonlight-stream/moonlight-qt/issues/697
|
||||||
export SDL_ENABLE_STEAM_CONTROLLERS=1
|
export SDL_ENABLE_STEAM_CONTROLLERS=1
|
||||||
|
|
||||||
|
# Disable gamepad sensors by default to avoid excessive CPU
|
||||||
|
# usage that can cause audio glitches. Remove the following
|
||||||
|
# line to enable gamepad sensors.
|
||||||
|
export SENSOR_REPORT_RATE_LIMIT_HZ=0
|
||||||
|
|
||||||
# Renice PE_Single_CPU which seems to host A/V stuff
|
# Renice PE_Single_CPU which seems to host A/V stuff
|
||||||
renice -10 -p $(pidof PE_Single_CPU)
|
renice -10 -p $(pidof PE_Single_CPU)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <Limelight.h>
|
#include <Limelight.h>
|
||||||
#include "SDL_compat.h"
|
#include "SDL_compat.h"
|
||||||
#include "settings/mappingmanager.h"
|
#include "settings/mappingmanager.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
|
||||||
@@ -188,6 +189,26 @@ Uint32 SdlInputHandler::mouseEmulationTimerCallback(Uint32 interval, void *param
|
|||||||
return interval;
|
return interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void updateAnalogStickAxis(short& value, short newValue, bool& dirty)
|
||||||
|
{
|
||||||
|
#ifdef STEAM_LINK
|
||||||
|
// Use a deadzone on Steam Link to reduce CPU usage from idle joysticks
|
||||||
|
newValue = abs(newValue) < 1500 ? 0 : newValue;
|
||||||
|
#endif
|
||||||
|
dirty |= (newValue != value);
|
||||||
|
value = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateTriggerAxis(unsigned char& value, unsigned char newValue, bool& dirty)
|
||||||
|
{
|
||||||
|
#ifdef STEAM_LINK
|
||||||
|
// Use a deadzone on Steam Link to reduce CPU usage from idle joysticks
|
||||||
|
newValue = newValue < 10 ? 0 : newValue;
|
||||||
|
#endif
|
||||||
|
dirty |= (newValue != value);
|
||||||
|
value = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event)
|
void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event)
|
||||||
{
|
{
|
||||||
SDL_JoystickID gameControllerId = event->which;
|
SDL_JoystickID gameControllerId = event->which;
|
||||||
@@ -198,11 +219,12 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event)
|
|||||||
|
|
||||||
// Batch all pending axis motion events for this gamepad to save CPU time
|
// Batch all pending axis motion events for this gamepad to save CPU time
|
||||||
SDL_Event nextEvent;
|
SDL_Event nextEvent;
|
||||||
|
bool dirty = false;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (event->axis)
|
switch (event->axis)
|
||||||
{
|
{
|
||||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||||
state->lsX = event->value;
|
updateAnalogStickAxis(state->lsX, event->value, dirty);
|
||||||
break;
|
break;
|
||||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||||
// Signed values have one more negative value than
|
// Signed values have one more negative value than
|
||||||
@@ -210,19 +232,19 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event)
|
|||||||
// could actually cause the value to overflow and
|
// could actually cause the value to overflow and
|
||||||
// wrap around to be negative again. Avoid that by
|
// wrap around to be negative again. Avoid that by
|
||||||
// capping the value at 32767.
|
// capping the value at 32767.
|
||||||
state->lsY = -qMax(event->value, (short)-32767);
|
updateAnalogStickAxis(state->lsY, -qMax(event->value, (short)-32767), dirty);
|
||||||
break;
|
break;
|
||||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||||
state->rsX = event->value;
|
updateAnalogStickAxis(state->rsX, event->value, dirty);
|
||||||
break;
|
break;
|
||||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||||
state->rsY = -qMax(event->value, (short)-32767);
|
updateAnalogStickAxis(state->rsY, -qMax(event->value, (short)-32767), dirty);
|
||||||
break;
|
break;
|
||||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||||
state->lt = (unsigned char)(event->value * 255UL / 32767);
|
updateTriggerAxis(state->lt, (unsigned char)(event->value * 255UL / 32767), dirty);
|
||||||
break;
|
break;
|
||||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||||
state->rt = (unsigned char)(event->value * 255UL / 32767);
|
updateTriggerAxis(state->rt, (unsigned char)(event->value * 255UL / 32767), dirty);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
@@ -247,7 +269,7 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only send the gamepad state to the host if it's not in mouse emulation mode
|
// Only send the gamepad state to the host if it's not in mouse emulation mode
|
||||||
if (state->mouseEmulationTimer == 0) {
|
if (state->mouseEmulationTimer == 0 && dirty) {
|
||||||
sendGamepadState(state);
|
sendGamepadState(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -897,6 +919,15 @@ void SdlInputHandler::setMotionEventState(uint16_t controllerNumber, uint8_t mot
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t reportRateHzLimit;
|
||||||
|
if (Utils::getEnvironmentVariableOverride("SENSOR_REPORT_RATE_LIMIT_HZ", &reportRateHzLimit) &&
|
||||||
|
reportRateHz > reportRateHzLimit) {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Sensor report rate limited to %u Hz by environment variable",
|
||||||
|
reportRateHzLimit);
|
||||||
|
reportRateHz = reportRateHzLimit;
|
||||||
|
}
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||||
if (m_GamepadState[controllerNumber].controller != nullptr) {
|
if (m_GamepadState[controllerNumber].controller != nullptr) {
|
||||||
uint8_t reportPeriodMs = reportRateHz ? (1000 / reportRateHz) : 0;
|
uint8_t reportPeriodMs = reportRateHz ? (1000 / reportRateHz) : 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user