Skip to content

Commit

Permalink
Avoid spamming the keymap lock during input processing
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Dec 21, 2023
1 parent ac20850 commit 16a31c2
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 11 deletions.
31 changes: 22 additions & 9 deletions Core/ControlMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,11 @@ void ControlMapper::UpdateAnalogOutput(int stick) {
}

void ControlMapper::ForceReleaseVKey(int vkey) {
// Note: This one is called from an onVKey_ handler, which already holds mutex_.

KeyMap::LockMappings();
std::vector<KeyMap::MultiInputMapping> multiMappings;
if (KeyMap::InputMappingsFromPspButton(vkey, &multiMappings, true)) {
if (KeyMap::InputMappingsFromPspButtonNoLock(vkey, &multiMappings, true)) {
double now = time_now_d();
for (const auto &entry : multiMappings) {
for (const auto &mapping : entry.mappings) {
Expand All @@ -165,6 +168,7 @@ void ControlMapper::ForceReleaseVKey(int vkey) {
}
}
}
KeyMap::UnlockMappings();
}

static int RotatePSPKeyCode(int x) {
Expand Down Expand Up @@ -251,7 +255,7 @@ void ControlMapper::SwapMappingIfEnabled(uint32_t *vkey) {
}

// Can only be called from Key or Axis.
// mutex_ should be locked.
// mutex_ should be locked, and also KeyMap::LockMappings().
// TODO: We should probably make a batched version of this.
bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping, double now) {
// Instead of taking an input key and finding what it outputs, we loop through the OUTPUTS and
Expand Down Expand Up @@ -282,7 +286,7 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping, double no
}

SwapMappingIfEnabled(&mappingBit);
if (!KeyMap::InputMappingsFromPspButton(mappingBit, &inputMappings, false))
if (!KeyMap::InputMappingsFromPspButtonNoLock(mappingBit, &inputMappings, false))
continue;

// If a mapping could consist of a combo, we could trivially check it here.
Expand Down Expand Up @@ -319,7 +323,7 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping, double no
uint32_t idForMapping = vkId;
SwapMappingIfEnabled(&idForMapping);

if (!KeyMap::InputMappingsFromPspButton(idForMapping, &inputMappings, false))
if (!KeyMap::InputMappingsFromPspButtonNoLock(idForMapping, &inputMappings, false))
continue;

// If a mapping could consist of a combo, we could trivially check it here.
Expand Down Expand Up @@ -421,15 +425,16 @@ bool ControlMapper::Key(const KeyInput &key, bool *pauseTrigger) {
// Claim that we handled this. Prevents volume key repeats from popping up the volume control on Android.
return true;
}
double now = time_now_d();
if (key.deviceId < DEVICE_ID_COUNT) {
deviceTimestamps_[(int)key.deviceId] = now;
}

double now = time_now_d();
InputMapping mapping(key.deviceId, key.keyCode);

std::lock_guard<std::mutex> guard(mutex_);

if (key.deviceId < DEVICE_ID_COUNT) {
deviceTimestamps_[(int)key.deviceId] = now;
}

if (key.flags & KEY_DOWN) {
curInput_[mapping] = { 1.0f, now };
} else if (key.flags & KEY_UP) {
Expand All @@ -446,10 +451,15 @@ bool ControlMapper::Key(const KeyInput &key, bool *pauseTrigger) {
}
}

return UpdatePSPState(mapping, now);
KeyMap::LockMappings();
bool retval = UpdatePSPState(mapping, now);
KeyMap::UnlockMappings();
return retval;
}

void ControlMapper::ToggleSwapAxes() {
std::lock_guard<std::mutex> guard(mutex_);

swapAxes_ = !swapAxes_;

updatePSPButtons_(0, CTRL_LEFT | CTRL_RIGHT | CTRL_UP | CTRL_DOWN);
Expand Down Expand Up @@ -478,6 +488,8 @@ void ControlMapper::Axis(const AxisInput *axes, size_t count) {
double now = time_now_d();

std::lock_guard<std::mutex> guard(mutex_);

KeyMap::LockMappings();
for (size_t i = 0; i < count; i++) {
const AxisInput &axis = axes[i];
size_t deviceIndex = (size_t)axis.deviceId; // this wraps -1 up high, so will get rejected on the next line.
Expand All @@ -500,6 +512,7 @@ void ControlMapper::Axis(const AxisInput *axes, size_t count) {
UpdatePSPState(opposite, now);
}
}
KeyMap::UnlockMappings();
}

void ControlMapper::Update(double now) {
Expand Down
17 changes: 15 additions & 2 deletions Core/KeyMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,8 +524,8 @@ bool InputMappingToPspButton(const InputMapping &mapping, std::vector<int> *pspB
return found;
}

bool InputMappingsFromPspButton(int btn, std::vector<MultiInputMapping> *mappings, bool ignoreMouse) {
std::lock_guard<std::recursive_mutex> guard(g_controllerMapLock);
// This is the main workhorse of the ControlMapper.
bool InputMappingsFromPspButtonNoLock(int btn, std::vector<MultiInputMapping> *mappings, bool ignoreMouse) {
auto iter = g_controllerMap.find(btn);
if (iter == g_controllerMap.end()) {
return false;
Expand All @@ -542,6 +542,19 @@ bool InputMappingsFromPspButton(int btn, std::vector<MultiInputMapping> *mapping
return mapped;
}

bool InputMappingsFromPspButton(int btn, std::vector<MultiInputMapping> *mappings, bool ignoreMouse) {
std::lock_guard<std::recursive_mutex> guard(g_controllerMapLock);
return InputMappingsFromPspButtonNoLock(btn, mappings, ignoreMouse);
}

void LockMappings() {
g_controllerMapLock.lock();
}

void UnlockMappings() {
g_controllerMapLock.unlock();
}

bool PspButtonHasMappings(int btn) {
std::lock_guard<std::recursive_mutex> guard(g_controllerMapLock);
auto iter = g_controllerMap.find(btn);
Expand Down
5 changes: 5 additions & 0 deletions Core/KeyMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ namespace KeyMap {
bool InputMappingToPspButton(const InputMapping &mapping, std::vector<int> *pspButtons);
bool InputMappingsFromPspButton(int btn, std::vector<MultiInputMapping> *keys, bool ignoreMouse);

// Careful with these.
bool InputMappingsFromPspButtonNoLock(int btn, std::vector<MultiInputMapping> *keys, bool ignoreMouse);
void LockMappings();
void UnlockMappings();

// Simplified check.
bool PspButtonHasMappings(int btn);

Expand Down

0 comments on commit 16a31c2

Please sign in to comment.