1 /*
2 * Copyright (C) 2012 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 "CpuConsumer_test"
18 //#define LOG_NDEBUG 0
19 //#define LOG_NNDEBUG 0
20
21 #ifdef LOG_NNDEBUG
22 #define ALOGVV(...) ALOGV(__VA_ARGS__)
23 #else
24 #define ALOGVV(...) ((void)0)
25 #endif
26
27 #include <gtest/gtest.h>
28 #include <gui/CpuConsumer.h>
29 #include <gui/Surface.h>
30 #include <ui/GraphicBuffer.h>
31 #include <utils/String8.h>
32 #include <utils/Thread.h>
33 #include <utils/Mutex.h>
34 #include <utils/Condition.h>
35
36 #include <thread>
37 #include <vector>
38 #define CPU_CONSUMER_TEST_FORMAT_RAW 0
39 #define CPU_CONSUMER_TEST_FORMAT_Y8 0
40 #define CPU_CONSUMER_TEST_FORMAT_Y16 0
41 #define CPU_CONSUMER_TEST_FORMAT_RGBA_8888 1
42
43 namespace android {
44
45 struct CpuConsumerTestParams {
46 uint32_t width;
47 uint32_t height;
48 int maxLockedBuffers;
49 PixelFormat format;
50 };
51
operator <<(::std::ostream & os,const CpuConsumerTestParams & p)52 ::std::ostream& operator<<(::std::ostream& os, const CpuConsumerTestParams& p) {
53 return os << "[ (" << p.width << ", " << p.height << "), B:"
54 << p.maxLockedBuffers << ", F:0x"
55 << ::std::hex << p.format << "]";
56 }
57
58 class CpuConsumerTest : public ::testing::TestWithParam<CpuConsumerTestParams> {
59 protected:
60
SetUp()61 virtual void SetUp() {
62 const ::testing::TestInfo* const test_info =
63 ::testing::UnitTest::GetInstance()->current_test_info();
64 CpuConsumerTestParams params = GetParam();
65 ALOGV("** Starting test %s (%d x %d, %d, 0x%x)",
66 test_info->name(),
67 params.width, params.height,
68 params.maxLockedBuffers, params.format);
69 sp<IGraphicBufferProducer> producer;
70 sp<IGraphicBufferConsumer> consumer;
71 BufferQueue::createBufferQueue(&producer, &consumer);
72 mCC = new CpuConsumer(consumer, params.maxLockedBuffers);
73 String8 name("CpuConsumer_Under_Test");
74 mCC->setName(name);
75 mSTC = new Surface(producer);
76 mANW = mSTC;
77 }
78
TearDown()79 virtual void TearDown() {
80 mANW.clear();
81 mSTC.clear();
82 mCC.clear();
83 }
84
85 class FrameWaiter : public CpuConsumer::FrameAvailableListener {
86 public:
FrameWaiter()87 FrameWaiter():
88 mPendingFrames(0) {
89 }
90
waitForFrame()91 void waitForFrame() {
92 Mutex::Autolock lock(mMutex);
93 while (mPendingFrames == 0) {
94 mCondition.wait(mMutex);
95 }
96 mPendingFrames--;
97 }
98
onFrameAvailable(const BufferItem &)99 virtual void onFrameAvailable(const BufferItem&) {
100 Mutex::Autolock lock(mMutex);
101 mPendingFrames++;
102 mCondition.signal();
103 }
104
105 int mPendingFrames;
106 Mutex mMutex;
107 Condition mCondition;
108 };
109
110 // Note that SurfaceTexture will lose the notifications
111 // onBuffersReleased and onFrameAvailable as there is currently
112 // no way to forward the events. This DisconnectWaiter will not let the
113 // disconnect finish until finishDisconnect() is called. It will
114 // also block until a disconnect is called
115 class DisconnectWaiter : public BufferQueue::ConsumerListener {
116 public:
DisconnectWaiter()117 DisconnectWaiter () :
118 mWaitForDisconnect(false),
119 mPendingFrames(0) {
120 }
121
waitForFrame()122 void waitForFrame() {
123 Mutex::Autolock lock(mMutex);
124 while (mPendingFrames == 0) {
125 mFrameCondition.wait(mMutex);
126 }
127 mPendingFrames--;
128 }
129
onFrameAvailable(const BufferItem &)130 virtual void onFrameAvailable(const BufferItem&) {
131 Mutex::Autolock lock(mMutex);
132 mPendingFrames++;
133 mFrameCondition.signal();
134 }
135
onBuffersReleased()136 virtual void onBuffersReleased() {
137 Mutex::Autolock lock(mMutex);
138 while (!mWaitForDisconnect) {
139 mDisconnectCondition.wait(mMutex);
140 }
141 }
142
finishDisconnect()143 void finishDisconnect() {
144 Mutex::Autolock lock(mMutex);
145 mWaitForDisconnect = true;
146 mDisconnectCondition.signal();
147 }
148
149 private:
150 Mutex mMutex;
151
152 bool mWaitForDisconnect;
153 Condition mDisconnectCondition;
154
155 int mPendingFrames;
156 Condition mFrameCondition;
157 };
158
159 sp<CpuConsumer> mCC;
160 sp<Surface> mSTC;
161 sp<ANativeWindow> mANW;
162 };
163
164 #define ASSERT_NO_ERROR(err, msg) \
165 ASSERT_EQ(NO_ERROR, err) << (msg) << strerror(-(err))
166
checkPixel(const CpuConsumer::LockedBuffer & buf,uint32_t x,uint32_t y,uint32_t r,uint32_t g=0,uint32_t b=0)167 void checkPixel(const CpuConsumer::LockedBuffer &buf,
168 uint32_t x, uint32_t y, uint32_t r, uint32_t g=0, uint32_t b=0) {
169 // Ignores components that don't exist for given pixel
170 switch(buf.format) {
171 case HAL_PIXEL_FORMAT_RAW16: {
172 String8 msg;
173 uint16_t *bPtr = (uint16_t*)buf.data;
174 bPtr += y * buf.stride + x;
175 // GRBG Bayer mosaic; only check the matching channel
176 switch( ((y & 1) << 1) | (x & 1) ) {
177 case 0: // G
178 case 3: // G
179 EXPECT_EQ(g, *bPtr);
180 break;
181 case 1: // R
182 EXPECT_EQ(r, *bPtr);
183 break;
184 case 2: // B
185 EXPECT_EQ(b, *bPtr);
186 break;
187 }
188 break;
189 }
190 // ignores g,b
191 case HAL_PIXEL_FORMAT_Y8: {
192 uint8_t *bPtr = (uint8_t*)buf.data;
193 bPtr += y * buf.stride + x;
194 EXPECT_EQ(r, *bPtr) << "at x = " << x << " y = " << y;
195 break;
196 }
197 // ignores g,b
198 case HAL_PIXEL_FORMAT_Y16: {
199 // stride is in pixels, not in bytes
200 uint16_t *bPtr = ((uint16_t*)buf.data) + y * buf.stride + x;
201
202 EXPECT_EQ(r, *bPtr) << "at x = " << x << " y = " << y;
203 break;
204 }
205 case HAL_PIXEL_FORMAT_RGBA_8888: {
206 const int bytesPerPixel = 4;
207 uint8_t *bPtr = (uint8_t*)buf.data;
208 bPtr += (y * buf.stride + x) * bytesPerPixel;
209
210 EXPECT_EQ(r, bPtr[0]) << "at x = " << x << " y = " << y;
211 EXPECT_EQ(g, bPtr[1]) << "at x = " << x << " y = " << y;
212 EXPECT_EQ(b, bPtr[2]) << "at x = " << x << " y = " << y;
213 break;
214 }
215 default: {
216 ADD_FAILURE() << "Unknown format for check:" << buf.format;
217 break;
218 }
219 }
220 }
221
222 // Fill a YV12 buffer with a multi-colored checkerboard pattern
223 void fillYV12Buffer(uint8_t* buf, int w, int h, int stride);
224
225 // Fill a Y8/Y16 buffer with a multi-colored checkerboard pattern
226 template <typename T> // T == uint8_t or uint16_t
fillGreyscaleBuffer(T * buf,int w,int h,int stride,int bpp)227 void fillGreyscaleBuffer(T* buf, int w, int h, int stride, int bpp) {
228 const int blockWidth = w > 16 ? w / 16 : 1;
229 const int blockHeight = h > 16 ? h / 16 : 1;
230 const int yuvTexOffsetY = 0;
231
232 ASSERT_TRUE(bpp == 8 || bpp == 16);
233 ASSERT_TRUE(sizeof(T)*8 == bpp);
234
235 // stride is in pixels, not in bytes
236 int yuvTexStrideY = stride;
237 for (int x = 0; x < w; x++) {
238 for (int y = 0; y < h; y++) {
239 int parityX = (x / blockWidth) & 1;
240 int parityY = (y / blockHeight) & 1;
241 T intensity = (parityX ^ parityY) ? 63 : 191;
242 buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
243 }
244 }
245 }
246
chooseColorRgba8888(int blockX,int blockY,uint8_t channel)247 inline uint8_t chooseColorRgba8888(int blockX, int blockY, uint8_t channel) {
248 const int colorVariations = 3;
249 uint8_t color = ((blockX % colorVariations) + (blockY % colorVariations))
250 % (colorVariations) == channel ? 191: 63;
251
252 return color;
253 }
254
255 // Fill a RGBA8888 buffer with a multi-colored checkerboard pattern
fillRgba8888Buffer(uint8_t * buf,int w,int h,int stride)256 void fillRgba8888Buffer(uint8_t* buf, int w, int h, int stride)
257 {
258 const int blockWidth = w > 16 ? w / 16 : 1;
259 const int blockHeight = h > 16 ? h / 16 : 1;
260 const int bytesPerPixel = 4;
261
262 // stride is in pixels, not in bytes
263 for (int x = 0; x < w; ++x) {
264 for (int y = 0; y < h; ++y) {
265 int blockX = (x / blockWidth);
266 int blockY = (y / blockHeight);
267
268 uint8_t r = chooseColorRgba8888(blockX, blockY, 0);
269 uint8_t g = chooseColorRgba8888(blockX, blockY, 1);
270 uint8_t b = chooseColorRgba8888(blockX, blockY, 2);
271
272 buf[(y*stride + x)*bytesPerPixel + 0] = r;
273 buf[(y*stride + x)*bytesPerPixel + 1] = g;
274 buf[(y*stride + x)*bytesPerPixel + 2] = b;
275 buf[(y*stride + x)*bytesPerPixel + 3] = 255;
276 }
277 }
278 }
279
280 // Fill a RAW sensor buffer with a multi-colored checkerboard pattern.
281 // Assumes GRBG mosaic ordering. Result should be a grid in a 2x2 pattern
282 // of [ R, B; G, W]
fillBayerRawBuffer(uint8_t * buf,int w,int h,int stride)283 void fillBayerRawBuffer(uint8_t* buf, int w, int h, int stride) {
284 ALOGVV("fillBayerRawBuffer: %p with %d x %d, stride %d", buf, w, h ,stride);
285 // Blocks need to be even-width/height, aim for 8-wide otherwise
286 const int blockWidth = (w > 16 ? w / 8 : 2) & ~0x1;
287 const int blockHeight = (h > 16 ? h / 8 : 2) & ~0x1;
288 for (int y = 0; y < h; y+=2) {
289 uint16_t *bPtr1 = ((uint16_t*)buf) + stride*y;
290 uint16_t *bPtr2 = bPtr1 + stride;
291 for (int x = 0; x < w; x+=2) {
292 int blockX = (x / blockWidth ) & 1;
293 int blockY = (y / blockHeight) & 1;
294 unsigned short r = (blockX == blockY) ? 1000 : 200;
295 unsigned short g = blockY ? 1000: 200;
296 unsigned short b = blockX ? 1000: 200;
297 // GR row
298 *bPtr1++ = g;
299 *bPtr1++ = r;
300 // BG row
301 *bPtr2++ = b;
302 *bPtr2++ = g;
303 }
304 }
305
306 }
307
308 template<typename T> // uint8_t or uint16_t
checkGreyscaleBuffer(const CpuConsumer::LockedBuffer & buf)309 void checkGreyscaleBuffer(const CpuConsumer::LockedBuffer &buf) {
310 uint32_t w = buf.width;
311 uint32_t h = buf.height;
312 const int blockWidth = w > 16 ? w / 16 : 1;
313 const int blockHeight = h > 16 ? h / 16 : 1;
314
315 // Top-left square is bright
316 checkPixel(buf, 0, 0, 191);
317 checkPixel(buf, 1, 0, 191);
318 checkPixel(buf, 0, 1, 191);
319 checkPixel(buf, 1, 1, 191);
320
321 // One-right square is dark
322 checkPixel(buf, blockWidth, 0, 63);
323 checkPixel(buf, blockWidth + 1, 0, 63);
324 checkPixel(buf, blockWidth, 1, 63);
325 checkPixel(buf, blockWidth + 1, 1, 63);
326
327 // One-down square is dark
328 checkPixel(buf, 0, blockHeight, 63);
329 checkPixel(buf, 1, blockHeight, 63);
330 checkPixel(buf, 0, blockHeight + 1, 63);
331 checkPixel(buf, 1, blockHeight + 1, 63);
332
333 // One-diag square is bright
334 checkPixel(buf, blockWidth, blockHeight, 191);
335 checkPixel(buf, blockWidth + 1, blockHeight, 191);
336 checkPixel(buf, blockWidth, blockHeight + 1, 191);
337 checkPixel(buf, blockWidth + 1, blockHeight + 1, 191);
338
339 // Test bottom-right pixel
340 const int maxBlockX = ((w-1 + (blockWidth-1)) / blockWidth) & 0x1;
341 const int maxBlockY = ((h-1 + (blockHeight-1)) / blockHeight) & 0x1;
342 uint32_t pixelValue = ((maxBlockX % 2) == (maxBlockY % 2)) ? 191 : 63;
343 checkPixel(buf, w-1, h-1, pixelValue);
344 }
345
checkRgba8888Buffer(const CpuConsumer::LockedBuffer & buf)346 void checkRgba8888Buffer(const CpuConsumer::LockedBuffer &buf) {
347 uint32_t w = buf.width;
348 uint32_t h = buf.height;
349 const int blockWidth = w > 16 ? w / 16 : 1;
350 const int blockHeight = h > 16 ? h / 16 : 1;
351
352 // Top-left square is bright red
353 checkPixel(buf, 0, 0, 191, 63, 63);
354 checkPixel(buf, 1, 0, 191, 63, 63);
355 checkPixel(buf, 0, 1, 191, 63, 63);
356 checkPixel(buf, 1, 1, 191, 63, 63);
357
358 // One-right square is bright green
359 checkPixel(buf, blockWidth, 0, 63, 191, 63);
360 checkPixel(buf, blockWidth + 1, 0, 63, 191, 63);
361 checkPixel(buf, blockWidth, 1, 63, 191, 63);
362 checkPixel(buf, blockWidth + 1, 1, 63, 191, 63);
363
364 // One-down square is bright green
365 checkPixel(buf, 0, blockHeight, 63, 191, 63);
366 checkPixel(buf, 1, blockHeight, 63, 191, 63);
367 checkPixel(buf, 0, blockHeight + 1, 63, 191, 63);
368 checkPixel(buf, 1, blockHeight + 1, 63, 191, 63);
369
370 // One-diag square is bright blue
371 checkPixel(buf, blockWidth, blockHeight, 63, 63, 191);
372 checkPixel(buf, blockWidth + 1, blockHeight, 63, 63, 191);
373 checkPixel(buf, blockWidth, blockHeight + 1, 63, 63, 191);
374 checkPixel(buf, blockWidth + 1, blockHeight + 1, 63, 63, 191);
375
376 // Test bottom-right pixel
377 {
378 const int maxBlockX = ((w-1) / blockWidth);
379 const int maxBlockY = ((h-1) / blockHeight);
380 uint8_t r = chooseColorRgba8888(maxBlockX, maxBlockY, 0);
381 uint8_t g = chooseColorRgba8888(maxBlockX, maxBlockY, 1);
382 uint8_t b = chooseColorRgba8888(maxBlockX, maxBlockY, 2);
383 checkPixel(buf, w-1, h-1, r, g, b);
384 }
385 }
386
checkBayerRawBuffer(const CpuConsumer::LockedBuffer & buf)387 void checkBayerRawBuffer(const CpuConsumer::LockedBuffer &buf) {
388 uint32_t w = buf.width;
389 uint32_t h = buf.height;
390 const int blockWidth = (w > 16 ? w / 8 : 2) & ~0x1;
391 const int blockHeight = (h > 16 ? h / 8 : 2) & ~0x1;
392
393 // Top-left square is red
394 checkPixel(buf, 0, 0, 1000, 200, 200);
395 checkPixel(buf, 1, 0, 1000, 200, 200);
396 checkPixel(buf, 0, 1, 1000, 200, 200);
397 checkPixel(buf, 1, 1, 1000, 200, 200);
398
399 // One-right square is blue
400 checkPixel(buf, blockWidth, 0, 200, 200, 1000);
401 checkPixel(buf, blockWidth + 1, 0, 200, 200, 1000);
402 checkPixel(buf, blockWidth, 1, 200, 200, 1000);
403 checkPixel(buf, blockWidth + 1, 1, 200, 200, 1000);
404
405 // One-down square is green
406 checkPixel(buf, 0, blockHeight, 200, 1000, 200);
407 checkPixel(buf, 1, blockHeight, 200, 1000, 200);
408 checkPixel(buf, 0, blockHeight + 1, 200, 1000, 200);
409 checkPixel(buf, 1, blockHeight + 1, 200, 1000, 200);
410
411 // One-diag square is white
412 checkPixel(buf, blockWidth, blockHeight, 1000, 1000, 1000);
413 checkPixel(buf, blockWidth + 1, blockHeight, 1000, 1000, 1000);
414 checkPixel(buf, blockWidth, blockHeight + 1, 1000, 1000, 1000);
415 checkPixel(buf, blockWidth + 1, blockHeight + 1, 1000, 1000, 1000);
416
417 // Test bottom-right pixel
418 const int maxBlockX = ((w-1) / blockWidth) & 0x1;
419 const int maxBlockY = ((w-1) / blockHeight) & 0x1;
420 unsigned short maxR = (maxBlockX == maxBlockY) ? 1000 : 200;
421 unsigned short maxG = maxBlockY ? 1000: 200;
422 unsigned short maxB = maxBlockX ? 1000: 200;
423 checkPixel(buf, w-1, h-1, maxR, maxG, maxB);
424 }
425
checkAnyBuffer(const CpuConsumer::LockedBuffer & buf,int format)426 void checkAnyBuffer(const CpuConsumer::LockedBuffer &buf, int format) {
427 switch (format) {
428 case HAL_PIXEL_FORMAT_RAW16:
429 checkBayerRawBuffer(buf);
430 break;
431 case HAL_PIXEL_FORMAT_Y8:
432 checkGreyscaleBuffer<uint8_t>(buf);
433 break;
434 case HAL_PIXEL_FORMAT_Y16:
435 checkGreyscaleBuffer<uint16_t>(buf);
436 break;
437 case HAL_PIXEL_FORMAT_RGBA_8888:
438 checkRgba8888Buffer(buf);
439 break;
440 }
441 }
442
443 // Configures the ANativeWindow producer-side interface based on test parameters
configureANW(const sp<ANativeWindow> & anw,const CpuConsumerTestParams & params,int maxBufferSlack)444 void configureANW(const sp<ANativeWindow>& anw,
445 const CpuConsumerTestParams& params,
446 int maxBufferSlack) {
447 status_t err;
448 err = native_window_api_connect(anw.get(), NATIVE_WINDOW_API_CPU);
449 ASSERT_NO_ERROR(err, "connect error: ");
450
451 err = native_window_set_buffers_dimensions(anw.get(),
452 params.width, params.height);
453 ASSERT_NO_ERROR(err, "set_buffers_dimensions error: ");
454
455 err = native_window_set_buffers_format(anw.get(), params.format);
456 ASSERT_NO_ERROR(err, "set_buffers_format error: ");
457
458 err = native_window_set_usage(anw.get(),
459 GRALLOC_USAGE_SW_WRITE_OFTEN);
460 ASSERT_NO_ERROR(err, "set_usage error: ");
461
462 int minUndequeuedBuffers;
463 err = anw.get()->query(anw.get(),
464 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
465 &minUndequeuedBuffers);
466 ASSERT_NO_ERROR(err, "query error: ");
467
468 ALOGVV("Setting buffer count to %d",
469 maxBufferSlack + 1 + minUndequeuedBuffers);
470 err = native_window_set_buffer_count(anw.get(),
471 maxBufferSlack + 1 + minUndequeuedBuffers);
472 ASSERT_NO_ERROR(err, "set_buffer_count error: ");
473
474 }
475
476 // Produce one frame of image data; assumes format and resolution configuration
477 // is already done.
produceOneFrame(const sp<ANativeWindow> & anw,const CpuConsumerTestParams & params,int64_t timestamp,uint32_t * stride)478 void produceOneFrame(const sp<ANativeWindow>& anw,
479 const CpuConsumerTestParams& params,
480 int64_t timestamp, uint32_t *stride) {
481 status_t err;
482 ANativeWindowBuffer* anb;
483 ALOGVV("Dequeue buffer from %p", anw.get());
484 err = native_window_dequeue_buffer_and_wait(anw.get(), &anb);
485 ASSERT_NO_ERROR(err, "dequeueBuffer error: ");
486
487 ASSERT_TRUE(anb != nullptr);
488
489 sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
490
491 *stride = buf->getStride();
492 uint8_t* img = nullptr;
493
494 ALOGVV("Lock buffer from %p for write", anw.get());
495 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
496 ASSERT_NO_ERROR(err, "lock error: ");
497
498 switch (params.format) {
499 case HAL_PIXEL_FORMAT_YV12:
500 fillYV12Buffer(img, params.width, params.height, *stride);
501 break;
502 case HAL_PIXEL_FORMAT_RAW16:
503 fillBayerRawBuffer(img, params.width, params.height, buf->getStride());
504 break;
505 case HAL_PIXEL_FORMAT_Y8:
506 fillGreyscaleBuffer<uint8_t>(img, params.width, params.height,
507 buf->getStride(), /*bpp*/8);
508 break;
509 case HAL_PIXEL_FORMAT_Y16:
510 fillGreyscaleBuffer<uint16_t>((uint16_t*)img, params.width,
511 params.height, buf->getStride(),
512 /*bpp*/16);
513 break;
514 case HAL_PIXEL_FORMAT_RGBA_8888:
515 fillRgba8888Buffer(img, params.width, params.height, buf->getStride());
516 break;
517 default:
518 FAIL() << "Unknown pixel format under test!";
519 break;
520 }
521 ALOGVV("Unlock buffer from %p", anw.get());
522 err = buf->unlock();
523 ASSERT_NO_ERROR(err, "unlock error: ");
524
525 ALOGVV("Set timestamp to %p", anw.get());
526 err = native_window_set_buffers_timestamp(anw.get(), timestamp);
527 ASSERT_NO_ERROR(err, "set_buffers_timestamp error: ");
528
529 ALOGVV("Queue buffer to %p", anw.get());
530 err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), -1);
531 ASSERT_NO_ERROR(err, "queueBuffer error:");
532 };
533
534 // This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
535 // supported on all devices.
TEST_P(CpuConsumerTest,FromCpuSingle)536 TEST_P(CpuConsumerTest, FromCpuSingle) {
537 status_t err;
538 CpuConsumerTestParams params = GetParam();
539
540 // Set up
541
542 ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, 1));
543
544 // Produce
545
546 const int64_t time = 12345678L;
547 uint32_t stride;
548 ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time,
549 &stride));
550
551 // Consume
552
553 CpuConsumer::LockedBuffer b;
554 err = mCC->lockNextBuffer(&b);
555 ASSERT_NO_ERROR(err, "getNextBuffer error: ");
556
557 ASSERT_TRUE(b.data != nullptr);
558 EXPECT_EQ(params.width, b.width);
559 EXPECT_EQ(params.height, b.height);
560 EXPECT_EQ(params.format, b.format);
561 EXPECT_EQ(stride, b.stride);
562 EXPECT_EQ(time, b.timestamp);
563
564 checkAnyBuffer(b, GetParam().format);
565 mCC->unlockBuffer(b);
566 }
567
568 // This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
569 // supported on all devices.
TEST_P(CpuConsumerTest,FromCpuManyInQueue)570 TEST_P(CpuConsumerTest, FromCpuManyInQueue) {
571 status_t err;
572 CpuConsumerTestParams params = GetParam();
573
574 const int numInQueue = 5;
575 // Set up
576
577 ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, numInQueue));
578
579 // Produce
580
581 const int64_t time[numInQueue] = { 1L, 2L, 3L, 4L, 5L};
582 uint32_t stride[numInQueue];
583
584 for (int i = 0; i < numInQueue; i++) {
585 ALOGV("Producing frame %d", i);
586 ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time[i],
587 &stride[i]));
588 }
589
590 // Consume
591
592 for (int i = 0; i < numInQueue; i++) {
593 ALOGV("Consuming frame %d", i);
594 CpuConsumer::LockedBuffer b;
595 err = mCC->lockNextBuffer(&b);
596 ASSERT_NO_ERROR(err, "getNextBuffer error: ");
597
598 ASSERT_TRUE(b.data != nullptr);
599 EXPECT_EQ(params.width, b.width);
600 EXPECT_EQ(params.height, b.height);
601 EXPECT_EQ(params.format, b.format);
602 EXPECT_EQ(stride[i], b.stride);
603 EXPECT_EQ(time[i], b.timestamp);
604
605 checkAnyBuffer(b, GetParam().format);
606
607 mCC->unlockBuffer(b);
608 }
609 }
610
611 // This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
612 // supported on all devices.
TEST_P(CpuConsumerTest,FromCpuLockMax)613 TEST_P(CpuConsumerTest, FromCpuLockMax) {
614 status_t err;
615 CpuConsumerTestParams params = GetParam();
616
617 // Set up
618
619 ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, params.maxLockedBuffers + 1));
620
621 // Produce
622
623 const int64_t time = 1234L;
624 uint32_t stride;
625
626 for (int i = 0; i < params.maxLockedBuffers + 1; i++) {
627 ALOGV("Producing frame %d", i);
628 ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time,
629 &stride));
630 }
631
632 // Consume
633
634 std::vector<CpuConsumer::LockedBuffer> b(params.maxLockedBuffers);
635 for (int i = 0; i < params.maxLockedBuffers; i++) {
636 ALOGV("Locking frame %d", i);
637 err = mCC->lockNextBuffer(&b[i]);
638 ASSERT_NO_ERROR(err, "getNextBuffer error: ");
639
640 ASSERT_TRUE(b[i].data != nullptr);
641 EXPECT_EQ(params.width, b[i].width);
642 EXPECT_EQ(params.height, b[i].height);
643 EXPECT_EQ(params.format, b[i].format);
644 EXPECT_EQ(stride, b[i].stride);
645 EXPECT_EQ(time, b[i].timestamp);
646
647 checkAnyBuffer(b[i], GetParam().format);
648 }
649
650 ALOGV("Locking frame %d (too many)", params.maxLockedBuffers);
651 CpuConsumer::LockedBuffer bTooMuch;
652 err = mCC->lockNextBuffer(&bTooMuch);
653 ASSERT_TRUE(err == NOT_ENOUGH_DATA) << "Allowing too many locks";
654
655 ALOGV("Unlocking frame 0");
656 err = mCC->unlockBuffer(b[0]);
657 ASSERT_NO_ERROR(err, "Could not unlock buffer 0: ");
658
659 ALOGV("Locking frame %d (should work now)", params.maxLockedBuffers);
660 err = mCC->lockNextBuffer(&bTooMuch);
661 ASSERT_NO_ERROR(err, "Did not allow new lock after unlock");
662
663 ASSERT_TRUE(bTooMuch.data != nullptr);
664 EXPECT_EQ(params.width, bTooMuch.width);
665 EXPECT_EQ(params.height, bTooMuch.height);
666 EXPECT_EQ(params.format, bTooMuch.format);
667 EXPECT_EQ(stride, bTooMuch.stride);
668 EXPECT_EQ(time, bTooMuch.timestamp);
669
670 checkAnyBuffer(bTooMuch, GetParam().format);
671
672 ALOGV("Unlocking extra buffer");
673 err = mCC->unlockBuffer(bTooMuch);
674 ASSERT_NO_ERROR(err, "Could not unlock extra buffer: ");
675
676 ALOGV("Locking frame %d (no more available)", params.maxLockedBuffers + 1);
677 err = mCC->lockNextBuffer(&b[0]);
678 ASSERT_EQ(BAD_VALUE, err) << "Not out of buffers somehow";
679
680 for (int i = 1; i < params.maxLockedBuffers; i++) {
681 mCC->unlockBuffer(b[i]);
682 }
683 }
684
TEST_P(CpuConsumerTest,FromCpuInvalid)685 TEST_P(CpuConsumerTest, FromCpuInvalid) {
686 status_t err = mCC->lockNextBuffer(nullptr);
687 ASSERT_EQ(BAD_VALUE, err) << "lockNextBuffer did not fail";
688
689 CpuConsumer::LockedBuffer b;
690 err = mCC->unlockBuffer(b);
691 ASSERT_EQ(BAD_VALUE, err) << "unlockBuffer did not fail";
692 }
693
TEST_P(CpuConsumerTest,FromCpuMultiThread)694 TEST_P(CpuConsumerTest, FromCpuMultiThread) {
695 CpuConsumerTestParams params = GetParam();
696 ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, params.maxLockedBuffers + 1));
697
698 for (int i = 0; i < 10; i++) {
699 std::atomic<int> threadReadyCount(0);
700 auto lockAndUnlock = [&]() {
701 threadReadyCount++;
702 // busy wait
703 while (threadReadyCount < params.maxLockedBuffers + 1);
704
705 CpuConsumer::LockedBuffer b;
706 status_t err = mCC->lockNextBuffer(&b);
707 if (err == NO_ERROR) {
708 usleep(1000);
709 err = mCC->unlockBuffer(b);
710 ASSERT_NO_ERROR(err, "Could not unlock buffer: ");
711 } else if (err == NOT_ENOUGH_DATA) {
712 // there are params.maxLockedBuffers+1 threads so one of the
713 // threads might get this error
714 } else {
715 FAIL() << "Could not lock buffer";
716 }
717 };
718
719 // produce buffers
720 for (int j = 0; j < params.maxLockedBuffers + 1; j++) {
721 const int64_t time = 1234L;
722 uint32_t stride;
723 ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time, &stride));
724 }
725
726 // spawn threads
727 std::vector<std::thread> threads;
728 for (int j = 0; j < params.maxLockedBuffers + 1; j++) {
729 threads.push_back(std::thread(lockAndUnlock));
730 }
731
732 // join threads
733 for (auto& thread : threads) {
734 thread.join();
735 }
736
737 // we produced N+1 buffers, but the threads might only consume N
738 CpuConsumer::LockedBuffer b;
739 if (mCC->lockNextBuffer(&b) == NO_ERROR) {
740 mCC->unlockBuffer(b);
741 }
742
743 if (HasFatalFailure()) {
744 break;
745 }
746 }
747 }
748
749 CpuConsumerTestParams y8TestSets[] = {
750 { 512, 512, 1, HAL_PIXEL_FORMAT_Y8},
751 { 512, 512, 3, HAL_PIXEL_FORMAT_Y8},
752 { 2608, 1960, 1, HAL_PIXEL_FORMAT_Y8},
753 { 2608, 1960, 3, HAL_PIXEL_FORMAT_Y8},
754 { 100, 100, 1, HAL_PIXEL_FORMAT_Y8},
755 { 100, 100, 3, HAL_PIXEL_FORMAT_Y8},
756 };
757
758 CpuConsumerTestParams y16TestSets[] = {
759 { 512, 512, 1, HAL_PIXEL_FORMAT_Y16},
760 { 512, 512, 3, HAL_PIXEL_FORMAT_Y16},
761 { 2608, 1960, 1, HAL_PIXEL_FORMAT_Y16},
762 { 2608, 1960, 3, HAL_PIXEL_FORMAT_Y16},
763 { 100, 100, 1, HAL_PIXEL_FORMAT_Y16},
764 { 100, 100, 3, HAL_PIXEL_FORMAT_Y16},
765 };
766
767 CpuConsumerTestParams rawTestSets[] = {
768 { 512, 512, 1, HAL_PIXEL_FORMAT_RAW16},
769 { 512, 512, 3, HAL_PIXEL_FORMAT_RAW16},
770 { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW16},
771 { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW16},
772 { 100, 100, 1, HAL_PIXEL_FORMAT_RAW16},
773 { 100, 100, 3, HAL_PIXEL_FORMAT_RAW16},
774 };
775
776 CpuConsumerTestParams rgba8888TestSets[] = {
777 { 512, 512, 1, HAL_PIXEL_FORMAT_RGBA_8888},
778 { 512, 512, 3, HAL_PIXEL_FORMAT_RGBA_8888},
779 { 2608, 1960, 1, HAL_PIXEL_FORMAT_RGBA_8888},
780 { 2608, 1960, 3, HAL_PIXEL_FORMAT_RGBA_8888},
781 { 100, 100, 1, HAL_PIXEL_FORMAT_RGBA_8888},
782 { 100, 100, 3, HAL_PIXEL_FORMAT_RGBA_8888},
783 };
784
785 #if CPU_CONSUMER_TEST_FORMAT_Y8
786 INSTANTIATE_TEST_CASE_P(Y8Tests,
787 CpuConsumerTest,
788 ::testing::ValuesIn(y8TestSets));
789 #endif
790
791 #if CPU_CONSUMER_TEST_FORMAT_Y16
792 INSTANTIATE_TEST_CASE_P(Y16Tests,
793 CpuConsumerTest,
794 ::testing::ValuesIn(y16TestSets));
795 #endif
796
797 #if CPU_CONSUMER_TEST_FORMAT_RAW
798 INSTANTIATE_TEST_CASE_P(RawTests,
799 CpuConsumerTest,
800 ::testing::ValuesIn(rawTestSets));
801 #endif
802
803 #if CPU_CONSUMER_TEST_FORMAT_RGBA_8888
804 INSTANTIATE_TEST_CASE_P(Rgba8888Tests,
805 CpuConsumerTest,
806 ::testing::ValuesIn(rgba8888TestSets));
807 #endif
808
809
810
811 } // namespace android
812