summaryrefslogtreecommitdiff
path: root/chromium/gpu/command_buffer/client/query_tracker_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/gpu/command_buffer/client/query_tracker_unittest.cc')
-rw-r--r--chromium/gpu/command_buffer/client/query_tracker_unittest.cc184
1 files changed, 168 insertions, 16 deletions
diff --git a/chromium/gpu/command_buffer/client/query_tracker_unittest.cc b/chromium/gpu/command_buffer/client/query_tracker_unittest.cc
index 78ab936d11d..8b5191e2608 100644
--- a/chromium/gpu/command_buffer/client/query_tracker_unittest.cc
+++ b/chromium/gpu/command_buffer/client/query_tracker_unittest.cc
@@ -20,6 +20,9 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::_;
+using testing::AnyNumber;
+
namespace gpu {
namespace gles2 {
@@ -39,13 +42,14 @@ class QuerySyncManagerTest : public testing::Test {
}
void TearDown() override {
+ EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)).Times(AnyNumber());
sync_manager_.reset();
mapped_memory_.reset();
helper_.reset();
command_buffer_.reset();
}
- std::unique_ptr<CommandBuffer> command_buffer_;
+ std::unique_ptr<MockClientCommandBuffer> command_buffer_;
std::unique_ptr<GLES2CmdHelper> helper_;
std::unique_ptr<MappedMemoryManager> mapped_memory_;
std::unique_ptr<QuerySyncManager> sync_manager_;
@@ -57,10 +61,10 @@ TEST_F(QuerySyncManagerTest, Basic) {
for (size_t ii = 0; ii < arraysize(infos); ++ii) {
EXPECT_TRUE(sync_manager_->Alloc(&infos[ii]));
- EXPECT_NE(0, infos[ii].shm_id);
ASSERT_TRUE(infos[ii].sync != NULL);
EXPECT_EQ(0, infos[ii].sync->process_count);
EXPECT_EQ(0u, infos[ii].sync->result);
+ EXPECT_EQ(0, infos[ii].submit_count);
}
for (size_t ii = 0; ii < arraysize(infos); ++ii) {
@@ -77,6 +81,126 @@ TEST_F(QuerySyncManagerTest, DontFree) {
}
}
+TEST_F(QuerySyncManagerTest, FreePendingSyncs) {
+ QuerySyncManager::QueryInfo info;
+ EXPECT_TRUE(sync_manager_->Alloc(&info));
+ QuerySyncManager::Bucket* bucket = info.bucket;
+
+ // Mark the query as in-use.
+ ++info.submit_count;
+
+ // Freeing the QueryInfo should keep the QuerySync busy as it's still in-use,
+ // but should be tracked in pending_syncs.
+ sync_manager_->Free(info);
+ EXPECT_FALSE(bucket->pending_syncs.empty());
+ EXPECT_TRUE(bucket->in_use_query_syncs.any());
+
+ // FreePendingSyncs should not free in-use QuerySync.
+ bucket->FreePendingSyncs();
+ EXPECT_FALSE(bucket->pending_syncs.empty());
+ EXPECT_TRUE(bucket->in_use_query_syncs.any());
+
+ // Mark the query as completed.
+ info.sync->process_count = info.submit_count;
+
+ // FreePendingSyncs should free the QuerySync.
+ bucket->FreePendingSyncs();
+ EXPECT_TRUE(bucket->pending_syncs.empty());
+ EXPECT_FALSE(bucket->in_use_query_syncs.any());
+
+ // Allocate a new Query, mark it in-use
+ EXPECT_TRUE(sync_manager_->Alloc(&info));
+ bucket = info.bucket;
+ ++info.submit_count;
+
+ // Mark the query as completed
+ info.sync->process_count = info.submit_count;
+
+ // FreePendingSyncs should not free the QuerySync. Even though the query is
+ // completed, is has not been deleted yet.
+ bucket->FreePendingSyncs();
+ EXPECT_TRUE(bucket->in_use_query_syncs.any());
+
+ // Free the QueryInfo, it should be immediately freed.
+ sync_manager_->Free(info);
+ EXPECT_TRUE(bucket->pending_syncs.empty());
+ EXPECT_FALSE(bucket->in_use_query_syncs.any());
+}
+
+TEST_F(QuerySyncManagerTest, Shrink) {
+ QuerySyncManager::QueryInfo info;
+ EXPECT_TRUE(sync_manager_->Alloc(&info));
+ QuerySyncManager::Bucket* bucket = info.bucket;
+ QuerySync* syncs = bucket->syncs;
+
+ FencedAllocator::State state =
+ mapped_memory_->GetPointerStatusForTest(syncs, nullptr);
+ EXPECT_EQ(FencedAllocator::IN_USE, state);
+
+ // Shrink while a query is allocated - should not release anything.
+ sync_manager_->Shrink(helper_.get());
+ state = mapped_memory_->GetPointerStatusForTest(syncs, nullptr);
+ EXPECT_EQ(FencedAllocator::IN_USE, state);
+
+ // Free query that was never submitted.
+ sync_manager_->Free(info);
+ EXPECT_TRUE(bucket->pending_syncs.empty());
+ EXPECT_FALSE(bucket->in_use_query_syncs.any());
+
+ // Shrink should release the memory immediately.
+ sync_manager_->Shrink(helper_.get());
+ EXPECT_TRUE(sync_manager_->buckets_.empty());
+ state = mapped_memory_->GetPointerStatusForTest(syncs, nullptr);
+ EXPECT_EQ(FencedAllocator::FREE, state);
+
+ EXPECT_TRUE(sync_manager_->Alloc(&info));
+ bucket = info.bucket;
+ syncs = bucket->syncs;
+
+ state = mapped_memory_->GetPointerStatusForTest(syncs, nullptr);
+ EXPECT_EQ(FencedAllocator::IN_USE, state);
+
+ // Free a query that was submitted, but not completed.
+ ++info.submit_count;
+ sync_manager_->Free(info);
+ EXPECT_FALSE(bucket->pending_syncs.empty());
+ EXPECT_TRUE(bucket->in_use_query_syncs.any());
+
+ int32_t last_token = helper_->InsertToken();
+
+ // Shrink should release the memory, pending a new token.
+ sync_manager_->Shrink(helper_.get());
+ EXPECT_TRUE(sync_manager_->buckets_.empty());
+ int32_t token = 0;
+ state = mapped_memory_->GetPointerStatusForTest(syncs, &token);
+ EXPECT_EQ(FencedAllocator::FREE_PENDING_TOKEN, state);
+ EXPECT_EQ(last_token + 1, token);
+
+ EXPECT_TRUE(sync_manager_->Alloc(&info));
+ bucket = info.bucket;
+ syncs = bucket->syncs;
+
+ state = mapped_memory_->GetPointerStatusForTest(syncs, nullptr);
+ EXPECT_EQ(FencedAllocator::IN_USE, state);
+
+ // Free a query that was submitted, but not completed yet.
+ ++info.submit_count;
+ int32_t submit_count = info.submit_count;
+ QuerySync* sync = info.sync;
+ sync_manager_->Free(info);
+ EXPECT_FALSE(bucket->pending_syncs.empty());
+ EXPECT_TRUE(bucket->in_use_query_syncs.any());
+
+ // Complete the query after Free.
+ sync->process_count = submit_count;
+
+ // Shrink should free the memory immediately since the query is completed.
+ sync_manager_->Shrink(helper_.get());
+ EXPECT_TRUE(sync_manager_->buckets_.empty());
+ state = mapped_memory_->GetPointerStatusForTest(syncs, nullptr);
+ EXPECT_EQ(FencedAllocator::FREE, state);
+}
+
class QueryTrackerTest : public testing::Test {
protected:
static const int32_t kNumCommandEntries = 400;
@@ -93,6 +217,8 @@ class QueryTrackerTest : public testing::Test {
}
void TearDown() override {
+ helper_->CommandBufferHelper::Flush();
+ EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)).Times(AnyNumber());
query_tracker_.reset();
mapped_memory_.reset();
helper_.reset();
@@ -108,12 +234,12 @@ class QueryTrackerTest : public testing::Test {
}
uint32_t GetBucketUsedCount(QuerySyncManager::Bucket* bucket) {
- return bucket->in_use_queries.count();
+ return bucket->in_use_query_syncs.count();
}
uint32_t GetFlushGeneration() { return helper_->flush_generation(); }
- std::unique_ptr<CommandBuffer> command_buffer_;
+ std::unique_ptr<MockClientCommandBuffer> command_buffer_;
std::unique_ptr<GLES2CmdHelper> helper_;
std::unique_ptr<MappedMemoryManager> mapped_memory_;
std::unique_ptr<QueryTracker> query_tracker_;
@@ -156,10 +282,11 @@ TEST_F(QueryTrackerTest, Query) {
EXPECT_FALSE(query->NeverUsed());
EXPECT_FALSE(query->Pending());
EXPECT_EQ(0, query->token());
- EXPECT_EQ(1, query->submit_count());
+ EXPECT_EQ(0, query->submit_count());
+ EXPECT_EQ(1, query->NextSubmitCount());
// Check MarkAsPending.
- query->MarkAsPending(kToken);
+ query->MarkAsPending(kToken, query->NextSubmitCount());
EXPECT_FALSE(query->NeverUsed());
EXPECT_TRUE(query->Pending());
EXPECT_EQ(kToken, query->token());
@@ -216,7 +343,9 @@ TEST_F(QueryTrackerTest, Remove) {
EXPECT_EQ(1u, GetBucketUsedCount(bucket));
query->MarkAsActive();
- query->MarkAsPending(kToken);
+ int32_t submit_count = query->NextSubmitCount();
+ query->MarkAsPending(kToken, submit_count);
+ QuerySync* sync = GetSync(query);
query_tracker_->RemoveQuery(kId1);
// Check we get nothing for a non-existent query.
@@ -224,17 +353,39 @@ TEST_F(QueryTrackerTest, Remove) {
// Check that memory was not freed.
EXPECT_EQ(1u, GetBucketUsedCount(bucket));
+ EXPECT_EQ(1u, bucket->pending_syncs.size());
// Simulate GPU process marking it as available.
- QuerySync* sync = GetSync(query);
- sync->process_count = query->submit_count();
sync->result = kResult;
+ sync->process_count = submit_count;
- // Check FreeCompletedQueries.
- query_tracker_->FreeCompletedQueries();
+ // Check FreePendingSyncs.
+ bucket->FreePendingSyncs();
EXPECT_EQ(0u, GetBucketUsedCount(bucket));
}
+TEST_F(QueryTrackerTest, RemoveActive) {
+ const GLuint kId1 = 123;
+
+ // Create a Query.
+ QueryTracker::Query* query =
+ query_tracker_->CreateQuery(kId1, GL_ANY_SAMPLES_PASSED_EXT);
+ ASSERT_TRUE(query != NULL);
+
+ QuerySyncManager::Bucket* bucket = GetBucket(query);
+ EXPECT_EQ(1u, GetBucketUsedCount(bucket));
+
+ query->MarkAsActive();
+
+ query_tracker_->RemoveQuery(kId1);
+ // Check we get nothing for a non-existent query.
+ EXPECT_TRUE(query_tracker_->GetQuery(kId1) == NULL);
+
+ // Check that memory was freed.
+ EXPECT_EQ(0u, GetBucketUsedCount(bucket));
+ EXPECT_EQ(0u, bucket->pending_syncs.size());
+}
+
TEST_F(QueryTrackerTest, ManyQueries) {
const GLuint kId1 = 123;
const int32_t kToken = 46;
@@ -264,11 +415,13 @@ TEST_F(QueryTrackerTest, ManyQueries) {
GLuint query_id = kId1 + queries.size();
EXPECT_EQ(query_id, query->id());
query->MarkAsActive();
- query->MarkAsPending(kToken);
+ int32_t submit_count = query->NextSubmitCount();
+ query->MarkAsPending(kToken, submit_count);
+ QuerySync* sync = GetSync(query);
QuerySyncManager::Bucket* bucket = GetBucket(query);
uint32_t use_count_before_remove = GetBucketUsedCount(bucket);
- query_tracker_->FreeCompletedQueries();
+ bucket->FreePendingSyncs();
EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket));
query_tracker_->RemoveQuery(query_id);
// Check we get nothing for a non-existent query.
@@ -278,12 +431,11 @@ TEST_F(QueryTrackerTest, ManyQueries) {
EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket));
// Simulate GPU process marking it as available.
- QuerySync* sync = GetSync(query);
- sync->process_count = query->submit_count();
+ sync->process_count = submit_count;
sync->result = kResult;
// Check FreeCompletedQueries.
- query_tracker_->FreeCompletedQueries();
+ bucket->FreePendingSyncs();
EXPECT_EQ(use_count_before_remove - 1, GetBucketUsedCount(bucket));
}
}