| Index: gpu/command_buffer/common/discardable_handle_unittest.cc
 | 
| diff --git a/gpu/command_buffer/common/discardable_handle_unittest.cc b/gpu/command_buffer/common/discardable_handle_unittest.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..8bb01ae849ae35a8326084f167dc0645bb574ae8
 | 
| --- /dev/null
 | 
| +++ b/gpu/command_buffer/common/discardable_handle_unittest.cc
 | 
| @@ -0,0 +1,129 @@
 | 
| +// Copyright (c) 2017 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/common/discardable_handle.h"
 | 
| +#include "gpu/command_buffer/common/buffer.h"
 | 
| +#include "testing/gtest/include/gtest/gtest.h"
 | 
| +
 | 
| +namespace gpu {
 | 
| +namespace {
 | 
| +
 | 
| +scoped_refptr<Buffer> MakeBufferForTesting(size_t num_handles) {
 | 
| +  size_t size = sizeof(base::subtle::Atomic32) * num_handles;
 | 
| +  std::unique_ptr<base::SharedMemory> shared_mem(new base::SharedMemory);
 | 
| +  shared_mem->CreateAndMapAnonymous(size);
 | 
| +  return MakeBufferFromSharedMemory(std::move(shared_mem), size);
 | 
| +}
 | 
| +
 | 
| +}  // namespace
 | 
| +
 | 
| +TEST(DiscardableHandleTest, BasicUsage) {
 | 
| +  scoped_refptr<Buffer> buffer = MakeBufferForTesting(1);
 | 
| +
 | 
| +  uint32_t byte_offset = 0;
 | 
| +  int32_t shm_id = 1;
 | 
| +  ClientDiscardableHandle client_handle(buffer, byte_offset, shm_id);
 | 
| +  EXPECT_EQ(client_handle.shm_id(), shm_id);
 | 
| +  EXPECT_TRUE(client_handle.IsLockedForTesting());
 | 
| +
 | 
| +  ServiceDiscardableHandle service_handle(buffer, byte_offset, shm_id);
 | 
| +  EXPECT_EQ(service_handle.shm_id(), shm_id);
 | 
| +  EXPECT_TRUE(service_handle.IsLockedForTesting());
 | 
| +
 | 
| +  EXPECT_FALSE(service_handle.Delete());
 | 
| +  EXPECT_FALSE(service_handle.IsDeletedForTesting());
 | 
| +  EXPECT_FALSE(client_handle.CanBeReUsed());
 | 
| +
 | 
| +  service_handle.Unlock();
 | 
| +  EXPECT_FALSE(service_handle.IsLockedForTesting());
 | 
| +  EXPECT_FALSE(client_handle.IsLockedForTesting());
 | 
| +
 | 
| +  EXPECT_TRUE(client_handle.Lock());
 | 
| +  EXPECT_TRUE(client_handle.IsLockedForTesting());
 | 
| +  EXPECT_TRUE(service_handle.IsLockedForTesting());
 | 
| +
 | 
| +  service_handle.Unlock();
 | 
| +  EXPECT_FALSE(service_handle.IsLockedForTesting());
 | 
| +  EXPECT_FALSE(client_handle.IsLockedForTesting());
 | 
| +
 | 
| +  EXPECT_TRUE(service_handle.Delete());
 | 
| +  EXPECT_TRUE(service_handle.IsDeletedForTesting());
 | 
| +  EXPECT_TRUE(client_handle.CanBeReUsed());
 | 
| +  EXPECT_FALSE(service_handle.IsLockedForTesting());
 | 
| +  EXPECT_FALSE(client_handle.IsLockedForTesting());
 | 
| +
 | 
| +  EXPECT_FALSE(client_handle.Lock());
 | 
| +  EXPECT_FALSE(service_handle.IsLockedForTesting());
 | 
| +  EXPECT_FALSE(client_handle.IsLockedForTesting());
 | 
| +  EXPECT_TRUE(service_handle.IsDeletedForTesting());
 | 
| +  EXPECT_TRUE(client_handle.IsDeletedForTesting());
 | 
| +}
 | 
| +
 | 
| +TEST(DiscardableHandleTest, MultiLock) {
 | 
| +  scoped_refptr<Buffer> buffer = MakeBufferForTesting(1);
 | 
| +
 | 
| +  uint32_t byte_offset = 0;
 | 
| +  int32_t shm_id = 1;
 | 
| +  ClientDiscardableHandle client_handle(buffer, byte_offset, shm_id);
 | 
| +  EXPECT_EQ(client_handle.shm_id(), shm_id);
 | 
| +  EXPECT_TRUE(client_handle.IsLockedForTesting());
 | 
| +
 | 
| +  ServiceDiscardableHandle service_handle(buffer, byte_offset, shm_id);
 | 
| +  EXPECT_EQ(service_handle.shm_id(), shm_id);
 | 
| +  EXPECT_TRUE(service_handle.IsLockedForTesting());
 | 
| +
 | 
| +  for (int i = 1; i < 10; ++i) {
 | 
| +    EXPECT_TRUE(client_handle.IsLockedForTesting());
 | 
| +    EXPECT_TRUE(service_handle.IsLockedForTesting());
 | 
| +    EXPECT_TRUE(client_handle.Lock());
 | 
| +  }
 | 
| +
 | 
| +  for (int i = 0; i < 10; ++i) {
 | 
| +    EXPECT_TRUE(client_handle.IsLockedForTesting());
 | 
| +    EXPECT_TRUE(service_handle.IsLockedForTesting());
 | 
| +    service_handle.Unlock();
 | 
| +  }
 | 
| +
 | 
| +  EXPECT_FALSE(client_handle.IsLockedForTesting());
 | 
| +  EXPECT_FALSE(service_handle.IsLockedForTesting());
 | 
| +}
 | 
| +
 | 
| +TEST(DiscardableHandleTest, Suballocations) {
 | 
| +  static const int32_t num_elements = 10;
 | 
| +  scoped_refptr<Buffer> buffer = MakeBufferForTesting(num_elements);
 | 
| +
 | 
| +  std::vector<ClientDiscardableHandle> client_handles;
 | 
| +  std::vector<ServiceDiscardableHandle> service_handles;
 | 
| +  for (int32_t i = 0; i < num_elements; ++i) {
 | 
| +    client_handles.emplace_back(buffer, sizeof(base::subtle::Atomic32) * i,
 | 
| +                                i + 1);
 | 
| +    EXPECT_EQ(client_handles[i].shm_id(), i + 1);
 | 
| +    EXPECT_TRUE(client_handles[i].IsLockedForTesting());
 | 
| +
 | 
| +    service_handles.emplace_back(buffer, sizeof(base::subtle::Atomic32) * i,
 | 
| +                                 i + 1);
 | 
| +    EXPECT_EQ(service_handles[i].shm_id(), i + 1);
 | 
| +    EXPECT_TRUE(service_handles[i].IsLockedForTesting());
 | 
| +  }
 | 
| +
 | 
| +  for (int32_t i = 0; i < num_elements; i += 2) {
 | 
| +    service_handles[i].Unlock();
 | 
| +  }
 | 
| +
 | 
| +  for (int32_t i = 1; i < num_elements; i += 2) {
 | 
| +    client_handles[i].Lock();
 | 
| +  }
 | 
| +
 | 
| +  for (int32_t i = 0; i < num_elements; ++i) {
 | 
| +    if (i % 2) {
 | 
| +      EXPECT_TRUE(client_handles[i].IsLockedForTesting());
 | 
| +      EXPECT_TRUE(service_handles[i].IsLockedForTesting());
 | 
| +    } else {
 | 
| +      EXPECT_FALSE(client_handles[i].IsLockedForTesting());
 | 
| +      EXPECT_FALSE(service_handles[i].IsLockedForTesting());
 | 
| +    }
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +}  // namespace gpu
 | 
| 
 |