// 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 <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/stl_util.h"
#include "gpu/command_buffer/service/buffer_manager.h"
#include "gpu/command_buffer/service/error_state_mock.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_mock.h"

using ::testing::_;
using ::testing::Return;
using ::testing::StrictMock;

namespace gpu {
namespace gles2 {

class BufferManagerTestBase : public GpuServiceTest {
 protected:
  void SetUpBase(
      MemoryTracker* memory_tracker,
      FeatureInfo* feature_info,
      const char* extensions) {
    GpuServiceTest::SetUp();
    if (feature_info) {
      TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), extensions);
      feature_info->InitializeForTesting();
    }
    error_state_.reset(new MockErrorState());
    manager_.reset(new BufferManager(memory_tracker, feature_info));
  }

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

  GLenum GetInitialTarget(const Buffer* buffer) const {
    return buffer->initial_target();
  }

  void DoBufferData(
      Buffer* buffer, GLenum target, GLsizeiptr size, GLenum usage,
      const GLvoid* data, GLenum error) {
    TestHelper::DoBufferData(
        gl_.get(), error_state_.get(), manager_.get(),
        buffer, target, size, usage, data, error);
  }

  bool DoBufferSubData(
      Buffer* buffer, GLenum target, GLintptr offset, GLsizeiptr size,
      const GLvoid* data) {
    if (!buffer->CheckRange(offset, size)) {
      return false;
    }
    if (!buffer->IsClientSideArray()) {
      EXPECT_CALL(*gl_, BufferSubData(target, offset, size, _))
          .Times(1)
          .RetiresOnSaturation();
    }
    manager_->DoBufferSubData(buffer, target, offset, size, data);
    return true;
  }

  void RunGetMaxValueForRangeUint8Test(bool enable_primitive_restart)
  {
    const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
    const GLuint kClientBufferId = 1;
    const GLuint kServiceBufferId = 11;
    const uint8_t data[] = {10, 9, 8, 7, 6, 0xFFu, 4, 3, 2, 1};
    const uint8_t new_data[] = {100, 120, 110};
    manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    ASSERT_TRUE(buffer != nullptr);
    manager_->SetTarget(buffer, kTarget);
    DoBufferData(buffer, kTarget, sizeof(data), GL_STATIC_DRAW, nullptr,
                 GL_NO_ERROR);
    EXPECT_TRUE(DoBufferSubData(buffer, kTarget, 0, sizeof(data), data));
    GLuint max_value;
    // Check entire range succeeds.
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        0, 10, GL_UNSIGNED_BYTE, enable_primitive_restart, &max_value));
    if (enable_primitive_restart) {
      EXPECT_EQ(10u, max_value);
    } else {
      EXPECT_EQ(0xFFu, max_value);
    }
    // Check sub range succeeds.
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        4, 3, GL_UNSIGNED_BYTE, enable_primitive_restart, &max_value));
    if (enable_primitive_restart) {
      EXPECT_EQ(6u, max_value);
    } else {
      EXPECT_EQ(0xFFu, max_value);
    }
    // Check changing sub range succeeds.
    EXPECT_TRUE(DoBufferSubData(buffer, kTarget, 4, sizeof(new_data),
                                new_data));
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        4, 3, GL_UNSIGNED_BYTE, enable_primitive_restart, &max_value));
    EXPECT_EQ(120u, max_value);
    max_value = 0;
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        0, 10, GL_UNSIGNED_BYTE, enable_primitive_restart, &max_value));
    EXPECT_EQ(120u, max_value);
    // Check out of range fails.
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        0, 11, GL_UNSIGNED_BYTE, enable_primitive_restart, &max_value));
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        10, 1, GL_UNSIGNED_BYTE, enable_primitive_restart, &max_value));
  }

  void RunGetMaxValueForRangeUint16Test(bool enable_primitive_restart) {
    const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
    const GLuint kClientBufferId = 1;
    const GLuint kServiceBufferId = 11;
    const uint16_t data[] = {10, 9, 8, 7, 6, 0xFFFF, 4, 3, 2, 1};
    const uint16_t new_data[] = {100, 120, 110};
    manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    ASSERT_TRUE(buffer != nullptr);
    manager_->SetTarget(buffer, kTarget);
    DoBufferData(buffer, kTarget, sizeof(data), GL_STATIC_DRAW, nullptr,
                 GL_NO_ERROR);
    EXPECT_TRUE(DoBufferSubData(buffer, kTarget, 0, sizeof(data), data));
    GLuint max_value;
    // Check entire range succeeds.
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        0, 10, GL_UNSIGNED_SHORT, enable_primitive_restart, &max_value));
    if (enable_primitive_restart) {
      EXPECT_EQ(10u, max_value);
    } else {
      EXPECT_EQ(0xFFFFu, max_value);
    }
    // Check odd offset fails for GL_UNSIGNED_SHORT.
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        1, 10, GL_UNSIGNED_SHORT, enable_primitive_restart, &max_value));
    // Check sub range succeeds.
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        8, 3, GL_UNSIGNED_SHORT, enable_primitive_restart, &max_value));
    if (enable_primitive_restart) {
      EXPECT_EQ(6u, max_value);
    } else {
      EXPECT_EQ(0xFFFFu, max_value);
    }
    // Check changing sub range succeeds.
    EXPECT_TRUE(DoBufferSubData(buffer, kTarget, 8, sizeof(new_data),
                                new_data));
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        8, 3, GL_UNSIGNED_SHORT, enable_primitive_restart, &max_value));
    EXPECT_EQ(120u, max_value);
    max_value = 0;
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        0, 10, GL_UNSIGNED_SHORT, enable_primitive_restart, &max_value));
    EXPECT_EQ(120u, max_value);
    // Check out of range fails.
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        0, 11, GL_UNSIGNED_SHORT, enable_primitive_restart, &max_value));
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        20, 1, GL_UNSIGNED_SHORT, enable_primitive_restart, &max_value));
  }

  void RunGetMaxValueForRangeUint32Test(bool enable_primitive_restart) {
    const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
    const GLuint kClientBufferId = 1;
    const GLuint kServiceBufferId = 11;
    const uint32_t data[] = {10, 9, 8, 7, 6, 0xFFFFFFFFu, 4, 3, 2, 1};
    const uint32_t new_data[] = {100, 120, 110};
    manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    ASSERT_TRUE(buffer != nullptr);
    manager_->SetTarget(buffer, kTarget);
    DoBufferData(buffer, kTarget, sizeof(data), GL_STATIC_DRAW, nullptr,
                 GL_NO_ERROR);
    EXPECT_TRUE(DoBufferSubData(buffer, kTarget, 0, sizeof(data), data));
    GLuint max_value;
    // Check entire range succeeds.
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        0, 10, GL_UNSIGNED_INT, enable_primitive_restart, &max_value));
    if (enable_primitive_restart) {
      EXPECT_EQ(10u, max_value);
    } else {
      EXPECT_EQ(0xFFFFFFFFu, max_value);
    }
    // Check non aligned offsets fails for GL_UNSIGNED_INT.
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        1, 10, GL_UNSIGNED_INT, enable_primitive_restart, &max_value));
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        2, 10, GL_UNSIGNED_INT, enable_primitive_restart, &max_value));
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        3, 10, GL_UNSIGNED_INT, enable_primitive_restart, &max_value));
    // Check sub range succeeds.
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        16, 3, GL_UNSIGNED_INT, enable_primitive_restart, &max_value));
    if (enable_primitive_restart) {
      EXPECT_EQ(6u, max_value);
    } else {
      EXPECT_EQ(0xFFFFFFFFu, max_value);
    }
    // Check changing sub range succeeds.
    EXPECT_TRUE(DoBufferSubData(buffer, kTarget, 16, sizeof(new_data),
                                new_data));
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        16, 3, GL_UNSIGNED_INT, enable_primitive_restart, &max_value));
    EXPECT_EQ(120u, max_value);
    max_value = 0;
    EXPECT_TRUE(buffer->GetMaxValueForRange(
        0, 10, GL_UNSIGNED_INT, enable_primitive_restart, &max_value));
    EXPECT_EQ(120u, max_value);
    // Check out of range fails.
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        0, 11, GL_UNSIGNED_INT, enable_primitive_restart, &max_value));
    EXPECT_FALSE(buffer->GetMaxValueForRange(
        40, 1, GL_UNSIGNED_INT, enable_primitive_restart, &max_value));
  }

  std::unique_ptr<BufferManager> manager_;
  std::unique_ptr<MockErrorState> error_state_;
};

class BufferManagerTest : public BufferManagerTestBase {
 protected:
  void SetUp() override { SetUpBase(nullptr, nullptr, ""); }
};

class BufferManagerMemoryTrackerTest : public BufferManagerTestBase {
 protected:
  void SetUp() override { SetUpBase(&mock_memory_tracker_, nullptr, ""); }

  StrictMock<MockMemoryTracker> mock_memory_tracker_;
};

class BufferManagerClientSideArraysTest : public BufferManagerTestBase {
 protected:
  void SetUp() override {
    GpuDriverBugWorkarounds gpu_driver_bug_workarounds;
    gpu_driver_bug_workarounds.use_client_side_arrays_for_stream_buffers = true;
    GpuFeatureInfo gpu_feature_info;
    feature_info_ =
        new FeatureInfo(gpu_driver_bug_workarounds, gpu_feature_info);
    SetUpBase(nullptr, feature_info_.get(), "");
  }

  scoped_refptr<FeatureInfo> feature_info_;
};

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

TEST_F(BufferManagerTest, Basic) {
  const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
  const GLuint kClientBuffer1Id = 1;
  const GLuint kServiceBuffer1Id = 11;
  const GLsizeiptr kBuffer1Size = 123;
  const GLuint kClientBuffer2Id = 2;
  // Check we can create buffer.
  manager_->CreateBuffer(kClientBuffer1Id, kServiceBuffer1Id);
  // Check buffer got created.
  Buffer* buffer1 = manager_->GetBuffer(kClientBuffer1Id);
  ASSERT_TRUE(buffer1 != nullptr);
  EXPECT_EQ(0u, GetInitialTarget(buffer1));
  EXPECT_EQ(0, buffer1->size());
  EXPECT_EQ(static_cast<GLenum>(GL_STATIC_DRAW), buffer1->usage());
  EXPECT_FALSE(buffer1->IsDeleted());
  EXPECT_FALSE(buffer1->IsClientSideArray());
  EXPECT_EQ(kServiceBuffer1Id, buffer1->service_id());
  GLuint client_id = 0;
  EXPECT_TRUE(manager_->GetClientId(buffer1->service_id(), &client_id));
  EXPECT_EQ(kClientBuffer1Id, client_id);
  manager_->SetTarget(buffer1, kTarget);
  EXPECT_EQ(kTarget, GetInitialTarget(buffer1));
  // Check we and set its size.
  DoBufferData(buffer1, kTarget, kBuffer1Size, GL_DYNAMIC_DRAW, nullptr,
               GL_NO_ERROR);
  EXPECT_EQ(kBuffer1Size, buffer1->size());
  EXPECT_EQ(static_cast<GLenum>(GL_DYNAMIC_DRAW), buffer1->usage());
  // Check we get nothing for a non-existent buffer.
  EXPECT_TRUE(manager_->GetBuffer(kClientBuffer2Id) == nullptr);
  // Check trying to a remove non-existent buffers does not crash.
  manager_->RemoveBuffer(kClientBuffer2Id);
  // Check that it gets deleted when the last reference is released.
  EXPECT_CALL(*gl_, DeleteBuffersARB(1, ::testing::Pointee(kServiceBuffer1Id)))
      .Times(1)
      .RetiresOnSaturation();
  // Check we can't get the buffer after we remove it.
  manager_->RemoveBuffer(kClientBuffer1Id);
  EXPECT_TRUE(manager_->GetBuffer(kClientBuffer1Id) == nullptr);
}

TEST_F(BufferManagerMemoryTrackerTest, Basic) {
  const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
  const GLuint kClientBuffer1Id = 1;
  const GLuint kServiceBuffer1Id = 11;
  const GLsizeiptr kBuffer1Size1 = 123;
  const GLsizeiptr kBuffer1Size2 = 456;
  // Check we can create buffer.
  manager_->CreateBuffer(kClientBuffer1Id, kServiceBuffer1Id);
  // Check buffer got created.
  Buffer* buffer1 = manager_->GetBuffer(kClientBuffer1Id);
  ASSERT_TRUE(buffer1 != nullptr);
  manager_->SetTarget(buffer1, kTarget);
  // Check we and set its size.
  EXPECT_MEMORY_ALLOCATION_CHANGE(0, kBuffer1Size1);
  DoBufferData(buffer1, kTarget, kBuffer1Size1, GL_DYNAMIC_DRAW, nullptr,
               GL_NO_ERROR);
  EXPECT_MEMORY_ALLOCATION_CHANGE(kBuffer1Size1, 0);
  EXPECT_MEMORY_ALLOCATION_CHANGE(0, kBuffer1Size2);
  DoBufferData(buffer1, kTarget, kBuffer1Size2, GL_DYNAMIC_DRAW, nullptr,
               GL_NO_ERROR);
  // On delete it will get freed.
  EXPECT_MEMORY_ALLOCATION_CHANGE(kBuffer1Size2, 0);
}

TEST_F(BufferManagerTest, Destroy) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  // Check we can create buffer.
  manager_->CreateBuffer(kClient1Id, kService1Id);
  // Check buffer got created.
  Buffer* buffer1 = manager_->GetBuffer(kClient1Id);
  ASSERT_TRUE(buffer1 != nullptr);
  EXPECT_CALL(*gl_, DeleteBuffersARB(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
  manager_->Destroy();
  // Check the resources were released.
  buffer1 = manager_->GetBuffer(kClient1Id);
  ASSERT_TRUE(buffer1 == nullptr);
}

TEST_F(BufferManagerTest, DoBufferSubData) {
  const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
  const GLuint kClientBufferId = 1;
  const GLuint kServiceBufferId = 11;
  const uint8_t data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
  manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
  Buffer* buffer = manager_->GetBuffer(kClientBufferId);
  ASSERT_TRUE(buffer != nullptr);
  manager_->SetTarget(buffer, kTarget);
  DoBufferData(buffer, kTarget, sizeof(data), GL_STATIC_DRAW, nullptr,
               GL_NO_ERROR);
  EXPECT_TRUE(DoBufferSubData(buffer, kTarget, 0, sizeof(data), data));
  EXPECT_TRUE(DoBufferSubData(buffer, kTarget, sizeof(data), 0, data));
  EXPECT_FALSE(DoBufferSubData(buffer, kTarget, sizeof(data), 1, data));
  EXPECT_FALSE(DoBufferSubData(buffer, kTarget, 0, sizeof(data) + 1, data));
  EXPECT_FALSE(DoBufferSubData(buffer, kTarget, -1, sizeof(data), data));
  EXPECT_FALSE(DoBufferSubData(buffer, kTarget, 0, -1, data));
  DoBufferData(buffer, kTarget, 1, GL_STATIC_DRAW, nullptr, GL_NO_ERROR);
  const int size = 0x20000;
  std::unique_ptr<uint8_t[]> temp(new uint8_t[size]);
  EXPECT_FALSE(DoBufferSubData(buffer, kTarget, 0 - size, size, temp.get()));
  EXPECT_FALSE(DoBufferSubData(buffer, kTarget, 1, size / 2, temp.get()));
}

TEST_F(BufferManagerTest, GetRange) {
  const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
  const GLuint kClientBufferId = 1;
  const GLuint kServiceBufferId = 11;
  const GLsizeiptr kDataSize = 10;
  manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
  Buffer* buffer = manager_->GetBuffer(kClientBufferId);
  ASSERT_TRUE(buffer != nullptr);
  manager_->SetTarget(buffer, kTarget);
  DoBufferData(buffer, kTarget, kDataSize, GL_STATIC_DRAW, nullptr,
               GL_NO_ERROR);
  const char* buf =
      static_cast<const char*>(buffer->GetRange(0, kDataSize));
  ASSERT_TRUE(buf != nullptr);
  const char* buf1 =
      static_cast<const char*>(buffer->GetRange(1, kDataSize - 1));
  EXPECT_EQ(buf + 1, buf1);
  EXPECT_TRUE(buffer->GetRange(kDataSize, 1) == nullptr);
  EXPECT_TRUE(buffer->GetRange(0, kDataSize + 1) == nullptr);
  EXPECT_TRUE(buffer->GetRange(-1, kDataSize) == nullptr);
  EXPECT_TRUE(buffer->GetRange(-0, -1) == nullptr);
  const int size = 0x20000;
  DoBufferData(buffer, kTarget, size / 2, GL_STATIC_DRAW, nullptr, GL_NO_ERROR);
  EXPECT_TRUE(buffer->GetRange(0 - size, size) == nullptr);
  EXPECT_TRUE(buffer->GetRange(1, size / 2) == nullptr);
}

TEST_F(BufferManagerTest, GetMaxValueForRangeUint8) {
  RunGetMaxValueForRangeUint8Test(false);
}

TEST_F(BufferManagerTest, GetMaxValueForRangeUint8PrimitiveRestart) {
  RunGetMaxValueForRangeUint8Test(true);
}

TEST_F(BufferManagerTest, GetMaxValueForRangeUint16) {
  RunGetMaxValueForRangeUint16Test(false);
}

TEST_F(BufferManagerTest, GetMaxValueForRangeUint16PrimitiveRestart) {
  RunGetMaxValueForRangeUint16Test(true);
}

TEST_F(BufferManagerTest, GetMaxValueForRangeUint32) {
  RunGetMaxValueForRangeUint32Test(false);
}

TEST_F(BufferManagerTest, GetMaxValueForRangeUint32PrimitiveRestart) {
  RunGetMaxValueForRangeUint32Test(true);
}

TEST_F(BufferManagerTest, UseDeletedBuffer) {
  const GLenum kTarget = GL_ARRAY_BUFFER;
  const GLuint kClientBufferId = 1;
  const GLuint kServiceBufferId = 11;
  const GLsizeiptr kDataSize = 10;
  manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
  scoped_refptr<Buffer> buffer = manager_->GetBuffer(kClientBufferId);
  ASSERT_TRUE(buffer.get() != nullptr);
  manager_->SetTarget(buffer.get(), kTarget);
  // Remove buffer
  manager_->RemoveBuffer(kClientBufferId);
  // Use it after removing
  DoBufferData(buffer.get(), kTarget, kDataSize, GL_STATIC_DRAW, nullptr,
               GL_NO_ERROR);
  // Check that it gets deleted when the last reference is released.
  EXPECT_CALL(*gl_, DeleteBuffersARB(1, ::testing::Pointee(kServiceBufferId)))
      .Times(1)
      .RetiresOnSaturation();
  buffer = nullptr;
}

// Test buffers get shadowed when they are supposed to be.
TEST_F(BufferManagerClientSideArraysTest, StreamBuffersAreShadowed) {
  const GLenum kTarget = GL_ARRAY_BUFFER;
  const GLuint kClientBufferId = 1;
  const GLuint kServiceBufferId = 11;
  static const uint32_t data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
  manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
  Buffer* buffer = manager_->GetBuffer(kClientBufferId);
  ASSERT_TRUE(buffer != nullptr);
  manager_->SetTarget(buffer, kTarget);
  DoBufferData(
      buffer, kTarget, sizeof(data), GL_STREAM_DRAW, data, GL_NO_ERROR);
  EXPECT_TRUE(buffer->IsClientSideArray());
  EXPECT_EQ(0, memcmp(data, buffer->GetRange(0, sizeof(data)), sizeof(data)));
  DoBufferData(
      buffer, kTarget, sizeof(data), GL_DYNAMIC_DRAW, data, GL_NO_ERROR);
  EXPECT_FALSE(buffer->IsClientSideArray());
}

TEST_F(BufferManagerTest, MaxValueCacheClearedCorrectly) {
  const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
  const GLuint kClientBufferId = 1;
  const GLuint kServiceBufferId = 11;
  const uint32_t data1[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
  const uint32_t data2[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
  const uint32_t data3[] = {30, 29, 28};
  manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
  Buffer* buffer = manager_->GetBuffer(kClientBufferId);
  ASSERT_TRUE(buffer != nullptr);
  manager_->SetTarget(buffer, kTarget);
  GLuint max_value;
  // Load the buffer with some initial data, and then get the maximum value for
  // a range, which has the side effect of caching it.
  DoBufferData(
      buffer, kTarget, sizeof(data1), GL_STATIC_DRAW, data1, GL_NO_ERROR);
  EXPECT_TRUE(
      buffer->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT, false, &max_value));
  EXPECT_EQ(10u, max_value);
  // Check that any cached values are invalidated if the buffer is reloaded
  // with the same amount of data (but different content)
  ASSERT_EQ(sizeof(data2), sizeof(data1));
  DoBufferData(
      buffer, kTarget, sizeof(data2), GL_STATIC_DRAW, data2, GL_NO_ERROR);
  EXPECT_TRUE(
      buffer->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT, false, &max_value));
  EXPECT_EQ(20u, max_value);
  // Check that any cached values are invalidated if the buffer is reloaded
  // with entirely different content.
  ASSERT_NE(sizeof(data3), sizeof(data1));
  DoBufferData(
      buffer, kTarget, sizeof(data3), GL_STATIC_DRAW, data3, GL_NO_ERROR);
  EXPECT_TRUE(
      buffer->GetMaxValueForRange(0, 3, GL_UNSIGNED_INT, false, &max_value));
  EXPECT_EQ(30u, max_value);
}

TEST_F(BufferManagerTest, BindBufferConflicts) {
  manager_->set_allow_buffers_on_multiple_targets(false);
  GLuint client_id = 1;
  GLuint service_id = 101;

  {
    // Once a buffer is bound to ELEMENT_ARRAY_BUFFER, it can't be bound to
    // any other targets except for GL_COPY_READ/WRITE_BUFFER.
    manager_->CreateBuffer(client_id, service_id);
    Buffer* buffer = manager_->GetBuffer(client_id);
    ASSERT_TRUE(buffer != nullptr);
    EXPECT_TRUE(manager_->SetTarget(buffer, GL_ELEMENT_ARRAY_BUFFER));
    EXPECT_TRUE(manager_->SetTarget(buffer, GL_COPY_READ_BUFFER));
    EXPECT_TRUE(manager_->SetTarget(buffer, GL_COPY_WRITE_BUFFER));
    EXPECT_FALSE(manager_->SetTarget(buffer, GL_ARRAY_BUFFER));
    EXPECT_FALSE(manager_->SetTarget(buffer, GL_PIXEL_PACK_BUFFER));
    EXPECT_FALSE(manager_->SetTarget(buffer, GL_PIXEL_UNPACK_BUFFER));
    EXPECT_FALSE(manager_->SetTarget(buffer, GL_TRANSFORM_FEEDBACK_BUFFER));
    EXPECT_FALSE(manager_->SetTarget(buffer, GL_UNIFORM_BUFFER));
  }

  {
    // Except for ELEMENT_ARRAY_BUFFER, a buffer can switch to any targets.
    const GLenum kTargets[] = {
      GL_ARRAY_BUFFER,
      GL_COPY_READ_BUFFER,
      GL_COPY_WRITE_BUFFER,
      GL_PIXEL_PACK_BUFFER,
      GL_PIXEL_UNPACK_BUFFER,
      GL_TRANSFORM_FEEDBACK_BUFFER,
      GL_UNIFORM_BUFFER
    };
    for (size_t ii = 0; ii < base::size(kTargets); ++ii) {
      client_id++;
      service_id++;
      manager_->CreateBuffer(client_id, service_id);
      Buffer* buffer = manager_->GetBuffer(client_id);
      ASSERT_TRUE(buffer != nullptr);

      EXPECT_TRUE(manager_->SetTarget(buffer, kTargets[ii]));
      for (size_t jj = 0; jj < base::size(kTargets); ++jj) {
        EXPECT_TRUE(manager_->SetTarget(buffer, kTargets[jj]));
      }
      EXPECT_EQ(kTargets[ii], GetInitialTarget(buffer));
    }
  }

  {
    // Once a buffer is bound to non ELEMENT_ARRAY_BUFFER target, it can't be
    // bound to ELEMENT_ARRAY_BUFFER target.
    const GLenum kTargets[] = {
      GL_ARRAY_BUFFER,
      GL_COPY_READ_BUFFER,
      GL_COPY_WRITE_BUFFER,
      GL_PIXEL_PACK_BUFFER,
      GL_PIXEL_UNPACK_BUFFER,
      GL_TRANSFORM_FEEDBACK_BUFFER,
      GL_UNIFORM_BUFFER
    };
    for (size_t ii = 0; ii < base::size(kTargets); ++ii) {
      client_id++;
      service_id++;
      manager_->CreateBuffer(client_id, service_id);
      Buffer* buffer = manager_->GetBuffer(client_id);
      ASSERT_TRUE(buffer != nullptr);

      EXPECT_TRUE(manager_->SetTarget(buffer, kTargets[ii]));
      for (size_t jj = 0; jj < base::size(kTargets); ++jj) {
        EXPECT_TRUE(manager_->SetTarget(buffer, kTargets[jj]));
      }
    }
  }
}

TEST_F(BufferManagerTest, DeleteBufferAfterContextLost) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  manager_->CreateBuffer(kClient1Id, kService1Id);
  Buffer* buffer1 = manager_->GetBuffer(kClient1Id);
  ASSERT_TRUE(buffer1 != nullptr);
  manager_->MarkContextLost();
  // Removing buffers after MarkContextLost cause no GL calls.
  manager_->RemoveBuffer(kClient1Id);
  manager_->Destroy();
  // Check the resources were released.
  buffer1 = manager_->GetBuffer(kClient1Id);
  ASSERT_TRUE(buffer1 == nullptr);
}

}  // namespace gles2
}  // namespace gpu
