// 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 "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 != NULL);
    manager_->SetTarget(buffer, kTarget);
    DoBufferData(
        buffer, kTarget, sizeof(data), GL_STATIC_DRAW, NULL, 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 != NULL);
    manager_->SetTarget(buffer, kTarget);
    DoBufferData(
        buffer, kTarget, sizeof(data), GL_STATIC_DRAW, NULL, 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 != NULL);
    manager_->SetTarget(buffer, kTarget);
    DoBufferData(
        buffer, kTarget, sizeof(data), GL_STATIC_DRAW, NULL, 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(NULL, NULL, ""); }
};

class BufferManagerMemoryTrackerTest : public BufferManagerTestBase {
 protected:
  void SetUp() override {
    mock_memory_tracker_ = new StrictMock<MockMemoryTracker>();
    SetUpBase(mock_memory_tracker_.get(), NULL, "");
  }

  scoped_refptr<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;
    feature_info_ = new FeatureInfo(gpu_driver_bug_workarounds);
    SetUpBase(NULL, feature_info_.get(), "");
  }

  scoped_refptr<FeatureInfo> feature_info_;
};

#define EXPECT_MEMORY_ALLOCATION_CHANGE(old_size, new_size)   \
  EXPECT_CALL(*mock_memory_tracker_.get(),                          \
              TrackMemoryAllocatedChange(old_size, new_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 != NULL);
  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, NULL, 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) == NULL);
  // 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) == NULL);
}

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.
  EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0);
  manager_->CreateBuffer(kClientBuffer1Id, kServiceBuffer1Id);
  // Check buffer got created.
  Buffer* buffer1 = manager_->GetBuffer(kClientBuffer1Id);
  ASSERT_TRUE(buffer1 != NULL);
  manager_->SetTarget(buffer1, kTarget);
  // Check we and set its size.
  EXPECT_MEMORY_ALLOCATION_CHANGE(0, kBuffer1Size1);
  DoBufferData(
      buffer1, kTarget, kBuffer1Size1, GL_DYNAMIC_DRAW, NULL, GL_NO_ERROR);
  EXPECT_MEMORY_ALLOCATION_CHANGE(kBuffer1Size1, 0);
  EXPECT_MEMORY_ALLOCATION_CHANGE(0, kBuffer1Size2);
  DoBufferData(
      buffer1, kTarget, kBuffer1Size2, GL_DYNAMIC_DRAW, NULL, 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 != NULL);
  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 == NULL);
}

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 != NULL);
  manager_->SetTarget(buffer, kTarget);
  DoBufferData(
      buffer, kTarget, sizeof(data), GL_STATIC_DRAW, NULL, 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, NULL, 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 != NULL);
  manager_->SetTarget(buffer, kTarget);
  DoBufferData(buffer, kTarget, kDataSize, GL_STATIC_DRAW, NULL, GL_NO_ERROR);
  const char* buf =
      static_cast<const char*>(buffer->GetRange(0, kDataSize));
  ASSERT_TRUE(buf != NULL);
  const char* buf1 =
      static_cast<const char*>(buffer->GetRange(1, kDataSize - 1));
  EXPECT_EQ(buf + 1, buf1);
  EXPECT_TRUE(buffer->GetRange(kDataSize, 1) == NULL);
  EXPECT_TRUE(buffer->GetRange(0, kDataSize + 1) == NULL);
  EXPECT_TRUE(buffer->GetRange(-1, kDataSize) == NULL);
  EXPECT_TRUE(buffer->GetRange(-0, -1) == NULL);
  const int size = 0x20000;
  DoBufferData(buffer, kTarget, size / 2, GL_STATIC_DRAW, NULL, GL_NO_ERROR);
  EXPECT_TRUE(buffer->GetRange(0 - size, size) == NULL);
  EXPECT_TRUE(buffer->GetRange(1, size / 2) == NULL);
}

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() != NULL);
  manager_->SetTarget(buffer.get(), kTarget);
  // Remove buffer
  manager_->RemoveBuffer(kClientBufferId);
  // Use it after removing
  DoBufferData(
      buffer.get(), kTarget, kDataSize, GL_STATIC_DRAW, NULL, 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 = NULL;
}

// 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 != NULL);
  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 != NULL);
  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 != NULL);
    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 < arraysize(kTargets); ++ii) {
      client_id++;
      service_id++;
      manager_->CreateBuffer(client_id, service_id);
      Buffer* buffer = manager_->GetBuffer(client_id);
      ASSERT_TRUE(buffer != NULL);

      EXPECT_TRUE(manager_->SetTarget(buffer, kTargets[ii]));
      for (size_t jj = 0; jj < arraysize(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 < arraysize(kTargets); ++ii) {
      client_id++;
      service_id++;
      manager_->CreateBuffer(client_id, service_id);
      Buffer* buffer = manager_->GetBuffer(client_id);
      ASSERT_TRUE(buffer != NULL);

      EXPECT_TRUE(manager_->SetTarget(buffer, kTargets[ii]));
      for (size_t jj = 0; jj < arraysize(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
