Handle account removal correctly on all platforms.
[chromium-blink-merge.git] / gpu / command_buffer / service / common_decoder_unittest.cc
blob0faa8e97c0e89e9bfda2198eb4a1b753847ae516
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
3 // found in the LICENSE file.
5 #include "gpu/command_buffer/service/common_decoder.h"
6 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
7 #include "testing/gtest/include/gtest/gtest.h"
9 namespace gpu {
11 TEST(CommonDecoderBucket, Basic) {
12 CommonDecoder::Bucket bucket;
13 EXPECT_EQ(0u, bucket.size());
14 EXPECT_TRUE(NULL == bucket.GetData(0, 0));
17 TEST(CommonDecoderBucket, Size) {
18 CommonDecoder::Bucket bucket;
19 bucket.SetSize(24);
20 EXPECT_EQ(24u, bucket.size());
21 bucket.SetSize(12);
22 EXPECT_EQ(12u, bucket.size());
25 TEST(CommonDecoderBucket, GetData) {
26 CommonDecoder::Bucket bucket;
28 bucket.SetSize(24);
29 EXPECT_TRUE(NULL != bucket.GetData(0, 0));
30 EXPECT_TRUE(NULL != bucket.GetData(24, 0));
31 EXPECT_TRUE(NULL == bucket.GetData(25, 0));
32 EXPECT_TRUE(NULL != bucket.GetData(0, 24));
33 EXPECT_TRUE(NULL == bucket.GetData(0, 25));
34 bucket.SetSize(23);
35 EXPECT_TRUE(NULL == bucket.GetData(0, 24));
38 TEST(CommonDecoderBucket, SetData) {
39 CommonDecoder::Bucket bucket;
40 static const char data[] = "testing";
42 bucket.SetSize(10);
43 EXPECT_TRUE(bucket.SetData(data, 0, sizeof(data)));
44 EXPECT_EQ(0, memcmp(data, bucket.GetData(0, sizeof(data)), sizeof(data)));
45 EXPECT_TRUE(bucket.SetData(data, 2, sizeof(data)));
46 EXPECT_EQ(0, memcmp(data, bucket.GetData(2, sizeof(data)), sizeof(data)));
47 EXPECT_FALSE(bucket.SetData(data, 0, sizeof(data) * 2));
48 EXPECT_FALSE(bucket.SetData(data, 5, sizeof(data)));
51 class TestCommonDecoder : public CommonDecoder {
52 public:
53 // Overridden from AsyncAPIInterface
54 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE {
55 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
58 // Overridden from AsyncAPIInterface
59 virtual error::Error DoCommand(
60 unsigned int command,
61 unsigned int arg_count,
62 const void* cmd_data) OVERRIDE {
63 return DoCommonCommand(command, arg_count, cmd_data);
66 CommonDecoder::Bucket* GetBucket(uint32 id) const {
67 return CommonDecoder::GetBucket(id);
71 class MockCommandBufferEngine : public CommandBufferEngine {
72 public:
73 static const int32 kStartValidShmId = 1;
74 static const int32 kValidShmId = 2;
75 static const int32 kInvalidShmId = 3;
76 static const size_t kBufferSize = 1024;
77 static const int32 kValidOffset = kBufferSize / 2;
78 static const int32 kInvalidOffset = kBufferSize;
80 MockCommandBufferEngine()
81 : CommandBufferEngine(),
82 token_(),
83 get_offset_(0) {
84 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
85 shared_memory->CreateAndMapAnonymous(kBufferSize);
86 buffer_ = MakeBufferFromSharedMemory(shared_memory.Pass(), kBufferSize);
89 // Overridden from CommandBufferEngine.
90 virtual scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32 shm_id)
91 OVERRIDE {
92 if (IsValidSharedMemoryId(shm_id))
93 return buffer_;
94 return NULL;
97 template <typename T>
98 T GetSharedMemoryAs(uint32 offset) {
99 DCHECK_LT(offset, kBufferSize);
100 int8* buffer_memory = static_cast<int8*>(buffer_->memory());
101 return reinterpret_cast<T>(&buffer_memory[offset]);
104 int32 GetSharedMemoryOffset(const void* memory) {
105 int8* buffer_memory = static_cast<int8*>(buffer_->memory());
106 ptrdiff_t offset = static_cast<const int8*>(memory) - &buffer_memory[0];
107 DCHECK_GE(offset, 0);
108 DCHECK_LT(static_cast<size_t>(offset), kBufferSize);
109 return static_cast<int32>(offset);
112 // Overridden from CommandBufferEngine.
113 virtual void set_token(int32 token) OVERRIDE {
114 token_ = token;
117 int32 token() const {
118 return token_;
121 // Overridden from CommandBufferEngine.
122 virtual bool SetGetBuffer(int32 transfer_buffer_id) OVERRIDE {
123 NOTREACHED();
124 return false;
127 // Overridden from CommandBufferEngine.
128 virtual bool SetGetOffset(int32 offset) OVERRIDE {
129 if (static_cast<size_t>(offset) < kBufferSize) {
130 get_offset_ = offset;
131 return true;
133 return false;
136 // Overridden from CommandBufferEngine.
137 virtual int32 GetGetOffset() OVERRIDE {
138 return get_offset_;
141 private:
142 bool IsValidSharedMemoryId(int32 shm_id) {
143 return shm_id == kValidShmId || shm_id == kStartValidShmId;
146 scoped_refptr<gpu::Buffer> buffer_;
147 int32 token_;
148 int32 get_offset_;
151 const int32 MockCommandBufferEngine::kStartValidShmId;
152 const int32 MockCommandBufferEngine::kValidShmId;
153 const int32 MockCommandBufferEngine::kInvalidShmId;
154 const size_t MockCommandBufferEngine::kBufferSize;
155 const int32 MockCommandBufferEngine::kValidOffset;
156 const int32 MockCommandBufferEngine::kInvalidOffset;
158 class CommonDecoderTest : public testing::Test {
159 protected:
160 virtual void SetUp() {
161 decoder_.set_engine(&engine_);
164 virtual void TearDown() {
167 template <typename T>
168 error::Error ExecuteCmd(const T& cmd) {
169 COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed);
170 return decoder_.DoCommands(
171 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd)), 0);
174 template <typename T>
175 error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) {
176 COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
177 return decoder_.DoCommands(
178 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd) + data_size), 0);
181 MockCommandBufferEngine engine_;
182 TestCommonDecoder decoder_;
185 TEST_F(CommonDecoderTest, Initialize) {
186 EXPECT_EQ(0, engine_.GetGetOffset());
189 TEST_F(CommonDecoderTest, DoCommonCommandInvalidCommand) {
190 EXPECT_EQ(error::kUnknownCommand, decoder_.DoCommand(999999, 0, NULL));
193 TEST_F(CommonDecoderTest, HandleNoop) {
194 cmd::Noop cmd;
195 const uint32 kSkipCount = 5;
196 cmd.Init(kSkipCount);
197 EXPECT_EQ(error::kNoError,
198 ExecuteImmediateCmd(
199 cmd, kSkipCount * kCommandBufferEntrySize));
200 const uint32 kSkipCount2 = 1;
201 cmd.Init(kSkipCount2);
202 EXPECT_EQ(error::kNoError,
203 ExecuteImmediateCmd(
204 cmd, kSkipCount2 * kCommandBufferEntrySize));
207 TEST_F(CommonDecoderTest, SetToken) {
208 cmd::SetToken cmd;
209 const int32 kTokenId = 123;
210 EXPECT_EQ(0, engine_.token());
211 cmd.Init(kTokenId);
212 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
213 EXPECT_EQ(kTokenId, engine_.token());
216 TEST_F(CommonDecoderTest, SetBucketSize) {
217 cmd::SetBucketSize cmd;
218 const uint32 kBucketId = 123;
219 const uint32 kBucketLength1 = 1234;
220 const uint32 kBucketLength2 = 78;
221 // Check the bucket does not exist.
222 EXPECT_TRUE(NULL == decoder_.GetBucket(kBucketId));
223 // Check we can create one.
224 cmd.Init(kBucketId, kBucketLength1);
225 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
226 CommonDecoder::Bucket* bucket;
227 bucket = decoder_.GetBucket(kBucketId);
228 EXPECT_TRUE(NULL != bucket);
229 EXPECT_EQ(kBucketLength1, bucket->size());
230 // Check we can change it.
231 cmd.Init(kBucketId, kBucketLength2);
232 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
233 bucket = decoder_.GetBucket(kBucketId);
234 EXPECT_TRUE(NULL != bucket);
235 EXPECT_EQ(kBucketLength2, bucket->size());
236 // Check we can delete it.
237 cmd.Init(kBucketId, 0);
238 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
239 bucket = decoder_.GetBucket(kBucketId);
240 EXPECT_EQ(0u, bucket->size());
243 TEST_F(CommonDecoderTest, SetBucketData) {
244 cmd::SetBucketSize size_cmd;
245 cmd::SetBucketData cmd;
247 static const char kData[] = "1234567890123456789";
249 const uint32 kBucketId = 123;
250 const uint32 kInvalidBucketId = 124;
252 size_cmd.Init(kBucketId, sizeof(kData));
253 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
254 CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId);
255 // Check the data is not there.
256 EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
258 // Check we can set it.
259 const uint32 kSomeOffsetInSharedMemory = 50;
260 void* memory = engine_.GetSharedMemoryAs<void*>(kSomeOffsetInSharedMemory);
261 memcpy(memory, kData, sizeof(kData));
262 cmd.Init(kBucketId, 0, sizeof(kData),
263 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
264 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
265 EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
267 // Check we can set it partially.
268 static const char kData2[] = "ABCEDFG";
269 const uint32 kSomeOffsetInBucket = 5;
270 memcpy(memory, kData2, sizeof(kData2));
271 cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2),
272 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
273 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
274 EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)),
275 kData2, sizeof(kData2)));
276 const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData));
277 // Check that nothing was affected outside of updated area.
278 EXPECT_EQ(kData[kSomeOffsetInBucket - 1],
279 bucket_data[kSomeOffsetInBucket - 1]);
280 EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)],
281 bucket_data[kSomeOffsetInBucket + sizeof(kData2)]);
283 // Check that it fails if the bucket_id is invalid
284 cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2),
285 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
286 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
288 // Check that it fails if the offset is out of range.
289 cmd.Init(kBucketId, bucket->size(), 1,
290 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
291 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
293 // Check that it fails if the size is out of range.
294 cmd.Init(kBucketId, 0, bucket->size() + 1,
295 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
296 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
299 TEST_F(CommonDecoderTest, SetBucketDataImmediate) {
300 cmd::SetBucketSize size_cmd;
301 int8 buffer[1024];
302 cmd::SetBucketDataImmediate& cmd =
303 *reinterpret_cast<cmd::SetBucketDataImmediate*>(&buffer);
305 static const char kData[] = "1234567890123456789";
307 const uint32 kBucketId = 123;
308 const uint32 kInvalidBucketId = 124;
310 size_cmd.Init(kBucketId, sizeof(kData));
311 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
312 CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId);
313 // Check the data is not there.
314 EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
316 // Check we can set it.
317 void* memory = &buffer[0] + sizeof(cmd);
318 memcpy(memory, kData, sizeof(kData));
319 cmd.Init(kBucketId, 0, sizeof(kData));
320 EXPECT_EQ(error::kNoError,
321 ExecuteImmediateCmd(cmd, sizeof(kData)));
322 EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
324 // Check we can set it partially.
325 static const char kData2[] = "ABCEDFG";
326 const uint32 kSomeOffsetInBucket = 5;
327 memcpy(memory, kData2, sizeof(kData2));
328 cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2));
329 EXPECT_EQ(error::kNoError,
330 ExecuteImmediateCmd(cmd, sizeof(kData2)));
331 EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)),
332 kData2, sizeof(kData2)));
333 const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData));
334 // Check that nothing was affected outside of updated area.
335 EXPECT_EQ(kData[kSomeOffsetInBucket - 1],
336 bucket_data[kSomeOffsetInBucket - 1]);
337 EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)],
338 bucket_data[kSomeOffsetInBucket + sizeof(kData2)]);
340 // Check that it fails if the bucket_id is invalid
341 cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2));
342 EXPECT_NE(error::kNoError,
343 ExecuteImmediateCmd(cmd, sizeof(kData2)));
345 // Check that it fails if the offset is out of range.
346 cmd.Init(kBucketId, bucket->size(), 1);
347 EXPECT_NE(error::kNoError,
348 ExecuteImmediateCmd(cmd, sizeof(kData2)));
350 // Check that it fails if the size is out of range.
351 cmd.Init(kBucketId, 0, bucket->size() + 1);
352 EXPECT_NE(error::kNoError,
353 ExecuteImmediateCmd(cmd, sizeof(kData2)));
356 TEST_F(CommonDecoderTest, GetBucketStart) {
357 cmd::SetBucketSize size_cmd;
358 cmd::SetBucketData set_cmd;
359 cmd::GetBucketStart cmd;
361 static const char kData[] = "1234567890123456789";
362 static const char zero[sizeof(kData)] = { 0, };
364 const uint32 kBucketSize = sizeof(kData);
365 const uint32 kBucketId = 123;
366 const uint32 kInvalidBucketId = 124;
368 // Put data in the bucket.
369 size_cmd.Init(kBucketId, sizeof(kData));
370 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
371 const uint32 kSomeOffsetInSharedMemory = 50;
372 uint8* start = engine_.GetSharedMemoryAs<uint8*>(kSomeOffsetInSharedMemory);
373 memcpy(start, kData, sizeof(kData));
374 set_cmd.Init(kBucketId, 0, sizeof(kData),
375 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
376 EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd));
378 // Check that the size is correct with no data buffer.
379 uint32* memory =
380 engine_.GetSharedMemoryAs<uint32*>(kSomeOffsetInSharedMemory);
381 *memory = 0x0;
382 cmd.Init(kBucketId,
383 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
384 0, 0, 0);
385 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
386 EXPECT_EQ(kBucketSize, *memory);
388 // Check that the data is copied with data buffer.
389 const uint32 kDataOffsetInSharedMemory = 54;
390 uint8* data = engine_.GetSharedMemoryAs<uint8*>(kDataOffsetInSharedMemory);
391 *memory = 0x0;
392 memset(data, 0, sizeof(kData));
393 cmd.Init(kBucketId,
394 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
395 kBucketSize, MockCommandBufferEngine::kValidShmId,
396 kDataOffsetInSharedMemory);
397 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
398 EXPECT_EQ(kBucketSize, *memory);
399 EXPECT_EQ(0, memcmp(data, kData, kBucketSize));
401 // Check that we can get a piece.
402 *memory = 0x0;
403 memset(data, 0, sizeof(kData));
404 const uint32 kPieceSize = kBucketSize / 2;
405 cmd.Init(kBucketId,
406 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
407 kPieceSize, MockCommandBufferEngine::kValidShmId,
408 kDataOffsetInSharedMemory);
409 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
410 EXPECT_EQ(kBucketSize, *memory);
411 EXPECT_EQ(0, memcmp(data, kData, kPieceSize));
412 EXPECT_EQ(0, memcmp(data + kPieceSize, zero, sizeof(kData) - kPieceSize));
414 // Check that it fails if the result_id is invalid
415 cmd.Init(kInvalidBucketId,
416 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
417 0, 0, 0);
418 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
420 // Check that it fails if the data_id is invalid
421 cmd.Init(kBucketId,
422 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
423 1, MockCommandBufferEngine::kInvalidShmId, 0);
424 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
426 // Check that it fails if the data_size is invalid
427 cmd.Init(kBucketId,
428 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
429 1, 0, 0);
430 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
431 cmd.Init(kBucketId,
432 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
433 MockCommandBufferEngine::kBufferSize + 1,
434 MockCommandBufferEngine::kValidShmId, 0);
435 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
437 // Check that it fails if the data_offset is invalid
438 cmd.Init(kBucketId,
439 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
440 0, 0, 1);
441 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
442 cmd.Init(kBucketId,
443 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
444 MockCommandBufferEngine::kBufferSize,
445 MockCommandBufferEngine::kValidShmId, 1);
446 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
448 // Check that it fails if the result size is not set to zero
449 *memory = 0x1;
450 cmd.Init(kBucketId,
451 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
452 0, 0, 0);
453 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
456 TEST_F(CommonDecoderTest, GetBucketData) {
457 cmd::SetBucketSize size_cmd;
458 cmd::SetBucketData set_cmd;
459 cmd::GetBucketData cmd;
461 static const char kData[] = "1234567890123456789";
462 static const char zero[sizeof(kData)] = { 0, };
464 const uint32 kBucketId = 123;
465 const uint32 kInvalidBucketId = 124;
467 size_cmd.Init(kBucketId, sizeof(kData));
468 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
469 const uint32 kSomeOffsetInSharedMemory = 50;
470 uint8* memory = engine_.GetSharedMemoryAs<uint8*>(kSomeOffsetInSharedMemory);
471 memcpy(memory, kData, sizeof(kData));
472 set_cmd.Init(kBucketId, 0, sizeof(kData),
473 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
474 EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd));
476 // Check we can get the whole thing.
477 memset(memory, 0, sizeof(kData));
478 cmd.Init(kBucketId, 0, sizeof(kData),
479 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
480 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
481 EXPECT_EQ(0, memcmp(memory, kData, sizeof(kData)));
483 // Check we can get a piece.
484 const uint32 kSomeOffsetInBucket = 5;
485 const uint32 kLengthOfPiece = 6;
486 const uint8 kSentinel = 0xff;
487 memset(memory, 0, sizeof(kData));
488 memory[-1] = kSentinel;
489 cmd.Init(kBucketId, kSomeOffsetInBucket, kLengthOfPiece,
490 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
491 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
492 EXPECT_EQ(0, memcmp(memory, kData + kSomeOffsetInBucket, kLengthOfPiece));
493 EXPECT_EQ(0, memcmp(memory + kLengthOfPiece, zero,
494 sizeof(kData) - kLengthOfPiece));
495 EXPECT_EQ(kSentinel, memory[-1]);
497 // Check that it fails if the bucket_id is invalid
498 cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData),
499 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
500 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
502 // Check that it fails if the offset is invalid
503 cmd.Init(kBucketId, sizeof(kData) + 1, 1,
504 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
505 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
507 // Check that it fails if the size is invalid
508 cmd.Init(kBucketId, 0, sizeof(kData) + 1,
509 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
510 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
513 } // namespace gpu