Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/renderer/gamepad_util.h" | |
| 6 | |
| 7 #include "base/debug/trace_event.h" | |
| 8 #include "base/metrics/histogram.h" | |
| 9 #include "content/common/gamepad_messages.h" | |
| 10 #include "content/public/renderer/render_thread.h" | |
| 11 #include "content/common/gamepad_hardware_buffer.h" | |
| 12 #include "ipc/ipc_sync_message_filter.h" | |
| 13 | |
| 14 using namespace content; | |
|
darin (slow to review)
2011/11/28 17:35:49
nit: the google c++ style guide forbids 'using nam
scottmg
2011/11/28 20:02:08
Done.
| |
| 15 using namespace gamepad; | |
| 16 | |
| 17 GamepadUtil::GamepadUtil() { | |
|
darin (slow to review)
2011/11/28 17:35:49
please come up with a better name for this class.
scottmg
2011/11/28 20:02:08
Done.
| |
| 18 memset(ever_interacted_with_, 0, sizeof(ever_interacted_with_)); | |
| 19 CHECK(RenderThread::Get()->Send(new GamepadHostMsg_StartPolling( | |
| 20 &renderer_shared_memory_handle_))); | |
| 21 renderer_shared_memory_.reset( | |
| 22 new base::SharedMemory(renderer_shared_memory_handle_, true)); | |
| 23 CHECK(renderer_shared_memory_->Map(sizeof(gamepad::GamepadHardwareBuffer))); | |
| 24 void *memory = renderer_shared_memory_->memory(); | |
| 25 CHECK(memory); | |
| 26 gamepad_hardware_buffer_ = static_cast<GamepadHardwareBuffer*>(memory); | |
| 27 } | |
| 28 | |
| 29 void GamepadUtil::SampleGamepads(WebKit::WebGamepads& gamepads) { | |
| 30 WebKit::WebGamepads read_into; | |
| 31 TRACE_EVENT0("GAMEPAD", "SampleGamepads"); | |
| 32 | |
| 33 // See gamepad_hardware_buffer.h for details on the read discipline. | |
| 34 base::subtle::Atomic32 start, end; | |
| 35 // Only try to read this many times before failing to avoid waiting here | |
| 36 // very long in case of contention with the writer. TODO(scottmg) Tune this | |
| 37 // number (as low as 1?) if histogram shows distribution as mostly | |
| 38 // 0-and-maximum. | |
| 39 const int maximum_contention_count = 10; | |
| 40 int contention_count = 0; | |
| 41 while (contention_count < maximum_contention_count) { | |
| 42 end = base::subtle::Acquire_Load(&gamepad_hardware_buffer_->end_marker); | |
|
darin (slow to review)
2011/11/28 17:35:49
i had expected to see a memory barrier here. i ad
scottmg
2011/11/28 20:02:08
I'm afraid that's probably a bug then. I thought I
| |
| 43 memcpy(&read_into, &gamepad_hardware_buffer_->buffer, sizeof(gamepads)); | |
|
darin (slow to review)
2011/11/28 17:35:49
i'm not the expert on our dynamic annotations syst
scottmg
2011/11/28 20:02:08
OK, will do.
| |
| 44 start = base::subtle::Acquire_Load(&gamepad_hardware_buffer_->start_marker); | |
| 45 if (start == end) | |
| 46 break; | |
| 47 ++contention_count; | |
| 48 base::PlatformThread::YieldCurrentThread(); | |
| 49 } | |
| 50 HISTOGRAM_COUNTS("Gamepad.ReadContentionCount", contention_count); | |
| 51 | |
| 52 if (contention_count == maximum_contention_count) { | |
| 53 // We failed to successfully read, presumably because the hardware | |
| 54 // thread was taking unusually long. Don't copy the data to the output | |
| 55 // buffer, and simply leave what was there before. | |
| 56 return; | |
| 57 } | |
| 58 | |
| 59 // New data was read successfully, copy it into the output buffer. | |
| 60 memcpy(&gamepads, &read_into, sizeof(gamepads)); | |
| 61 | |
| 62 // Override the "connected" with false until the user has interacted | |
| 63 // with the gamepad. This is to prevent fingerprinting on drive-by pages. | |
| 64 for (unsigned i = 0; i < WebKit::WebGamepads::itemsLengthCap; ++i) { | |
| 65 WebKit::WebGamepad& pad = gamepads.items[i]; | |
| 66 // If the device is physically connected, then check if we should | |
| 67 // keep it disabled. We track if any of the primary 4 buttons have been | |
| 68 // pressed to determine a reasonable intentional interaction from the user. | |
| 69 if (pad.connected) { | |
| 70 if (ever_interacted_with_[i]) | |
| 71 continue; | |
| 72 const unsigned primaryInteractionButtons = 4; | |
|
darin (slow to review)
2011/11/28 17:35:49
nit: use kFooBar for google c++ style constants.
scottmg
2011/11/28 20:02:08
Done.
| |
| 73 for (unsigned j = 0; j < primaryInteractionButtons; ++j) | |
| 74 ever_interacted_with_[i] |= pad.buttons[j] > 0.5f; | |
| 75 // If we've not previously set, and the user still hasn't touched | |
| 76 // these buttons, then don't pass the data on to the Chromium port. | |
| 77 if (!ever_interacted_with_[i]) | |
| 78 pad.connected = false; | |
| 79 } | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 GamepadUtil::~GamepadUtil() { | |
| 84 RenderThread::Get()->Send(new GamepadHostMsg_StopPolling()); | |
|
darin (slow to review)
2011/11/28 17:35:49
note: i'm not sure if you are doing this yet, but
scottmg
2011/11/28 20:02:08
After talking to John I have some other work to do
| |
| 85 } | |
| OLD | NEW |