OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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. | |
4 | |
5 // This file defines tests that implementations of GpuMemoryBufferFactory should | |
6 // pass in order to be conformant. | |
7 | |
8 #ifndef CONTENT_TEST_GPU_MEMORY_BUFFER_IMPL_TEST_TEMPLATE_H_ | |
9 #define CONTENT_TEST_GPU_MEMORY_BUFFER_IMPL_TEST_TEMPLATE_H_ | |
10 | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 #include "ui/gfx/buffer_format_util.h" | |
13 | |
14 namespace content { | |
15 | |
16 template <typename GpuMemoryBufferImplType> | |
17 class GpuMemoryBufferImplTest : public testing::Test { | |
18 public: | |
19 GpuMemoryBufferImpl::DestructionCallback AllocateGpuMemoryBuffer( | |
20 const gfx::Size& size, | |
21 gfx::BufferFormat format, | |
22 gfx::BufferUsage usage, | |
23 gfx::GpuMemoryBufferHandle* handle, | |
24 bool* destroyed) { | |
25 return base::Bind(&GpuMemoryBufferImplTest::FreeGpuMemoryBuffer, | |
26 base::Unretained(this), | |
27 GpuMemoryBufferImplType::AllocateForTesting( | |
28 size, format, usage, handle), | |
29 base::Unretained(destroyed)); | |
30 } | |
31 | |
32 private: | |
33 void FreeGpuMemoryBuffer(const base::Closure& free_callback, | |
34 bool* destroyed, | |
35 uint32 sync_point) { | |
36 free_callback.Run(); | |
37 if (destroyed) | |
38 *destroyed = true; | |
39 } | |
40 }; | |
41 | |
42 TYPED_TEST_CASE_P(GpuMemoryBufferImplTest); | |
43 | |
44 TYPED_TEST_P(GpuMemoryBufferImplTest, CreateFromHandle) { | |
45 gfx::Size buffer_size(8, 8); | |
46 | |
47 for (auto format : gfx::GetBufferFormats()) { | |
48 gfx::BufferUsage usages[] = {gfx::BufferUsage::MAP, | |
49 gfx::BufferUsage::PERSISTENT_MAP, | |
50 gfx::BufferUsage::SCANOUT}; | |
51 for (auto usage : usages) { | |
52 if (!TypeParam::IsConfigurationSupported(format, usage)) | |
53 continue; | |
54 | |
55 bool destroyed = false; | |
56 gfx::GpuMemoryBufferHandle handle; | |
57 GpuMemoryBufferImpl::DestructionCallback destroy_callback = | |
58 TestFixture::AllocateGpuMemoryBuffer( | |
59 buffer_size, format, gfx::BufferUsage::MAP, &handle, &destroyed); | |
60 scoped_ptr<TypeParam> buffer(TypeParam::CreateFromHandle( | |
61 handle, buffer_size, format, usage, destroy_callback)); | |
62 ASSERT_TRUE(buffer); | |
63 EXPECT_EQ(buffer->GetFormat(), format); | |
64 | |
65 // Check if destruction callback is executed when deleting the buffer. | |
66 buffer.reset(); | |
67 EXPECT_TRUE(destroyed); | |
piman
2015/10/07 01:20:17
nit: ASSERT_TRUE
reveman
2015/10/07 09:05:01
Done.
| |
68 } | |
69 } | |
70 } | |
71 | |
72 TYPED_TEST_P(GpuMemoryBufferImplTest, Map) { | |
73 // Use a multiple of 4 for both dimensions to support compressed formats. | |
74 gfx::Size buffer_size(4, 4); | |
75 | |
76 for (auto format : gfx::GetBufferFormats()) { | |
77 if (!TypeParam::IsConfigurationSupported(format, gfx::BufferUsage::MAP)) | |
78 continue; | |
79 | |
80 gfx::GpuMemoryBufferHandle handle; | |
81 GpuMemoryBufferImpl::DestructionCallback destroy_callback = | |
82 TestFixture::AllocateGpuMemoryBuffer( | |
83 buffer_size, format, gfx::BufferUsage::MAP, &handle, nullptr); | |
84 scoped_ptr<TypeParam> buffer(TypeParam::CreateFromHandle( | |
85 handle, buffer_size, format, gfx::BufferUsage::MAP, destroy_callback)); | |
86 ASSERT_TRUE(buffer); | |
87 EXPECT_FALSE(buffer->IsMapped()); | |
88 | |
89 size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format); | |
90 | |
91 // Map buffer into user space. | |
92 scoped_ptr<void* []> mapped_buffers(new void*[num_planes]); | |
93 bool rv = buffer->Map(mapped_buffers.get()); | |
94 ASSERT_TRUE(rv); | |
95 EXPECT_TRUE(buffer->IsMapped()); | |
96 | |
97 // Get strides. | |
98 scoped_ptr<int[]> strides(new int[num_planes]); | |
99 buffer->GetStride(strides.get()); | |
100 | |
101 // Copy and compare mapped buffers. | |
102 for (size_t plane = 0; plane < num_planes; ++plane) { | |
103 size_t row_size_in_bytes = 0; | |
104 EXPECT_TRUE(gfx::RowSizeForBufferFormatChecked( | |
105 buffer_size.width(), format, plane, &row_size_in_bytes)); | |
106 EXPECT_GT(row_size_in_bytes, 0u); | |
piman
2015/10/07 01:20:17
Consider adding EXPECT_GT(strides[plane], row_size
reveman
2015/10/07 09:05:01
I'd rather not as that would break support for neg
| |
107 | |
108 scoped_ptr<char[]> data(new char[row_size_in_bytes]); | |
109 memset(data.get(), 0x2a + plane, row_size_in_bytes); | |
110 | |
111 size_t height = buffer_size.height() / | |
112 gfx::SubsamplingFactorForBufferFormat(format, plane); | |
113 for (size_t y = 0; y < height; ++y) { | |
114 memcpy(static_cast<char*>(mapped_buffers[plane]) + y * strides[plane], | |
115 data.get(), row_size_in_bytes); | |
116 EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) + | |
117 y * strides[plane], | |
118 data.get(), row_size_in_bytes), | |
119 0); | |
120 } | |
121 } | |
122 | |
123 buffer->Unmap(); | |
124 EXPECT_FALSE(buffer->IsMapped()); | |
125 } | |
126 } | |
127 | |
128 TYPED_TEST_P(GpuMemoryBufferImplTest, PersistentMap) { | |
129 // Use a multiple of 4 for both dimensions to support compressed formats. | |
130 gfx::Size buffer_size(4, 4); | |
131 | |
132 for (auto format : gfx::GetBufferFormats()) { | |
133 if (!TypeParam::IsConfigurationSupported( | |
134 format, gfx::BufferUsage::PERSISTENT_MAP)) { | |
135 continue; | |
136 } | |
137 | |
138 gfx::GpuMemoryBufferHandle handle; | |
139 GpuMemoryBufferImpl::DestructionCallback destroy_callback = | |
140 TestFixture::AllocateGpuMemoryBuffer(buffer_size, format, | |
141 gfx::BufferUsage::PERSISTENT_MAP, | |
142 &handle, nullptr); | |
143 scoped_ptr<TypeParam> buffer(TypeParam::CreateFromHandle( | |
144 handle, buffer_size, format, gfx::BufferUsage::PERSISTENT_MAP, | |
145 destroy_callback)); | |
146 ASSERT_TRUE(buffer); | |
147 EXPECT_FALSE(buffer->IsMapped()); | |
148 | |
149 size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format); | |
150 | |
151 // Map buffer into user space. | |
152 scoped_ptr<void* []> mapped_buffers(new void*[num_planes]); | |
153 bool rv = buffer->Map(mapped_buffers.get()); | |
154 ASSERT_TRUE(rv); | |
155 EXPECT_TRUE(buffer->IsMapped()); | |
156 | |
157 // Get strides. | |
158 scoped_ptr<int[]> strides(new int[num_planes]); | |
159 buffer->GetStride(strides.get()); | |
160 | |
161 // Copy and compare mapped buffers. | |
162 for (size_t plane = 0; plane < num_planes; ++plane) { | |
163 size_t row_size_in_bytes; | |
164 EXPECT_TRUE(gfx::RowSizeForBufferFormatChecked( | |
165 buffer_size.width(), format, plane, &row_size_in_bytes)); | |
166 | |
167 scoped_ptr<char[]> data(new char[row_size_in_bytes]); | |
168 memset(data.get(), 0x2a + plane, row_size_in_bytes); | |
169 | |
170 size_t height = buffer_size.height() / | |
171 gfx::SubsamplingFactorForBufferFormat(format, plane); | |
172 for (size_t y = 0; y < height; ++y) { | |
173 memcpy(static_cast<char*>(mapped_buffers[plane]) + y * strides[plane], | |
174 data.get(), row_size_in_bytes); | |
175 EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) + | |
176 y * strides[plane], | |
177 data.get(), row_size_in_bytes), | |
178 0); | |
179 } | |
180 } | |
181 | |
182 buffer->Unmap(); | |
183 EXPECT_FALSE(buffer->IsMapped()); | |
184 | |
185 // Remap the buffer, and compare again. It should contain the same data. | |
186 rv = buffer->Map(mapped_buffers.get()); | |
187 ASSERT_TRUE(rv); | |
188 EXPECT_TRUE(buffer->IsMapped()); | |
189 | |
190 buffer->GetStride(strides.get()); | |
191 | |
192 for (size_t plane = 0; plane < num_planes; ++plane) { | |
193 size_t row_size_in_bytes; | |
194 EXPECT_TRUE(gfx::RowSizeForBufferFormatChecked( | |
195 buffer_size.width(), format, plane, &row_size_in_bytes)); | |
196 | |
197 scoped_ptr<char[]> data(new char[row_size_in_bytes]); | |
198 memset(data.get(), 0x2a + plane, row_size_in_bytes); | |
199 | |
200 size_t height = buffer_size.height() / | |
201 gfx::SubsamplingFactorForBufferFormat(format, plane); | |
202 for (size_t y = 0; y < height; ++y) { | |
203 EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) + | |
204 y * strides[plane], | |
205 data.get(), row_size_in_bytes), | |
206 0); | |
207 } | |
208 } | |
209 | |
210 buffer->Unmap(); | |
211 EXPECT_FALSE(buffer->IsMapped()); | |
212 } | |
213 } | |
214 | |
215 // The GpuMemoryBufferImplTest test case verifies behavior that is expected | |
216 // from a GpuMemoryBuffer implementation in order to be conformant. | |
217 REGISTER_TYPED_TEST_CASE_P(GpuMemoryBufferImplTest, | |
218 CreateFromHandle, | |
219 Map, | |
220 PersistentMap); | |
221 | |
222 } // namespace content | |
223 | |
224 #endif // CONTENT_TEST_GPU_MEMORY_BUFFER_IMPL_TEST_TEMPLATE_H_ | |
OLD | NEW |