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.
4
5// This file contains the tests for the CommandBufferSharedState class.
6
7#include "gpu/command_buffer/common/command_buffer_shared.h"
8#include "base/bind.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/threading/thread.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace gpu {
14
15class CommandBufferSharedTest : public testing::Test {
16 protected:
17
18  virtual void SetUp() {
19    shared_state_.reset(new CommandBufferSharedState());
20    shared_state_->Initialize();
21  }
22
23  scoped_ptr<CommandBufferSharedState> shared_state_;
24};
25
26TEST_F(CommandBufferSharedTest, TestBasic) {
27  CommandBuffer::State state;
28
29  shared_state_->Read(&state);
30
31  EXPECT_LT(state.generation, 0x80000000);
32  EXPECT_EQ(state.get_offset, 0);
33  EXPECT_EQ(state.put_offset, 0);
34  EXPECT_EQ(state.token, -1);
35  EXPECT_EQ(state.error, gpu::error::kNoError);
36  EXPECT_EQ(state.context_lost_reason, gpu::error::kUnknown);
37}
38
39static const int kSize = 100000;
40
41void WriteToState(int32 *buffer,
42                  CommandBufferSharedState* shared_state) {
43  CommandBuffer::State state;
44  for (int i = 0; i < kSize; i++) {
45    state.token = i - 1;
46    state.get_offset = i + 1;
47    state.generation = i + 2;
48    state.error = static_cast<gpu::error::Error>(i + 3);
49    // Ensure that the producer doesn't update the buffer until after the
50    // consumer reads from it.
51    EXPECT_EQ(buffer[i], 0);
52
53    shared_state->Write(state);
54  }
55}
56
57TEST_F(CommandBufferSharedTest, TestConsistency) {
58  scoped_ptr<int32[]> buffer;
59  buffer.reset(new int32[kSize]);
60  base::Thread consumer("Reader Thread");
61
62  memset(buffer.get(), 0, kSize * sizeof(int32));
63
64  consumer.Start();
65  consumer.message_loop()->PostTask(
66      FROM_HERE, base::Bind(&WriteToState, buffer.get(),
67                            shared_state_.get()));
68
69  CommandBuffer::State last_state;
70  while (1) {
71    CommandBuffer::State state = last_state;
72
73    shared_state_->Read(&state);
74
75    if (state.generation < last_state.generation)
76      continue;
77
78    if (state.get_offset >= 1) {
79      buffer[state.get_offset - 1] = 1;
80      // Check that the state is consistent
81      EXPECT_LE(last_state.token, state.token);
82      EXPECT_LE(last_state.generation, state.generation);
83      last_state = state;
84      EXPECT_EQ(state.token, state.get_offset - 2);
85      EXPECT_EQ(state.generation,
86                static_cast<unsigned int>(state.get_offset) + 1);
87      EXPECT_EQ(state.error, state.get_offset + 2);
88
89      if (state.get_offset == kSize)
90        break;
91    }
92  }
93}
94
95}  // namespace gpu
96
97