Commit 7550995f authored by Matt Reynolds's avatar Matt Reynolds Committed by Commit Bot

Remove pepper's parallel gamepad struct definitions

Before gamepad was partially servicified, gamepad struct definitions
resided in WebKit. These definitions must be identical for all readers
and writers to the shared memory buffer for consistency. Since pepper
may not depend on WebKit, the structs were duplicated in the pepper
gamepad client.

Now these structs have been moved out of WebKit and can be shared with
other components by depending on the target
//device/gamepad/public/cpp:shared_with_blink. This CL removes the
duplicate pepper definitions and switches all usages to the //device
definitions.

BUG=694998

Change-Id: I4cf596f5cff18f6dc8945a422a3cc9f70711c10c
Reviewed-on: https://chromium-review.googlesource.com/1062600Reviewed-by: default avatarBill Budge <bbudge@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Commit-Queue: Matt Reynolds <mattreynolds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560914}
parent f2feeff8
......@@ -7,12 +7,12 @@
#include "base/bind.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "device/gamepad/gamepad_service.h"
#include "device/gamepad/gamepad_shared_buffer.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppb_gamepad_shared.h"
namespace content {
......@@ -72,7 +72,7 @@ void PepperGamepadHost::GotUserGesture(
gamepad_service_->DuplicateSharedMemoryHandle();
context.params.AppendHandle(ppapi::proxy::SerializedHandle(
handle, sizeof(ppapi::ContentGamepadHardwareBuffer)));
handle, sizeof(device::GamepadHardwareBuffer)));
host()->SendReply(context, PpapiPluginMsg_Gamepad_SendMemory());
}
......
......@@ -16,12 +16,12 @@
#include "content/browser/renderer_host/pepper/browser_ppapi_host_test.h"
#include "device/gamepad/gamepad_shared_buffer.h"
#include "device/gamepad/gamepad_test_helpers.h"
#include "device/gamepad/public/cpp/gamepads.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/proxy/gamepad_resource.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"
#include "ppapi/shared_impl/ppb_gamepad_shared.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
......@@ -48,84 +48,8 @@ class PepperGamepadHostTest : public testing::Test,
DISALLOW_COPY_AND_ASSIGN(PepperGamepadHostTest);
};
inline ptrdiff_t AddressDiff(const void* a, const void* b) {
return static_cast<const char*>(a) - static_cast<const char*>(b);
}
} // namespace
// Validate the memory layout of the Pepper proxy struct matches the content
// one. The proxy can't depend on content so has a duplicate definition. This
// code can see both definitions so we do the validation here.
TEST_F(PepperGamepadHostTest, ValidateHardwareBuffersMatch) {
// Hardware buffer.
static_assert(sizeof(ppapi::ContentGamepadHardwareBuffer) ==
sizeof(device::GamepadHardwareBuffer),
"gamepad hardware buffers must match");
ppapi::ContentGamepadHardwareBuffer ppapi_buf;
device::GamepadHardwareBuffer content_buf;
EXPECT_EQ(AddressDiff(&content_buf.seqlock, &content_buf),
AddressDiff(&ppapi_buf.sequence, &ppapi_buf));
EXPECT_EQ(AddressDiff(&content_buf.data, &content_buf),
AddressDiff(&ppapi_buf.buffer, &ppapi_buf));
}
TEST_F(PepperGamepadHostTest, ValidateGamepadsMatch) {
// Gamepads.
static_assert(sizeof(ppapi::WebKitGamepads) == sizeof(device::Gamepads),
"gamepads data must match");
ppapi::WebKitGamepads ppapi_gamepads;
device::Gamepads web_gamepads;
// See comment below on storage & the EXPECT macro.
size_t webkit_items_length_cap = device::Gamepads::kItemsLengthCap;
size_t ppapi_items_length_cap = ppapi::WebKitGamepads::kItemsLengthCap;
EXPECT_EQ(webkit_items_length_cap, ppapi_items_length_cap);
for (size_t i = 0; i < webkit_items_length_cap; i++) {
EXPECT_EQ(AddressDiff(&web_gamepads.items[0], &web_gamepads),
AddressDiff(&ppapi_gamepads.items[0], &ppapi_gamepads));
}
}
TEST_F(PepperGamepadHostTest, ValidateGamepadMatch) {
// Gamepad.
static_assert(sizeof(ppapi::WebKitGamepad) == sizeof(device::Gamepad),
"gamepad data must match");
ppapi::WebKitGamepad ppapi_gamepad;
device::Gamepad web_gamepad;
// Using EXPECT seems to force storage for the parameter, which the constants
// in the WebKit/PPAPI headers don't have. So we have to use temporaries
// before comparing them.
size_t webkit_id_length_cap = device::Gamepad::kIdLengthCap;
size_t ppapi_id_length_cap = ppapi::WebKitGamepad::kIdLengthCap;
EXPECT_EQ(webkit_id_length_cap, ppapi_id_length_cap);
size_t webkit_axes_length_cap = device::Gamepad::kAxesLengthCap;
size_t ppapi_axes_length_cap = ppapi::WebKitGamepad::kAxesLengthCap;
EXPECT_EQ(webkit_axes_length_cap, ppapi_axes_length_cap);
size_t webkit_buttons_length_cap = device::Gamepad::kButtonsLengthCap;
size_t ppapi_buttons_length_cap = ppapi::WebKitGamepad::kButtonsLengthCap;
EXPECT_EQ(webkit_buttons_length_cap, ppapi_buttons_length_cap);
EXPECT_EQ(AddressDiff(&web_gamepad.connected, &web_gamepad),
AddressDiff(&ppapi_gamepad.connected, &ppapi_gamepad));
EXPECT_EQ(AddressDiff(&web_gamepad.id, &web_gamepad),
AddressDiff(&ppapi_gamepad.id, &ppapi_gamepad));
EXPECT_EQ(AddressDiff(&web_gamepad.timestamp, &web_gamepad),
AddressDiff(&ppapi_gamepad.timestamp, &ppapi_gamepad));
EXPECT_EQ(AddressDiff(&web_gamepad.axes_length, &web_gamepad),
AddressDiff(&ppapi_gamepad.axes_length, &ppapi_gamepad));
EXPECT_EQ(AddressDiff(&web_gamepad.axes, &web_gamepad),
AddressDiff(&ppapi_gamepad.axes, &ppapi_gamepad));
EXPECT_EQ(AddressDiff(&web_gamepad.buttons_length, &web_gamepad),
AddressDiff(&ppapi_gamepad.buttons_length, &ppapi_gamepad));
EXPECT_EQ(AddressDiff(&web_gamepad.buttons, &web_gamepad),
AddressDiff(&ppapi_gamepad.buttons, &ppapi_gamepad));
}
TEST_F(PepperGamepadHostTest, WaitForReply) {
device::Gamepads default_data;
memset(&default_data, 0, sizeof(device::Gamepads));
......@@ -172,17 +96,16 @@ TEST_F(PepperGamepadHostTest, WaitForReply) {
// Validate the shared memory.
base::SharedMemory shared_memory(reply_handle, true);
EXPECT_TRUE(shared_memory.Map(sizeof(ppapi::ContentGamepadHardwareBuffer)));
const ppapi::ContentGamepadHardwareBuffer* buffer =
static_cast<const ppapi::ContentGamepadHardwareBuffer*>(
shared_memory.memory());
EXPECT_TRUE(shared_memory.Map(sizeof(device::GamepadHardwareBuffer)));
const device::GamepadHardwareBuffer* buffer =
static_cast<const device::GamepadHardwareBuffer*>(shared_memory.memory());
EXPECT_EQ(button_down_data.items[0].buttons_length,
buffer->buffer.items[0].buttons_length);
for (size_t i = 0; i < ppapi::WebKitGamepad::kButtonsLengthCap; i++) {
buffer->data.items[0].buttons_length);
for (size_t i = 0; i < device::Gamepad::kButtonsLengthCap; i++) {
EXPECT_EQ(button_down_data.items[0].buttons[i].value,
buffer->buffer.items[0].buttons[i].value);
buffer->data.items[0].buttons[i].value);
EXPECT_EQ(button_down_data.items[0].buttons[i].pressed,
buffer->buffer.items[0].buttons[i].pressed);
buffer->data.items[0].buttons[i].pressed);
}
// Duplicate requests should be denied.
......
......@@ -277,6 +277,8 @@ component("proxy") {
deps = [
":common",
"//base",
"//device/base/synchronization",
"//device/gamepad/public/cpp:shared_with_blink",
"//gpu/command_buffer/client:gles2_implementation",
"//gpu/command_buffer/common",
"//gpu/ipc/common:command_buffer_traits",
......
include_rules = [
"+base",
"+device",
"+gin",
"+gpu",
"+ipc",
......
......@@ -7,7 +7,9 @@
#include <string.h>
#include "base/bind.h"
#include "base/memory/shared_memory.h"
#include "base/threading/platform_thread.h"
#include "device/gamepad/public/cpp/gamepads.h"
#include "ppapi/proxy/dispatch_reply_message.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppb_gamepad_shared.h"
......@@ -15,34 +17,6 @@
namespace ppapi {
namespace proxy {
namespace {
// This is the read logic from content/common/gamepad_seqlock.h
base::subtle::Atomic32 ReadBegin(const base::subtle::Atomic32* sequence) {
base::subtle::Atomic32 version;
for (;;) {
version = base::subtle::NoBarrier_Load(sequence);
// If the counter is even, then the associated data might be in a
// consistent state, so we can try to read.
if ((version & 1) == 0)
break;
// Otherwise, the writer is in the middle of an update. Retry the read.
base::PlatformThread::YieldCurrentThread();
}
return version;
}
bool ReadRetry(const base::subtle::Atomic32* sequence,
base::subtle::Atomic32 version) {
// If the sequence number was updated then a read should be re-attempted.
// -- Load fence, read membarrier
return base::subtle::Release_Load(sequence) != version;
}
} // namespace
GamepadResource::GamepadResource(Connection connection, PP_Instance instance)
: PluginResource(connection, instance),
buffer_(NULL) {
......@@ -83,19 +57,19 @@ void GamepadResource::Sample(PP_Instance /* instance */,
const int kMaximumContentionCount = 10;
int contention_count = -1;
base::subtle::Atomic32 version;
WebKitGamepads read_into;
device::Gamepads read_into;
do {
version = ReadBegin(&buffer_->sequence);
memcpy(&read_into, &buffer_->buffer, sizeof(read_into));
version = buffer_->seqlock.ReadBegin();
memcpy(&read_into, &buffer_->data, sizeof(read_into));
++contention_count;
if (contention_count == kMaximumContentionCount)
break;
} while (ReadRetry(&buffer_->sequence, version));
} while (buffer_->seqlock.ReadRetry(version));
// In the event of a read failure, just leave the last read data as-is (the
// hardware thread is taking unusally long).
if (contention_count < kMaximumContentionCount)
ConvertWebKitGamepadData(read_into, &last_read_);
ConvertDeviceGamepadData(read_into, &last_read_);
memcpy(data, &last_read_, sizeof(PP_GamepadsSampleData));
}
......@@ -107,8 +81,8 @@ void GamepadResource::OnPluginMsgSendMemory(
params.TakeSharedMemoryHandleAtIndex(0, &handle);
shared_memory_.reset(new base::SharedMemory(handle, true));
CHECK(shared_memory_->Map(sizeof(ContentGamepadHardwareBuffer)));
buffer_ = static_cast<const ContentGamepadHardwareBuffer*>(
CHECK(shared_memory_->Map(sizeof(device::GamepadHardwareBuffer)));
buffer_ = static_cast<const device::GamepadHardwareBuffer*>(
shared_memory_->memory());
}
......
......@@ -9,11 +9,10 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/shared_memory.h"
#include "device/gamepad/gamepad_shared_buffer.h"
#include "ppapi/c/ppb_gamepad.h"
#include "ppapi/proxy/plugin_resource.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/shared_impl/ppb_gamepad_shared.h"
#include "ppapi/thunk/ppb_gamepad_api.h"
struct PP_GamepadsSampleData;
......@@ -46,7 +45,7 @@ class PPAPI_PROXY_EXPORT GamepadResource
void OnPluginMsgSendMemory(const ResourceMessageReplyParams& params);
std::unique_ptr<base::SharedMemory> shared_memory_;
const ContentGamepadHardwareBuffer* buffer_;
const device::GamepadHardwareBuffer* buffer_;
// Last data returned so we can use this in the event of a read failure.
PP_GamepadsSampleData last_read_;
......
......@@ -4,39 +4,12 @@
#include "ppapi/shared_impl/ppb_gamepad_shared.h"
#include <string.h>
#include <algorithm>
#include <cstring>
#include "device/gamepad/public/cpp/gamepads.h"
namespace ppapi {
const size_t WebKitGamepads::kItemsLengthCap;
// TODO: Remove this function and use ConvertDeviceGamepadData() instead.
void ConvertWebKitGamepadData(const WebKitGamepads& webkit_data,
PP_GamepadsSampleData* output_data) {
output_data->length = WebKitGamepads::kItemsLengthCap;
for (unsigned i = 0; i < WebKitGamepads::kItemsLengthCap; ++i) {
PP_GamepadSampleData& output_pad = output_data->items[i];
const WebKitGamepad& webkit_pad = webkit_data.items[i];
output_pad.connected = webkit_pad.connected ? PP_TRUE : PP_FALSE;
if (webkit_pad.connected) {
static_assert(sizeof(output_pad.id) == sizeof(webkit_pad.id),
"id size does not match");
memcpy(output_pad.id, webkit_pad.id, sizeof(output_pad.id));
output_pad.timestamp = static_cast<double>(webkit_pad.timestamp);
output_pad.axes_length = webkit_pad.axes_length;
for (unsigned j = 0; j < webkit_pad.axes_length; ++j)
output_pad.axes[j] = static_cast<float>(webkit_pad.axes[j]);
output_pad.buttons_length = webkit_pad.buttons_length;
for (unsigned j = 0; j < webkit_pad.buttons_length; ++j)
output_pad.buttons[j] = static_cast<float>(webkit_pad.buttons[j].value);
}
}
}
void ConvertDeviceGamepadData(const device::Gamepads& device_data,
PP_GamepadsSampleData* output_data) {
output_data->length = device::Gamepads::kItemsLengthCap;
......@@ -47,7 +20,7 @@ void ConvertDeviceGamepadData(const device::Gamepads& device_data,
if (device_pad.connected) {
static_assert(sizeof(output_pad.id) == sizeof(device_pad.id),
"id size does not match");
memcpy(output_pad.id, device_pad.id, sizeof(output_pad.id));
std::memcpy(output_pad.id, device_pad.id, sizeof(output_pad.id));
output_pad.timestamp = static_cast<double>(device_pad.timestamp);
output_pad.axes_length = device_pad.axes_length;
for (unsigned j = 0; j < device_pad.axes_length; ++j)
......
......@@ -5,144 +5,17 @@
#ifndef PPAPI_SHARED_IMPL_PPB_GAMEPAD_SHARED_H_
#define PPAPI_SHARED_IMPL_PPB_GAMEPAD_SHARED_H_
#include <stddef.h>
#include "base/atomicops.h"
#include "base/strings/string16.h"
#include "ppapi/c/ppb_gamepad.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"
namespace device {
class Gamepads;
}
} // namespace device
namespace ppapi {
// TODO(brettw) when we remove the non-IPC-based gamepad implementation, this
// code should all move into the GamepadResource.
#pragma pack(push, 4)
struct WebKitGamepadButton {
bool pressed;
bool touched;
double value;
};
enum WebKitGamepadHapticActuatorType {
WEBKIT_GAMEPAD_HAPTIC_ACTUATOR_TYPE_VIBRATION = 0,
WEBKIT_GAMEPAD_HAPTIC_ACTUATOR_TYPE_DUAL_RUMBLE = 1
};
struct WebKitGamepadHapticActuator {
bool notNull;
WebKitGamepadHapticActuatorType type;
};
struct WebKitGamepadVector {
bool notNull;
float x, y, z;
};
struct WebKitGamepadQuaternion {
bool notNull;
float x, y, z, w;
};
struct WebKitGamepadPose {
bool notNull;
bool hasOrientation;
bool hasPosition;
WebKitGamepadQuaternion orientation;
WebKitGamepadVector position;
WebKitGamepadVector angularVelocity;
WebKitGamepadVector linearVelocity;
WebKitGamepadVector angularAcceleration;
WebKitGamepadVector linearAcceleration;
};
enum WebKitGamepadHand {
WEBKIT_GAMEPAD_HAND_NONE = 0,
WEBKIT_GAMEPAD_HAND_LEFT = 1,
WEBKIT_GAMEPAD_HAND_RIGHT = 2
};
// This must match the definition of blink::Gamepad. The GamepadHost unit test
// has some compile asserts to validate this. Some members are unused but must
// be present to ensure the struct layout is the same.
struct WebKitGamepad {
static const size_t kIdLengthCap = 128;
static const size_t kMappingLengthCap = 16;
static const size_t kAxesLengthCap = 16;
static const size_t kButtonsLengthCap = 32;
// Is there a gamepad connected at this index?
bool connected;
// Device identifier (based on manufacturer, model, etc.).
base::char16 id[kIdLengthCap];
// Monotonically increasing value referring to when the data were last
// updated.
unsigned long long timestamp;
// Number of valid entries in the axes array.
unsigned axes_length;
// Normalized values representing axes, in the range [-1..1].
double axes[kAxesLengthCap];
// Number of valid entries in the buttons array.
unsigned buttons_length;
// Normalized values representing buttons, in the range [0..1].
WebKitGamepadButton buttons[kButtonsLengthCap];
// Gamepad Extensions member, unused by ppapi.
WebKitGamepadHapticActuator vibrationActuator;
// Mapping type (for example "standard")
base::char16 mapping[kMappingLengthCap];
// Gamepad Extensions member, unused by ppapi.
WebKitGamepadPose pose;
// Gamepad Extensions member, unused by ppapi.
WebKitGamepadHand hand;
// ID of the VRDisplay this gamepad is associated with, if any. Unused by
// ppapi.
unsigned display_id;
// True if this controller is backed by VR APIs, unused by ppapi.
bool is_xr;
};
// This must match the definition of blink::Gamepads. The GamepadHost unit
// test has some compile asserts to validate this.
struct WebKitGamepads {
static const size_t kItemsLengthCap = 4;
// Gamepad data for N separate gamepad devices.
WebKitGamepad items[kItemsLengthCap];
};
// This is the structure store in shared memory. It must match
// device::GamepadHardwareBuffer. The GamepadHost unit test has
// some compile asserts to validate this.
struct ContentGamepadHardwareBuffer {
base::subtle::Atomic32 sequence;
WebKitGamepads buffer;
};
#pragma pack(pop)
PPAPI_SHARED_EXPORT void ConvertWebKitGamepadData(
const WebKitGamepads& webkit_data,
PP_GamepadsSampleData* output_data);
PPAPI_SHARED_EXPORT void ConvertDeviceGamepadData(
const device::Gamepads& device_data,
PP_GamepadsSampleData* output_data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment