// Copyright (c) 2015 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.

#include "gpu/command_buffer/service/path_manager.h"

#include <memory>

#include "gpu/command_buffer/service/gpu_service_test.h"
#include "gpu/command_buffer/service/mocks.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_mock.h"

namespace gpu {
namespace gles2 {

class PathManagerTest : public GpuServiceTest {
 public:
  PathManagerTest() {}

 protected:
  void SetUp() override {
    SetUpWithGLVersion("3.0", "GL_NV_path_rendering");
    manager_.reset(new PathManager());
  }

  void TearDown() override {
    manager_->Destroy(true);
    manager_.reset();
    GpuServiceTest::TearDown();
  }

  std::unique_ptr<PathManager> manager_;
};

TEST_F(PathManagerTest, Basic) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  const GLuint kClient2Id = 2;
  GLuint service_id = 0;
  manager_->CreatePathRange(kClient1Id, kClient1Id, kService1Id);
  ASSERT_TRUE(manager_->HasPathsInRange(kClient1Id, kClient1Id));
  EXPECT_TRUE(manager_->GetPath(kClient1Id, &service_id));
  EXPECT_EQ(kService1Id, service_id);

  // Check we get nothing for a non-existent path.
  service_id = 123u;
  ASSERT_FALSE(manager_->HasPathsInRange(kClient2Id, kClient2Id));
  EXPECT_FALSE(manager_->GetPath(kClient2Id, &service_id));
  EXPECT_EQ(123u, service_id);

  // Check trying to remove non-existent paths does not crash.
  manager_->RemovePaths(kClient2Id, kClient2Id);

  // Check that it gets deleted when the last reference is released.
  EXPECT_CALL(*gl_, DeletePathsNV(kService1Id, 1))
      .Times(1)
      .RetiresOnSaturation();

  // Check we can't get the path after we remove it.
  manager_->RemovePaths(kClient1Id, kClient1Id);
  ASSERT_FALSE(manager_->HasPathsInRange(kClient1Id, kClient1Id));
  EXPECT_FALSE(manager_->GetPath(kClient1Id, &service_id));
}

// Tests that path manager does not merge ranges that contain service ids that
//  prevent the merging. Path ranges A and B can be merged if
// * client ids of B start immediately after the last client id of A
// * service ids of B start immediately after the last service id of A
// and similarly for the 'before' case.
TEST_F(PathManagerTest, NonContiguousServiceIds) {
  const GLuint kMergeCheckRange = 54;

  const struct {
    GLuint first_client_id;
    GLuint last_client_id;
    GLuint first_service_id;
  } kIdRanges[] = {{500, 1000, 900}, {1001, 1155, 1}, {200, 499, 4888}};
  for (auto& range : kIdRanges) {
    manager_->CreatePathRange(range.first_client_id, range.last_client_id,
                              range.first_service_id);
    ASSERT_TRUE(manager_->HasPathsInRange(range.first_client_id,
                                          range.first_client_id));
    ASSERT_TRUE(
        manager_->HasPathsInRange(range.last_client_id, range.last_client_id));
    ASSERT_TRUE(
        manager_->HasPathsInRange(range.first_client_id, range.last_client_id));
    GLuint service_id = 0u;
    EXPECT_TRUE(manager_->GetPath(range.first_client_id + 5u, &service_id));
    EXPECT_EQ(range.first_service_id + 5u, service_id);
  }

  // Insert a mergeable range last, to check that merges
  // work. Otherwise the test could succeed because merges were not
  // working.
  auto& merge_candidate = kIdRanges[1];
  GLuint merge_candidate_range =
      merge_candidate.last_client_id - merge_candidate.first_client_id + 1;
  manager_->CreatePathRange(
      merge_candidate.last_client_id + 1,
      merge_candidate.last_client_id + kMergeCheckRange,
      merge_candidate.first_service_id + merge_candidate_range);

  // We detect that ranges were not merged accidentally by detecting individual
  // deletes.
  for (auto& range : kIdRanges) {
    if (&range == &merge_candidate)
      continue;
    GLsizei range_amount = range.last_client_id - range.first_client_id + 1;
    EXPECT_CALL(*gl_, DeletePathsNV(range.first_service_id, range_amount))
        .Times(1)
        .RetiresOnSaturation();
  }

  // Just a check that merges work.
  EXPECT_CALL(*gl_, DeletePathsNV(merge_candidate.first_service_id,
                                  merge_candidate_range + kMergeCheckRange))
      .Times(1)
      .RetiresOnSaturation();

  // Remove all ids. This should cause the expected amount of DeletePathsNV
  // calls.
  manager_->RemovePaths(1, std::numeric_limits<GLsizei>::max());

  for (auto& range : kIdRanges) {
    ASSERT_FALSE(
        manager_->HasPathsInRange(range.first_client_id, range.last_client_id));
  }
}

TEST_F(PathManagerTest, DeleteBigRange) {
  // Allocates two ranges which in path manager end up merging as one
  // big range. The range will be too big to fit in one DeletePaths
  // call.  Test that the range is deleted correctly with two calls.
  const GLuint kFirstClientId1 = 1;
  const GLsizei kRange1 = std::numeric_limits<GLsizei>::max() - 3;
  const GLuint kLastClientId1 = kFirstClientId1 + kRange1 - 1;
  const GLuint kFirstServiceId1 = 77;
  const GLuint kLastServiceId1 = kFirstServiceId1 + kRange1 - 1;

  const GLuint kFirstClientId2 = kLastClientId1 + 1;
  const GLsizei kRange2 = 15;
  const GLuint kLastClientId2 = kFirstClientId2 + kRange2 - 1;
  const GLuint kFirstServiceId2 = kLastServiceId1 + 1;

  const GLsizei kFirstDeleteRange = std::numeric_limits<GLsizei>::max();
  const GLsizei kSecondDeleteRange = kRange2 - (kFirstDeleteRange - kRange1);
  const GLuint kSecondDeleteFirstServiceId =
      kFirstServiceId1 + kFirstDeleteRange;

  EXPECT_CALL(*gl_, DeletePathsNV(kFirstServiceId1,
                                  std::numeric_limits<GLsizei>::max()))
      .RetiresOnSaturation();

  EXPECT_CALL(*gl_, DeletePathsNV(kSecondDeleteFirstServiceId,
                                  kSecondDeleteRange)).RetiresOnSaturation();

  manager_->CreatePathRange(kFirstClientId1, kLastClientId1, kFirstServiceId1);
  manager_->CreatePathRange(kFirstClientId2, kLastClientId2, kFirstServiceId2);
  manager_->RemovePaths(0, std::numeric_limits<GLuint>::max());
}

}  // namespace gles2

}  // namespace gpu
