| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Tests for the QueryTracker. | 5 // Tests for the QueryTracker. |
| 6 | 6 |
| 7 #include "gpu/command_buffer/client/query_tracker.h" | 7 #include "gpu/command_buffer/client/query_tracker.h" |
| 8 | 8 |
| 9 #include <GLES2/gl2ext.h> | 9 #include <GLES2/gl2ext.h> |
| 10 #include <stddef.h> |
| 11 #include <stdint.h> |
| 10 | 12 |
| 11 #include <vector> | 13 #include <vector> |
| 12 | 14 |
| 13 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 14 #include "gpu/command_buffer/client/client_test_helper.h" | 16 #include "gpu/command_buffer/client/client_test_helper.h" |
| 15 #include "gpu/command_buffer/client/gles2_cmd_helper.h" | 17 #include "gpu/command_buffer/client/gles2_cmd_helper.h" |
| 16 #include "gpu/command_buffer/client/mapped_memory.h" | 18 #include "gpu/command_buffer/client/mapped_memory.h" |
| 17 #include "gpu/command_buffer/common/command_buffer.h" | 19 #include "gpu/command_buffer/common/command_buffer.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" | |
| 20 | 22 |
| 21 namespace gpu { | 23 namespace gpu { |
| 22 namespace gles2 { | 24 namespace gles2 { |
| 23 | 25 |
| 24 class QuerySyncManagerTest : public testing::Test { | 26 class QuerySyncManagerTest : public testing::Test { |
| 25 protected: | 27 protected: |
| 26 static const int32 kNumCommandEntries = 400; | 28 static const int32_t kNumCommandEntries = 400; |
| 27 static const int32 kCommandBufferSizeBytes = | 29 static const int32_t kCommandBufferSizeBytes = |
| 28 kNumCommandEntries * sizeof(CommandBufferEntry); | 30 kNumCommandEntries * sizeof(CommandBufferEntry); |
| 29 | 31 |
| 30 void SetUp() override { | 32 void SetUp() override { |
| 31 command_buffer_.reset(new MockClientCommandBuffer()); | 33 command_buffer_.reset(new MockClientCommandBuffer()); |
| 32 helper_.reset(new GLES2CmdHelper(command_buffer_.get())); | 34 helper_.reset(new GLES2CmdHelper(command_buffer_.get())); |
| 33 helper_->Initialize(kCommandBufferSizeBytes); | 35 helper_->Initialize(kCommandBufferSizeBytes); |
| 34 mapped_memory_.reset( | 36 mapped_memory_.reset( |
| 35 new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit)); | 37 new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit)); |
| 36 sync_manager_.reset(new QuerySyncManager(mapped_memory_.get())); | 38 sync_manager_.reset(new QuerySyncManager(mapped_memory_.get())); |
| 37 } | 39 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 QuerySyncManager::QueryInfo infos[4]; | 72 QuerySyncManager::QueryInfo infos[4]; |
| 71 memset(&infos, 0xBD, sizeof(infos)); | 73 memset(&infos, 0xBD, sizeof(infos)); |
| 72 | 74 |
| 73 for (size_t ii = 0; ii < arraysize(infos); ++ii) { | 75 for (size_t ii = 0; ii < arraysize(infos); ++ii) { |
| 74 EXPECT_TRUE(sync_manager_->Alloc(&infos[ii])); | 76 EXPECT_TRUE(sync_manager_->Alloc(&infos[ii])); |
| 75 } | 77 } |
| 76 } | 78 } |
| 77 | 79 |
| 78 class QueryTrackerTest : public testing::Test { | 80 class QueryTrackerTest : public testing::Test { |
| 79 protected: | 81 protected: |
| 80 static const int32 kNumCommandEntries = 400; | 82 static const int32_t kNumCommandEntries = 400; |
| 81 static const int32 kCommandBufferSizeBytes = | 83 static const int32_t kCommandBufferSizeBytes = |
| 82 kNumCommandEntries * sizeof(CommandBufferEntry); | 84 kNumCommandEntries * sizeof(CommandBufferEntry); |
| 83 | 85 |
| 84 void SetUp() override { | 86 void SetUp() override { |
| 85 command_buffer_.reset(new MockClientCommandBuffer()); | 87 command_buffer_.reset(new MockClientCommandBuffer()); |
| 86 helper_.reset(new GLES2CmdHelper(command_buffer_.get())); | 88 helper_.reset(new GLES2CmdHelper(command_buffer_.get())); |
| 87 helper_->Initialize(kCommandBufferSizeBytes); | 89 helper_->Initialize(kCommandBufferSizeBytes); |
| 88 mapped_memory_.reset( | 90 mapped_memory_.reset( |
| 89 new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit)); | 91 new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit)); |
| 90 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 92 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
| 91 } | 93 } |
| 92 | 94 |
| 93 void TearDown() override { | 95 void TearDown() override { |
| 94 query_tracker_.reset(); | 96 query_tracker_.reset(); |
| 95 mapped_memory_.reset(); | 97 mapped_memory_.reset(); |
| 96 helper_.reset(); | 98 helper_.reset(); |
| 97 command_buffer_.reset(); | 99 command_buffer_.reset(); |
| 98 } | 100 } |
| 99 | 101 |
| 100 QuerySync* GetSync(QueryTracker::Query* query) { | 102 QuerySync* GetSync(QueryTracker::Query* query) { |
| 101 return query->info_.sync; | 103 return query->info_.sync; |
| 102 } | 104 } |
| 103 | 105 |
| 104 QuerySyncManager::Bucket* GetBucket(QueryTracker::Query* query) { | 106 QuerySyncManager::Bucket* GetBucket(QueryTracker::Query* query) { |
| 105 return query->info_.bucket; | 107 return query->info_.bucket; |
| 106 } | 108 } |
| 107 | 109 |
| 108 uint32 GetBucketUsedCount(QuerySyncManager::Bucket* bucket) { | 110 uint32_t GetBucketUsedCount(QuerySyncManager::Bucket* bucket) { |
| 109 return bucket->in_use_queries.count(); | 111 return bucket->in_use_queries.count(); |
| 110 } | 112 } |
| 111 | 113 |
| 112 uint32 GetFlushGeneration() { return helper_->flush_generation(); } | 114 uint32_t GetFlushGeneration() { return helper_->flush_generation(); } |
| 113 | 115 |
| 114 scoped_ptr<CommandBuffer> command_buffer_; | 116 scoped_ptr<CommandBuffer> command_buffer_; |
| 115 scoped_ptr<GLES2CmdHelper> helper_; | 117 scoped_ptr<GLES2CmdHelper> helper_; |
| 116 scoped_ptr<MappedMemoryManager> mapped_memory_; | 118 scoped_ptr<MappedMemoryManager> mapped_memory_; |
| 117 scoped_ptr<QueryTracker> query_tracker_; | 119 scoped_ptr<QueryTracker> query_tracker_; |
| 118 }; | 120 }; |
| 119 | 121 |
| 120 TEST_F(QueryTrackerTest, Basic) { | 122 TEST_F(QueryTrackerTest, Basic) { |
| 121 const GLuint kId1 = 123; | 123 const GLuint kId1 = 123; |
| 122 const GLuint kId2 = 124; | 124 const GLuint kId2 = 124; |
| 123 | 125 |
| 124 // Check we can create a Query. | 126 // Check we can create a Query. |
| 125 QueryTracker::Query* query = query_tracker_->CreateQuery( | 127 QueryTracker::Query* query = query_tracker_->CreateQuery( |
| 126 kId1, GL_ANY_SAMPLES_PASSED_EXT); | 128 kId1, GL_ANY_SAMPLES_PASSED_EXT); |
| 127 ASSERT_TRUE(query != NULL); | 129 ASSERT_TRUE(query != NULL); |
| 128 // Check we can get the same Query. | 130 // Check we can get the same Query. |
| 129 EXPECT_EQ(query, query_tracker_->GetQuery(kId1)); | 131 EXPECT_EQ(query, query_tracker_->GetQuery(kId1)); |
| 130 // Check we get nothing for a non-existent query. | 132 // Check we get nothing for a non-existent query. |
| 131 EXPECT_TRUE(query_tracker_->GetQuery(kId2) == NULL); | 133 EXPECT_TRUE(query_tracker_->GetQuery(kId2) == NULL); |
| 132 // Check we can delete the query. | 134 // Check we can delete the query. |
| 133 query_tracker_->RemoveQuery(kId1); | 135 query_tracker_->RemoveQuery(kId1); |
| 134 // Check we get nothing for a non-existent query. | 136 // Check we get nothing for a non-existent query. |
| 135 EXPECT_TRUE(query_tracker_->GetQuery(kId1) == NULL); | 137 EXPECT_TRUE(query_tracker_->GetQuery(kId1) == NULL); |
| 136 } | 138 } |
| 137 | 139 |
| 138 TEST_F(QueryTrackerTest, Query) { | 140 TEST_F(QueryTrackerTest, Query) { |
| 139 const GLuint kId1 = 123; | 141 const GLuint kId1 = 123; |
| 140 const int32 kToken = 46; | 142 const int32_t kToken = 46; |
| 141 const uint32 kResult = 456; | 143 const uint32_t kResult = 456; |
| 142 | 144 |
| 143 // Create a Query. | 145 // Create a Query. |
| 144 QueryTracker::Query* query = query_tracker_->CreateQuery( | 146 QueryTracker::Query* query = query_tracker_->CreateQuery( |
| 145 kId1, GL_ANY_SAMPLES_PASSED_EXT); | 147 kId1, GL_ANY_SAMPLES_PASSED_EXT); |
| 146 ASSERT_TRUE(query != NULL); | 148 ASSERT_TRUE(query != NULL); |
| 147 EXPECT_TRUE(query->NeverUsed()); | 149 EXPECT_TRUE(query->NeverUsed()); |
| 148 EXPECT_FALSE(query->Pending()); | 150 EXPECT_FALSE(query->Pending()); |
| 149 EXPECT_EQ(0, query->token()); | 151 EXPECT_EQ(0, query->token()); |
| 150 EXPECT_EQ(0, query->submit_count()); | 152 EXPECT_EQ(0, query->submit_count()); |
| 151 | 153 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 163 EXPECT_EQ(kToken, query->token()); | 165 EXPECT_EQ(kToken, query->token()); |
| 164 EXPECT_EQ(1, query->submit_count()); | 166 EXPECT_EQ(1, query->submit_count()); |
| 165 | 167 |
| 166 // Flush only once if no more flushes happened between a call to | 168 // Flush only once if no more flushes happened between a call to |
| 167 // EndQuery command and CheckResultsAvailable | 169 // EndQuery command and CheckResultsAvailable |
| 168 // Advance put_ so flush calls in CheckResultsAvailable go through | 170 // Advance put_ so flush calls in CheckResultsAvailable go through |
| 169 // and updates flush_generation count | 171 // and updates flush_generation count |
| 170 helper_->Noop(1); | 172 helper_->Noop(1); |
| 171 | 173 |
| 172 // Store FlushGeneration count after EndQuery is called | 174 // Store FlushGeneration count after EndQuery is called |
| 173 uint32 gen1 = GetFlushGeneration(); | 175 uint32_t gen1 = GetFlushGeneration(); |
| 174 | 176 |
| 175 // Check CheckResultsAvailable. | 177 // Check CheckResultsAvailable. |
| 176 EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); | 178 EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); |
| 177 EXPECT_FALSE(query->NeverUsed()); | 179 EXPECT_FALSE(query->NeverUsed()); |
| 178 EXPECT_TRUE(query->Pending()); | 180 EXPECT_TRUE(query->Pending()); |
| 179 | 181 |
| 180 uint32 gen2 = GetFlushGeneration(); | 182 uint32_t gen2 = GetFlushGeneration(); |
| 181 EXPECT_NE(gen1, gen2); | 183 EXPECT_NE(gen1, gen2); |
| 182 | 184 |
| 183 // Repeated calls to CheckResultsAvailable should not flush unnecessarily | 185 // Repeated calls to CheckResultsAvailable should not flush unnecessarily |
| 184 EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); | 186 EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); |
| 185 gen1 = GetFlushGeneration(); | 187 gen1 = GetFlushGeneration(); |
| 186 EXPECT_EQ(gen1, gen2); | 188 EXPECT_EQ(gen1, gen2); |
| 187 EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); | 189 EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); |
| 188 gen1 = GetFlushGeneration(); | 190 gen1 = GetFlushGeneration(); |
| 189 EXPECT_EQ(gen1, gen2); | 191 EXPECT_EQ(gen1, gen2); |
| 190 | 192 |
| 191 // Simulate GPU process marking it as available. | 193 // Simulate GPU process marking it as available. |
| 192 QuerySync* sync = GetSync(query); | 194 QuerySync* sync = GetSync(query); |
| 193 sync->process_count = query->submit_count(); | 195 sync->process_count = query->submit_count(); |
| 194 sync->result = kResult; | 196 sync->result = kResult; |
| 195 | 197 |
| 196 // Check CheckResultsAvailable. | 198 // Check CheckResultsAvailable. |
| 197 EXPECT_TRUE(query->CheckResultsAvailable(helper_.get())); | 199 EXPECT_TRUE(query->CheckResultsAvailable(helper_.get())); |
| 198 EXPECT_EQ(kResult, query->GetResult()); | 200 EXPECT_EQ(kResult, query->GetResult()); |
| 199 EXPECT_FALSE(query->NeverUsed()); | 201 EXPECT_FALSE(query->NeverUsed()); |
| 200 EXPECT_FALSE(query->Pending()); | 202 EXPECT_FALSE(query->Pending()); |
| 201 } | 203 } |
| 202 | 204 |
| 203 TEST_F(QueryTrackerTest, Remove) { | 205 TEST_F(QueryTrackerTest, Remove) { |
| 204 const GLuint kId1 = 123; | 206 const GLuint kId1 = 123; |
| 205 const int32 kToken = 46; | 207 const int32_t kToken = 46; |
| 206 const uint32 kResult = 456; | 208 const uint32_t kResult = 456; |
| 207 | 209 |
| 208 // Create a Query. | 210 // Create a Query. |
| 209 QueryTracker::Query* query = query_tracker_->CreateQuery( | 211 QueryTracker::Query* query = query_tracker_->CreateQuery( |
| 210 kId1, GL_ANY_SAMPLES_PASSED_EXT); | 212 kId1, GL_ANY_SAMPLES_PASSED_EXT); |
| 211 ASSERT_TRUE(query != NULL); | 213 ASSERT_TRUE(query != NULL); |
| 212 | 214 |
| 213 QuerySyncManager::Bucket* bucket = GetBucket(query); | 215 QuerySyncManager::Bucket* bucket = GetBucket(query); |
| 214 EXPECT_EQ(1u, GetBucketUsedCount(bucket)); | 216 EXPECT_EQ(1u, GetBucketUsedCount(bucket)); |
| 215 | 217 |
| 216 query->MarkAsActive(); | 218 query->MarkAsActive(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 228 sync->process_count = query->submit_count(); | 230 sync->process_count = query->submit_count(); |
| 229 sync->result = kResult; | 231 sync->result = kResult; |
| 230 | 232 |
| 231 // Check FreeCompletedQueries. | 233 // Check FreeCompletedQueries. |
| 232 query_tracker_->FreeCompletedQueries(); | 234 query_tracker_->FreeCompletedQueries(); |
| 233 EXPECT_EQ(0u, GetBucketUsedCount(bucket)); | 235 EXPECT_EQ(0u, GetBucketUsedCount(bucket)); |
| 234 } | 236 } |
| 235 | 237 |
| 236 TEST_F(QueryTrackerTest, ManyQueries) { | 238 TEST_F(QueryTrackerTest, ManyQueries) { |
| 237 const GLuint kId1 = 123; | 239 const GLuint kId1 = 123; |
| 238 const int32 kToken = 46; | 240 const int32_t kToken = 46; |
| 239 const uint32 kResult = 456; | 241 const uint32_t kResult = 456; |
| 240 | 242 |
| 241 const size_t kTestSize = 4000; | 243 const size_t kTestSize = 4000; |
| 242 static_assert(kTestSize > QuerySyncManager::kSyncsPerBucket, | 244 static_assert(kTestSize > QuerySyncManager::kSyncsPerBucket, |
| 243 "We want to use more than one bucket"); | 245 "We want to use more than one bucket"); |
| 244 // Create lots of queries. | 246 // Create lots of queries. |
| 245 std::vector<QueryTracker::Query*> queries; | 247 std::vector<QueryTracker::Query*> queries; |
| 246 for (size_t i = 0; i < kTestSize; i++) { | 248 for (size_t i = 0; i < kTestSize; i++) { |
| 247 QueryTracker::Query* query = | 249 QueryTracker::Query* query = |
| 248 query_tracker_->CreateQuery(kId1 + i, GL_ANY_SAMPLES_PASSED_EXT); | 250 query_tracker_->CreateQuery(kId1 + i, GL_ANY_SAMPLES_PASSED_EXT); |
| 249 ASSERT_TRUE(query != NULL); | 251 ASSERT_TRUE(query != NULL); |
| 250 queries.push_back(query); | 252 queries.push_back(query); |
| 251 QuerySyncManager::Bucket* bucket = GetBucket(query); | 253 QuerySyncManager::Bucket* bucket = GetBucket(query); |
| 252 EXPECT_LE(1u, GetBucketUsedCount(bucket)); | 254 EXPECT_LE(1u, GetBucketUsedCount(bucket)); |
| 253 } | 255 } |
| 254 | 256 |
| 255 QuerySyncManager::Bucket* query_0_bucket = GetBucket(queries[0]); | 257 QuerySyncManager::Bucket* query_0_bucket = GetBucket(queries[0]); |
| 256 uint32 expected_use_count = QuerySyncManager::kSyncsPerBucket; | 258 uint32_t expected_use_count = QuerySyncManager::kSyncsPerBucket; |
| 257 EXPECT_EQ(expected_use_count, GetBucketUsedCount(query_0_bucket)); | 259 EXPECT_EQ(expected_use_count, GetBucketUsedCount(query_0_bucket)); |
| 258 | 260 |
| 259 while (!queries.empty()) { | 261 while (!queries.empty()) { |
| 260 QueryTracker::Query* query = queries.back(); | 262 QueryTracker::Query* query = queries.back(); |
| 261 queries.pop_back(); | 263 queries.pop_back(); |
| 262 GLuint query_id = kId1 + queries.size(); | 264 GLuint query_id = kId1 + queries.size(); |
| 263 EXPECT_EQ(query_id, query->id()); | 265 EXPECT_EQ(query_id, query->id()); |
| 264 query->MarkAsActive(); | 266 query->MarkAsActive(); |
| 265 query->MarkAsPending(kToken); | 267 query->MarkAsPending(kToken); |
| 266 | 268 |
| 267 QuerySyncManager::Bucket* bucket = GetBucket(query); | 269 QuerySyncManager::Bucket* bucket = GetBucket(query); |
| 268 uint32 use_count_before_remove = GetBucketUsedCount(bucket); | 270 uint32_t use_count_before_remove = GetBucketUsedCount(bucket); |
| 269 query_tracker_->FreeCompletedQueries(); | 271 query_tracker_->FreeCompletedQueries(); |
| 270 EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket)); | 272 EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket)); |
| 271 query_tracker_->RemoveQuery(query_id); | 273 query_tracker_->RemoveQuery(query_id); |
| 272 // Check we get nothing for a non-existent query. | 274 // Check we get nothing for a non-existent query. |
| 273 EXPECT_TRUE(query_tracker_->GetQuery(query_id) == NULL); | 275 EXPECT_TRUE(query_tracker_->GetQuery(query_id) == NULL); |
| 274 | 276 |
| 275 // Check that memory was not freed since it was not completed. | 277 // Check that memory was not freed since it was not completed. |
| 276 EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket)); | 278 EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket)); |
| 277 | 279 |
| 278 // Simulate GPU process marking it as available. | 280 // Simulate GPU process marking it as available. |
| 279 QuerySync* sync = GetSync(query); | 281 QuerySync* sync = GetSync(query); |
| 280 sync->process_count = query->submit_count(); | 282 sync->process_count = query->submit_count(); |
| 281 sync->result = kResult; | 283 sync->result = kResult; |
| 282 | 284 |
| 283 // Check FreeCompletedQueries. | 285 // Check FreeCompletedQueries. |
| 284 query_tracker_->FreeCompletedQueries(); | 286 query_tracker_->FreeCompletedQueries(); |
| 285 EXPECT_EQ(use_count_before_remove - 1, GetBucketUsedCount(bucket)); | 287 EXPECT_EQ(use_count_before_remove - 1, GetBucketUsedCount(bucket)); |
| 286 } | 288 } |
| 287 } | 289 } |
| 288 | 290 |
| 289 } // namespace gles2 | 291 } // namespace gles2 |
| 290 } // namespace gpu | 292 } // namespace gpu |
| 291 | 293 |
| 292 | 294 |
| OLD | NEW |