Skip to content
Snippets Groups Projects
Commit 6c9886c9 authored by Chris Martin's avatar Chris Martin
Browse files

Bug 1776655 - Allocate input report context for each gamepad. r=mccr8, a=RyanVM

parent 3d636815
No related branches found
No related tags found
No related merge requests found
......@@ -28,7 +28,6 @@ namespace {
using namespace mozilla;
using namespace mozilla::dom;
using std::vector;
class DarwinGamepadService;
DarwinGamepadService* gService = nullptr;
......@@ -80,6 +79,11 @@ const unsigned kBackUsage = 0x224;
// 50ms is arbitrarily chosen.
const uint32_t kDarwinGamepadPollInterval = 50;
struct GamepadInputReportContext {
DarwinGamepadService* service;
size_t gamepadSlot;
};
class Gamepad {
private:
IOHIDDeviceRef mDevice;
......@@ -120,7 +124,8 @@ class Gamepad {
GamepadHandle mHandle;
RefPtr<GamepadRemapper> mRemapper;
std::vector<uint8_t> mInputReport;
nsTArray<uint8_t> mInputReport;
UniquePtr<GamepadInputReportContext> mInputReportContext;
};
void Gamepad::init(IOHIDDeviceRef aDevice, bool aDefaultRemapper) {
......@@ -179,7 +184,7 @@ void Gamepad::init(IOHIDDeviceRef aDevice, bool aDefaultRemapper) {
class DarwinGamepadService {
private:
IOHIDManagerRef mManager;
vector<Gamepad> mGamepads;
nsTArray<Gamepad> mGamepads;
nsCOMPtr<nsIThread> mMonitorThread;
nsCOMPtr<nsIThread> mBackgroundThread;
......@@ -272,14 +277,14 @@ void DarwinGamepadService::DeviceAdded(IOHIDDeviceRef device) {
}
size_t slot = size_t(-1);
for (size_t i = 0; i < mGamepads.size(); i++) {
for (size_t i = 0; i < mGamepads.Length(); i++) {
if (mGamepads[i] == device) return;
if (slot == size_t(-1) && mGamepads[i].empty()) slot = i;
}
if (slot == size_t(-1)) {
slot = mGamepads.size();
mGamepads.push_back(Gamepad());
slot = mGamepads.Length();
mGamepads.AppendElement(Gamepad());
}
// Gather some identifying information
......@@ -322,13 +327,15 @@ void DarwinGamepadService::DeviceAdded(IOHIDDeviceRef device) {
}
mGamepads[slot].mHandle = handle;
mGamepads[slot].mInputReport.resize(remapper->GetMaxInputReportLength());
mGamepads[slot].mInputReport.SetLength(remapper->GetMaxInputReportLength());
mGamepads[slot].mInputReportContext = UniquePtr<GamepadInputReportContext>(
new GamepadInputReportContext{this, slot});
mGamepads[slot].mRemapper = remapper.forget();
IOHIDDeviceRegisterInputReportCallback(
device, mGamepads[slot].mInputReport.data(),
mGamepads[slot].mInputReport.size(), ReportChangedCallback,
&mGamepads[slot]);
device, mGamepads[slot].mInputReport.Elements(),
mGamepads[slot].mInputReport.Length(), ReportChangedCallback,
mGamepads[slot].mInputReportContext.get());
}
void DarwinGamepadService::DeviceRemoved(IOHIDDeviceRef device) {
......@@ -337,13 +344,16 @@ void DarwinGamepadService::DeviceRemoved(IOHIDDeviceRef device) {
if (!service) {
return;
}
for (size_t i = 0; i < mGamepads.size(); i++) {
if (mGamepads[i] == device) {
for (Gamepad& gamepad : mGamepads) {
if (gamepad == device) {
IOHIDDeviceRegisterInputReportCallback(
device, mGamepads[i].mInputReport.data(), 0, NULL, &mGamepads[i]);
device, gamepad.mInputReport.Elements(), 0, NULL,
gamepad.mInputReportContext.get());
gamepad.mInputReportContext.reset();
service->RemoveGamepad(mGamepads[i].mHandle);
mGamepads[i].clear();
service->RemoveGamepad(gamepad.mHandle);
gamepad.clear();
return;
}
}
......@@ -354,7 +364,10 @@ void DarwinGamepadService::ReportChangedCallback(
void* context, IOReturn result, void* sender, IOHIDReportType report_type,
uint32_t report_id, uint8_t* report, CFIndex report_length) {
if (context && report_type == kIOHIDReportTypeInput && report_length) {
reinterpret_cast<Gamepad*>(context)->ReportChanged(report, report_length);
auto reportContext = static_cast<GamepadInputReportContext*>(context);
DarwinGamepadService* service = reportContext->service;
service->mGamepads[reportContext->gamepadSlot].ReportChanged(report,
report_length);
}
}
......@@ -388,8 +401,7 @@ void DarwinGamepadService::InputValueChanged(IOHIDValueRef value) {
IOHIDElementRef element = IOHIDValueGetElement(value);
IOHIDDeviceRef device = IOHIDElementGetDevice(element);
for (unsigned i = 0; i < mGamepads.size(); i++) {
Gamepad& gamepad = mGamepads[i];
for (Gamepad& gamepad : mGamepads) {
if (gamepad == device) {
// Axis elements represent axes and d-pads.
if (Axis* axis = gamepad.lookupAxis(element)) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment