Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / gpu / command_buffer / client / query_tracker_unittest.cc
blobcba94d1d01ccc49974bfb82162b26667927cc5d4
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 // Tests for the QueryTracker.
7 #include "gpu/command_buffer/client/query_tracker.h"
9 #include <GLES2/gl2ext.h>
11 #include <vector>
13 #include "base/memory/scoped_ptr.h"
14 #include "gpu/command_buffer/client/client_test_helper.h"
15 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
16 #include "gpu/command_buffer/client/mapped_memory.h"
17 #include "gpu/command_buffer/common/command_buffer.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/gmock/include/gmock/gmock.h"
21 namespace gpu {
22 namespace gles2 {
24 namespace {
25 void EmptyPoll() {
29 class QuerySyncManagerTest : public testing::Test {
30 protected:
31 static const int32 kNumCommandEntries = 400;
32 static const int32 kCommandBufferSizeBytes =
33 kNumCommandEntries * sizeof(CommandBufferEntry);
35 void SetUp() override {
36 command_buffer_.reset(new MockClientCommandBuffer());
37 helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
38 helper_->Initialize(kCommandBufferSizeBytes);
39 mapped_memory_.reset(new MappedMemoryManager(
40 helper_.get(), base::Bind(&EmptyPoll), MappedMemoryManager::kNoLimit));
41 sync_manager_.reset(new QuerySyncManager(mapped_memory_.get()));
44 void TearDown() override {
45 sync_manager_.reset();
46 mapped_memory_.reset();
47 helper_.reset();
48 command_buffer_.reset();
51 scoped_ptr<CommandBuffer> command_buffer_;
52 scoped_ptr<GLES2CmdHelper> helper_;
53 scoped_ptr<MappedMemoryManager> mapped_memory_;
54 scoped_ptr<QuerySyncManager> sync_manager_;
57 TEST_F(QuerySyncManagerTest, Basic) {
58 QuerySyncManager::QueryInfo infos[4];
59 memset(&infos, 0xBD, sizeof(infos));
61 for (size_t ii = 0; ii < arraysize(infos); ++ii) {
62 EXPECT_TRUE(sync_manager_->Alloc(&infos[ii]));
63 EXPECT_NE(0, infos[ii].shm_id);
64 ASSERT_TRUE(infos[ii].sync != NULL);
65 EXPECT_EQ(0, infos[ii].sync->process_count);
66 EXPECT_EQ(0u, infos[ii].sync->result);
69 for (size_t ii = 0; ii < arraysize(infos); ++ii) {
70 sync_manager_->Free(infos[ii]);
74 TEST_F(QuerySyncManagerTest, DontFree) {
75 QuerySyncManager::QueryInfo infos[4];
76 memset(&infos, 0xBD, sizeof(infos));
78 for (size_t ii = 0; ii < arraysize(infos); ++ii) {
79 EXPECT_TRUE(sync_manager_->Alloc(&infos[ii]));
83 class QueryTrackerTest : public testing::Test {
84 protected:
85 static const int32 kNumCommandEntries = 400;
86 static const int32 kCommandBufferSizeBytes =
87 kNumCommandEntries * sizeof(CommandBufferEntry);
89 void SetUp() override {
90 command_buffer_.reset(new MockClientCommandBuffer());
91 helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
92 helper_->Initialize(kCommandBufferSizeBytes);
93 mapped_memory_.reset(new MappedMemoryManager(
94 helper_.get(), base::Bind(&EmptyPoll), MappedMemoryManager::kNoLimit));
95 query_tracker_.reset(new QueryTracker(mapped_memory_.get()));
98 void TearDown() override {
99 query_tracker_.reset();
100 mapped_memory_.reset();
101 helper_.reset();
102 command_buffer_.reset();
105 QuerySync* GetSync(QueryTracker::Query* query) {
106 return query->info_.sync;
109 QuerySyncManager::Bucket* GetBucket(QueryTracker::Query* query) {
110 return query->info_.bucket;
113 uint32 GetBucketUsedCount(QuerySyncManager::Bucket* bucket) {
114 return bucket->in_use_queries.count();
117 uint32 GetFlushGeneration() { return helper_->flush_generation(); }
119 scoped_ptr<CommandBuffer> command_buffer_;
120 scoped_ptr<GLES2CmdHelper> helper_;
121 scoped_ptr<MappedMemoryManager> mapped_memory_;
122 scoped_ptr<QueryTracker> query_tracker_;
125 TEST_F(QueryTrackerTest, Basic) {
126 const GLuint kId1 = 123;
127 const GLuint kId2 = 124;
129 // Check we can create a Query.
130 QueryTracker::Query* query = query_tracker_->CreateQuery(
131 kId1, GL_ANY_SAMPLES_PASSED_EXT);
132 ASSERT_TRUE(query != NULL);
133 // Check we can get the same Query.
134 EXPECT_EQ(query, query_tracker_->GetQuery(kId1));
135 // Check we get nothing for a non-existent query.
136 EXPECT_TRUE(query_tracker_->GetQuery(kId2) == NULL);
137 // Check we can delete the query.
138 query_tracker_->RemoveQuery(kId1);
139 // Check we get nothing for a non-existent query.
140 EXPECT_TRUE(query_tracker_->GetQuery(kId1) == NULL);
143 TEST_F(QueryTrackerTest, Query) {
144 const GLuint kId1 = 123;
145 const int32 kToken = 46;
146 const uint32 kResult = 456;
148 // Create a Query.
149 QueryTracker::Query* query = query_tracker_->CreateQuery(
150 kId1, GL_ANY_SAMPLES_PASSED_EXT);
151 ASSERT_TRUE(query != NULL);
152 EXPECT_TRUE(query->NeverUsed());
153 EXPECT_FALSE(query->Pending());
154 EXPECT_EQ(0, query->token());
155 EXPECT_EQ(0, query->submit_count());
157 // Check MarkAsActive.
158 query->MarkAsActive();
159 EXPECT_FALSE(query->NeverUsed());
160 EXPECT_FALSE(query->Pending());
161 EXPECT_EQ(0, query->token());
162 EXPECT_EQ(1, query->submit_count());
164 // Check MarkAsPending.
165 query->MarkAsPending(kToken);
166 EXPECT_FALSE(query->NeverUsed());
167 EXPECT_TRUE(query->Pending());
168 EXPECT_EQ(kToken, query->token());
169 EXPECT_EQ(1, query->submit_count());
171 // Flush only once if no more flushes happened between a call to
172 // EndQuery command and CheckResultsAvailable
173 // Advance put_ so flush calls in CheckResultsAvailable go through
174 // and updates flush_generation count
175 helper_->Noop(1);
177 // Store FlushGeneration count after EndQuery is called
178 uint32 gen1 = GetFlushGeneration();
180 // Check CheckResultsAvailable.
181 EXPECT_FALSE(query->CheckResultsAvailable(helper_.get()));
182 EXPECT_FALSE(query->NeverUsed());
183 EXPECT_TRUE(query->Pending());
185 uint32 gen2 = GetFlushGeneration();
186 EXPECT_NE(gen1, gen2);
188 // Repeated calls to CheckResultsAvailable should not flush unnecessarily
189 EXPECT_FALSE(query->CheckResultsAvailable(helper_.get()));
190 gen1 = GetFlushGeneration();
191 EXPECT_EQ(gen1, gen2);
192 EXPECT_FALSE(query->CheckResultsAvailable(helper_.get()));
193 gen1 = GetFlushGeneration();
194 EXPECT_EQ(gen1, gen2);
196 // Simulate GPU process marking it as available.
197 QuerySync* sync = GetSync(query);
198 sync->process_count = query->submit_count();
199 sync->result = kResult;
201 // Check CheckResultsAvailable.
202 EXPECT_TRUE(query->CheckResultsAvailable(helper_.get()));
203 EXPECT_EQ(kResult, query->GetResult());
204 EXPECT_FALSE(query->NeverUsed());
205 EXPECT_FALSE(query->Pending());
208 TEST_F(QueryTrackerTest, Remove) {
209 const GLuint kId1 = 123;
210 const int32 kToken = 46;
211 const uint32 kResult = 456;
213 // Create a Query.
214 QueryTracker::Query* query = query_tracker_->CreateQuery(
215 kId1, GL_ANY_SAMPLES_PASSED_EXT);
216 ASSERT_TRUE(query != NULL);
218 QuerySyncManager::Bucket* bucket = GetBucket(query);
219 EXPECT_EQ(1u, GetBucketUsedCount(bucket));
221 query->MarkAsActive();
222 query->MarkAsPending(kToken);
224 query_tracker_->RemoveQuery(kId1);
225 // Check we get nothing for a non-existent query.
226 EXPECT_TRUE(query_tracker_->GetQuery(kId1) == NULL);
228 // Check that memory was not freed.
229 EXPECT_EQ(1u, GetBucketUsedCount(bucket));
231 // Simulate GPU process marking it as available.
232 QuerySync* sync = GetSync(query);
233 sync->process_count = query->submit_count();
234 sync->result = kResult;
236 // Check FreeCompletedQueries.
237 query_tracker_->FreeCompletedQueries();
238 EXPECT_EQ(0u, GetBucketUsedCount(bucket));
241 TEST_F(QueryTrackerTest, ManyQueries) {
242 const GLuint kId1 = 123;
243 const int32 kToken = 46;
244 const uint32 kResult = 456;
246 const size_t kTestSize = 4000;
247 static_assert(kTestSize > QuerySyncManager::kSyncsPerBucket,
248 "We want to use more than one bucket");
249 // Create lots of queries.
250 std::vector<QueryTracker::Query*> queries;
251 for (size_t i = 0; i < kTestSize; i++) {
252 QueryTracker::Query* query =
253 query_tracker_->CreateQuery(kId1 + i, GL_ANY_SAMPLES_PASSED_EXT);
254 ASSERT_TRUE(query != NULL);
255 queries.push_back(query);
256 QuerySyncManager::Bucket* bucket = GetBucket(query);
257 EXPECT_LE(1u, GetBucketUsedCount(bucket));
260 QuerySyncManager::Bucket* query_0_bucket = GetBucket(queries[0]);
261 uint32 expected_use_count = QuerySyncManager::kSyncsPerBucket;
262 EXPECT_EQ(expected_use_count, GetBucketUsedCount(query_0_bucket));
264 while (!queries.empty()) {
265 QueryTracker::Query* query = queries.back();
266 queries.pop_back();
267 GLuint query_id = kId1 + queries.size();
268 EXPECT_EQ(query_id, query->id());
269 query->MarkAsActive();
270 query->MarkAsPending(kToken);
272 QuerySyncManager::Bucket* bucket = GetBucket(query);
273 uint32 use_count_before_remove = GetBucketUsedCount(bucket);
274 query_tracker_->FreeCompletedQueries();
275 EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket));
276 query_tracker_->RemoveQuery(query_id);
277 // Check we get nothing for a non-existent query.
278 EXPECT_TRUE(query_tracker_->GetQuery(query_id) == NULL);
280 // Check that memory was not freed since it was not completed.
281 EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket));
283 // Simulate GPU process marking it as available.
284 QuerySync* sync = GetSync(query);
285 sync->process_count = query->submit_count();
286 sync->result = kResult;
288 // Check FreeCompletedQueries.
289 query_tracker_->FreeCompletedQueries();
290 EXPECT_EQ(use_count_before_remove - 1, GetBucketUsedCount(bucket));
294 } // namespace gles2
295 } // namespace gpu