• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "VtsHalGraphicsMapperV2_0TargetTest"
18 
19 #include <VtsHalHidlTargetTestBase.h>
20 #include <android-base/logging.h>
21 #include <mapper-vts/2.0/MapperVts.h>
22 
23 namespace android {
24 namespace hardware {
25 namespace graphics {
26 namespace mapper {
27 namespace V2_0 {
28 namespace vts {
29 namespace {
30 
31 using android::hardware::graphics::common::V1_0::BufferUsage;
32 using android::hardware::graphics::common::V1_0::PixelFormat;
33 
34 // Test environment for graphics.mapper.
35 class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
36    public:
37     // get the test environment singleton
Instance()38     static GraphicsMapperHidlEnvironment* Instance() {
39         static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
40         return instance;
41     }
42 
registerTestServices()43     virtual void registerTestServices() override {
44         registerTestService<IAllocator>();
45         registerTestService<IMapper>();
46     }
47 };
48 
49 class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
50    protected:
SetUp()51     void SetUp() override {
52         ASSERT_NO_FATAL_FAILURE(
53             mGralloc = std::make_unique<Gralloc>(
54                 GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
55                 GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
56 
57         mDummyDescriptorInfo.width = 64;
58         mDummyDescriptorInfo.height = 64;
59         mDummyDescriptorInfo.layerCount = 1;
60         mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
61         mDummyDescriptorInfo.usage =
62             static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
63     }
64 
TearDown()65     void TearDown() override {}
66 
67     std::unique_ptr<Gralloc> mGralloc;
68     IMapper::BufferDescriptorInfo mDummyDescriptorInfo{};
69 };
70 
71 /**
72  * Test IAllocator::dumpDebugInfo by calling it.
73  */
TEST_F(GraphicsMapperHidlTest,AllocatorDumpDebugInfo)74 TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
75     mGralloc->dumpDebugInfo();
76 }
77 
78 /**
79  * Test IAllocator::allocate with valid buffer descriptors.
80  */
TEST_F(GraphicsMapperHidlTest,AllocatorAllocate)81 TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
82     BufferDescriptor descriptor;
83     ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
84 
85     for (uint32_t count = 0; count < 5; count++) {
86         std::vector<const native_handle_t*> bufferHandles;
87         uint32_t stride;
88         ASSERT_NO_FATAL_FAILURE(bufferHandles =
89                                     mGralloc->allocate(descriptor, count, false, &stride));
90 
91         if (count >= 1) {
92             EXPECT_LE(mDummyDescriptorInfo.width, stride) << "invalid buffer stride";
93         }
94 
95         for (auto bufferHandle : bufferHandles) {
96             mGralloc->freeBuffer(bufferHandle);
97         }
98     }
99 }
100 
101 /**
102  * Test IAllocator::allocate with invalid buffer descriptors.
103  */
TEST_F(GraphicsMapperHidlTest,AllocatorAllocateNegative)104 TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
105     // this assumes any valid descriptor is non-empty
106     BufferDescriptor descriptor;
107     mGralloc->getAllocator()->allocate(descriptor, 1,
108                                        [&](const auto& tmpError, const auto&, const auto&) {
109                                            EXPECT_EQ(Error::BAD_DESCRIPTOR, tmpError);
110                                        });
111 }
112 
113 /**
114  * Test IAllocator::allocate does not leak.
115  */
TEST_F(GraphicsMapperHidlTest,AllocatorAllocateNoLeak)116 TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
117     auto info = mDummyDescriptorInfo;
118     info.width = 1024;
119     info.height = 1024;
120 
121     for (int i = 0; i < 2048; i++) {
122         auto bufferHandle = mGralloc->allocate(info, false);
123         mGralloc->freeBuffer(bufferHandle);
124     }
125 }
126 
127 /**
128  * Test IMapper::createDescriptor with valid descriptor info.
129  */
TEST_F(GraphicsMapperHidlTest,CreateDescriptorBasic)130 TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
131     ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
132 }
133 
134 /**
135  * Test IMapper::createDescriptor with invalid descriptor info.
136  */
TEST_F(GraphicsMapperHidlTest,CreateDescriptorNegative)137 TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
138     auto info = mDummyDescriptorInfo;
139     info.width = 0;
140     mGralloc->getMapper()->createDescriptor(info, [&](const auto& tmpError, const auto&) {
141         EXPECT_EQ(Error::BAD_VALUE, tmpError) << "createDescriptor did not fail with BAD_VALUE";
142     });
143 }
144 
145 /**
146  * Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
147  */
TEST_F(GraphicsMapperHidlTest,ImportFreeBufferBasic)148 TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
149     const native_handle_t* bufferHandle;
150     ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
151     ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
152 }
153 
154 /**
155  * Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
156  */
TEST_F(GraphicsMapperHidlTest,ImportFreeBufferClone)157 TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
158     const native_handle_t* clonedBufferHandle;
159     ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
160 
161     // A cloned handle is a raw handle. Check that we can import it multiple
162     // times.
163     const native_handle_t* importedBufferHandles[2];
164     ASSERT_NO_FATAL_FAILURE(importedBufferHandles[0] = mGralloc->importBuffer(clonedBufferHandle));
165     ASSERT_NO_FATAL_FAILURE(importedBufferHandles[1] = mGralloc->importBuffer(clonedBufferHandle));
166     ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[0]));
167     ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[1]));
168 
169     ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(clonedBufferHandle));
170 }
171 
172 /**
173  * Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
174  */
TEST_F(GraphicsMapperHidlTest,ImportFreeBufferSingleton)175 TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
176     const native_handle_t* rawHandle;
177     ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
178 
179     native_handle_t* importedHandle = nullptr;
180     mGralloc->getMapper()->importBuffer(rawHandle, [&](const auto& tmpError, const auto& buffer) {
181         ASSERT_EQ(Error::NONE, tmpError);
182         importedHandle = static_cast<native_handle_t*>(buffer);
183     });
184 
185     // free the imported handle with another mapper
186     std::unique_ptr<Gralloc> anotherGralloc;
187     ASSERT_NO_FATAL_FAILURE(
188         anotherGralloc = std::make_unique<Gralloc>(
189             GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
190             GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
191     Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
192     ASSERT_EQ(Error::NONE, error);
193 
194     ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(rawHandle));
195 }
196 
197 /**
198  * Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
199  */
TEST_F(GraphicsMapperHidlTest,ImportFreeBufferNoLeak)200 TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
201     auto info = mDummyDescriptorInfo;
202     info.width = 1024;
203     info.height = 1024;
204 
205     for (int i = 0; i < 2048; i++) {
206         auto bufferHandle = mGralloc->allocate(info, true);
207         mGralloc->freeBuffer(bufferHandle);
208     }
209 }
210 
211 /**
212  * Test IMapper::importBuffer with invalid buffers.
213  */
TEST_F(GraphicsMapperHidlTest,ImportBufferNegative)214 TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
215     native_handle_t* invalidHandle = nullptr;
216     mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
217         EXPECT_EQ(Error::BAD_BUFFER, tmpError)
218             << "importBuffer with nullptr did not fail with BAD_BUFFER";
219     });
220 
221     invalidHandle = native_handle_create(0, 0);
222     mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
223         EXPECT_EQ(Error::BAD_BUFFER, tmpError)
224             << "importBuffer with invalid handle did not fail with BAD_BUFFER";
225     });
226     native_handle_delete(invalidHandle);
227 }
228 
229 /**
230  * Test IMapper::freeBuffer with invalid buffers.
231  */
TEST_F(GraphicsMapperHidlTest,FreeBufferNegative)232 TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
233     native_handle_t* invalidHandle = nullptr;
234     Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
235     EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with nullptr did not fail with BAD_BUFFER";
236 
237     invalidHandle = native_handle_create(0, 0);
238     error = mGralloc->getMapper()->freeBuffer(invalidHandle);
239     EXPECT_EQ(Error::BAD_BUFFER, error)
240         << "freeBuffer with invalid handle did not fail with BAD_BUFFER";
241     native_handle_delete(invalidHandle);
242 
243     const native_handle_t* clonedBufferHandle;
244     ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
245     error = mGralloc->getMapper()->freeBuffer(invalidHandle);
246     EXPECT_EQ(Error::BAD_BUFFER, error)
247         << "freeBuffer with un-imported handle did not fail with BAD_BUFFER";
248 
249     mGralloc->freeBuffer(clonedBufferHandle);
250 }
251 
252 /**
253  * Test IMapper::lock and IMapper::unlock.
254  */
TEST_F(GraphicsMapperHidlTest,LockUnlockBasic)255 TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
256     const auto& info = mDummyDescriptorInfo;
257 
258     const native_handle_t* bufferHandle;
259     uint32_t stride;
260     ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride));
261 
262     // lock buffer for writing
263     const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
264                                static_cast<int32_t>(info.height)};
265     int fence = -1;
266     uint8_t* data;
267     ASSERT_NO_FATAL_FAILURE(
268         data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
269 
270     // RGBA_8888
271     size_t strideInBytes = stride * 4;
272     size_t writeInBytes = info.width * 4;
273 
274     for (uint32_t y = 0; y < info.height; y++) {
275         memset(data, y, writeInBytes);
276         data += strideInBytes;
277     }
278 
279     ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
280 
281     // lock again for reading
282     ASSERT_NO_FATAL_FAILURE(
283         data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
284     for (uint32_t y = 0; y < info.height; y++) {
285         for (size_t i = 0; i < writeInBytes; i++) {
286             EXPECT_EQ(static_cast<uint8_t>(y), data[i]);
287         }
288         data += strideInBytes;
289     }
290 
291     ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
292     if (fence >= 0) {
293         close(fence);
294     }
295 }
296 
297 /**
298  * Test IMapper::lockYCbCr.  This locks a YV12 buffer, and makes sure we can
299  * write to and read from it.
300  */
TEST_F(GraphicsMapperHidlTest,LockYCbCrBasic)301 TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
302     auto info = mDummyDescriptorInfo;
303     info.format = PixelFormat::YV12;
304 
305     const native_handle_t* bufferHandle;
306     uint32_t stride;
307     ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride));
308 
309     // lock buffer for writing
310     const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
311                                static_cast<int32_t>(info.height)};
312     int fence = -1;
313     YCbCrLayout layout;
314     ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
315 
316     auto yData = static_cast<uint8_t*>(layout.y);
317     auto cbData = static_cast<uint8_t*>(layout.cb);
318     auto crData = static_cast<uint8_t*>(layout.cr);
319     for (uint32_t y = 0; y < info.height; y++) {
320         for (uint32_t x = 0; x < info.width; x++) {
321             auto val = static_cast<uint8_t>(info.height * y + x);
322 
323             yData[layout.yStride * y + x] = val;
324             if (y % 2 == 0 && x % 2 == 0) {
325                 cbData[layout.cStride * y / 2 + x / 2] = val;
326                 crData[layout.cStride * y / 2 + x / 2] = val;
327             }
328         }
329     }
330 
331     ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
332 
333     // lock again for reading
334     ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
335 
336     yData = static_cast<uint8_t*>(layout.y);
337     cbData = static_cast<uint8_t*>(layout.cb);
338     crData = static_cast<uint8_t*>(layout.cr);
339     for (uint32_t y = 0; y < info.height; y++) {
340         for (uint32_t x = 0; x < info.width; x++) {
341             auto val = static_cast<uint8_t>(info.height * y + x);
342 
343             EXPECT_EQ(val, yData[layout.yStride * y + x]);
344             if (y % 2 == 0 && x % 2 == 0) {
345                 EXPECT_EQ(val, cbData[layout.cStride * y / 2 + x / 2]);
346                 EXPECT_EQ(val, crData[layout.cStride * y / 2 + x / 2]);
347             }
348         }
349     }
350 
351     ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
352     if (fence >= 0) {
353         close(fence);
354     }
355 }
356 
357 /**
358  * Test IMapper::unlock with invalid buffers.
359  */
TEST_F(GraphicsMapperHidlTest,UnlockNegative)360 TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
361     native_handle_t* invalidHandle = nullptr;
362     mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
363         EXPECT_EQ(Error::BAD_BUFFER, tmpError)
364             << "unlock with nullptr did not fail with BAD_BUFFER";
365     });
366 
367     invalidHandle = native_handle_create(0, 0);
368     mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
369         EXPECT_EQ(Error::BAD_BUFFER, tmpError)
370             << "unlock with invalid handle did not fail with BAD_BUFFER";
371     });
372     native_handle_delete(invalidHandle);
373 
374     ASSERT_NO_FATAL_FAILURE(invalidHandle = const_cast<native_handle_t*>(
375                                 mGralloc->allocate(mDummyDescriptorInfo, false)));
376     mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
377         EXPECT_EQ(Error::BAD_BUFFER, tmpError)
378             << "unlock with un-imported handle did not fail with BAD_BUFFER";
379     });
380     mGralloc->freeBuffer(invalidHandle);
381 
382 // disabled as it fails on many existing drivers
383 #if 0
384   ASSERT_NO_FATAL_FAILURE(invalidHandle = const_cast<native_handle_t*>(
385                               mGralloc->allocate(mDummyDescriptorInfo, true)));
386   mGralloc->getMapper()->unlock(
387       invalidHandle, [&](const auto& tmpError, const auto&) {
388         EXPECT_EQ(Error::BAD_BUFFER, tmpError)
389             << "unlock with unlocked handle did not fail with BAD_BUFFER";
390       });
391   mGralloc->freeBuffer(invalidHandle);
392 #endif
393 }
394 
395 }  // namespace
396 }  // namespace vts
397 }  // namespace V2_0
398 }  // namespace mapper
399 }  // namespace graphics
400 }  // namespace hardware
401 }  // namespace android
402 
main(int argc,char ** argv)403 int main(int argc, char** argv) {
404     using android::hardware::graphics::mapper::V2_0::vts::GraphicsMapperHidlEnvironment;
405     ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
406     ::testing::InitGoogleTest(&argc, argv);
407     GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
408     int status = RUN_ALL_TESTS();
409     LOG(INFO) << "Test result = " << status;
410     return status;
411 }
412