| Index: content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc
 | 
| diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc b/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc
 | 
| index 94046f1cf15cbc09d4e95e51149342423fdb161b..a3ed45fc4d38a7293473e1446ed04732c0ad2934 100644
 | 
| --- a/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc
 | 
| +++ b/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc
 | 
| @@ -79,7 +79,8 @@ TEST_P(GpuMemoryBufferImplTest, CreateFromHandle) {
 | 
|  TEST_P(GpuMemoryBufferImplTest, Map) {
 | 
|    const int kBufferId = 1;
 | 
|  
 | 
| -  gfx::Size buffer_size(2, 2);
 | 
| +  // Use a multiple of 4 for both dimensions to support compressed formats.
 | 
| +  gfx::Size buffer_size(4, 4);
 | 
|  
 | 
|    for (auto configuration : supported_configurations_) {
 | 
|      if (configuration.usage != gfx::GpuMemoryBuffer::MAP)
 | 
| @@ -138,6 +139,95 @@ TEST_P(GpuMemoryBufferImplTest, Map) {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +TEST_P(GpuMemoryBufferImplTest, PersistentMap) {
 | 
| +  const int kBufferId = 1;
 | 
| +
 | 
| +  // Use a multiple of 4 for both dimensions to support compressed formats.
 | 
| +  gfx::Size buffer_size(4, 4);
 | 
| +
 | 
| +  for (auto configuration : supported_configurations_) {
 | 
| +    if (configuration.usage != gfx::GpuMemoryBuffer::PERSISTENT_MAP)
 | 
| +      continue;
 | 
| +
 | 
| +    scoped_ptr<GpuMemoryBufferImpl> buffer(
 | 
| +        GpuMemoryBufferImpl::CreateFromHandle(
 | 
| +            CreateGpuMemoryBuffer(kBufferId, buffer_size, configuration.format,
 | 
| +                                  configuration.usage),
 | 
| +            buffer_size, configuration.format,
 | 
| +            base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer,
 | 
| +                       base::Unretained(this), kBufferId)));
 | 
| +    ASSERT_TRUE(buffer);
 | 
| +    EXPECT_FALSE(buffer->IsMapped());
 | 
| +
 | 
| +    size_t num_planes =
 | 
| +        GpuMemoryBufferImpl::NumberOfPlanesForGpuMemoryBufferFormat(
 | 
| +            configuration.format);
 | 
| +
 | 
| +    // Map buffer into user space.
 | 
| +    scoped_ptr<void* []> mapped_buffers(new void* [num_planes]);
 | 
| +    bool rv = buffer->Map(mapped_buffers.get());
 | 
| +    ASSERT_TRUE(rv);
 | 
| +    EXPECT_TRUE(buffer->IsMapped());
 | 
| +
 | 
| +    // Get strides.
 | 
| +    scoped_ptr<int[]> strides(new int[num_planes]);
 | 
| +    buffer->GetStride(strides.get());
 | 
| +
 | 
| +    // Copy and compare mapped buffers.
 | 
| +    for (size_t plane = 0; plane < num_planes; ++plane) {
 | 
| +      size_t row_size_in_bytes;
 | 
| +      EXPECT_TRUE(GpuMemoryBufferImpl::RowSizeInBytes(
 | 
| +          buffer_size.width(), configuration.format, plane,
 | 
| +          &row_sizes_in_bytes));
 | 
| +
 | 
| +      scoped_ptr<char[]> data(new char[row_size_in_bytes]);
 | 
| +      memset(data.get(), 0x2a + plane, row_size_in_bytes);
 | 
| +
 | 
| +      size_t height =
 | 
| +          buffer_size.height() /
 | 
| +          GpuMemoryBufferImpl::SubsamplingFactor(configuration.format, plane);
 | 
| +      for (size_t y = 0; y < height; ++y) {
 | 
| +        memcpy(static_cast<char*>(mapped_buffers[plane]) + y * strides[plane],
 | 
| +               data.get(), row_size_in_bytes);
 | 
| +        EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) +
 | 
| +                             y * strides[plane],
 | 
| +                         data.get(), row_size_in_bytes),
 | 
| +                  0);
 | 
| +      }
 | 
| +    }
 | 
| +
 | 
| +    buffer->Unmap();
 | 
| +    EXPECT_FALSE(buffer->IsMapped());
 | 
| +
 | 
| +    // Remap the buffer, and compare again. It should contain the same data.
 | 
| +    rv = buffer->Map(mapped_buffers.get());
 | 
| +    ASSERT_TRUE(rv);
 | 
| +    EXPECT_TRUE(buffer->IsMapped());
 | 
| +
 | 
| +    buffer->GetStride(strides.get());
 | 
| +
 | 
| +    for (size_t plane = 0; plane < num_planes; ++plane) {
 | 
| +      size_t row_size_in_bytes;
 | 
| +      EXPECT_TRUE(GpuMemoryBufferImpl::RowSizeInBytes(
 | 
| +          buffer_size.width(), configuration.format, plane,
 | 
| +          &row_sizes_in_bytes));
 | 
| +
 | 
| +      scoped_ptr<char[]> data(new char[row_size_in_bytes]);
 | 
| +      memset(data.get(), 0x2a + plane, row_size_in_bytes);
 | 
| +
 | 
| +      size_t height =
 | 
| +          buffer_size.height() /
 | 
| +          GpuMemoryBufferImpl::SubsamplingFactor(configuration.format, plane);
 | 
| +      for (size_t y = 0; y < height; ++y) {
 | 
| +        EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) +
 | 
| +                             y * strides[plane],
 | 
| +                         data.get(), row_size_in_bytes),
 | 
| +                  0);
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  std::vector<gfx::GpuMemoryBufferType> GetSupportedGpuMemoryBufferTypes() {
 | 
|    std::vector<gfx::GpuMemoryBufferType> supported_types;
 | 
|    GpuMemoryBufferFactory::GetSupportedTypes(&supported_types);
 | 
| 
 |