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