summaryrefslogtreecommitdiffstats
path: root/o3d/core/cross
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/core/cross')
-rw-r--r--o3d/core/cross/client_info.cc9
-rw-r--r--o3d/core/cross/client_info.h14
-rw-r--r--o3d/core/cross/client_info_test.cc8
-rw-r--r--o3d/core/cross/message_commands.h154
-rw-r--r--o3d/core/cross/message_commands_test.cc15
-rw-r--r--o3d/core/cross/message_queue.cc52
-rw-r--r--o3d/core/cross/message_queue_test.cc96
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