// 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.

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

#include <set>
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
#include "gpu/command_buffer/service/mocks.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_mock.h"

using ::testing::StrictMock;

namespace gpu {
namespace gles2 {

class RenderbufferManagerTestBase : public GpuServiceTest {
 public:
  static const GLint kMaxSize = 128;
  static const GLint kMaxSamples = 4;

 protected:
  void SetUpBase(MemoryTracker* memory_tracker,
                 bool depth24_supported,
                 bool use_gles) {
    GpuServiceTest::SetUp();
    feature_info_ = new FeatureInfo();
    TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
        gl_.get(),
        depth24_supported ? "GL_OES_depth24" : "",
        "",
        use_gles ? "OpenGL ES 2.0" : "OpenGL 2.1");
    feature_info_->InitializeForTesting();
    manager_.reset(new RenderbufferManager(
        memory_tracker, kMaxSize, kMaxSamples, feature_info_.get()));
  }

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

  scoped_refptr<FeatureInfo> feature_info_;
  scoped_ptr<RenderbufferManager> manager_;
};

class RenderbufferManagerTest : public RenderbufferManagerTestBase {
 protected:
  void SetUp() override {
    bool depth24_supported = false;
    bool use_gles = false;
    SetUpBase(NULL, depth24_supported, use_gles);
  }
};

class RenderbufferManagerMemoryTrackerTest
    : public RenderbufferManagerTestBase {
 protected:
  void SetUp() override {
    mock_memory_tracker_ = new StrictMock<MockMemoryTracker>();
    bool depth24_supported = false;
    bool use_gles = false;
    SetUpBase(mock_memory_tracker_.get(), depth24_supported, use_gles);
  }

  scoped_refptr<MockMemoryTracker> mock_memory_tracker_;
};

#define EXPECT_MEMORY_ALLOCATION_CHANGE(old_size, new_size)   \
  EXPECT_CALL(*mock_memory_tracker_.get(),                    \
              TrackMemoryAllocatedChange(old_size, new_size)) \
      .Times(1).RetiresOnSaturation()

// GCC requires these declarations, but MSVC requires they not be present
#ifndef COMPILER_MSVC
const GLint RenderbufferManagerTestBase::kMaxSize;
const GLint RenderbufferManagerTestBase::kMaxSamples;
#endif

TEST_F(RenderbufferManagerTest, Basic) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  const GLuint kClient2Id = 2;
  EXPECT_EQ(kMaxSize, manager_->max_renderbuffer_size());
  EXPECT_EQ(kMaxSamples, manager_->max_samples());
  EXPECT_FALSE(manager_->HaveUnclearedRenderbuffers());
  // Check we can create renderbuffer.
  manager_->CreateRenderbuffer(kClient1Id, kService1Id);
  // Check renderbuffer got created.
  scoped_refptr<Renderbuffer> renderbuffer1 =
      manager_->GetRenderbuffer(kClient1Id);
  ASSERT_TRUE(renderbuffer1.get() != NULL);
  EXPECT_FALSE(manager_->HaveUnclearedRenderbuffers());
  EXPECT_EQ(kClient1Id, renderbuffer1->client_id());
  // Check we get nothing for a non-existent renderbuffer.
  EXPECT_TRUE(manager_->GetRenderbuffer(kClient2Id) == NULL);
  // Check trying to a remove non-existent renderbuffers does not crash.
  manager_->RemoveRenderbuffer(kClient2Id);
  // Check that the renderbuffer is deleted when the last ref is released.
  EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
  // Check we can't get the renderbuffer after we remove it.
  manager_->RemoveRenderbuffer(kClient1Id);
  EXPECT_TRUE(manager_->GetRenderbuffer(kClient1Id) == NULL);
  EXPECT_FALSE(manager_->HaveUnclearedRenderbuffers());
  EXPECT_EQ(0u, renderbuffer1->client_id());
}

TEST_F(RenderbufferManagerTest, Destroy) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  // Check we can create renderbuffer.
  manager_->CreateRenderbuffer(kClient1Id, kService1Id);
  // Check renderbuffer got created.
  Renderbuffer* renderbuffer1 =
      manager_->GetRenderbuffer(kClient1Id);
  ASSERT_TRUE(renderbuffer1 != NULL);
  EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
  manager_->Destroy(true);
  renderbuffer1 = manager_->GetRenderbuffer(kClient1Id);
  ASSERT_TRUE(renderbuffer1 == NULL);
}

TEST_F(RenderbufferManagerTest, Renderbuffer) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  // Check we can create renderbuffer.
  manager_->CreateRenderbuffer(kClient1Id, kService1Id);
  // Check renderbuffer got created.
  Renderbuffer* renderbuffer1 =
      manager_->GetRenderbuffer(kClient1Id);
  ASSERT_TRUE(renderbuffer1 != NULL);
  EXPECT_EQ(kService1Id, renderbuffer1->service_id());
  EXPECT_EQ(0, renderbuffer1->samples());
  EXPECT_EQ(static_cast<GLenum>(GL_RGBA4), renderbuffer1->internal_format());
  EXPECT_EQ(0, renderbuffer1->width());
  EXPECT_EQ(0, renderbuffer1->height());
  EXPECT_TRUE(renderbuffer1->cleared());
  EXPECT_EQ(0u, renderbuffer1->EstimatedSize());

  // Check if we set the info it gets marked as not cleared.
  const GLsizei kSamples = 4;
  const GLenum kFormat = GL_RGBA4;
  const GLsizei kWidth = 128;
  const GLsizei kHeight = 64;
  manager_->SetInfo(renderbuffer1, kSamples, kFormat, kWidth, kHeight);
  EXPECT_EQ(kSamples, renderbuffer1->samples());
  EXPECT_EQ(kFormat, renderbuffer1->internal_format());
  EXPECT_EQ(kWidth, renderbuffer1->width());
  EXPECT_EQ(kHeight, renderbuffer1->height());
  EXPECT_FALSE(renderbuffer1->cleared());
  EXPECT_FALSE(renderbuffer1->IsDeleted());
  EXPECT_TRUE(manager_->HaveUnclearedRenderbuffers());
  EXPECT_EQ(kWidth * kHeight * 4u * 4u, renderbuffer1->EstimatedSize());

  manager_->SetCleared(renderbuffer1, true);
  EXPECT_TRUE(renderbuffer1->cleared());
  EXPECT_FALSE(manager_->HaveUnclearedRenderbuffers());

  manager_->SetInfo(renderbuffer1, kSamples, kFormat, kWidth, kHeight);
  EXPECT_TRUE(manager_->HaveUnclearedRenderbuffers());

  // Check that the renderbuffer is deleted when the last ref is released.
  EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
  manager_->RemoveRenderbuffer(kClient1Id);
  EXPECT_FALSE(manager_->HaveUnclearedRenderbuffers());
}

TEST_F(RenderbufferManagerMemoryTrackerTest, Basic) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0);
  manager_->CreateRenderbuffer(kClient1Id, kService1Id);
  Renderbuffer* renderbuffer1 =
      manager_->GetRenderbuffer(kClient1Id);
  ASSERT_TRUE(renderbuffer1 != NULL);

  const GLsizei kSamples = 4;
  const GLenum kFormat = GL_RGBA4;
  const GLsizei kWidth = 128;
  const GLsizei kHeight1 = 64;
  const GLsizei kHeight2 = 32;
  uint32 expected_size_1 = 0;
  uint32 expected_size_2 = 0;
  manager_->ComputeEstimatedRenderbufferSize(
      kWidth, kHeight1, kSamples, kFormat, &expected_size_1);
  manager_->ComputeEstimatedRenderbufferSize(
      kWidth, kHeight2, kSamples, kFormat, &expected_size_2);
  EXPECT_MEMORY_ALLOCATION_CHANGE(0, expected_size_1);
  manager_->SetInfo(renderbuffer1, kSamples, kFormat, kWidth, kHeight1);
  EXPECT_MEMORY_ALLOCATION_CHANGE(expected_size_1, 0);
  EXPECT_MEMORY_ALLOCATION_CHANGE(0, expected_size_2);
  manager_->SetInfo(renderbuffer1, kSamples, kFormat, kWidth, kHeight2);
  EXPECT_MEMORY_ALLOCATION_CHANGE(expected_size_2, 0);
  EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
}

TEST_F(RenderbufferManagerTest, UseDeletedRenderbufferInfo) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  manager_->CreateRenderbuffer(kClient1Id, kService1Id);
  scoped_refptr<Renderbuffer> renderbuffer1(
      manager_->GetRenderbuffer(kClient1Id));
  ASSERT_TRUE(renderbuffer1.get() != NULL);
  // Remove it.
  manager_->RemoveRenderbuffer(kClient1Id);
  // Use after removing.
  const GLsizei kSamples = 4;
  const GLenum kFormat = GL_RGBA4;
  const GLsizei kWidth = 128;
  const GLsizei kHeight = 64;
  manager_->SetInfo(renderbuffer1.get(), kSamples, kFormat, kWidth, kHeight);
  // See that it still affects manager.
  EXPECT_TRUE(manager_->HaveUnclearedRenderbuffers());
  manager_->SetCleared(renderbuffer1.get(), true);
  EXPECT_FALSE(manager_->HaveUnclearedRenderbuffers());
  // Check that the renderbuffer is deleted when the last ref is released.
  EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
  renderbuffer1 = NULL;
}

namespace {

bool InSet(std::set<std::string>* string_set, const std::string& str) {
  std::pair<std::set<std::string>::iterator, bool> result =
      string_set->insert(str);
  return !result.second;
}

}  // anonymous namespace

TEST_F(RenderbufferManagerTest, AddToSignature) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  manager_->CreateRenderbuffer(kClient1Id, kService1Id);
  scoped_refptr<Renderbuffer> renderbuffer1(
      manager_->GetRenderbuffer(kClient1Id));
  ASSERT_TRUE(renderbuffer1.get() != NULL);
  const GLsizei kSamples = 4;
  const GLenum kFormat = GL_RGBA4;
  const GLsizei kWidth = 128;
  const GLsizei kHeight = 64;
  manager_->SetInfo(renderbuffer1.get(), kSamples, kFormat, kWidth, kHeight);
  std::string signature1;
  std::string signature2;
  renderbuffer1->AddToSignature(&signature1);

  std::set<std::string> string_set;
  EXPECT_FALSE(InSet(&string_set, signature1));

  // change things and see that the signatures change.
  manager_->SetInfo(
      renderbuffer1.get(), kSamples + 1, kFormat, kWidth, kHeight);
  renderbuffer1->AddToSignature(&signature2);
  EXPECT_FALSE(InSet(&string_set, signature2));

  manager_->SetInfo(
      renderbuffer1.get(), kSamples, kFormat + 1, kWidth, kHeight);
  signature2.clear();
  renderbuffer1->AddToSignature(&signature2);
  EXPECT_FALSE(InSet(&string_set, signature2));

  manager_->SetInfo(
      renderbuffer1.get(), kSamples, kFormat, kWidth + 1, kHeight);
  signature2.clear();
  renderbuffer1->AddToSignature(&signature2);
  EXPECT_FALSE(InSet(&string_set, signature2));

  manager_->SetInfo(
      renderbuffer1.get(), kSamples, kFormat, kWidth, kHeight + 1);
  signature2.clear();
  renderbuffer1->AddToSignature(&signature2);
  EXPECT_FALSE(InSet(&string_set, signature2));

  // put it back to the same and it should be the same.
  manager_->SetInfo(renderbuffer1.get(), kSamples, kFormat, kWidth, kHeight);
  signature2.clear();
  renderbuffer1->AddToSignature(&signature2);
  EXPECT_EQ(signature1, signature2);

  // Check the set was acutally getting different signatures.
  EXPECT_EQ(5u, string_set.size());

  EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
}

class RenderbufferManagerFormatGLESTest : public RenderbufferManagerTestBase {
 protected:
  void SetUp() override {
    bool depth24_supported = true;
    bool use_gles = true;
    SetUpBase(NULL, depth24_supported, use_gles);
  }
};

TEST_F(RenderbufferManagerFormatGLESTest, UpgradeDepthFormatOnGLES) {
  GLenum impl_format =
      manager_->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16);
  EXPECT_EQ(static_cast<GLenum>(GL_DEPTH_COMPONENT24), impl_format);
}

class RenderbufferManagerFormatNonGLESTest :
      public RenderbufferManagerTestBase {
 protected:
  void SetUp() override {
    bool depth24_supported = true;
    bool use_gles = false;
    SetUpBase(NULL, depth24_supported, use_gles);
  }
};

TEST_F(RenderbufferManagerFormatNonGLESTest, UseUnsizedDepthFormatOnNonGLES) {
  GLenum impl_format =
      manager_->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16);
  EXPECT_EQ(static_cast<GLenum>(GL_DEPTH_COMPONENT), impl_format);
}

}  // namespace gles2
}  // namespace gpu


