1 /*
2 * Copyright (C) 2018 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 #include <android-base/properties.h>
18 #include <android/hardware_buffer.h>
19 #include <android/log.h>
20 #include <errno.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include <sys/socket.h>
24 #include <sys/types.h>
25 #include <sys/un.h>
26 #include <unistd.h>
27
28 #include <limits>
29 #include <sstream>
30 #include <string>
31 #include <thread>
32
33 // #define LOG_NDEBUG 0
34
35 #define BAD_VALUE -EINVAL
36 #define INVALID_OPERATION -ENOSYS
37 #define NO_ERROR 0
38
39 #define LOG_TAG "AHBTest"
40 #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
41
42 namespace {
43
44 using testing::AnyOf;
45 using testing::Eq;
46 using testing::Ge;
47 using testing::NotNull;
48
49 #define FORMAT_CASE(x) \
50 case AHARDWAREBUFFER_FORMAT_##x: \
51 os << #x; \
52 break
53
PrintAhbFormat(std::ostream & os,uint64_t format)54 void PrintAhbFormat(std::ostream& os, uint64_t format) {
55 switch (format) {
56 FORMAT_CASE(R8G8B8A8_UNORM);
57 FORMAT_CASE(R8G8B8X8_UNORM);
58 FORMAT_CASE(R8G8B8_UNORM);
59 FORMAT_CASE(R5G6B5_UNORM);
60 FORMAT_CASE(R16G16B16A16_FLOAT);
61 FORMAT_CASE(R10G10B10A2_UNORM);
62 FORMAT_CASE(BLOB);
63 FORMAT_CASE(D16_UNORM);
64 FORMAT_CASE(D24_UNORM);
65 FORMAT_CASE(D24_UNORM_S8_UINT);
66 FORMAT_CASE(D32_FLOAT);
67 FORMAT_CASE(D32_FLOAT_S8_UINT);
68 FORMAT_CASE(S8_UINT);
69 FORMAT_CASE(Y8Cb8Cr8_420);
70 FORMAT_CASE(YCbCr_P010);
71 FORMAT_CASE(YCbCr_P210);
72 FORMAT_CASE(R8_UNORM);
73 FORMAT_CASE(R16_UINT);
74 FORMAT_CASE(R16G16_UINT);
75 FORMAT_CASE(R10G10B10A10_UNORM);
76 default:
77 os << "unknown";
78 break;
79 }
80 }
81
82 #define BITS_CASE(x) \
83 case AHARDWAREBUFFER_USAGE_##x: \
84 os << #x; \
85 break
86 #define PRINT_FLAG(x) \
87 do { \
88 if (usage & AHARDWAREBUFFER_USAGE_##x) { \
89 os << #x << " "; \
90 } \
91 } while (0)
92
PrintAhbUsage(std::ostream & os,uint64_t usage)93 void PrintAhbUsage(std::ostream& os, uint64_t usage) {
94 if (usage == 0) {
95 os << "none";
96 return;
97 }
98 switch (usage & AHARDWAREBUFFER_USAGE_CPU_READ_MASK) {
99 BITS_CASE(CPU_READ_NEVER);
100 BITS_CASE(CPU_READ_RARELY);
101 BITS_CASE(CPU_READ_OFTEN);
102 default:
103 break;
104 }
105 switch (usage & AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK) {
106 BITS_CASE(CPU_WRITE_NEVER);
107 BITS_CASE(CPU_WRITE_RARELY);
108 BITS_CASE(CPU_WRITE_OFTEN);
109 default:
110 break;
111 }
112
113 PRINT_FLAG(GPU_SAMPLED_IMAGE);
114 PRINT_FLAG(GPU_COLOR_OUTPUT);
115 PRINT_FLAG(PROTECTED_CONTENT);
116 PRINT_FLAG(VIDEO_ENCODE);
117 PRINT_FLAG(SENSOR_DIRECT_DATA);
118 PRINT_FLAG(GPU_DATA_BUFFER);
119 PRINT_FLAG(GPU_CUBE_MAP);
120 PRINT_FLAG(GPU_MIPMAP_COMPLETE);
121
122 PRINT_FLAG(VENDOR_0);
123 PRINT_FLAG(VENDOR_1);
124 PRINT_FLAG(VENDOR_2);
125 PRINT_FLAG(VENDOR_3);
126 PRINT_FLAG(VENDOR_4);
127 PRINT_FLAG(VENDOR_5);
128 PRINT_FLAG(VENDOR_6);
129 PRINT_FLAG(VENDOR_7);
130 PRINT_FLAG(VENDOR_8);
131 PRINT_FLAG(VENDOR_9);
132 PRINT_FLAG(VENDOR_10);
133 PRINT_FLAG(VENDOR_11);
134 PRINT_FLAG(VENDOR_12);
135 PRINT_FLAG(VENDOR_13);
136 PRINT_FLAG(VENDOR_14);
137 PRINT_FLAG(VENDOR_15);
138 PRINT_FLAG(VENDOR_16);
139 PRINT_FLAG(VENDOR_17);
140 PRINT_FLAG(VENDOR_18);
141 PRINT_FLAG(VENDOR_19);
142 }
143
GetDescription(AHardwareBuffer * buffer)144 AHardwareBuffer_Desc GetDescription(AHardwareBuffer* buffer) {
145 AHardwareBuffer_Desc description;
146 AHardwareBuffer_describe(buffer, &description);
147 return description;
148 }
149
IsSoftwareRenderer()150 bool IsSoftwareRenderer() {
151 return android::base::GetIntProperty("ro.cpuvulkan.version", 0) > 0;
152 }
153
154 } // namespace
155
156 // GTest printer for AHardwareBuffer_Desc. Has to be in the global namespace.
PrintTo(const AHardwareBuffer_Desc & desc,::std::ostream * os)157 void PrintTo(const AHardwareBuffer_Desc& desc, ::std::ostream* os) {
158 *os << "AHardwareBuffer_Desc " << desc.width << "x" << desc.height;
159 if (desc.layers > 1) {
160 *os << ", " << desc.layers << " layers";
161 }
162 *os << ", usage = ";
163 PrintAhbUsage(*os, desc.usage);
164 *os << ", format = ";
165 PrintAhbFormat(*os, desc.format);
166 }
167
168 // Equality operators for AHardwareBuffer_Desc. Have to be in the global namespace.
operator ==(const AHardwareBuffer_Desc & a,const AHardwareBuffer_Desc & b)169 bool operator==(const AHardwareBuffer_Desc& a, const AHardwareBuffer_Desc& b) {
170 return a.width == b.width && a.height == b.height && a.layers == b.layers &&
171 a.usage == b.usage && a.format == b.format;
172 }
operator !=(const AHardwareBuffer_Desc & a,const AHardwareBuffer_Desc & b)173 bool operator!=(const AHardwareBuffer_Desc& a, const AHardwareBuffer_Desc& b) {
174 return !(a == b);
175 }
176
177 namespace android {
178
179 // Test that passing in NULL values to allocate works as expected.
TEST(AHardwareBufferTest,AllocateFailsWithNullInput)180 TEST(AHardwareBufferTest, AllocateFailsWithNullInput) {
181 AHardwareBuffer* buffer;
182 AHardwareBuffer_Desc desc;
183
184 memset(&desc, 0, sizeof(AHardwareBuffer_Desc));
185
186 int res = AHardwareBuffer_allocate(&desc, (AHardwareBuffer * * _Nonnull)NULL);
187 EXPECT_EQ(BAD_VALUE, res);
188 res = AHardwareBuffer_allocate((AHardwareBuffer_Desc* _Nonnull)NULL, &buffer);
189 EXPECT_EQ(BAD_VALUE, res);
190 res = AHardwareBuffer_allocate((AHardwareBuffer_Desc* _Nonnull)NULL,
191 (AHardwareBuffer * * _Nonnull)NULL);
192 EXPECT_EQ(BAD_VALUE, res);
193 }
194
195 // Test that passing in NULL values to allocate works as expected.
TEST(AHardwareBufferTest,BlobFormatRequiresHeight1)196 TEST(AHardwareBufferTest, BlobFormatRequiresHeight1) {
197 AHardwareBuffer* buffer;
198 AHardwareBuffer_Desc desc = {};
199
200 desc.width = 2;
201 desc.height = 4;
202 desc.layers = 1;
203 desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
204 desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
205 int res = AHardwareBuffer_allocate(&desc, &buffer);
206 EXPECT_EQ(BAD_VALUE, res);
207
208 desc.height = 1;
209 res = AHardwareBuffer_allocate(&desc, &buffer);
210 EXPECT_EQ(NO_ERROR, res);
211 EXPECT_EQ(desc, GetDescription(buffer));
212 AHardwareBuffer_release(buffer);
213 buffer = NULL;
214 }
215
216 // Test that allocate can create an AHardwareBuffer correctly.
TEST(AHardwareBufferTest,AllocateSucceeds)217 TEST(AHardwareBufferTest, AllocateSucceeds) {
218 AHardwareBuffer* buffer = NULL;
219 AHardwareBuffer_Desc desc = {};
220
221 desc.width = 2;
222 desc.height = 4;
223 desc.layers = 1;
224 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
225 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
226 int res = AHardwareBuffer_allocate(&desc, &buffer);
227 EXPECT_EQ(NO_ERROR, res);
228 EXPECT_EQ(desc, GetDescription(buffer));
229 AHardwareBuffer_release(buffer);
230 buffer = NULL;
231
232 desc.width = 4;
233 desc.height = 12;
234 desc.layers = 1;
235 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
236 desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
237 res = AHardwareBuffer_allocate(&desc, &buffer);
238 EXPECT_EQ(NO_ERROR, res);
239 EXPECT_EQ(desc, GetDescription(buffer));
240 AHardwareBuffer_release(buffer);
241 }
242
243 // Test that allocate can create YUV AHardwareBuffers correctly.
TEST(AHardwareBufferTest,YuvAllocateSucceeds)244 TEST(AHardwareBufferTest, YuvAllocateSucceeds) {
245 AHardwareBuffer* buffer = NULL;
246 AHardwareBuffer_Desc desc = {};
247
248 desc.width = 16;
249 desc.height = 16;
250 desc.layers = 1;
251 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
252 desc.format = AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
253 int res = AHardwareBuffer_allocate(&desc, &buffer);
254 EXPECT_EQ(NO_ERROR, res);
255 EXPECT_EQ(desc, GetDescription(buffer));
256 AHardwareBuffer_release(buffer);
257 buffer = NULL;
258 }
259
TEST(AHardwareBufferTest,DescribeSucceeds)260 TEST(AHardwareBufferTest, DescribeSucceeds) {
261 AHardwareBuffer* buffer = NULL;
262 AHardwareBuffer_Desc desc = {};
263
264 desc.width = 2;
265 desc.height = 4;
266 desc.layers = 1;
267 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
268 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
269 int res = AHardwareBuffer_allocate(&desc, &buffer);
270 EXPECT_EQ(NO_ERROR, res);
271
272 // Description of a null buffer should be all zeros.
273 AHardwareBuffer_Desc scratch_desc;
274 memset(&scratch_desc, 0, sizeof(AHardwareBuffer_Desc));
275 AHardwareBuffer_describe((AHardwareBuffer* _Nonnull)NULL, &scratch_desc);
276 EXPECT_EQ(0U, scratch_desc.width);
277 EXPECT_EQ(0U, scratch_desc.height);
278
279 // This shouldn't crash.
280 AHardwareBuffer_describe(buffer, (AHardwareBuffer_Desc* _Nonnull)NULL);
281
282 // Description of created buffer should match requsted description.
283 EXPECT_EQ(desc, GetDescription(buffer));
284 AHardwareBuffer_release(buffer);
285 }
286
287 struct ClientData {
288 int fd;
289 AHardwareBuffer* buffer;
ClientDataandroid::ClientData290 ClientData(int fd_in, AHardwareBuffer* buffer_in) : fd(fd_in), buffer(buffer_in) {}
291 };
292
clientFunction(void * data)293 static void* clientFunction(void* data) {
294 ClientData* pdata = reinterpret_cast<ClientData*>(data);
295 int err = AHardwareBuffer_sendHandleToUnixSocket(pdata->buffer, pdata->fd);
296 EXPECT_EQ(NO_ERROR, err);
297 close(pdata->fd);
298 return 0;
299 }
300
TEST(AHardwareBufferTest,SendAndRecvSucceeds)301 TEST(AHardwareBufferTest, SendAndRecvSucceeds) {
302 AHardwareBuffer* buffer = NULL;
303 AHardwareBuffer_Desc desc = {};
304
305 desc.width = 2;
306 desc.height = 4;
307 desc.layers = 1;
308 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
309 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
310
311 // Test that an invalid buffer fails.
312 int err = AHardwareBuffer_sendHandleToUnixSocket((AHardwareBuffer* _Nonnull)NULL, 0);
313 EXPECT_EQ(BAD_VALUE, err);
314 err = 0;
315 err = AHardwareBuffer_sendHandleToUnixSocket(buffer, 0);
316 EXPECT_EQ(BAD_VALUE, err);
317
318 // Allocate the buffer.
319 err = AHardwareBuffer_allocate(&desc, &buffer);
320 EXPECT_EQ(NO_ERROR, err);
321
322 int fds[2];
323 err = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds);
324
325 // Launch a client that will send the buffer back.
326 ClientData data(fds[1], buffer);
327 pthread_t thread;
328 EXPECT_EQ(0, pthread_create(&thread, NULL, clientFunction, &data));
329
330 // Receive the buffer.
331 err = AHardwareBuffer_recvHandleFromUnixSocket(fds[0], (AHardwareBuffer * * _Nonnull)NULL);
332 EXPECT_EQ(BAD_VALUE, err);
333
334 AHardwareBuffer* received = NULL;
335 err = AHardwareBuffer_recvHandleFromUnixSocket(fds[0], &received);
336 EXPECT_EQ(NO_ERROR, err);
337 EXPECT_TRUE(received != NULL);
338 EXPECT_EQ(desc, GetDescription(received));
339
340 void* ret_val;
341 EXPECT_EQ(0, pthread_join(thread, &ret_val));
342 EXPECT_EQ(NULL, ret_val);
343 close(fds[0]);
344
345 AHardwareBuffer_release(buffer);
346 AHardwareBuffer_release(received);
347 }
348
TEST(AHardwareBufferTest,LockAndGetInfoAndUnlockSucceed)349 TEST(AHardwareBufferTest, LockAndGetInfoAndUnlockSucceed) {
350 AHardwareBuffer* buffer = nullptr;
351 AHardwareBuffer_Desc desc = {};
352
353 desc.width = 2;
354 desc.height = 4;
355 desc.layers = 1;
356 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
357 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
358
359 int32_t bytesPerPixel = std::numeric_limits<int32_t>::min();
360 int32_t bytesPerStride = std::numeric_limits<int32_t>::min();
361
362 // Test that an invalid buffer fails.
363 int err =
364 AHardwareBuffer_lockAndGetInfo((AHardwareBuffer* _Nonnull)NULL, 0, -1, NULL,
365 (void** _Nonnull)NULL, &bytesPerPixel, &bytesPerStride);
366 EXPECT_EQ(BAD_VALUE, err);
367
368 err = AHardwareBuffer_allocate(&desc, &buffer);
369 EXPECT_EQ(NO_ERROR, err);
370 void* bufferData = NULL;
371
372 // Test invalid usage flag
373 err = AHardwareBuffer_lockAndGetInfo(buffer,
374 ~(AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK |
375 AHARDWAREBUFFER_USAGE_CPU_READ_MASK),
376 -1, NULL, &bufferData, &bytesPerPixel, &bytesPerStride);
377 EXPECT_EQ(BAD_VALUE, err);
378
379 err = AHardwareBuffer_lockAndGetInfo(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1, NULL,
380 &bufferData, &bytesPerPixel, &bytesPerStride);
381
382 if (bytesPerPixel == -1 || bytesPerStride == -1) {
383 EXPECT_EQ(INVALID_OPERATION, err);
384 } else {
385 EXPECT_EQ(NO_ERROR, err);
386 EXPECT_LE(0, bytesPerPixel);
387 EXPECT_LE(0, bytesPerStride);
388 EXPECT_TRUE(bufferData != NULL);
389
390 err = AHardwareBuffer_unlock(buffer, nullptr);
391 EXPECT_EQ(NO_ERROR, err);
392 }
393 AHardwareBuffer_release(buffer);
394 }
395
TEST(AHardwareBufferTest,LockAndUnlockSucceed)396 TEST(AHardwareBufferTest, LockAndUnlockSucceed) {
397 AHardwareBuffer* buffer = NULL;
398 AHardwareBuffer_Desc desc = {};
399
400 desc.width = 2;
401 desc.height = 4;
402 desc.layers = 1;
403 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
404 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
405
406 // Test that an invalid buffer fails.
407 int err = AHardwareBuffer_lock((AHardwareBuffer* _Nonnull)NULL, 0, -1, NULL,
408 (void** _Nonnull)NULL);
409 EXPECT_EQ(BAD_VALUE, err);
410 err = 0;
411
412 // Allocate the buffer.
413 err = AHardwareBuffer_allocate(&desc, &buffer);
414 EXPECT_EQ(NO_ERROR, err);
415 void* bufferData = NULL;
416 err = AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1, NULL,
417 &bufferData);
418 EXPECT_EQ(NO_ERROR, err);
419 EXPECT_TRUE(bufferData != NULL);
420 err = AHardwareBuffer_unlock(buffer, nullptr);
421
422 AHardwareBuffer_release(buffer);
423 }
424
TEST(AHardwareBufferTest,PlanarLockAndUnlockYuvSucceed)425 TEST(AHardwareBufferTest, PlanarLockAndUnlockYuvSucceed) {
426 AHardwareBuffer* buffer = NULL;
427 AHardwareBuffer_Desc desc = {};
428
429 desc.width = 16;
430 desc.height = 32;
431 desc.layers = 1;
432 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
433 desc.format = AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
434
435 // Test that an invalid buffer fails.
436 int err = AHardwareBuffer_lock((AHardwareBuffer* _Nonnull)NULL, 0, -1, NULL,
437 (void** _Nonnull)NULL);
438 EXPECT_EQ(BAD_VALUE, err);
439 err = 0;
440
441 // Allocate the buffer.
442 err = AHardwareBuffer_allocate(&desc, &buffer);
443 EXPECT_EQ(NO_ERROR, err);
444
445 // Lock its planes
446 AHardwareBuffer_Planes planes;
447 err = AHardwareBuffer_lockPlanes(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1, NULL,
448 &planes);
449
450 // Make sure everything looks right
451 EXPECT_EQ(NO_ERROR, err);
452 EXPECT_EQ(3U, planes.planeCount);
453
454 EXPECT_TRUE(planes.planes[0].data != NULL);
455 EXPECT_EQ(1U, planes.planes[0].pixelStride);
456 EXPECT_TRUE(planes.planes[0].rowStride >= 16);
457
458 EXPECT_TRUE(planes.planes[1].data != NULL);
459 EXPECT_THAT(planes.planes[1].pixelStride, AnyOf(Eq(1U), Eq(2U)));
460 EXPECT_TRUE(planes.planes[1].rowStride >= 8);
461
462 EXPECT_TRUE(planes.planes[2].data != NULL);
463 EXPECT_THAT(planes.planes[2].pixelStride, AnyOf(Eq(1U), Eq(2U)));
464 EXPECT_TRUE(planes.planes[2].rowStride >= 8);
465
466 // Unlock
467 err = AHardwareBuffer_unlock(buffer, nullptr);
468 EXPECT_EQ(NO_ERROR, err);
469
470 AHardwareBuffer_release(buffer);
471 }
472
TEST(AHardwareBufferTest,PlanarLockAndUnlockYuvP010Succeed)473 TEST(AHardwareBufferTest, PlanarLockAndUnlockYuvP010Succeed) {
474 AHardwareBuffer* buffer = NULL;
475 AHardwareBuffer_Desc desc = {};
476
477 desc.width = 32;
478 desc.height = 32;
479 desc.layers = 1;
480 desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
481 desc.format = AHARDWAREBUFFER_FORMAT_YCbCr_P010;
482
483 if (!AHardwareBuffer_isSupported(&desc)) {
484 ALOGI("Test skipped: AHARDWAREBUFFER_FORMAT_YCbCr_P010 not supported.");
485 return;
486 }
487
488 // Allocate the buffer.
489 int err = AHardwareBuffer_allocate(&desc, &buffer);
490 EXPECT_EQ(NO_ERROR, err);
491
492 // Lock its planes
493 AHardwareBuffer_Planes planes;
494 err = AHardwareBuffer_lockPlanes(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1, NULL,
495 &planes);
496
497 // Make sure everything looks right
498 EXPECT_EQ(NO_ERROR, err);
499 EXPECT_EQ(3U, planes.planeCount);
500
501 const uint32_t yPlaneWidth = desc.width;
502 const uint32_t cPlaneWidth = desc.width / 2;
503 const uint32_t bytesPerPixel = 2;
504
505 EXPECT_THAT(planes.planes[0].data, NotNull());
506 EXPECT_THAT(planes.planes[0].pixelStride, Eq(bytesPerPixel));
507 EXPECT_THAT(planes.planes[0].rowStride, Ge(yPlaneWidth * bytesPerPixel));
508
509 EXPECT_THAT(planes.planes[1].data, NotNull());
510 EXPECT_THAT(planes.planes[1].pixelStride, Eq(bytesPerPixel * /*interleaved=*/2));
511 EXPECT_THAT(planes.planes[1].rowStride, Ge(cPlaneWidth * planes.planes[1].pixelStride));
512
513 EXPECT_THAT(planes.planes[2].data, NotNull());
514 EXPECT_THAT(planes.planes[2].pixelStride, Eq(bytesPerPixel * /*interleaved=*/2));
515 EXPECT_THAT(planes.planes[2].rowStride, Ge(cPlaneWidth * planes.planes[2].pixelStride));
516
517 // Unlock
518 err = AHardwareBuffer_unlock(buffer, nullptr);
519 EXPECT_EQ(NO_ERROR, err);
520
521 AHardwareBuffer_release(buffer);
522 }
523
TEST(AHardwareBufferTest,PlanarLockAndUnlockYuvP210Succeed)524 TEST(AHardwareBufferTest, PlanarLockAndUnlockYuvP210Succeed) {
525 AHardwareBuffer* buffer = NULL;
526 AHardwareBuffer_Desc desc = {};
527
528 desc.width = 32;
529 desc.height = 32;
530 desc.layers = 1;
531 desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
532 desc.format = AHARDWAREBUFFER_FORMAT_YCbCr_P210;
533
534 if (!AHardwareBuffer_isSupported(&desc)) {
535 ALOGI("Test skipped: AHARDWAREBUFFER_FORMAT_YCbCr_P210 not supported.");
536 return;
537 }
538
539 // Allocate the buffer.
540 int err = AHardwareBuffer_allocate(&desc, &buffer);
541 EXPECT_EQ(NO_ERROR, err);
542
543 // Lock its planes
544 AHardwareBuffer_Planes planes;
545 err = AHardwareBuffer_lockPlanes(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1, NULL,
546 &planes);
547
548 // Make sure everything looks right
549 EXPECT_EQ(NO_ERROR, err);
550 EXPECT_EQ(3U, planes.planeCount);
551
552 const uint32_t yPlaneWidth = desc.width;
553 const uint32_t cPlaneWidth = desc.width / 2;
554 const uint32_t bytesPerPixel = 2;
555
556 EXPECT_THAT(planes.planes[0].data, NotNull());
557 EXPECT_THAT(planes.planes[0].pixelStride, Eq(bytesPerPixel));
558 EXPECT_THAT(planes.planes[0].rowStride, Ge(yPlaneWidth * bytesPerPixel));
559
560 EXPECT_THAT(planes.planes[1].data, NotNull());
561 EXPECT_THAT(planes.planes[1].pixelStride, Eq(bytesPerPixel * /*interleaved=*/2));
562 EXPECT_THAT(planes.planes[1].rowStride, Ge(cPlaneWidth * planes.planes[1].pixelStride));
563
564 EXPECT_THAT(planes.planes[2].data, NotNull());
565 EXPECT_THAT(planes.planes[2].pixelStride, Eq(bytesPerPixel * /*interleaved=*/2));
566 EXPECT_THAT(planes.planes[2].rowStride, Ge(cPlaneWidth * planes.planes[2].pixelStride));
567
568 // Unlock
569 err = AHardwareBuffer_unlock(buffer, nullptr);
570 EXPECT_EQ(NO_ERROR, err);
571
572 AHardwareBuffer_release(buffer);
573 }
574
TEST(AHardwareBufferTest,PlanarLockAndUnlockRgbaSucceed)575 TEST(AHardwareBufferTest, PlanarLockAndUnlockRgbaSucceed) {
576 AHardwareBuffer* buffer = NULL;
577 AHardwareBuffer_Desc desc = {};
578
579 desc.width = 16;
580 desc.height = 32;
581 desc.layers = 1;
582 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
583 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
584
585 // Test that an invalid buffer fails.
586 int err = AHardwareBuffer_lock((AHardwareBuffer* _Nonnull)NULL, 0, -1, NULL,
587 (void** _Nonnull)NULL);
588 EXPECT_EQ(BAD_VALUE, err);
589 err = 0;
590
591 // Allocate the buffer.
592 err = AHardwareBuffer_allocate(&desc, &buffer);
593 EXPECT_EQ(NO_ERROR, err);
594
595 // Lock its planes
596 AHardwareBuffer_Planes planes;
597 err = AHardwareBuffer_lockPlanes(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1, NULL,
598 &planes);
599
600 // Make sure everything looks right
601 EXPECT_EQ(NO_ERROR, err);
602 EXPECT_EQ(1U, planes.planeCount);
603
604 EXPECT_TRUE(planes.planes[0].data != NULL);
605 EXPECT_EQ(4U, planes.planes[0].pixelStride);
606 EXPECT_TRUE(planes.planes[0].rowStride >= 64);
607
608 // Unlock
609 err = AHardwareBuffer_unlock(buffer, nullptr);
610 EXPECT_EQ(NO_ERROR, err);
611
612 AHardwareBuffer_release(buffer);
613 }
614
TEST(AHardwareBufferTest,ProtectedContentAndCpuReadIncompatible)615 TEST(AHardwareBufferTest, ProtectedContentAndCpuReadIncompatible) {
616 AHardwareBuffer* buffer = NULL;
617 AHardwareBuffer_Desc desc = {};
618 desc.width = 120;
619 desc.height = 240;
620 desc.layers = 1;
621 desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
622 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
623
624 // Allocation of a CPU-readable buffer should succeed...
625 int err = AHardwareBuffer_allocate(&desc, &buffer);
626 EXPECT_EQ(NO_ERROR, err);
627 AHardwareBuffer_release(buffer);
628 buffer = nullptr;
629
630 // ...but not if it's a protected buffer.
631 desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
632 AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
633 err = AHardwareBuffer_allocate(&desc, &buffer);
634 EXPECT_NE(NO_ERROR, err);
635
636 desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_CPU_READ_RARELY |
637 AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
638 err = AHardwareBuffer_allocate(&desc, &buffer);
639 EXPECT_NE(NO_ERROR, err);
640 }
641
TEST(AHardwareBufferTest,GetIdSucceed)642 TEST(AHardwareBufferTest, GetIdSucceed) {
643 AHardwareBuffer* buffer1 = nullptr;
644 uint64_t id1 = 0;
645 const AHardwareBuffer_Desc desc = {
646 .width = 4,
647 .height = 4,
648 .layers = 1,
649 .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
650 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,
651 };
652 int err = AHardwareBuffer_allocate(&desc, &buffer1);
653 EXPECT_EQ(NO_ERROR, err);
654 EXPECT_NE(nullptr, buffer1);
655 EXPECT_EQ(0, AHardwareBuffer_getId(buffer1, &id1));
656 EXPECT_NE(id1, 0ULL);
657
658 AHardwareBuffer* buffer2 = nullptr;
659 uint64_t id2 = 0;
660 err = AHardwareBuffer_allocate(&desc, &buffer2);
661 EXPECT_EQ(NO_ERROR, err);
662 EXPECT_NE(nullptr, buffer2);
663 EXPECT_EQ(0, AHardwareBuffer_getId(buffer2, &id2));
664 EXPECT_NE(id2, 0ULL);
665
666 EXPECT_NE(id1, id2);
667 }
668
TEST(AHardwareBufferTest,AllocateLockUnlockDeallocateStressTest)669 TEST(AHardwareBufferTest, AllocateLockUnlockDeallocateStressTest) {
670 constexpr int kNumThreads = 20;
671 std::vector<std::thread> threads;
672
673 for (int job = 0; job < kNumThreads; ++job) {
674 threads.emplace_back([]() {
675 constexpr int kNumIterations = 10000;
676 for (int i = 0; i < kNumIterations; ++i) {
677 // Allocate
678 AHardwareBuffer* ahwb = nullptr;
679 int error = 0;
680 const AHardwareBuffer_Desc desc = {.width = 1,
681 .height = 1,
682 .layers = 1,
683 .format = AHARDWAREBUFFER_FORMAT_BLOB,
684 .usage = AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
685 AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
686 AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER};
687 error = AHardwareBuffer_allocate(&desc, &ahwb);
688 EXPECT_EQ(NO_ERROR, error) << "AHardwareBuffer_allocate failed: " << error;
689 EXPECT_NE(nullptr, ahwb);
690
691 // Lock
692 void* mem = nullptr;
693 error = AHardwareBuffer_lock(ahwb, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1,
694 nullptr, &mem);
695 EXPECT_EQ(NO_ERROR, error) << "AHardwareBuffer_lock failed: " << error;
696
697 // Unlock
698 error = AHardwareBuffer_unlock(ahwb, /*fence_file_descriptor*/ nullptr);
699 EXPECT_EQ(NO_ERROR, error) << "AHardwareBuffer_unlock failed: " << error;
700
701 // Release
702 AHardwareBuffer_release(ahwb);
703 }
704 });
705 }
706 for (auto& thread : threads) {
707 thread.join();
708 }
709 }
710
711 // The test tried to lock buffer without cpu access
TEST(AHardwareBufferTest,LockWithZeroAccessTest)712 TEST(AHardwareBufferTest, LockWithZeroAccessTest) {
713 if (IsSoftwareRenderer()) {
714 ALOGI("Test skipped: device uses software rendering which implicitly handles GPU usages as "
715 "CPU usages.");
716 return;
717 }
718
719 const AHardwareBuffer_Desc ahbDesc {
720 .width = 128,
721 .height = 128,
722 .layers = 1,
723 .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
724 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER
725 };
726 AHardwareBuffer* aHardwareBuffer = nullptr;
727 int err = AHardwareBuffer_allocate(&ahbDesc, &aHardwareBuffer);
728 EXPECT_EQ(NO_ERROR, err);
729
730 AHardwareBuffer_Planes planeInfo = {};
731 err = AHardwareBuffer_lockPlanes(aHardwareBuffer, 0, -1, nullptr, &planeInfo);
732 EXPECT_NE(NO_ERROR, err);
733
734 AHardwareBuffer_release(aHardwareBuffer);
735 }
736
737 } // namespace android
738