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// Tests for the BufferTracker.
6
7#include "gpu/command_buffer/client/buffer_tracker.h"
8
9#include <GLES2/gl2ext.h>
10#include "base/memory/scoped_ptr.h"
11#include "gpu/command_buffer/client/client_test_helper.h"
12#include "gpu/command_buffer/client/gles2_cmd_helper.h"
13#include "gpu/command_buffer/client/mapped_memory.h"
14#include "gpu/command_buffer/common/command_buffer.h"
15#include "testing/gmock/include/gmock/gmock.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18namespace gpu {
19namespace gles2 {
20
21class MockClientCommandBufferImpl : public MockClientCommandBuffer {
22 public:
23  MockClientCommandBufferImpl()
24      : MockClientCommandBuffer(),
25        context_lost_(false) {}
26  virtual ~MockClientCommandBufferImpl() {}
27
28  virtual scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
29                                                          int32* id) OVERRIDE {
30    if (context_lost_) {
31      *id = -1;
32      return NULL;
33    }
34    return MockClientCommandBuffer::CreateTransferBuffer(size, id);
35  }
36
37  void set_context_lost(bool context_lost) {
38    context_lost_ = context_lost;
39  }
40
41 private:
42  bool context_lost_;
43};
44
45namespace {
46void EmptyPoll() {
47}
48}
49
50class BufferTrackerTest : public testing::Test {
51 protected:
52  static const int32 kNumCommandEntries = 400;
53  static const int32 kCommandBufferSizeBytes =
54      kNumCommandEntries * sizeof(CommandBufferEntry);
55
56  virtual void SetUp() {
57    command_buffer_.reset(new MockClientCommandBufferImpl());
58    helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
59    helper_->Initialize(kCommandBufferSizeBytes);
60    mapped_memory_.reset(new MappedMemoryManager(
61        helper_.get(), base::Bind(&EmptyPoll), MappedMemoryManager::kNoLimit));
62    buffer_tracker_.reset(new BufferTracker(mapped_memory_.get()));
63  }
64
65  virtual void TearDown() {
66    buffer_tracker_.reset();
67    mapped_memory_.reset();
68    helper_.reset();
69    command_buffer_.reset();
70  }
71
72  scoped_ptr<MockClientCommandBufferImpl> command_buffer_;
73  scoped_ptr<GLES2CmdHelper> helper_;
74  scoped_ptr<MappedMemoryManager> mapped_memory_;
75  scoped_ptr<BufferTracker> buffer_tracker_;
76};
77
78TEST_F(BufferTrackerTest, Basic) {
79  const GLuint kId1 = 123;
80  const GLuint kId2 = 124;
81  const GLsizeiptr size = 64;
82
83  // Check we can create a Buffer.
84  BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer(kId1, size);
85  ASSERT_TRUE(buffer != NULL);
86  // Check we can get the same Buffer.
87  EXPECT_EQ(buffer, buffer_tracker_->GetBuffer(kId1));
88  // Check mapped memory address.
89  EXPECT_TRUE(buffer->address() != NULL);
90  // Check shared memory was allocated.
91  EXPECT_EQ(1lu, mapped_memory_->num_chunks());
92  // Check we get nothing for a non-existent buffer.
93  EXPECT_TRUE(buffer_tracker_->GetBuffer(kId2) == NULL);
94  // Check we can delete the buffer.
95  buffer_tracker_->RemoveBuffer(kId1);
96  // Check shared memory was freed.
97  mapped_memory_->FreeUnused();
98  EXPECT_EQ(0lu, mapped_memory_->num_chunks());
99  // Check we get nothing for a non-existent buffer.
100  EXPECT_TRUE(buffer_tracker_->GetBuffer(kId1) == NULL);
101}
102
103TEST_F(BufferTrackerTest, ZeroSize) {
104  const GLuint kId = 123;
105
106  // Check we can create a Buffer with zero size.
107  BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer(kId, 0);
108  ASSERT_TRUE(buffer != NULL);
109  // Check mapped memory address.
110  EXPECT_TRUE(buffer->address() == NULL);
111  // Check no shared memory was allocated.
112  EXPECT_EQ(0lu, mapped_memory_->num_chunks());
113  // Check we can delete the buffer.
114  buffer_tracker_->RemoveBuffer(kId);
115}
116
117TEST_F(BufferTrackerTest, LostContext) {
118  const GLuint kId = 123;
119  const GLsizeiptr size = 64;
120
121  command_buffer_->set_context_lost(true);
122  // Check we can create a Buffer when after losing context.
123  BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer(kId, size);
124  ASSERT_TRUE(buffer != NULL);
125  // Check mapped memory address.
126  EXPECT_EQ(64u, buffer->size());
127  // Check mapped memory address.
128  EXPECT_TRUE(buffer->address() == NULL);
129  // Check no shared memory was allocated.
130  EXPECT_EQ(0lu, mapped_memory_->num_chunks());
131  // Check we can delete the buffer.
132  buffer_tracker_->RemoveBuffer(kId);
133}
134
135TEST_F(BufferTrackerTest, Unmanage) {
136  const GLuint kId = 123;
137  const GLsizeiptr size = 64;
138
139  BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer(kId, size);
140  ASSERT_TRUE(buffer != NULL);
141  EXPECT_EQ(mapped_memory_->bytes_in_use(), static_cast<size_t>(size));
142
143  void* mem = buffer->address();
144  buffer_tracker_->Unmanage(buffer);
145  buffer_tracker_->RemoveBuffer(kId);
146  EXPECT_EQ(mapped_memory_->bytes_in_use(), static_cast<size_t>(size));
147
148  mapped_memory_->Free(mem);
149  EXPECT_EQ(mapped_memory_->bytes_in_use(), static_cast<size_t>(0));
150}
151
152}  // namespace gles2
153}  // namespace gpu
154