text: // 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 {
  
  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()));
      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(0u, 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()));
      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;
    }
  
    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, false);
    // 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(0u, query->submit_count());
  
    // Check MarkAsActive.
    query->MarkAsActive();
    EXPECT_FALSE(query->NeverUsed());
    EXPECT_FALSE(query->Pending());
    EXPECT_EQ(0, query->token());
    EXPECT_EQ(1u, query->submit_count());
  
    // Check MarkAsPending.
    query->MarkAsPending(kToken);
    EXPECT_FALSE(query->NeverUsed());
    EXPECT_TRUE(query->Pending());
    EXPECT_EQ(kToken, query->token());
    EXPECT_EQ(1u, query->submit_count());
  
    // Check CheckResultsAvailable.
    EXPECT_FALSE(query->CheckResultsAvailable(helper_.get()));
    EXPECT_FALSE(query->NeverUsed());
    EXPECT_TRUE(query->Pending());
  
    // 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());
  }
  
  }  // namespace gles2
  }  // namespace gpu
  
  
  