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