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"
8 #include "content/common/gpu/gpu_memory_buffer_factory.h"
9 #include "testing/gtest/include/gtest/gtest.h"
14 const int kClientId
= 1;
16 class GpuMemoryBufferImplTest
17 : public testing::TestWithParam
<gfx::GpuMemoryBufferType
> {
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(gfx::GpuMemoryBufferId id
,
30 const gfx::Size
& size
,
31 gfx::BufferFormat format
,
32 gfx::BufferUsage usage
) {
34 return factory_
->CreateGpuMemoryBuffer(id
, size
, format
, usage
, kClientId
,
35 gfx::kNullPluginWindow
);
38 void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id
, uint32 sync_point
) {
39 factory_
->DestroyGpuMemoryBuffer(id
, kClientId
);
40 DCHECK_GT(buffer_count_
, 0);
44 std::vector
<GpuMemoryBufferFactory::Configuration
> supported_configurations_
;
48 scoped_ptr
<GpuMemoryBufferFactory
> factory_
;
51 TEST_P(GpuMemoryBufferImplTest
, CreateFromHandle
) {
52 const int kBufferId
= 1;
54 gfx::Size
buffer_size(8, 8);
56 for (auto configuration
: supported_configurations_
) {
57 scoped_ptr
<GpuMemoryBufferImpl
> buffer(
58 GpuMemoryBufferImpl::CreateFromHandle(
59 CreateGpuMemoryBuffer(kBufferId
, buffer_size
, configuration
.format
,
61 buffer_size
, configuration
.format
, configuration
.usage
,
62 base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer
,
63 base::Unretained(this), kBufferId
)));
64 EXPECT_EQ(1, buffer_count_
);
66 EXPECT_EQ(buffer
->GetFormat(), configuration
.format
);
68 // Check if destruction callback is executed when deleting the buffer.
70 EXPECT_EQ(0, buffer_count_
);
74 TEST_P(GpuMemoryBufferImplTest
, Map
) {
75 const int kBufferId
= 1;
77 // Use a multiple of 4 for both dimensions to support compressed formats.
78 gfx::Size
buffer_size(4, 4);
80 for (auto configuration
: supported_configurations_
) {
81 if (configuration
.usage
!= gfx::BufferUsage::MAP
)
84 scoped_ptr
<GpuMemoryBufferImpl
> buffer(
85 GpuMemoryBufferImpl::CreateFromHandle(
86 CreateGpuMemoryBuffer(kBufferId
, buffer_size
, configuration
.format
,
88 buffer_size
, configuration
.format
, configuration
.usage
,
89 base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer
,
90 base::Unretained(this), kBufferId
)));
92 EXPECT_FALSE(buffer
->IsMapped());
95 GpuMemoryBufferImpl::NumberOfPlanesForGpuMemoryBufferFormat(
96 configuration
.format
);
98 // Map buffer into user space.
99 scoped_ptr
<void*[]> mapped_buffers(new void*[num_planes
]);
100 bool rv
= buffer
->Map(mapped_buffers
.get());
102 EXPECT_TRUE(buffer
->IsMapped());
105 scoped_ptr
<int[]> strides(new int[num_planes
]);
106 buffer
->GetStride(strides
.get());
108 // Copy and compare mapped buffers.
109 for (size_t plane
= 0; plane
< num_planes
; ++plane
) {
110 size_t row_size_in_bytes
= 0;
111 EXPECT_TRUE(GpuMemoryBufferImpl::RowSizeInBytes(
112 buffer_size
.width(), configuration
.format
, plane
,
113 &row_size_in_bytes
));
114 EXPECT_GT(row_size_in_bytes
, 0u);
116 scoped_ptr
<char[]> data(new char[row_size_in_bytes
]);
117 memset(data
.get(), 0x2a + plane
, row_size_in_bytes
);
120 buffer_size
.height() /
121 GpuMemoryBufferImpl::SubsamplingFactor(configuration
.format
, plane
);
122 for (size_t y
= 0; y
< height
; ++y
) {
123 memcpy(static_cast<char*>(mapped_buffers
[plane
]) + y
* strides
[plane
],
124 data
.get(), row_size_in_bytes
);
125 EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers
[plane
]) +
127 data
.get(), row_size_in_bytes
),
133 EXPECT_FALSE(buffer
->IsMapped());
137 TEST_P(GpuMemoryBufferImplTest
, PersistentMap
) {
138 const int kBufferId
= 1;
140 // Use a multiple of 4 for both dimensions to support compressed formats.
141 gfx::Size
buffer_size(4, 4);
143 for (auto configuration
: supported_configurations_
) {
144 if (configuration
.usage
!= gfx::BufferUsage::PERSISTENT_MAP
)
147 scoped_ptr
<GpuMemoryBufferImpl
> buffer(
148 GpuMemoryBufferImpl::CreateFromHandle(
149 CreateGpuMemoryBuffer(kBufferId
, buffer_size
, configuration
.format
,
150 configuration
.usage
),
151 buffer_size
, configuration
.format
, configuration
.usage
,
152 base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer
,
153 base::Unretained(this), kBufferId
)));
155 EXPECT_FALSE(buffer
->IsMapped());
158 GpuMemoryBufferImpl::NumberOfPlanesForGpuMemoryBufferFormat(
159 configuration
.format
);
161 // Map buffer into user space.
162 scoped_ptr
<void* []> mapped_buffers(new void* [num_planes
]);
163 bool rv
= buffer
->Map(mapped_buffers
.get());
165 EXPECT_TRUE(buffer
->IsMapped());
168 scoped_ptr
<int[]> strides(new int[num_planes
]);
169 buffer
->GetStride(strides
.get());
171 // Copy and compare mapped buffers.
172 for (size_t plane
= 0; plane
< num_planes
; ++plane
) {
173 size_t row_size_in_bytes
;
174 EXPECT_TRUE(GpuMemoryBufferImpl::RowSizeInBytes(
175 buffer_size
.width(), configuration
.format
, plane
,
176 &row_size_in_bytes
));
178 scoped_ptr
<char[]> data(new char[row_size_in_bytes
]);
179 memset(data
.get(), 0x2a + plane
, row_size_in_bytes
);
182 buffer_size
.height() /
183 GpuMemoryBufferImpl::SubsamplingFactor(configuration
.format
, plane
);
184 for (size_t y
= 0; y
< height
; ++y
) {
185 memcpy(static_cast<char*>(mapped_buffers
[plane
]) + y
* strides
[plane
],
186 data
.get(), row_size_in_bytes
);
187 EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers
[plane
]) +
189 data
.get(), row_size_in_bytes
),
195 EXPECT_FALSE(buffer
->IsMapped());
197 // Remap the buffer, and compare again. It should contain the same data.
198 rv
= buffer
->Map(mapped_buffers
.get());
200 EXPECT_TRUE(buffer
->IsMapped());
202 buffer
->GetStride(strides
.get());
204 for (size_t plane
= 0; plane
< num_planes
; ++plane
) {
205 size_t row_size_in_bytes
;
206 EXPECT_TRUE(GpuMemoryBufferImpl::RowSizeInBytes(
207 buffer_size
.width(), configuration
.format
, plane
,
208 &row_size_in_bytes
));
210 scoped_ptr
<char[]> data(new char[row_size_in_bytes
]);
211 memset(data
.get(), 0x2a + plane
, row_size_in_bytes
);
214 buffer_size
.height() /
215 GpuMemoryBufferImpl::SubsamplingFactor(configuration
.format
, plane
);
216 for (size_t y
= 0; y
< height
; ++y
) {
217 EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers
[plane
]) +
219 data
.get(), row_size_in_bytes
),
225 EXPECT_FALSE(buffer
->IsMapped());
229 std::vector
<gfx::GpuMemoryBufferType
> GetSupportedGpuMemoryBufferTypes() {
230 std::vector
<gfx::GpuMemoryBufferType
> supported_types
;
231 GpuMemoryBufferFactory::GetSupportedTypes(&supported_types
);
232 return supported_types
;
235 INSTANTIATE_TEST_CASE_P(
236 GpuMemoryBufferImplTests
,
237 GpuMemoryBufferImplTest
,
238 ::testing::ValuesIn(GetSupportedGpuMemoryBufferTypes()));
241 } // namespace content