// 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 "base/memory/scoped_ptr.h"
#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/gtest/include/gtest/gtest.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace gpu {
namespace gles2 {

namespace {
void EmptyPoll() {
}
}

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

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

  virtual void TearDown() {
    sync_manager_.reset();
    mapped_memory_.reset();
    helper_.reset();
    command_buffer_.reset();
  }

  scoped_ptr<CommandBuffer> command_buffer_;
  scoped_ptr<GLES2CmdHelper> helper_;
  scoped_ptr<MappedMemoryManager> mapped_memory_;
  scoped_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]));
    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);
  }

  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]));
  }
}

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

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

  virtual void TearDown() {
    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 GetFlushGeneration() { return helper_->flush_generation(); }

  scoped_ptr<CommandBuffer> command_buffer_;
  scoped_ptr<GLES2CmdHelper> helper_;
  scoped_ptr<MappedMemoryManager> mapped_memory_;
  scoped_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 kToken = 46;
  const uint32 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(1, query->submit_count());

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

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

  // 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);
  // Set Query in pending state_ to simulate EndQuery command is called
  query->MarkAsPending(kToken);
  EXPECT_TRUE(query->Pending());
  // Store FlushGeneration count after EndQuery is called
  uint32 gen1 = GetFlushGeneration();
  EXPECT_FALSE(query->CheckResultsAvailable(helper_.get()));
  uint32 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 kToken = 46;
  const uint32 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, bucket->used_query_count);

  query->MarkAsActive();
  query->MarkAsPending(kToken);

  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, bucket->used_query_count);

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

  // Check FreeCompletedQueries.
  query_tracker_->FreeCompletedQueries();
  EXPECT_EQ(0u, bucket->used_query_count);
}

}  // namespace gles2
}  // namespace gpu


