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

Side by Side Diff: ppapi/proxy/gamepad_resource.cc

Issue 10912062: Implement the gamepad API in the IPC proxy (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months 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 | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/gamepad_resource.h ('k') | ppapi/proxy/plugin_dispatcher.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ppapi/proxy/gamepad_resource.h" 5 #include "ppapi/proxy/gamepad_resource.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "ppapi/c/ppb_gamepad.h" 9 #include "base/threading/platform_thread.h"
10 #include "ppapi/proxy/dispatch_reply_message.h" 10 #include "ppapi/proxy/dispatch_reply_message.h"
11 #include "ppapi/proxy/ppapi_messages.h" 11 #include "ppapi/proxy/ppapi_messages.h"
12 #include "ppapi/shared_impl/ppb_gamepad_shared.h"
12 13
13 namespace ppapi { 14 namespace ppapi {
14 namespace proxy { 15 namespace proxy {
15 16
17 namespace {
18
19 // This is the read logic from content/common/gamepad_seqlock.h
20 base::subtle::Atomic32 ReadBegin(const base::subtle::Atomic32* sequence) {
21 base::subtle::Atomic32 version;
22 for (;;) {
23 version = base::subtle::NoBarrier_Load(sequence);
24
25 // If the counter is even, then the associated data might be in a
26 // consistent state, so we can try to read.
27 if ((version & 1) == 0)
28 break;
29
30 // Otherwise, the writer is in the middle of an update. Retry the read.
31 base::PlatformThread::YieldCurrentThread();
32 }
33 return version;
34 }
35
36 bool ReadRetry(const base::subtle::Atomic32* sequence,
37 base::subtle::Atomic32 version) {
38 // If the sequence number was updated then a read should be re-attempted.
39 // -- Load fence, read membarrier
40 return base::subtle::Release_Load(sequence) != version;
41 }
42
43 } // namespace
44
16 GamepadResource::GamepadResource(Connection connection, PP_Instance instance) 45 GamepadResource::GamepadResource(Connection connection, PP_Instance instance)
17 : PluginResource(connection, instance), 46 : PluginResource(connection, instance),
18 buffer_(NULL) { 47 buffer_(NULL) {
48 memset(&last_read_, 0, sizeof(last_read_));
49
19 SendCreateToBrowser(PpapiHostMsg_Gamepad_Create()); 50 SendCreateToBrowser(PpapiHostMsg_Gamepad_Create());
20 CallBrowser(PpapiHostMsg_Gamepad_RequestMemory()); 51 CallBrowser(PpapiHostMsg_Gamepad_RequestMemory());
21 } 52 }
22 53
23 GamepadResource::~GamepadResource() { 54 GamepadResource::~GamepadResource() {
24 } 55 }
25 56
26 void GamepadResource::Sample(PP_GamepadsSampleData* data) { 57 void GamepadResource::Sample(PP_GamepadsSampleData* data) {
27 if (!buffer_) { 58 if (!buffer_) {
28 // Browser hasn't sent back our shared memory, give the plugin gamepad 59 // Browser hasn't sent back our shared memory, give the plugin gamepad
29 // data corresponding to "not connected". 60 // data corresponding to "not connected".
30 memset(data, 0, sizeof(PP_GamepadsSampleData)); 61 memset(data, 0, sizeof(PP_GamepadsSampleData));
31 } else { 62 return;
32 memcpy(data, buffer_, sizeof(PP_GamepadsSampleData));
33 } 63 }
64
65 // ==========
66 // DANGER
67 // ==========
68 //
69 // This logic is duplicated in the renderer as well. If you change it, that
70 // also needs to be in sync. See gamepad_shared_memory_reader.cc.
71
72 // Only try to read this many times before failing to avoid waiting here
73 // very long in case of contention with the writer.
74 const int kMaximumContentionCount = 10;
75 int contention_count = -1;
76 base::subtle::Atomic32 version;
77 WebKitGamepads read_into;
78 do {
79 version = ReadBegin(&buffer_->sequence);
80 memcpy(&read_into, &buffer_->buffer, sizeof(read_into));
81 ++contention_count;
82 if (contention_count == kMaximumContentionCount)
83 break;
84 } while (ReadRetry(&buffer_->sequence, version));
85
86 // In the event of a read failure, just leave the last read data as-is (the
87 // hardware thread is taking unusally long).
88 if (contention_count < kMaximumContentionCount)
89 ConvertWebKitGamepadData(read_into, &last_read_);
90
91 memcpy(data, &last_read_, sizeof(PP_GamepadsSampleData));
34 } 92 }
35 93
36 void GamepadResource::OnReplyReceived(const ResourceMessageReplyParams& params, 94 void GamepadResource::OnReplyReceived(const ResourceMessageReplyParams& params,
37 const IPC::Message& msg) { 95 const IPC::Message& msg) {
38 IPC_BEGIN_MESSAGE_MAP(GamepadResource, msg) 96 IPC_BEGIN_MESSAGE_MAP(GamepadResource, msg)
39 PPAPI_DISPATCH_RESOURCE_REPLY(PpapiPluginMsg_Gamepad_SendMemory, 97 PPAPI_DISPATCH_RESOURCE_REPLY_0(PpapiPluginMsg_Gamepad_SendMemory,
40 OnPluginMsgSendMemory) 98 OnPluginMsgSendMemory)
41 IPC_END_MESSAGE_MAP() 99 IPC_END_MESSAGE_MAP()
42 } 100 }
43 101
44 void GamepadResource::OnPluginMsgSendMemory( 102 void GamepadResource::OnPluginMsgSendMemory(
45 const ResourceMessageReplyParams& params, 103 const ResourceMessageReplyParams& params) {
46 base::SharedMemoryHandle shared_memory_handle) { 104 // On failure, the handle will be null and the CHECK below will be tripped.
47 /* TODO(brettw) implement this when we have shared gamepad code. It would be 105 base::SharedMemoryHandle handle;
48 something like this: 106 params.GetSharedMemoryHandleAtIndex(0, &handle);
49 shared_memory_.reset( 107
50 new base::SharedMemory(shared_memory_handle, true)); 108 shared_memory_.reset(new base::SharedMemory(handle, true));
51 CHECK(shared_memory_->Map(sizeof(GamepadHardwareBuffer))); 109 CHECK(shared_memory_->Map(sizeof(ContentGamepadHardwareBuffer)));
52 void *memory = shared_memory_->memory(); 110 buffer_ = static_cast<const ContentGamepadHardwareBuffer*>(
53 // Use the memory... 111 shared_memory_->memory());
54 */
55 } 112 }
56 113
57 } // namespace proxy 114 } // namespace proxy
58 } // namespace ppapi 115 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/gamepad_resource.h ('k') | ppapi/proxy/plugin_dispatcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698