Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: content/browser/gamepad/gamepad_provider.cc

Issue 8689011: Renderer reading side of gamepad (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: rebase to HEAD Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <cmath> 5 #include <cmath>
6 #include <set> 6 #include <set>
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/task.h" 12 #include "base/task.h"
13 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
14 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
15 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
16 #include "content/browser/gamepad/gamepad_provider.h" 16 #include "content/browser/gamepad/gamepad_provider.h"
17 #include "content/browser/gamepad/data_fetcher.h" 17 #include "content/browser/gamepad/data_fetcher.h"
18 #include "content/common/gamepad_messages.h" 18 #include "content/common/gamepad_messages.h"
19 19
20 #if defined(OS_WIN) 20 #if defined(OS_WIN)
21 #include "content/browser/gamepad/data_fetcher_win.h" 21 #include "content/browser/gamepad/data_fetcher_win.h"
22 #endif 22 #endif
23 23
24 namespace gamepad { 24 namespace content {
25 25
26 Provider* Provider::instance_ = NULL; 26 GamepadProvider* GamepadProvider::instance_ = NULL;
27 27
28 using namespace content; 28 // Define the default data fetcher that GamepadProvider will use if none is
29 29 // supplied. (GamepadPlatformDataFetcher).
30 // Define the default data fetcher that Provider will use if none is supplied.
31 // (PlatformDataFetcher).
32 #if defined(OS_WIN) 30 #if defined(OS_WIN)
33 31
34 typedef DataFetcherWindows PlatformDataFetcher; 32 typedef GamepadDataFetcherWindows GamepadPlatformDataFetcher;
35 33
36 #else 34 #else
37 35
38 class EmptyDataFetcher : public DataFetcher { 36 class GamepadEmptyDataFetcher : public GamepadDataFetcher {
39 public: 37 public:
40 void GetGamepadData(WebKit::WebGamepads* pads, bool) { 38 void GetGamepadData(WebKit::WebGamepads* pads, bool) {
41 pads->length = 0; 39 pads->length = 0;
42 } 40 }
43 }; 41 };
44 typedef EmptyDataFetcher PlatformDataFetcher; 42 typedef GamepadEmptyDataFetcher GamepadPlatformDataFetcher;
45 43
46 #endif 44 #endif
47 45
48 Provider::Provider(DataFetcher* fetcher) 46 GamepadProvider::GamepadProvider(GamepadDataFetcher* fetcher)
49 : creator_loop_(MessageLoop::current()->message_loop_proxy()), 47 : creator_loop_(MessageLoop::current()->message_loop_proxy()),
50 provided_fetcher_(fetcher), 48 provided_fetcher_(fetcher),
51 devices_changed_(true), 49 devices_changed_(true),
52 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 50 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
53 size_t data_size = sizeof(GamepadHardwareBuffer); 51 size_t data_size = sizeof(GamepadHardwareBuffer);
54 base::SystemMonitor* monitor = base::SystemMonitor::Get(); 52 base::SystemMonitor* monitor = base::SystemMonitor::Get();
55 if (monitor) 53 if (monitor)
56 monitor->AddDevicesChangedObserver(this); 54 monitor->AddDevicesChangedObserver(this);
57 gamepad_shared_memory_.CreateAndMapAnonymous(data_size); 55 gamepad_shared_memory_.CreateAndMapAnonymous(data_size);
58 GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer(); 56 GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer();
59 memset(hwbuf, 0, sizeof(GamepadHardwareBuffer)); 57 memset(hwbuf, 0, sizeof(GamepadHardwareBuffer));
60 } 58 }
61 59
62 Provider::~Provider() { 60 GamepadProvider::~GamepadProvider() {
63 base::SystemMonitor* monitor = base::SystemMonitor::Get(); 61 base::SystemMonitor* monitor = base::SystemMonitor::Get();
64 if (monitor) 62 if (monitor)
65 monitor->RemoveDevicesChangedObserver(this); 63 monitor->RemoveDevicesChangedObserver(this);
66 Stop(); 64 Stop();
67 } 65 }
68 66
69 base::SharedMemoryHandle Provider::GetRendererSharedMemoryHandle( 67 base::SharedMemoryHandle GamepadProvider::GetRendererSharedMemoryHandle(
70 base::ProcessHandle process) { 68 base::ProcessHandle process) {
71 base::SharedMemoryHandle renderer_handle; 69 base::SharedMemoryHandle renderer_handle;
72 gamepad_shared_memory_.ShareToProcess(process, &renderer_handle); 70 gamepad_shared_memory_.ShareToProcess(process, &renderer_handle);
73 return renderer_handle; 71 return renderer_handle;
74 } 72 }
75 73
76 void Provider::OnDevicesChanged() { 74 void GamepadProvider::OnDevicesChanged() {
77 devices_changed_ = true; 75 devices_changed_ = true;
78 } 76 }
79 77
80 void Provider::Start() { 78 void GamepadProvider::Start() {
81 DCHECK(MessageLoop::current()->message_loop_proxy() == creator_loop_); 79 DCHECK(MessageLoop::current()->message_loop_proxy() == creator_loop_);
82 80
83 if (polling_thread_.get()) 81 if (polling_thread_.get())
84 return; 82 return;
85 83
86 polling_thread_.reset(new base::Thread("Gamepad polling thread")); 84 polling_thread_.reset(new base::Thread("Gamepad polling thread"));
87 if (!polling_thread_->Start()) { 85 if (!polling_thread_->Start()) {
88 LOG(ERROR) << "Failed to start gamepad polling thread"; 86 LOG(ERROR) << "Failed to start gamepad polling thread";
89 polling_thread_.reset(); 87 polling_thread_.reset();
90 return; 88 return;
91 } 89 }
92 90
93 MessageLoop* polling_loop = polling_thread_->message_loop(); 91 MessageLoop* polling_loop = polling_thread_->message_loop();
94 polling_loop->PostTask( 92 polling_loop->PostTask(
95 FROM_HERE, 93 FROM_HERE,
96 base::Bind(&Provider::DoInitializePollingThread, this)); 94 base::Bind(&GamepadProvider::DoInitializePollingThread, this));
97 } 95 }
98 96
99 void Provider::Stop() { 97 void GamepadProvider::Stop() {
100 DCHECK(MessageLoop::current()->message_loop_proxy() == creator_loop_); 98 DCHECK(MessageLoop::current()->message_loop_proxy() == creator_loop_);
101 99
102 polling_thread_.reset(); 100 polling_thread_.reset();
103 data_fetcher_.reset(); 101 data_fetcher_.reset();
104 } 102 }
105 103
106 void Provider::DoInitializePollingThread() { 104 void GamepadProvider::DoInitializePollingThread() {
107 DCHECK(MessageLoop::current() == polling_thread_->message_loop()); 105 DCHECK(MessageLoop::current() == polling_thread_->message_loop());
108 106
109 if (!provided_fetcher_.get()) 107 if (!provided_fetcher_.get())
110 provided_fetcher_.reset(new PlatformDataFetcher); 108 provided_fetcher_.reset(new GamepadPlatformDataFetcher);
111 109
112 // Pass ownership of fetcher to provider_. 110 // Pass ownership of fetcher to provider_.
113 data_fetcher_.swap(provided_fetcher_); 111 data_fetcher_.swap(provided_fetcher_);
114 112
115 // Start polling. 113 // Start polling.
116 ScheduleDoPoll(); 114 ScheduleDoPoll();
117 } 115 }
118 116
119 void Provider::DoPoll() { 117 void GamepadProvider::DoPoll() {
120 DCHECK(MessageLoop::current() == polling_thread_->message_loop()); 118 DCHECK(MessageLoop::current() == polling_thread_->message_loop());
121 GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer(); 119 GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer();
122 base::subtle::Barrier_AtomicIncrement(&hwbuf->start_marker, 1); 120
121 ANNOTATE_BENIGN_RACE_SIZED(
122 &hwbuf->buffer,
123 sizeof(WebKit::WebGamepads),
124 "Racey reads are discarded");
125
126 // Acquire the SeqLock. There is only ever one writer to this data.
127 // See gamepad_hardware_buffer.h.
128 hwbuf->sequence.WriteBegin();
123 data_fetcher_->GetGamepadData(&hwbuf->buffer, devices_changed_); 129 data_fetcher_->GetGamepadData(&hwbuf->buffer, devices_changed_);
124 base::subtle::Barrier_AtomicIncrement(&hwbuf->end_marker, 1); 130 hwbuf->sequence.WriteEnd();
125 devices_changed_ = false; 131 devices_changed_ = false;
126 // Schedule our next interval of polling. 132 // Schedule our next interval of polling.
127 ScheduleDoPoll(); 133 ScheduleDoPoll();
128 } 134 }
129 135
130 void Provider::ScheduleDoPoll() { 136 void GamepadProvider::ScheduleDoPoll() {
131 DCHECK(MessageLoop::current() == polling_thread_->message_loop()); 137 DCHECK(MessageLoop::current() == polling_thread_->message_loop());
132 138
133 MessageLoop::current()->PostDelayedTask( 139 MessageLoop::current()->PostDelayedTask(
134 FROM_HERE, 140 FROM_HERE,
135 base::Bind(&Provider::DoPoll, weak_factory_.GetWeakPtr()), 141 base::Bind(&GamepadProvider::DoPoll, weak_factory_.GetWeakPtr()),
136 kDesiredSamplingIntervalMs); 142 kDesiredSamplingIntervalMs);
137 } 143 }
138 144
139 GamepadHardwareBuffer* Provider::SharedMemoryAsHardwareBuffer() { 145 GamepadHardwareBuffer* GamepadProvider::SharedMemoryAsHardwareBuffer() {
140 void* mem = gamepad_shared_memory_.memory(); 146 void* mem = gamepad_shared_memory_.memory();
141 DCHECK(mem); 147 DCHECK(mem);
142 return static_cast<GamepadHardwareBuffer*>(mem); 148 return static_cast<GamepadHardwareBuffer*>(mem);
143 } 149 }
144 150
145 } // namespace gamepad 151 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gamepad/gamepad_provider.h ('k') | content/browser/gamepad/gamepad_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698