// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Tests for the QueryTracker.

#include "gpu/command_buffer/client/query_tracker.h"

#include <GLES2/gl2ext.h>
#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <vector>

#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/mapped_memory.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::AnyNumber;

namespace gpu {
namespace gles2 {

class QuerySyncManagerTest : public testing::Test {
 protected:
  static const int32_t kNumCommandEntries = 400;
  static const int32_t kCommandBufferSizeBytes =
      kNumCommandEntries * sizeof(CommandBufferEntry);

  void SetUp() override {
    command_buffer_.reset(new MockClientCommandBuffer());
    helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
    helper_->Initialize(kCommandBufferSizeBytes);
    mapped_memory_.reset(
        new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit));
    sync_manager_.reset(new QuerySyncManager(mapped_memory_.get()));
  }

  void TearDown() override {
    EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)).Times(AnyNumber());
    sync_manager_.reset();
    mapped_memory_.reset();
    helper_.reset();
    command_buffer_.reset();
  }

  std::unique_ptr<MockClientCommandBuffer> command_buffer_;
  std::unique_ptr<GLES2CmdHelper> helper_;
  std::unique_ptr<MappedMemoryManager> mapped_memory_;
  std::unique_ptr<QuerySyncManager> sync_manager_;
};

TEST_F(QuerySyncManagerTest, Basic) {
  QuerySyncManager::QueryInfo infos[4];
  memset(&infos, 0xBD, sizeof(infos));

  for (size_t ii = 0; ii < arraysize(infos); ++ii) {
    EXPECT_TRUE(sync_manager_->Alloc(&infos[ii]));
    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) {
    sync_manager_->Free(infos[ii]);
  }
}

TEST_F(QuerySyncManagerTest, DontFree) {
  QuerySyncManager::QueryInfo infos[4];
  memset(&infos, 0xBD, sizeof(infos));

  for (size_t ii = 0; ii < arraysize(infos); ++ii) {
    EXPECT_TRUE(sync_manager_->Alloc(&infos[ii]));
  }
}

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;
  static const int32_t kCommandBufferSizeBytes =
      kNumCommandEntries * sizeof(CommandBufferEntry);

  void SetUp() override {
    command_buffer_.reset(new MockClientCommandBuffer());
    helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
    helper_->Initialize(kCommandBufferSizeBytes);
    mapped_memory_.reset(
        new MappedMemoryManager(helper_.get(), MappedMemoryManager::kNoLimit));
    query_tracker_.reset(new QueryTracker(mapped_memory_.get()));
  }

  void TearDown() override {
    helper_->CommandBufferHelper::Flush();
    EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)).Times(AnyNumber());
    query_tracker_.reset();
    mapped_memory_.reset();
    helper_.reset();
    command_buffer_.reset();
  }

  QuerySync* GetSync(QueryTracker::Query* query) {
    return query->info_.sync;
  }

  QuerySyncManager::Bucket* GetBucket(QueryTracker::Query* query) {
    return query->info_.bucket;
  }

  uint32_t GetBucketUsedCount(QuerySyncManager::Bucket* bucket) {
    return bucket->in_use_query_syncs.count();
  }

  uint32_t GetFlushGeneration() { return helper_->flush_generation(); }

  std::unique_ptr<MockClientCommandBuffer> command_buffer_;
  std::unique_ptr<GLES2CmdHelper> helper_;
  std::unique_ptr<MappedMemoryManager> mapped_memory_;
  std::unique_ptr<QueryTracker> query_tracker_;
};

TEST_F(QueryTrackerTest, Basic) {
  const GLuint kId1 = 123;
  const GLuint kId2 = 124;

  // Check we can create a Query.
  QueryTracker::Query* query = query_tracker_->CreateQuery(
      kId1, GL_ANY_SAMPLES_PASSED_EXT);
  ASSERT_TRUE(query != NULL);
  // Check we can get the same Query.
  EXPECT_EQ(query, query_tracker_->GetQuery(kId1));
  // Check we get nothing for a non-existent query.
  EXPECT_TRUE(query_tracker_->GetQuery(kId2) == NULL);
  // Check we can delete the query.
  query_tracker_->RemoveQuery(kId1);
  // Check we get nothing for a non-existent query.
  EXPECT_TRUE(query_tracker_->GetQuery(kId1) == NULL);
}

TEST_F(QueryTrackerTest, Query) {
  const GLuint kId1 = 123;
  const int32_t kToken = 46;
  const uint32_t kResult = 456;

  // Create a Query.
  QueryTracker::Query* query = query_tracker_->CreateQuery(
      kId1, GL_ANY_SAMPLES_PASSED_EXT);
  ASSERT_TRUE(query != NULL);
  EXPECT_TRUE(query->NeverUsed());
  EXPECT_FALSE(query->Pending());
  EXPECT_EQ(0, query->token());
  EXPECT_EQ(0, query->submit_count());

  // Check MarkAsActive.
  query->MarkAsActive();
  EXPECT_FALSE(query->NeverUsed());
  EXPECT_FALSE(query->Pending());
  EXPECT_EQ(0, query->token());
  EXPECT_EQ(0, query->submit_count());
  EXPECT_EQ(1, query->NextSubmitCount());

  // Check MarkAsPending.
  query->MarkAsPending(kToken, query->NextSubmitCount());
  EXPECT_FALSE(query->NeverUsed());
  EXPECT_TRUE(query->Pending());
  EXPECT_EQ(kToken, query->token());
  EXPECT_EQ(1, query->submit_count());

  // Flush only once if no more flushes happened between a call to
  // EndQuery command and CheckResultsAvailable
  // Advance put_ so flush calls in CheckResultsAvailable go through
  // and updates flush_generation count
  helper_->Noop(1);

  // Store FlushGeneration count after EndQuery is called
  uint32_t gen1 = GetFlushGeneration();

  // Check CheckResultsAvailable.
  EXPECT_FALSE(query->CheckResultsAvailable(helper_.get()));
  EXPECT_FALSE(query->NeverUsed());
  EXPECT_TRUE(query->Pending());

  uint32_t gen2 = GetFlushGeneration();
  EXPECT_NE(gen1, gen2);

  // Repeated calls to CheckResultsAvailable should not flush unnecessarily
  EXPECT_FALSE(query->CheckResultsAvailable(helper_.get()));
  gen1 = GetFlushGeneration();
  EXPECT_EQ(gen1, gen2);
  EXPECT_FALSE(query->CheckResultsAvailable(helper_.get()));
  gen1 = GetFlushGeneration();
  EXPECT_EQ(gen1, gen2);

  // Simulate GPU process marking it as available.
  QuerySync* sync = GetSync(query);
  sync->process_count = query->submit_count();
  sync->result = kResult;

  // Check CheckResultsAvailable.
  EXPECT_TRUE(query->CheckResultsAvailable(helper_.get()));
  EXPECT_EQ(kResult, query->GetResult());
  EXPECT_FALSE(query->NeverUsed());
  EXPECT_FALSE(query->Pending());
}

TEST_F(QueryTrackerTest, Remove) {
  const GLuint kId1 = 123;
  const int32_t kToken = 46;
  const uint32_t kResult = 456;

  // 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();
  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.
  EXPECT_TRUE(query_tracker_->GetQuery(kId1) == NULL);

  // 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.
  sync->result = kResult;
  sync->process_count = submit_count;

  // 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;
  const uint32_t kResult = 456;

  const size_t kTestSize = 4000;
  static_assert(kTestSize > QuerySyncManager::kSyncsPerBucket,
                "We want to use more than one bucket");
  // Create lots of queries.
  std::vector<QueryTracker::Query*> queries;
  for (size_t i = 0; i < kTestSize; i++) {
    QueryTracker::Query* query =
        query_tracker_->CreateQuery(kId1 + i, GL_ANY_SAMPLES_PASSED_EXT);
    ASSERT_TRUE(query != NULL);
    queries.push_back(query);
    QuerySyncManager::Bucket* bucket = GetBucket(query);
    EXPECT_LE(1u, GetBucketUsedCount(bucket));
  }

  QuerySyncManager::Bucket* query_0_bucket = GetBucket(queries[0]);
  uint32_t expected_use_count = QuerySyncManager::kSyncsPerBucket;
  EXPECT_EQ(expected_use_count, GetBucketUsedCount(query_0_bucket));

  while (!queries.empty()) {
    QueryTracker::Query* query = queries.back();
    queries.pop_back();
    GLuint query_id = kId1 + queries.size();
    EXPECT_EQ(query_id, query->id());
    query->MarkAsActive();
    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);
    bucket->FreePendingSyncs();
    EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket));
    query_tracker_->RemoveQuery(query_id);
    // Check we get nothing for a non-existent query.
    EXPECT_TRUE(query_tracker_->GetQuery(query_id) == NULL);

    // Check that memory was not freed since it was not completed.
    EXPECT_EQ(use_count_before_remove, GetBucketUsedCount(bucket));

    // Simulate GPU process marking it as available.
    sync->process_count = submit_count;
    sync->result = kResult;

    // Check FreeCompletedQueries.
    bucket->FreePendingSyncs();
    EXPECT_EQ(use_count_before_remove - 1, GetBucketUsedCount(bucket));
  }
}

}  // namespace gles2
}  // namespace gpu


