diff options
Diffstat (limited to 'o3d/core/cross')
-rw-r--r-- | o3d/core/cross/client_info.cc | 9 | ||||
-rw-r--r-- | o3d/core/cross/client_info.h | 14 | ||||
-rw-r--r-- | o3d/core/cross/client_info_test.cc | 8 | ||||
-rw-r--r-- | o3d/core/cross/message_commands.h | 154 | ||||
-rw-r--r-- | o3d/core/cross/message_commands_test.cc | 15 | ||||
-rw-r--r-- | o3d/core/cross/message_queue.cc | 52 | ||||
-rw-r--r-- | o3d/core/cross/message_queue_test.cc | 96 |
7 files changed, 283 insertions, 65 deletions
diff --git a/o3d/core/cross/client_info.cc b/o3d/core/cross/client_info.cc index 0c75a94..5cbcef6 100644 --- a/o3d/core/cross/client_info.cc +++ b/o3d/core/cross/client_info.cc @@ -41,6 +41,15 @@ namespace o3d { +ClientInfo::ClientInfo() + : num_objects_(0), + texture_memory_used_(0), + buffer_memory_used_(0), + software_renderer_(false), + non_power_of_two_textures_(false), + version_(O3D_PLUGIN_VERSION) { +} + const InterfaceId ClientInfoManager::kInterfaceId = InterfaceTraits<ClientInfoManager>::kInterfaceId; diff --git a/o3d/core/cross/client_info.h b/o3d/core/cross/client_info.h index e8b24a9..40cda3c 100644 --- a/o3d/core/cross/client_info.h +++ b/o3d/core/cross/client_info.h @@ -44,13 +44,7 @@ namespace o3d { // This class is used to report infomation about the client.
class ClientInfo {
public:
- ClientInfo()
- : num_objects_(0),
- texture_memory_used_(0),
- buffer_memory_used_(0),
- software_renderer_(false),
- non_power_of_two_textures_(false) {
- }
+ ClientInfo();
// The number of objects the client is currently tracking.
int num_objects() const {
@@ -83,6 +77,11 @@ class ClientInfo { return non_power_of_two_textures_;
}
+ // Gets the O3D version.
+ const String& version() const {
+ return version_;
+ }
+
private:
friend class ClientInfoManager;
@@ -91,6 +90,7 @@ class ClientInfo { int buffer_memory_used_;
bool software_renderer_;
bool non_power_of_two_textures_;
+ String version_;
};
// A class to manage the client info so other classes can easily look it up.
diff --git a/o3d/core/cross/client_info_test.cc b/o3d/core/cross/client_info_test.cc index c24c406..6fb4722 100644 --- a/o3d/core/cross/client_info_test.cc +++ b/o3d/core/cross/client_info_test.cc @@ -79,6 +79,14 @@ TEST_F(ClientInfoManagerTest, Basic) { EXPECT_FALSE(client_info_manager->client_info().software_renderer()); EXPECT_FALSE(client_info_manager->client_info().non_power_of_two_textures()); + int version[4] = { -1, -1, -1, -1 }; + sscanf(client_info_manager->client_info().version().c_str(), + "%d.%d.%d.%d", &version[0], &version[1], &version[2], &version[3]); + EXPECT_NE(-1, version[0]); + EXPECT_NE(-1, version[1]); + EXPECT_NE(-1, version[2]); + EXPECT_NE(-1, version[3]); + delete client_info_manager; } diff --git a/o3d/core/cross/message_commands.h b/o3d/core/cross/message_commands.h index ce92d59..712e7b5 100644 --- a/o3d/core/cross/message_commands.h +++ b/o3d/core/cross/message_commands.h @@ -61,6 +61,7 @@ O3D_PUSH_STRUCTURE_PACKING_1; OP(UNREGISTER_SHARED_MEMORY, MessageUnregisterSharedMemory) \
OP(UPDATE_TEXTURE2D_RECT, MessageUpdateTexture2DRect) \
OP(RENDER, MessageRender) \
+ OP(GET_VERSION, MessageGetVersion) \
namespace imc {
@@ -123,15 +124,30 @@ struct MessageAllocateSharedMemory { int32 mem_size;
};
+ // The response data.
+ struct ResponseData {
+ int32 buffer_id;
+ };
+
+ // A wrapper to manage the response data.
+ struct Response {
+ public:
+ Response(int32 buffer_id) {
+ data.buffer_id = buffer_id;
+ }
+
+ ResponseData data;
+ };
+
MessageAllocateSharedMemory() {
msg.message_id = Msg::kMessageId;
}
// Parameters:
- // in_mem_size: The number of bytes to allocate.
- explicit MessageAllocateSharedMemory(int32 in_mem_size) {
+ // mem_size: The number of bytes to allocate.
+ explicit MessageAllocateSharedMemory(int32 mem_size) {
msg.message_id = Msg::kMessageId;
- msg.mem_size = in_mem_size;
+ msg.mem_size = mem_size;
}
Msg msg;
@@ -171,26 +187,26 @@ struct MessageUpdateTexture2D { }
// Parameters:
- // in_texture_id: The id of the texture to set.
- // in_level: The mip level of the texture to set.
- // in_shared_memory_id: The id of the shared memory the contains the data
+ // texture_id: The id of the texture to set.
+ // level: The mip level of the texture to set.
+ // shared_memory_id: The id of the shared memory the contains the data
// to use to set the texture.
- // in_offset: The offset inside the shared memory where the texture data
+ // offset: The offset inside the shared memory where the texture data
// starts.
- // in_number_of_bytes: The number of bytes to get out of shared memory.
+ // number_of_bytes: The number of bytes to get out of shared memory.
// NOTE: this number MUST match the size of the texture. For example for
// an ARGB texture it must be mip_width * mip_height * 4 * sizeof(uint8)
- MessageUpdateTexture2D(Id in_texture_id,
- int32 in_level,
- int32 in_shared_memory_id,
- int32 in_offset,
- int32 in_number_of_bytes) {
+ MessageUpdateTexture2D(Id texture_id,
+ int32 level,
+ int32 shared_memory_id,
+ int32 offset,
+ int32 number_of_bytes) {
msg.message_id = Msg::kMessageId;
- msg.texture_id = in_texture_id;
- msg.level = in_level;
- msg.shared_memory_id = in_shared_memory_id;
- msg.offset = in_offset;
- msg.number_of_bytes = in_number_of_bytes;
+ msg.texture_id = texture_id;
+ msg.level = level;
+ msg.shared_memory_id = shared_memory_id;
+ msg.offset = offset;
+ msg.number_of_bytes = number_of_bytes;
}
Msg msg;
@@ -211,9 +227,9 @@ struct MessageRegisterSharedMemory { msg.message_id = Msg::kMessageId;
}
- explicit MessageRegisterSharedMemory(int32 in_mem_size) {
+ explicit MessageRegisterSharedMemory(int32 mem_size) {
msg.message_id = Msg::kMessageId;
- msg.mem_size = in_mem_size;
+ msg.mem_size = mem_size;
}
Msg msg;
@@ -234,10 +250,10 @@ struct MessageUnregisterSharedMemory { }
// Parameters:
- // in_buffer_id: The id of the buffer to unregister.
- explicit MessageUnregisterSharedMemory(int32 in_buffer_id) {
+ // buffer_id: The id of the buffer to unregister.
+ explicit MessageUnregisterSharedMemory(int32 buffer_id) {
msg.message_id = Msg::kMessageId;
- msg.buffer_id = in_buffer_id;
+ msg.buffer_id = buffer_id;
}
Msg msg;
@@ -286,36 +302,36 @@ struct MessageUpdateTexture2DRect { }
// Parameters:
- // in_texture_id: The id of the texture to set.
- // in_level: The mip level of the texture to set.
- // in_x: The left edge of the rectangle to update in the texture.
- // in_y: The top edge of the rectangle to update in the texture.
- // in_width: The width of the rectangle to update in the texture.
- // in_height: The height of the rectangle to update in the texture.
- // in_shared_memory_id: The id of the shared memory the contains the data to
+ // texture_id: The id of the texture to set.
+ // level: The mip level of the texture to set.
+ // x: The left edge of the rectangle to update in the texture.
+ // y: The top edge of the rectangle to update in the texture.
+ // width: The width of the rectangle to update in the texture.
+ // height: The height of the rectangle to update in the texture.
+ // shared_memory_id: The id of the shared memory the contains the data to
// use to set the texture.
- // in_offset: The offset inside the shared memory where the texture data
+ // offset: The offset inside the shared memory where the texture data
// starts.
- // in_pitch: The number of bytes bytes across 1 row in the source data.
- MessageUpdateTexture2DRect(Id in_texture_id,
- int32 in_level,
- int32 in_x,
- int32 in_y,
- int32 in_width,
- int32 in_height,
- int32 in_shared_memory_id,
- int32 in_offset,
- int32 in_pitch) {
+ // pitch: The number of bytes bytes across 1 row in the source data.
+ MessageUpdateTexture2DRect(Id texture_id,
+ int32 level,
+ int32 x,
+ int32 y,
+ int32 width,
+ int32 height,
+ int32 shared_memory_id,
+ int32 offset,
+ int32 pitch) {
msg.message_id = Msg::kMessageId;
- msg.texture_id = in_texture_id;
- msg.level = in_level;
- msg.x = in_x;
- msg.y = in_y;
- msg.width = in_width;
- msg.height = in_height;
- msg.shared_memory_id = in_shared_memory_id;
- msg.offset = in_offset;
- msg.pitch = in_pitch;
+ msg.texture_id = texture_id;
+ msg.level = level;
+ msg.x = x;
+ msg.y = y;
+ msg.width = width;
+ msg.height = height;
+ msg.shared_memory_id = shared_memory_id;
+ msg.offset = offset;
+ msg.pitch = pitch;
}
Msg msg;
@@ -338,6 +354,44 @@ struct MessageRender { Msg msg;
};
+// Get the O3D version.
+struct MessageGetVersion {
+ // Message Content.
+ struct Msg {
+ static const imc::MessageId kMessageId = imc::GET_VERSION;
+
+ imc::MessageId message_id;
+ };
+
+ // The response data.
+ struct ResponseData {
+ static const size_t kMaxVersionLength = 128;
+ // a null terminated version string in the format "x.x.x.x" where x is an
+ // integer number. Note: There may be other data after the last digit which
+ // is currently undefined.
+ char version[kMaxVersionLength];
+ };
+
+ // A wrapper to manage the response data.
+ struct Response {
+ public:
+ Response(const char* version) {
+ strncpy(data.version, version,
+ std::min(strlen(version) + 1, sizeof(data.version)));
+ data.version[sizeof(data.version) - 1] = '\0';
+ }
+
+ ResponseData data;
+ };
+
+
+ MessageGetVersion() {
+ msg.message_id = Msg::kMessageId;
+ }
+
+ Msg msg;
+};
+
O3D_POP_STRUCTURE_PACKING;
diff --git a/o3d/core/cross/message_commands_test.cc b/o3d/core/cross/message_commands_test.cc index 3e089aa..8bdecfb 100644 --- a/o3d/core/cross/message_commands_test.cc +++ b/o3d/core/cross/message_commands_test.cc @@ -143,7 +143,7 @@ TEST_F(MessageCommandsTest, MessageUpdateTexture2DRect) { EXPECT_EQ(10, msg2.msg.pitch); } -TEST_F(MessageCommandsTest, MessageRenderTest) { +TEST_F(MessageCommandsTest, MessageRender) { EXPECT_EQ(static_cast<int>(imc::RENDER), 7); EXPECT_EQ(0u, offsetof(MessageRender::Msg, message_id)); MessageRender msg; @@ -151,6 +151,19 @@ TEST_F(MessageCommandsTest, MessageRenderTest) { EXPECT_EQ(4u, sizeof msg.msg); } +TEST_F(MessageCommandsTest, MessageGetVersion) { + EXPECT_EQ(static_cast<int>(imc::GET_VERSION), 8); + EXPECT_EQ(0u, offsetof(MessageGetVersion::Msg, message_id)); + MessageGetVersion msg; + EXPECT_EQ(imc::GET_VERSION, msg.msg.message_id); + EXPECT_EQ(4u, sizeof msg.msg); + const char* kVersion = "0.1.2.3"; + MessageGetVersion::Response response(kVersion); + EXPECT_EQ(0u, offsetof(MessageGetVersion::ResponseData, version)); + EXPECT_EQ(128u, sizeof(MessageGetVersion::ResponseData)); // NOLINT + EXPECT_STREQ(kVersion, response.data.version); +} + } // namespace o3d diff --git a/o3d/core/cross/message_queue.cc b/o3d/core/cross/message_queue.cc index 23fa55e..8c0bb3e 100644 --- a/o3d/core/cross/message_queue.cc +++ b/o3d/core/cross/message_queue.cc @@ -39,6 +39,7 @@ #include <unistd.h> #endif #include "core/cross/message_queue.h" +#include "core/cross/client_info.h" #include "core/cross/object_manager.h" #include "core/cross/bitmap.h" #include "core/cross/texture.h" @@ -506,13 +507,13 @@ bool MessageQueue::ProcessMessageAllocateSharedMemory( } // Create a unique id for the shared memory buffer. - int32 buffer_id = next_shared_memory_id_++; + MessageAllocateSharedMemory::Response response(next_shared_memory_id_++); // Send the shared memory handle and the buffer id back to the client. nacl::MessageHeader response_header; nacl::IOVec id_vec; - id_vec.base = &buffer_id; - id_vec.length = sizeof(buffer_id); + id_vec.base = &response.data; + id_vec.length = sizeof(response.data); response_header.iov = &id_vec; response_header.iov_length = 1; @@ -520,7 +521,7 @@ bool MessageQueue::ProcessMessageAllocateSharedMemory( response_header.handle_count = 1; int result = nacl::SendDatagram(client->client_handle(), &response_header, 0); - if (result != sizeof(buffer_id)) { + if (result != sizeof(response.data)) { LOG_IMC_ERROR("Failed to send shared memory handle back to the client"); nacl::Unmap(shared_region, mem_size); nacl::Close(shared_memory); @@ -528,7 +529,7 @@ bool MessageQueue::ProcessMessageAllocateSharedMemory( } // Register the newly created shared memory with the connected client. - client->RegisterSharedMemory(buffer_id, + client->RegisterSharedMemory(response.data.buffer_id, shared_memory, shared_region, mem_size); @@ -812,4 +813,45 @@ bool MessageQueue::ProcessMessageRender( return true; } +// Processes a request to get the O3D version. +bool MessageQueue::ProcessMessageGetVersion( + ConnectedClient* client, + int message_length, + nacl::MessageHeader* header, + nacl::Handle* handles, + const MessageGetVersion::Msg& message) { + if (header->iov_length != 1 || + header->handle_count != 0) { + LOG(ERROR) << "Malformed message for GET_VERSION"; + return false; + } + + ClientInfoManager* manager(service_locator_->GetService<ClientInfoManager>()); + static const char* const kNullString = ""; + const char* version = kNullString; + if (manager) { + version = manager->client_info().version().c_str(); + } + + // Send the version string. + DCHECK_LT(strlen(version), + MessageGetVersion::ResponseData::kMaxVersionLength); + MessageGetVersion::Response response(version); + + nacl::MessageHeader response_header; + nacl::IOVec id_vec; + id_vec.base = &response.data; + id_vec.length = sizeof(response.data); + + response_header.iov = &id_vec; + response_header.iov_length = 1; + response_header.handles = NULL; + response_header.handle_count = 0; + int result = nacl::SendDatagram(client->client_handle(), &response_header, 0); + + return true; +} + + + } // namespace o3d diff --git a/o3d/core/cross/message_queue_test.cc b/o3d/core/cross/message_queue_test.cc index 1e2cf60..2987779 100644 --- a/o3d/core/cross/message_queue_test.cc +++ b/o3d/core/cross/message_queue_test.cc @@ -33,6 +33,7 @@ // Tests the functionality defined in MessageQueue.cc/h #include "core/cross/message_queue.h" +#include "core/cross/client_info.h" #include "core/cross/object_manager.h" #include "core/cross/pack.h" #include "core/cross/error_status.h" @@ -255,6 +256,9 @@ class TextureUpdateHelper { // Tells the renderer to render. bool Render(); + // Gets the version + bool GetVersion(); + private: // Handle of the socket that's connected to o3d. nacl::Handle o3d_handle_; @@ -584,7 +588,49 @@ bool TextureUpdateHelper::Render() { // Send message. int result = nacl::SendDatagram(o3d_handle_, &header, 0); EXPECT_EQ(static_cast<int>(vec.length), result); - // Read back the boolean reply from the O3D plugin + return true; +} + +bool TextureUpdateHelper::GetVersion() { + MessageGetVersion msg; + nacl::MessageHeader header; + nacl::IOVec vec; + + vec.base = &msg.msg; + vec.length = sizeof(msg.msg); + header.iov = &vec; + header.iov_length = 1; + header.handles = NULL; + header.handle_count = 0; + + // Send message. + int result = nacl::SendDatagram(o3d_handle_, &header, 0); + EXPECT_EQ(static_cast<int>(vec.length), result); + + // Wait for a message back from the server containing the version of O3D. + MessageGetVersion::ResponseData response; + nacl::MessageHeader reply_header; + nacl::IOVec version_vec; + version_vec.base = &response; + version_vec.length = sizeof(response); + reply_header.iov = &version_vec; + reply_header.iov_length = 1; + reply_header.handles = NULL; + reply_header.handle_count = 0; + + result = nacl::ReceiveDatagram(o3d_handle_, &reply_header, 0); + EXPECT_EQ(version_vec.length, static_cast<unsigned>(result)); + EXPECT_EQ(0, reply_header.flags & nacl::kMessageTruncated); + EXPECT_EQ(0U, reply_header.handle_count); + EXPECT_EQ(1U, reply_header.iov_length); + + ClientInfoManager* manager( + g_service_locator->GetService<ClientInfoManager>()); + EXPECT_TRUE(manager != NULL); + if (manager) { + EXPECT_EQ(0, manager->client_info().version().compare(response.version)); + } + return true; } @@ -1145,7 +1191,7 @@ TEST_F(MessageQueueTest, ConcurrentSharedMemoryOperations) { namespace { -// This helper class for Render test. +// This is a helper class for Render test. class RenderTest : public PerThreadConnectedTest { private: int num_iterations_; @@ -1214,4 +1260,50 @@ TEST_F(MessageQueueTest, Render) { EXPECT_TRUE(renderer->need_to_render()); } +namespace { + +// This is a helper class for GetVersion test. +class GetVersionTest : public PerThreadConnectedTest { + private: + int num_iterations_; + + public: + explicit GetVersionTest(int num_iterations) { + num_iterations_ = num_iterations; + } + + void Run(MessageQueue* queue, nacl::Handle socket_handle) { + String socket_addr = queue->GetSocketAddress(); + TextureUpdateHelper helper; + if (!helper.ConnectToO3D(socket_addr.c_str(), socket_handle)) { + FAIL_TEST("Failed to connect to O3D"); + } + + for (int i = 0; i < num_iterations_; i++) { + bool result = helper.GetVersion(); + if (!result) { + FAIL_TEST("Failed to request a GetVersion"); + } + } + + Pass(); + } +}; + +} // anonymous namespace. + +// Tests requesting a GetVersion. +TEST_F(MessageQueueTest, GetVersion) { + class Provider : public TestProvider { + public: + virtual PerThreadConnectedTest* CreateTest() { + return new GetVersionTest(1); + } + }; + + Provider provider; + RunTests(1, TimeDelta::FromSeconds(1), &provider); + EXPECT_FALSE(CheckErrorExists()); +} + } // namespace o3d |