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

Unified Diff: content/browser/gamepad/gamepad_provider.cc

Issue 8568029: Add gamepad hardware data fetcher, and higher level thread container (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: swap search path order for platformsdk/directx Created 9 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/gamepad/gamepad_provider.cc
diff --git a/content/browser/gamepad/gamepad_provider.cc b/content/browser/gamepad/gamepad_provider.cc
new file mode 100644
index 0000000000000000000000000000000000000000..642e2445a7bbe8fa0d0fc8fa7fd1fcbe2827c101
--- /dev/null
+++ b/content/browser/gamepad/gamepad_provider.cc
@@ -0,0 +1,145 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cmath>
+#include <set>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/task.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_restrictions.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/browser/gamepad/gamepad_provider.h"
+#include "content/browser/gamepad/data_fetcher.h"
+#include "content/common/gamepad_messages.h"
+
+#if defined(OS_WIN)
+#include "content/browser/gamepad/data_fetcher_win.h"
+#endif
+
+namespace gamepad {
+
+Provider* Provider::instance_ = NULL;
+
+using namespace content;
+
+// Define the default data fetcher that Provider will use if none is supplied.
+// (PlatformDataFetcher).
+#if defined(OS_WIN)
+
+typedef DataFetcherWindows PlatformDataFetcher;
+
+#else
+
+class EmptyDataFetcher : public DataFetcher {
+ public:
+ void GetGamepadData(WebKit::WebGamepads* pads, bool) {
+ pads->length = 0;
+ }
+};
+typedef EmptyDataFetcher PlatformDataFetcher;
+
+#endif
+
+Provider::Provider(DataFetcher* fetcher)
+ : creator_loop_(MessageLoop::current()->message_loop_proxy()),
+ provided_fetcher_(fetcher),
+ devices_changed_(true),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ size_t data_size = sizeof(GamepadHardwareBuffer);
+ base::SystemMonitor* monitor = base::SystemMonitor::Get();
+ if (monitor)
+ monitor->AddDevicesChangedObserver(this);
+ gamepad_shared_memory_.CreateAndMapAnonymous(data_size);
+ GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer();
+ memset(hwbuf, 0, sizeof(GamepadHardwareBuffer));
+}
+
+Provider::~Provider() {
+ base::SystemMonitor* monitor = base::SystemMonitor::Get();
+ if (monitor)
+ monitor->RemoveDevicesChangedObserver(this);
+ Stop();
+}
+
+base::SharedMemoryHandle Provider::GetRendererSharedMemoryHandle(
+ base::ProcessHandle process) {
+ base::SharedMemoryHandle renderer_handle;
+ gamepad_shared_memory_.ShareToProcess(process, &renderer_handle);
+ return renderer_handle;
+}
+
+void Provider::OnDevicesChanged() {
+ devices_changed_ = true;
+}
+
+void Provider::Start() {
+ DCHECK(MessageLoop::current()->message_loop_proxy() == creator_loop_);
+
+ if (polling_thread_.get())
+ return;
+
+ polling_thread_.reset(new base::Thread("Gamepad polling thread"));
+ if (!polling_thread_->Start()) {
+ LOG(ERROR) << "Failed to start gamepad polling thread";
+ polling_thread_.reset();
+ return;
+ }
+
+ MessageLoop* polling_loop = polling_thread_->message_loop();
+ polling_loop->PostTask(
+ FROM_HERE,
+ base::Bind(&Provider::DoInitializePollingThread, this));
+}
+
+void Provider::Stop() {
+ DCHECK(MessageLoop::current()->message_loop_proxy() == creator_loop_);
+
+ polling_thread_.reset();
+ data_fetcher_.reset();
+}
+
+void Provider::DoInitializePollingThread() {
+ DCHECK(MessageLoop::current() == polling_thread_->message_loop());
+
+ if (!provided_fetcher_.get())
+ provided_fetcher_.reset(new PlatformDataFetcher);
+
+ // Pass ownership of fetcher to provider_.
+ data_fetcher_.swap(provided_fetcher_);
+
+ // Start polling.
+ ScheduleDoPoll();
+}
+
+void Provider::DoPoll() {
+ DCHECK(MessageLoop::current() == polling_thread_->message_loop());
+ GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer();
+ base::subtle::Barrier_AtomicIncrement(&hwbuf->start_marker, 1);
+ data_fetcher_->GetGamepadData(&hwbuf->buffer, devices_changed_);
+ base::subtle::Barrier_AtomicIncrement(&hwbuf->end_marker, 1);
+ devices_changed_ = false;
+ // Schedule our next interval of polling.
+ ScheduleDoPoll();
+}
+
+void Provider::ScheduleDoPoll() {
+ DCHECK(MessageLoop::current() == polling_thread_->message_loop());
+
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&Provider::DoPoll, weak_factory_.GetWeakPtr()),
+ kDesiredSamplingIntervalMs);
+}
+
+GamepadHardwareBuffer* Provider::SharedMemoryAsHardwareBuffer() {
+ void* mem = gamepad_shared_memory_.memory();
+ DCHECK(mem);
+ return static_cast<GamepadHardwareBuffer*>(mem);
+}
+
+} // namespace gamepad
« 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