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