Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / content / common / gpu / client / gpu_memory_buffer_impl_unittest.cc
blob91be10a9c9a39cd018ebbc95d26dfa31a89e053e
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/common/gpu/client/gpu_memory_buffer_impl.h"
7 #include "base/bind.h"
8 #include "content/common/gpu/gpu_memory_buffer_factory.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 namespace content {
12 namespace {
14 const int kClientId = 1;
16 class GpuMemoryBufferImplTest
17 : public testing::TestWithParam<gfx::GpuMemoryBufferType> {
18 public:
19 GpuMemoryBufferImplTest() : buffer_count_(0), factory_(nullptr) {}
21 // Overridden from testing::Test:
22 void SetUp() override {
23 factory_ = GpuMemoryBufferFactory::Create(GetParam());
24 factory_->GetSupportedGpuMemoryBufferConfigurations(
25 &supported_configurations_);
27 void TearDown() override { factory_.reset(); }
29 gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
30 gfx::GpuMemoryBufferId id,
31 const gfx::Size& size,
32 gfx::GpuMemoryBuffer::Format format,
33 gfx::GpuMemoryBuffer::Usage usage) {
34 ++buffer_count_;
35 return factory_->CreateGpuMemoryBuffer(id, size, format, usage, kClientId,
36 gfx::kNullPluginWindow);
39 void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, uint32 sync_point) {
40 factory_->DestroyGpuMemoryBuffer(id, kClientId);
41 DCHECK_GT(buffer_count_, 0);
42 --buffer_count_;
45 std::vector<GpuMemoryBufferFactory::Configuration> supported_configurations_;
46 int buffer_count_;
48 private:
49 scoped_ptr<GpuMemoryBufferFactory> factory_;
52 TEST_P(GpuMemoryBufferImplTest, CreateFromHandle) {
53 const int kBufferId = 1;
55 gfx::Size buffer_size(8, 8);
57 for (auto configuration : supported_configurations_) {
58 scoped_ptr<GpuMemoryBufferImpl> buffer(
59 GpuMemoryBufferImpl::CreateFromHandle(
60 CreateGpuMemoryBuffer(kBufferId, buffer_size, configuration.format,
61 configuration.usage),
62 buffer_size, configuration.format, configuration.usage,
63 base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer,
64 base::Unretained(this), kBufferId)));
65 EXPECT_EQ(1, buffer_count_);
66 ASSERT_TRUE(buffer);
67 EXPECT_EQ(buffer->GetFormat(), configuration.format);
69 // Check if destruction callback is executed when deleting the buffer.
70 buffer.reset();
71 EXPECT_EQ(0, buffer_count_);
75 TEST_P(GpuMemoryBufferImplTest, Map) {
76 const int kBufferId = 1;
78 // Use a multiple of 4 for both dimensions to support compressed formats.
79 gfx::Size buffer_size(4, 4);
81 for (auto configuration : supported_configurations_) {
82 if (configuration.usage != gfx::GpuMemoryBuffer::MAP)
83 continue;
85 scoped_ptr<GpuMemoryBufferImpl> buffer(
86 GpuMemoryBufferImpl::CreateFromHandle(
87 CreateGpuMemoryBuffer(kBufferId, buffer_size, configuration.format,
88 configuration.usage),
89 buffer_size, configuration.format, configuration.usage,
90 base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer,
91 base::Unretained(this), kBufferId)));
92 ASSERT_TRUE(buffer);
93 EXPECT_FALSE(buffer->IsMapped());
95 size_t num_planes =
96 GpuMemoryBufferImpl::NumberOfPlanesForGpuMemoryBufferFormat(
97 configuration.format);
99 // Map buffer into user space.
100 scoped_ptr<void*[]> mapped_buffers(new void*[num_planes]);
101 bool rv = buffer->Map(mapped_buffers.get());
102 ASSERT_TRUE(rv);
103 EXPECT_TRUE(buffer->IsMapped());
105 // Get strides.
106 scoped_ptr<int[]> strides(new int[num_planes]);
107 buffer->GetStride(strides.get());
109 // Copy and compare mapped buffers.
110 for (size_t plane = 0; plane < num_planes; ++plane) {
111 size_t row_size_in_bytes = 0;
112 EXPECT_TRUE(GpuMemoryBufferImpl::RowSizeInBytes(
113 buffer_size.width(), configuration.format, plane,
114 &row_size_in_bytes));
115 EXPECT_GT(row_size_in_bytes, 0u);
117 scoped_ptr<char[]> data(new char[row_size_in_bytes]);
118 memset(data.get(), 0x2a + plane, row_size_in_bytes);
120 size_t height =
121 buffer_size.height() /
122 GpuMemoryBufferImpl::SubsamplingFactor(configuration.format, plane);
123 for (size_t y = 0; y < height; ++y) {
124 memcpy(static_cast<char*>(mapped_buffers[plane]) + y * strides[plane],
125 data.get(), row_size_in_bytes);
126 EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) +
127 y * strides[plane],
128 data.get(), row_size_in_bytes),
133 buffer->Unmap();
134 EXPECT_FALSE(buffer->IsMapped());
138 TEST_P(GpuMemoryBufferImplTest, PersistentMap) {
139 const int kBufferId = 1;
141 // Use a multiple of 4 for both dimensions to support compressed formats.
142 gfx::Size buffer_size(4, 4);
144 for (auto configuration : supported_configurations_) {
145 if (configuration.usage != gfx::GpuMemoryBuffer::PERSISTENT_MAP)
146 continue;
148 scoped_ptr<GpuMemoryBufferImpl> buffer(
149 GpuMemoryBufferImpl::CreateFromHandle(
150 CreateGpuMemoryBuffer(kBufferId, buffer_size, configuration.format,
151 configuration.usage),
152 buffer_size, configuration.format, configuration.usage,
153 base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer,
154 base::Unretained(this), kBufferId)));
155 ASSERT_TRUE(buffer);
156 EXPECT_FALSE(buffer->IsMapped());
158 size_t num_planes =
159 GpuMemoryBufferImpl::NumberOfPlanesForGpuMemoryBufferFormat(
160 configuration.format);
162 // Map buffer into user space.
163 scoped_ptr<void* []> mapped_buffers(new void* [num_planes]);
164 bool rv = buffer->Map(mapped_buffers.get());
165 ASSERT_TRUE(rv);
166 EXPECT_TRUE(buffer->IsMapped());
168 // Get strides.
169 scoped_ptr<int[]> strides(new int[num_planes]);
170 buffer->GetStride(strides.get());
172 // Copy and compare mapped buffers.
173 for (size_t plane = 0; plane < num_planes; ++plane) {
174 size_t row_size_in_bytes;
175 EXPECT_TRUE(GpuMemoryBufferImpl::RowSizeInBytes(
176 buffer_size.width(), configuration.format, plane,
177 &row_size_in_bytes));
179 scoped_ptr<char[]> data(new char[row_size_in_bytes]);
180 memset(data.get(), 0x2a + plane, row_size_in_bytes);
182 size_t height =
183 buffer_size.height() /
184 GpuMemoryBufferImpl::SubsamplingFactor(configuration.format, plane);
185 for (size_t y = 0; y < height; ++y) {
186 memcpy(static_cast<char*>(mapped_buffers[plane]) + y * strides[plane],
187 data.get(), row_size_in_bytes);
188 EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) +
189 y * strides[plane],
190 data.get(), row_size_in_bytes),
195 buffer->Unmap();
196 EXPECT_FALSE(buffer->IsMapped());
198 // Remap the buffer, and compare again. It should contain the same data.
199 rv = buffer->Map(mapped_buffers.get());
200 ASSERT_TRUE(rv);
201 EXPECT_TRUE(buffer->IsMapped());
203 buffer->GetStride(strides.get());
205 for (size_t plane = 0; plane < num_planes; ++plane) {
206 size_t row_size_in_bytes;
207 EXPECT_TRUE(GpuMemoryBufferImpl::RowSizeInBytes(
208 buffer_size.width(), configuration.format, plane,
209 &row_size_in_bytes));
211 scoped_ptr<char[]> data(new char[row_size_in_bytes]);
212 memset(data.get(), 0x2a + plane, row_size_in_bytes);
214 size_t height =
215 buffer_size.height() /
216 GpuMemoryBufferImpl::SubsamplingFactor(configuration.format, plane);
217 for (size_t y = 0; y < height; ++y) {
218 EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) +
219 y * strides[plane],
220 data.get(), row_size_in_bytes),
225 buffer->Unmap();
226 EXPECT_FALSE(buffer->IsMapped());
230 std::vector<gfx::GpuMemoryBufferType> GetSupportedGpuMemoryBufferTypes() {
231 std::vector<gfx::GpuMemoryBufferType> supported_types;
232 GpuMemoryBufferFactory::GetSupportedTypes(&supported_types);
233 return supported_types;
236 INSTANTIATE_TEST_CASE_P(
237 GpuMemoryBufferImplTests,
238 GpuMemoryBufferImplTest,
239 ::testing::ValuesIn(GetSupportedGpuMemoryBufferTypes()));
241 } // namespace
242 } // namespace content