Fix crash in SpeechRecognizerImpl introduced in AudioParams refactor.
[chromium-blink-merge.git] / gpu / command_buffer / service / common_decoder_unittest.cc
blob31823ec0446e02c69d4cb9396003da961b1d6601
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 const char* GetCommandName(unsigned int command_id) const override {
55 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
58 // Overridden from AsyncAPIInterface
59 error::Error DoCommand(unsigned int command,
60 unsigned int arg_count,
61 const void* cmd_data) override {
62 return DoCommonCommand(command, arg_count, cmd_data);
65 CommonDecoder::Bucket* GetBucket(uint32 id) const {
66 return CommonDecoder::GetBucket(id);
70 class MockCommandBufferEngine : public CommandBufferEngine {
71 public:
72 static const int32 kStartValidShmId = 1;
73 static const int32 kValidShmId = 2;
74 static const int32 kInvalidShmId = 3;
75 static const size_t kBufferSize = 1024;
76 static const int32 kValidOffset = kBufferSize / 2;
77 static const int32 kInvalidOffset = kBufferSize;
79 MockCommandBufferEngine()
80 : CommandBufferEngine(),
81 token_(),
82 get_offset_(0) {
83 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
84 shared_memory->CreateAndMapAnonymous(kBufferSize);
85 buffer_ = MakeBufferFromSharedMemory(shared_memory.Pass(), kBufferSize);
88 // Overridden from CommandBufferEngine.
89 scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32 shm_id) override {
90 if (IsValidSharedMemoryId(shm_id))
91 return buffer_;
92 return NULL;
95 template <typename T>
96 T GetSharedMemoryAs(uint32 offset) {
97 DCHECK_LT(offset, kBufferSize);
98 int8* buffer_memory = static_cast<int8*>(buffer_->memory());
99 return reinterpret_cast<T>(&buffer_memory[offset]);
102 int32 GetSharedMemoryOffset(const void* memory) {
103 int8* buffer_memory = static_cast<int8*>(buffer_->memory());
104 ptrdiff_t offset = static_cast<const int8*>(memory) - &buffer_memory[0];
105 DCHECK_GE(offset, 0);
106 DCHECK_LT(static_cast<size_t>(offset), kBufferSize);
107 return static_cast<int32>(offset);
110 // Overridden from CommandBufferEngine.
111 void set_token(int32 token) override { token_ = token; }
113 int32 token() const {
114 return token_;
117 // Overridden from CommandBufferEngine.
118 bool SetGetBuffer(int32 transfer_buffer_id) override {
119 NOTREACHED();
120 return false;
123 // Overridden from CommandBufferEngine.
124 bool SetGetOffset(int32 offset) override {
125 if (static_cast<size_t>(offset) < kBufferSize) {
126 get_offset_ = offset;
127 return true;
129 return false;
132 // Overridden from CommandBufferEngine.
133 int32 GetGetOffset() override { return get_offset_; }
135 private:
136 bool IsValidSharedMemoryId(int32 shm_id) {
137 return shm_id == kValidShmId || shm_id == kStartValidShmId;
140 scoped_refptr<gpu::Buffer> buffer_;
141 int32 token_;
142 int32 get_offset_;
145 const int32 MockCommandBufferEngine::kStartValidShmId;
146 const int32 MockCommandBufferEngine::kValidShmId;
147 const int32 MockCommandBufferEngine::kInvalidShmId;
148 const size_t MockCommandBufferEngine::kBufferSize;
149 const int32 MockCommandBufferEngine::kValidOffset;
150 const int32 MockCommandBufferEngine::kInvalidOffset;
152 class CommonDecoderTest : public testing::Test {
153 protected:
154 void SetUp() override { decoder_.set_engine(&engine_); }
156 void TearDown() override {}
158 template <typename T>
159 error::Error ExecuteCmd(const T& cmd) {
160 static_assert(T::kArgFlags == cmd::kFixed,
161 "T::kArgFlags should equal cmd::kFixed");
162 return decoder_.DoCommands(
163 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd)), 0);
166 template <typename T>
167 error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) {
168 static_assert(T::kArgFlags == cmd::kAtLeastN,
169 "T::kArgFlags should equal cmd::kAtLeastN");
170 return decoder_.DoCommands(
171 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd) + data_size), 0);
174 MockCommandBufferEngine engine_;
175 TestCommonDecoder decoder_;
178 TEST_F(CommonDecoderTest, Initialize) {
179 EXPECT_EQ(0, engine_.GetGetOffset());
182 TEST_F(CommonDecoderTest, DoCommonCommandInvalidCommand) {
183 EXPECT_EQ(error::kUnknownCommand, decoder_.DoCommand(999999, 0, NULL));
186 TEST_F(CommonDecoderTest, HandleNoop) {
187 cmd::Noop cmd;
188 const uint32 kSkipCount = 5;
189 cmd.Init(kSkipCount);
190 EXPECT_EQ(error::kNoError,
191 ExecuteImmediateCmd(
192 cmd, kSkipCount * kCommandBufferEntrySize));
193 const uint32 kSkipCount2 = 1;
194 cmd.Init(kSkipCount2);
195 EXPECT_EQ(error::kNoError,
196 ExecuteImmediateCmd(
197 cmd, kSkipCount2 * kCommandBufferEntrySize));
200 TEST_F(CommonDecoderTest, SetToken) {
201 cmd::SetToken cmd;
202 const int32 kTokenId = 123;
203 EXPECT_EQ(0, engine_.token());
204 cmd.Init(kTokenId);
205 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
206 EXPECT_EQ(kTokenId, engine_.token());
209 TEST_F(CommonDecoderTest, SetBucketSize) {
210 cmd::SetBucketSize cmd;
211 const uint32 kBucketId = 123;
212 const uint32 kBucketLength1 = 1234;
213 const uint32 kBucketLength2 = 78;
214 // Check the bucket does not exist.
215 EXPECT_TRUE(NULL == decoder_.GetBucket(kBucketId));
216 // Check we can create one.
217 cmd.Init(kBucketId, kBucketLength1);
218 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
219 CommonDecoder::Bucket* bucket;
220 bucket = decoder_.GetBucket(kBucketId);
221 EXPECT_TRUE(NULL != bucket);
222 EXPECT_EQ(kBucketLength1, bucket->size());
223 // Check we can change it.
224 cmd.Init(kBucketId, kBucketLength2);
225 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
226 bucket = decoder_.GetBucket(kBucketId);
227 EXPECT_TRUE(NULL != bucket);
228 EXPECT_EQ(kBucketLength2, bucket->size());
229 // Check we can delete it.
230 cmd.Init(kBucketId, 0);
231 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
232 bucket = decoder_.GetBucket(kBucketId);
233 EXPECT_EQ(0u, bucket->size());
236 TEST_F(CommonDecoderTest, SetBucketData) {
237 cmd::SetBucketSize size_cmd;
238 cmd::SetBucketData cmd;
240 static const char kData[] = "1234567890123456789";
242 const uint32 kBucketId = 123;
243 const uint32 kInvalidBucketId = 124;
245 size_cmd.Init(kBucketId, sizeof(kData));
246 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
247 CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId);
248 // Check the data is not there.
249 EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
251 // Check we can set it.
252 const uint32 kSomeOffsetInSharedMemory = 50;
253 void* memory = engine_.GetSharedMemoryAs<void*>(kSomeOffsetInSharedMemory);
254 memcpy(memory, kData, sizeof(kData));
255 cmd.Init(kBucketId, 0, sizeof(kData),
256 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
257 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
258 EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
260 // Check we can set it partially.
261 static const char kData2[] = "ABCEDFG";
262 const uint32 kSomeOffsetInBucket = 5;
263 memcpy(memory, kData2, sizeof(kData2));
264 cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2),
265 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
266 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
267 EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)),
268 kData2, sizeof(kData2)));
269 const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData));
270 // Check that nothing was affected outside of updated area.
271 EXPECT_EQ(kData[kSomeOffsetInBucket - 1],
272 bucket_data[kSomeOffsetInBucket - 1]);
273 EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)],
274 bucket_data[kSomeOffsetInBucket + sizeof(kData2)]);
276 // Check that it fails if the bucket_id is invalid
277 cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2),
278 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
279 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
281 // Check that it fails if the offset is out of range.
282 cmd.Init(kBucketId, bucket->size(), 1,
283 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
284 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
286 // Check that it fails if the size is out of range.
287 cmd.Init(kBucketId, 0, bucket->size() + 1,
288 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
289 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
292 TEST_F(CommonDecoderTest, SetBucketDataImmediate) {
293 cmd::SetBucketSize size_cmd;
294 int8 buffer[1024];
295 cmd::SetBucketDataImmediate& cmd =
296 *reinterpret_cast<cmd::SetBucketDataImmediate*>(&buffer);
298 static const char kData[] = "1234567890123456789";
300 const uint32 kBucketId = 123;
301 const uint32 kInvalidBucketId = 124;
303 size_cmd.Init(kBucketId, sizeof(kData));
304 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
305 CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId);
306 // Check the data is not there.
307 EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
309 // Check we can set it.
310 void* memory = &buffer[0] + sizeof(cmd);
311 memcpy(memory, kData, sizeof(kData));
312 cmd.Init(kBucketId, 0, sizeof(kData));
313 EXPECT_EQ(error::kNoError,
314 ExecuteImmediateCmd(cmd, sizeof(kData)));
315 EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
317 // Check we can set it partially.
318 static const char kData2[] = "ABCEDFG";
319 const uint32 kSomeOffsetInBucket = 5;
320 memcpy(memory, kData2, sizeof(kData2));
321 cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2));
322 EXPECT_EQ(error::kNoError,
323 ExecuteImmediateCmd(cmd, sizeof(kData2)));
324 EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)),
325 kData2, sizeof(kData2)));
326 const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData));
327 // Check that nothing was affected outside of updated area.
328 EXPECT_EQ(kData[kSomeOffsetInBucket - 1],
329 bucket_data[kSomeOffsetInBucket - 1]);
330 EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)],
331 bucket_data[kSomeOffsetInBucket + sizeof(kData2)]);
333 // Check that it fails if the bucket_id is invalid
334 cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2));
335 EXPECT_NE(error::kNoError,
336 ExecuteImmediateCmd(cmd, sizeof(kData2)));
338 // Check that it fails if the offset is out of range.
339 cmd.Init(kBucketId, bucket->size(), 1);
340 EXPECT_NE(error::kNoError,
341 ExecuteImmediateCmd(cmd, sizeof(kData2)));
343 // Check that it fails if the size is out of range.
344 cmd.Init(kBucketId, 0, bucket->size() + 1);
345 EXPECT_NE(error::kNoError,
346 ExecuteImmediateCmd(cmd, sizeof(kData2)));
349 TEST_F(CommonDecoderTest, GetBucketStart) {
350 cmd::SetBucketSize size_cmd;
351 cmd::SetBucketData set_cmd;
352 cmd::GetBucketStart cmd;
354 static const char kData[] = "1234567890123456789";
355 static const char zero[sizeof(kData)] = { 0, };
357 const uint32 kBucketSize = sizeof(kData);
358 const uint32 kBucketId = 123;
359 const uint32 kInvalidBucketId = 124;
361 // Put data in the bucket.
362 size_cmd.Init(kBucketId, sizeof(kData));
363 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
364 const uint32 kSomeOffsetInSharedMemory = 50;
365 uint8* start = engine_.GetSharedMemoryAs<uint8*>(kSomeOffsetInSharedMemory);
366 memcpy(start, kData, sizeof(kData));
367 set_cmd.Init(kBucketId, 0, sizeof(kData),
368 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
369 EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd));
371 // Check that the size is correct with no data buffer.
372 uint32* memory =
373 engine_.GetSharedMemoryAs<uint32*>(kSomeOffsetInSharedMemory);
374 *memory = 0x0;
375 cmd.Init(kBucketId,
376 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
377 0, 0, 0);
378 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
379 EXPECT_EQ(kBucketSize, *memory);
381 // Check that the data is copied with data buffer.
382 const uint32 kDataOffsetInSharedMemory = 54;
383 uint8* data = engine_.GetSharedMemoryAs<uint8*>(kDataOffsetInSharedMemory);
384 *memory = 0x0;
385 memset(data, 0, sizeof(kData));
386 cmd.Init(kBucketId,
387 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
388 kBucketSize, MockCommandBufferEngine::kValidShmId,
389 kDataOffsetInSharedMemory);
390 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
391 EXPECT_EQ(kBucketSize, *memory);
392 EXPECT_EQ(0, memcmp(data, kData, kBucketSize));
394 // Check that we can get a piece.
395 *memory = 0x0;
396 memset(data, 0, sizeof(kData));
397 const uint32 kPieceSize = kBucketSize / 2;
398 cmd.Init(kBucketId,
399 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
400 kPieceSize, MockCommandBufferEngine::kValidShmId,
401 kDataOffsetInSharedMemory);
402 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
403 EXPECT_EQ(kBucketSize, *memory);
404 EXPECT_EQ(0, memcmp(data, kData, kPieceSize));
405 EXPECT_EQ(0, memcmp(data + kPieceSize, zero, sizeof(kData) - kPieceSize));
407 // Check that it fails if the result_id is invalid
408 cmd.Init(kInvalidBucketId,
409 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
410 0, 0, 0);
411 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
413 // Check that it fails if the data_id is invalid
414 cmd.Init(kBucketId,
415 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
416 1, MockCommandBufferEngine::kInvalidShmId, 0);
417 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
419 // Check that it fails if the data_size is invalid
420 cmd.Init(kBucketId,
421 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
422 1, 0, 0);
423 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
424 cmd.Init(kBucketId,
425 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
426 MockCommandBufferEngine::kBufferSize + 1,
427 MockCommandBufferEngine::kValidShmId, 0);
428 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
430 // Check that it fails if the data_offset is invalid
431 cmd.Init(kBucketId,
432 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
433 0, 0, 1);
434 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
435 cmd.Init(kBucketId,
436 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
437 MockCommandBufferEngine::kBufferSize,
438 MockCommandBufferEngine::kValidShmId, 1);
439 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
441 // Check that it fails if the result size is not set to zero
442 *memory = 0x1;
443 cmd.Init(kBucketId,
444 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
445 0, 0, 0);
446 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
449 TEST_F(CommonDecoderTest, GetBucketData) {
450 cmd::SetBucketSize size_cmd;
451 cmd::SetBucketData set_cmd;
452 cmd::GetBucketData cmd;
454 static const char kData[] = "1234567890123456789";
455 static const char zero[sizeof(kData)] = { 0, };
457 const uint32 kBucketId = 123;
458 const uint32 kInvalidBucketId = 124;
460 size_cmd.Init(kBucketId, sizeof(kData));
461 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
462 const uint32 kSomeOffsetInSharedMemory = 50;
463 uint8* memory = engine_.GetSharedMemoryAs<uint8*>(kSomeOffsetInSharedMemory);
464 memcpy(memory, kData, sizeof(kData));
465 set_cmd.Init(kBucketId, 0, sizeof(kData),
466 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
467 EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd));
469 // Check we can get the whole thing.
470 memset(memory, 0, sizeof(kData));
471 cmd.Init(kBucketId, 0, sizeof(kData),
472 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
473 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
474 EXPECT_EQ(0, memcmp(memory, kData, sizeof(kData)));
476 // Check we can get a piece.
477 const uint32 kSomeOffsetInBucket = 5;
478 const uint32 kLengthOfPiece = 6;
479 const uint8 kSentinel = 0xff;
480 memset(memory, 0, sizeof(kData));
481 memory[-1] = kSentinel;
482 cmd.Init(kBucketId, kSomeOffsetInBucket, kLengthOfPiece,
483 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
484 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
485 EXPECT_EQ(0, memcmp(memory, kData + kSomeOffsetInBucket, kLengthOfPiece));
486 EXPECT_EQ(0, memcmp(memory + kLengthOfPiece, zero,
487 sizeof(kData) - kLengthOfPiece));
488 EXPECT_EQ(kSentinel, memory[-1]);
490 // Check that it fails if the bucket_id is invalid
491 cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData),
492 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
493 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
495 // Check that it fails if the offset is invalid
496 cmd.Init(kBucketId, sizeof(kData) + 1, 1,
497 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
498 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
500 // Check that it fails if the size is invalid
501 cmd.Init(kBucketId, 0, sizeof(kData) + 1,
502 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
503 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
506 } // namespace gpu