Index: gpu/command_buffer/service/common_decoder_unittest.cc |
=================================================================== |
--- gpu/command_buffer/service/common_decoder_unittest.cc (revision 0) |
+++ gpu/command_buffer/service/common_decoder_unittest.cc (revision 0) |
@@ -0,0 +1,418 @@ |
+// Copyright (c) 2009 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 "gpu/command_buffer/service/common_decoder.h" |
+#include "gpu/command_buffer/service/cmd_buffer_engine.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace command_buffer { |
+ |
+TEST(CommonDecoderBucket, Basic) { |
+ CommonDecoder::Bucket bucket; |
+ EXPECT_EQ(0, bucket.size()); |
+ EXPECT_TRUE(NULL == bucket.GetData(0, 0)); |
+} |
+ |
+TEST(CommonDecoderBucket, Size) { |
+ CommonDecoder::Bucket bucket; |
+ bucket.SetSize(24); |
+ EXPECT_EQ(24, bucket.size()); |
+ bucket.SetSize(12); |
+ EXPECT_EQ(12, bucket.size()); |
+} |
+ |
+TEST(CommonDecoderBucket, GetData) { |
+ CommonDecoder::Bucket bucket; |
+ |
+ bucket.SetSize(24); |
+ EXPECT_TRUE(NULL != bucket.GetData(0, 0)); |
+ EXPECT_TRUE(NULL != bucket.GetData(24, 0)); |
+ EXPECT_TRUE(NULL == bucket.GetData(25, 0)); |
+ EXPECT_TRUE(NULL != bucket.GetData(0, 24)); |
+ EXPECT_TRUE(NULL == bucket.GetData(0, 25)); |
+ bucket.SetSize(23); |
+ EXPECT_TRUE(NULL == bucket.GetData(0, 24)); |
+} |
+ |
+TEST(CommonDecoderBucket, SetData) { |
+ CommonDecoder::Bucket bucket; |
+ static const char data[] = "testing"; |
+ |
+ bucket.SetSize(10); |
+ EXPECT_TRUE(bucket.SetData(data, 0, sizeof(data))); |
+ EXPECT_EQ(0, memcmp(data, bucket.GetData(0, sizeof(data)), sizeof(data))); |
+ EXPECT_TRUE(bucket.SetData(data, 2, sizeof(data))); |
+ EXPECT_EQ(0, memcmp(data, bucket.GetData(2, sizeof(data)), sizeof(data))); |
+ EXPECT_FALSE(bucket.SetData(data, 0, sizeof(data) * 2)); |
+ EXPECT_FALSE(bucket.SetData(data, 5, sizeof(data))); |
+} |
+ |
+class TestCommonDecoder : public CommonDecoder { |
+ public: |
+ // Overridden from AsyncAPIInterface |
+ const char* GetCommandName(unsigned int command_id) const { |
+ return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); |
+ } |
+ |
+ // Overridden from AsyncAPIInterface |
+ parse_error::ParseError DoCommand( |
+ unsigned int command, |
+ unsigned int arg_count, |
+ const void* cmd_data) { |
+ return DoCommonCommand(command, arg_count, cmd_data); |
+ } |
+ |
+ CommonDecoder::Bucket* GetBucket(uint32 id) const { |
+ return CommonDecoder::GetBucket(id); |
+ } |
+}; |
+ |
+class MockCommandBufferEngine : public CommandBufferEngine { |
+ public: |
+ static const int32 kValidShmId = 1; |
+ |
+ MockCommandBufferEngine() |
+ : CommandBufferEngine(), |
+ token_() { |
+ } |
+ |
+ // Overridden from CommandBufferEngine. |
+ virtual void* GetSharedMemoryAddress(int32 shm_id) { |
+ return (shm_id == kValidShmId) ? buffer_ : NULL; |
+ } |
+ |
+ // Overridden from CommandBufferEngine. |
+ virtual size_t GetSharedMemorySize(int32 shm_id) { |
+ return (shm_id == kValidShmId) ? kBufferSize : 0; |
+ } |
+ |
+ template <typename T> |
+ T GetSharedMemoryAs(uint32 offset) { |
+ DCHECK(offset < kBufferSize); |
+ return reinterpret_cast<T>(&buffer_[offset]); |
+ } |
+ |
+ uint32 GetSharedMemoryOffset(const void* memory) { |
+ ptrdiff_t offset = reinterpret_cast<const int8*>(memory) - &buffer_[0]; |
+ DCHECK(offset >= 0); |
+ DCHECK(offset < kBufferSize); |
+ return static_cast<uint32>(offset); |
+ } |
+ |
+ // Overridden from CommandBufferEngine. |
+ virtual void set_token(int32 token) { |
+ token_ = token; |
+ } |
+ |
+ int32 token() const { |
+ return token_; |
+ } |
+ |
+ private: |
+ static const size_t kBufferSize = 1024; |
+ |
+ int8 buffer_[kBufferSize]; |
+ int32 token_; |
+}; |
+ |
+class CommonDecoderTest : public testing::Test { |
+ protected: |
+ virtual void SetUp() { |
+ decoder_.set_engine(&engine_); |
+ } |
+ |
+ virtual void TearDown() { |
+ } |
+ |
+ template <typename T> |
+ parse_error::ParseError ExecuteCmd(const T& cmd) { |
+ COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); |
+ return decoder_.DoCommand(cmd.kCmdId, |
+ ComputeNumEntries(sizeof(cmd)) - 1, |
+ &cmd); |
+ } |
+ |
+ template <typename T> |
+ parse_error::ParseError ExecuteImmediateCmd(const T& cmd, size_t data_size) { |
+ COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); |
+ return decoder_.DoCommand(cmd.kCmdId, |
+ ComputeNumEntries(sizeof(cmd) + data_size) - 1, |
+ &cmd); |
+ } |
+ |
+ MockCommandBufferEngine engine_; |
+ TestCommonDecoder decoder_; |
+}; |
+ |
+TEST_F(CommonDecoderTest, HandleNoop) { |
+ cmd::Noop cmd; |
+ const uint32 kSkipCount = 5; |
+ cmd.Init(kSkipCount); |
+ EXPECT_EQ(parse_error::kParseNoError, |
+ ExecuteImmediateCmd( |
+ cmd, kSkipCount * kCommandBufferEntrySize)); |
+} |
+ |
+TEST_F(CommonDecoderTest, SetToken) { |
+ cmd::SetToken cmd; |
+ const int32 kTokenId = 123; |
+ EXPECT_EQ(0, engine_.token()); |
+ cmd.Init(kTokenId); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(kTokenId, engine_.token()); |
+} |
+ |
+TEST_F(CommonDecoderTest, Jump) { |
+ // cmd::Jump cmd; |
+ // TODO(gman): implement. |
+} |
+ |
+TEST_F(CommonDecoderTest, JumpRelative) { |
+ // cmd::JumpRelative cmd; |
+ // TODO(gman): implement. |
+} |
+ |
+TEST_F(CommonDecoderTest, Call) { |
+ // cmd::Call cmd; |
+ // TODO(gman): implement. |
+} |
+ |
+TEST_F(CommonDecoderTest, CallRelative) { |
+ // cmd::CallRelative cmd; |
+ // TODO(gman): implement. |
+} |
+ |
+TEST_F(CommonDecoderTest, Return) { |
+ // cmd::Return cmd; |
+ // TODO(gman): implement. |
+} |
+ |
+TEST_F(CommonDecoderTest, SetBucketSize) { |
+ cmd::SetBucketSize cmd; |
+ const uint32 kBucketId = 123; |
+ const uint32 kBucketLength1 = 1234; |
+ const uint32 kBucketLength2 = 78; |
+ // Check the bucket does not exist. |
+ EXPECT_TRUE(NULL == decoder_.GetBucket(kBucketId)); |
+ // Check we can create one. |
+ cmd.Init(kBucketId, kBucketLength1); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ CommonDecoder::Bucket* bucket; |
+ bucket = decoder_.GetBucket(kBucketId); |
+ EXPECT_TRUE(NULL != bucket); |
+ EXPECT_EQ(kBucketLength1, bucket->size()); |
+ // Check we can change it. |
+ cmd.Init(kBucketId, kBucketLength2); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ bucket = decoder_.GetBucket(kBucketId); |
+ EXPECT_TRUE(NULL != bucket); |
+ EXPECT_EQ(kBucketLength2, bucket->size()); |
+ // Check we can delete it. |
+ cmd.Init(kBucketId, 0); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ bucket = decoder_.GetBucket(kBucketId); |
+ EXPECT_EQ(0, bucket->size()); |
+} |
+ |
+TEST_F(CommonDecoderTest, SetBucketData) { |
+ cmd::SetBucketSize size_cmd; |
+ cmd::SetBucketData cmd; |
+ |
+ static const char kData[] = "1234567890123456789"; |
+ |
+ const uint32 kBucketId = 123; |
+ const uint32 kInvalidBucketId = 124; |
+ |
+ size_cmd.Init(kBucketId, sizeof(kData)); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(size_cmd)); |
+ CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId); |
+ // Check the data is not there. |
+ EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData))); |
+ |
+ // Check we can set it. |
+ const uint32 kSomeOffsetInSharedMemory = 50; |
+ void* memory = engine_.GetSharedMemoryAs<void*>(kSomeOffsetInSharedMemory); |
+ memcpy(memory, kData, sizeof(kData)); |
+ cmd.Init(kBucketId, 0, sizeof(kData), |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData))); |
+ |
+ // Check we can set it partially. |
+ static const char kData2[] = "ABCEDFG"; |
+ const uint32 kSomeOffsetInBucket = 5; |
+ memcpy(memory, kData2, sizeof(kData2)); |
+ cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2), |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)), |
+ kData2, sizeof(kData2))); |
+ const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData)); |
+ // Check that nothing was affected outside of updated area. |
+ EXPECT_EQ(kData[kSomeOffsetInBucket - 1], |
+ bucket_data[kSomeOffsetInBucket - 1]); |
+ EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)], |
+ bucket_data[kSomeOffsetInBucket + sizeof(kData2)]); |
+ |
+ // Check that it fails if the bucket_id is invalid |
+ cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2), |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_NE(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ |
+ // Check that it fails if the offset is out of range. |
+ cmd.Init(kBucketId, bucket->size(), 1, |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_NE(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ |
+ // Check that it fails if the size is out of range. |
+ cmd.Init(kBucketId, 0, bucket->size() + 1, |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_NE(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+} |
+ |
+TEST_F(CommonDecoderTest, SetBucketDataImmediate) { |
+ cmd::SetBucketSize size_cmd; |
+ int8 buffer[1024]; |
+ cmd::SetBucketDataImmediate& cmd = |
+ *reinterpret_cast<cmd::SetBucketDataImmediate*>(&buffer); |
+ |
+ static const char kData[] = "1234567890123456789"; |
+ |
+ const uint32 kBucketId = 123; |
+ const uint32 kInvalidBucketId = 124; |
+ |
+ size_cmd.Init(kBucketId, sizeof(kData)); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(size_cmd)); |
+ CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId); |
+ // Check the data is not there. |
+ EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData))); |
+ |
+ // Check we can set it. |
+ void* memory = &buffer[0] + sizeof(cmd); |
+ memcpy(memory, kData, sizeof(kData)); |
+ cmd.Init(kBucketId, 0, sizeof(kData)); |
+ EXPECT_EQ(parse_error::kParseNoError, |
+ ExecuteImmediateCmd(cmd, sizeof(kData))); |
+ EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData))); |
+ |
+ // Check we can set it partially. |
+ static const char kData2[] = "ABCEDFG"; |
+ const uint32 kSomeOffsetInBucket = 5; |
+ memcpy(memory, kData2, sizeof(kData2)); |
+ cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2)); |
+ EXPECT_EQ(parse_error::kParseNoError, |
+ ExecuteImmediateCmd(cmd, sizeof(kData2))); |
+ EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)), |
+ kData2, sizeof(kData2))); |
+ const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData)); |
+ // Check that nothing was affected outside of updated area. |
+ EXPECT_EQ(kData[kSomeOffsetInBucket - 1], |
+ bucket_data[kSomeOffsetInBucket - 1]); |
+ EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)], |
+ bucket_data[kSomeOffsetInBucket + sizeof(kData2)]); |
+ |
+ // Check that it fails if the bucket_id is invalid |
+ cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2)); |
+ EXPECT_NE(parse_error::kParseNoError, |
+ ExecuteImmediateCmd(cmd, sizeof(kData2))); |
+ |
+ // Check that it fails if the offset is out of range. |
+ cmd.Init(kBucketId, bucket->size(), 1); |
+ EXPECT_NE(parse_error::kParseNoError, |
+ ExecuteImmediateCmd(cmd, sizeof(kData2))); |
+ |
+ // Check that it fails if the size is out of range. |
+ cmd.Init(kBucketId, 0, bucket->size() + 1); |
+ EXPECT_NE(parse_error::kParseNoError, |
+ ExecuteImmediateCmd(cmd, sizeof(kData2))); |
+} |
+ |
+TEST_F(CommonDecoderTest, GetBucketSize) { |
+ cmd::SetBucketSize size_cmd; |
+ cmd::GetBucketSize cmd; |
+ |
+ const uint32 kBucketSize = 456; |
+ const uint32 kBucketId = 123; |
+ const uint32 kInvalidBucketId = 124; |
+ |
+ size_cmd.Init(kBucketId, kBucketSize); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(size_cmd)); |
+ |
+ // Check that the size is correct. |
+ const uint32 kSomeOffsetInSharedMemory = 50; |
+ uint32* memory = |
+ engine_.GetSharedMemoryAs<uint32*>(kSomeOffsetInSharedMemory); |
+ *memory = 0xFFFFFFFF; |
+ cmd.Init(kBucketId, |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(kBucketSize, *memory); |
+ |
+ // Check that it fails if the bucket_id is invalid |
+ cmd.Init(kInvalidBucketId, |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_NE(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+} |
+ |
+TEST_F(CommonDecoderTest, GetBucketData) { |
+ cmd::SetBucketSize size_cmd; |
+ cmd::SetBucketData set_cmd; |
+ cmd::GetBucketData cmd; |
+ |
+ static const char kData[] = "1234567890123456789"; |
+ static const char zero[sizeof(kData)] = { 0, }; |
+ |
+ const uint32 kBucketId = 123; |
+ const uint32 kInvalidBucketId = 124; |
+ |
+ size_cmd.Init(kBucketId, sizeof(kData)); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(size_cmd)); |
+ CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId); |
+ const uint32 kSomeOffsetInSharedMemory = 50; |
+ uint8* memory = engine_.GetSharedMemoryAs<uint8*>(kSomeOffsetInSharedMemory); |
+ memcpy(memory, kData, sizeof(kData)); |
+ set_cmd.Init(kBucketId, 0, sizeof(kData), |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(set_cmd)); |
+ |
+ // Check we can get the whole thing. |
+ memset(memory, 0, sizeof(kData)); |
+ cmd.Init(kBucketId, 0, sizeof(kData), |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(0, memcmp(memory, kData, sizeof(kData))); |
+ |
+ // Check we can get a piece. |
+ const uint32 kSomeOffsetInBucket = 5; |
+ const uint32 kLengthOfPiece = 6; |
+ const uint8 kSentinel = 0xff; |
+ memset(memory, 0, sizeof(kData)); |
+ memory[-1] = kSentinel; |
+ cmd.Init(kBucketId, kSomeOffsetInBucket, kLengthOfPiece, |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(0, memcmp(memory, kData + kSomeOffsetInBucket, kLengthOfPiece)); |
+ EXPECT_EQ(0, memcmp(memory + kLengthOfPiece, zero, |
+ sizeof(kData) - kLengthOfPiece)); |
+ EXPECT_EQ(kSentinel, memory[-1]); |
+ |
+ // Check that it fails if the bucket_id is invalid |
+ cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData), |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_NE(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ |
+ // Check that it fails if the offset is invalid |
+ cmd.Init(kBucketId, sizeof(kData) + 1, 1, |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_NE(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+ |
+ // Check that it fails if the size is invalid |
+ cmd.Init(kBucketId, 0, sizeof(kData) + 1, |
+ MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); |
+ EXPECT_NE(parse_error::kParseNoError, ExecuteCmd(cmd)); |
+} |
+ |
+ |
+} // namespace command_buffer |
+ |
Property changes on: gpu\command_buffer\service\common_decoder_unittest.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |