CpuConsumer_test.cpp revision 29e2047cb4335234ddc0575be1bae66d4e2ff691
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 <ui/FramebufferNativeWindow.h>
37
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
43namespace android {
44
45struct CpuConsumerTestParams {
46    uint32_t width;
47    uint32_t height;
48    int maxLockedBuffers;
49    PixelFormat format;
50};
51
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
58class CpuConsumerTest : public ::testing::TestWithParam<CpuConsumerTestParams> {
59protected:
60
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        mCC = new CpuConsumer(params.maxLockedBuffers);
70        String8 name("CpuConsumer_Under_Test");
71        mCC->setName(name);
72        mSTC = new Surface(mCC->getProducerInterface());
73        mANW = mSTC;
74    }
75
76    virtual void TearDown() {
77        mANW.clear();
78        mSTC.clear();
79        mCC.clear();
80    }
81
82    class FrameWaiter : public CpuConsumer::FrameAvailableListener {
83    public:
84        FrameWaiter():
85                mPendingFrames(0) {
86        }
87
88        void waitForFrame() {
89            Mutex::Autolock lock(mMutex);
90            while (mPendingFrames == 0) {
91                mCondition.wait(mMutex);
92            }
93            mPendingFrames--;
94        }
95
96        virtual void onFrameAvailable() {
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:
114        DisconnectWaiter () :
115            mWaitForDisconnect(false),
116            mPendingFrames(0) {
117        }
118
119        void waitForFrame() {
120            Mutex::Autolock lock(mMutex);
121            while (mPendingFrames == 0) {
122                mFrameCondition.wait(mMutex);
123            }
124            mPendingFrames--;
125        }
126
127        virtual void onFrameAvailable() {
128            Mutex::Autolock lock(mMutex);
129            mPendingFrames++;
130            mFrameCondition.signal();
131        }
132
133        virtual void onBuffersReleased() {
134            Mutex::Autolock lock(mMutex);
135            while (!mWaitForDisconnect) {
136                mDisconnectCondition.wait(mMutex);
137            }
138        }
139
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
164void 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_RAW_SENSOR: {
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
220void fillYV12Buffer(uint8_t* buf, int w, int h, int stride);
221
222// Fill a Y8/Y16 buffer with a multi-colored checkerboard pattern
223template <typename T> // T == uint8_t or uint16_t
224void 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
244inline 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
253void 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]
280void 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
305template<typename T> // uint8_t or uint16_t
306void 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    const int blockRows = h / blockHeight;
312    const int blockCols = w / blockWidth;
313
314    // Top-left square is bright
315    checkPixel(buf, 0, 0, 191);
316    checkPixel(buf, 1, 0, 191);
317    checkPixel(buf, 0, 1, 191);
318    checkPixel(buf, 1, 1, 191);
319
320    // One-right square is dark
321    checkPixel(buf, blockWidth,     0, 63);
322    checkPixel(buf, blockWidth + 1, 0, 63);
323    checkPixel(buf, blockWidth,     1, 63);
324    checkPixel(buf, blockWidth + 1, 1, 63);
325
326    // One-down square is dark
327    checkPixel(buf, 0, blockHeight, 63);
328    checkPixel(buf, 1, blockHeight, 63);
329    checkPixel(buf, 0, blockHeight + 1, 63);
330    checkPixel(buf, 1, blockHeight + 1, 63);
331
332    // One-diag square is bright
333    checkPixel(buf, blockWidth,     blockHeight, 191);
334    checkPixel(buf, blockWidth + 1, blockHeight, 191);
335    checkPixel(buf, blockWidth,     blockHeight + 1, 191);
336    checkPixel(buf, blockWidth + 1, blockHeight + 1, 191);
337
338    // Test bottom-right pixel
339    const int maxBlockX = ((w-1 + (blockWidth-1)) / blockWidth) & 0x1;
340    const int maxBlockY = ((h-1 + (blockHeight-1)) / blockHeight) & 0x1;
341    uint32_t pixelValue = ((maxBlockX % 2) == (maxBlockY % 2)) ? 191 : 63;
342    checkPixel(buf, w-1, h-1, pixelValue);
343}
344
345void checkRgba8888Buffer(const CpuConsumer::LockedBuffer &buf) {
346    uint32_t w = buf.width;
347    uint32_t h = buf.height;
348    const int blockWidth = w > 16 ? w / 16 : 1;
349    const int blockHeight = h > 16 ? h / 16 : 1;
350    const int blockRows = h / blockHeight;
351    const int blockCols = w / blockWidth;
352
353    // Top-left square is bright red
354    checkPixel(buf, 0, 0, 191, 63, 63);
355    checkPixel(buf, 1, 0, 191, 63, 63);
356    checkPixel(buf, 0, 1, 191, 63, 63);
357    checkPixel(buf, 1, 1, 191, 63, 63);
358
359    // One-right square is bright green
360    checkPixel(buf, blockWidth,     0, 63, 191, 63);
361    checkPixel(buf, blockWidth + 1, 0, 63, 191, 63);
362    checkPixel(buf, blockWidth,     1, 63, 191, 63);
363    checkPixel(buf, blockWidth + 1, 1, 63, 191, 63);
364
365    // One-down square is bright green
366    checkPixel(buf, 0, blockHeight, 63, 191, 63);
367    checkPixel(buf, 1, blockHeight, 63, 191, 63);
368    checkPixel(buf, 0, blockHeight + 1, 63, 191, 63);
369    checkPixel(buf, 1, blockHeight + 1, 63, 191, 63);
370
371    // One-diag square is bright blue
372    checkPixel(buf, blockWidth,     blockHeight, 63, 63, 191);
373    checkPixel(buf, blockWidth + 1, blockHeight, 63, 63, 191);
374    checkPixel(buf, blockWidth,     blockHeight + 1, 63, 63, 191);
375    checkPixel(buf, blockWidth + 1, blockHeight + 1, 63, 63, 191);
376
377    // Test bottom-right pixel
378    {
379        const int maxBlockX = ((w-1) / blockWidth);
380        const int maxBlockY = ((h-1) / blockHeight);
381        uint8_t r = chooseColorRgba8888(maxBlockX, maxBlockY, 0);
382        uint8_t g = chooseColorRgba8888(maxBlockX, maxBlockY, 1);
383        uint8_t b = chooseColorRgba8888(maxBlockX, maxBlockY, 2);
384        checkPixel(buf, w-1, h-1, r, g, b);
385    }
386}
387
388void checkBayerRawBuffer(const CpuConsumer::LockedBuffer &buf) {
389    uint32_t w = buf.width;
390    uint32_t h = buf.height;
391    const int blockWidth = (w > 16 ? w / 8 : 2) & ~0x1;
392    const int blockHeight = (h > 16 ? h / 8 : 2) & ~0x1;
393    const int blockRows = h / blockHeight;
394    const int blockCols = w / blockWidth;
395
396    // Top-left square is red
397    checkPixel(buf, 0, 0, 1000, 200, 200);
398    checkPixel(buf, 1, 0, 1000, 200, 200);
399    checkPixel(buf, 0, 1, 1000, 200, 200);
400    checkPixel(buf, 1, 1, 1000, 200, 200);
401
402    // One-right square is blue
403    checkPixel(buf, blockWidth,     0, 200, 200, 1000);
404    checkPixel(buf, blockWidth + 1, 0, 200, 200, 1000);
405    checkPixel(buf, blockWidth,     1, 200, 200, 1000);
406    checkPixel(buf, blockWidth + 1, 1, 200, 200, 1000);
407
408    // One-down square is green
409    checkPixel(buf, 0, blockHeight, 200, 1000, 200);
410    checkPixel(buf, 1, blockHeight, 200, 1000, 200);
411    checkPixel(buf, 0, blockHeight + 1, 200, 1000, 200);
412    checkPixel(buf, 1, blockHeight + 1, 200, 1000, 200);
413
414    // One-diag square is white
415    checkPixel(buf, blockWidth,     blockHeight, 1000, 1000, 1000);
416    checkPixel(buf, blockWidth + 1, blockHeight, 1000, 1000, 1000);
417    checkPixel(buf, blockWidth,     blockHeight + 1, 1000, 1000, 1000);
418    checkPixel(buf, blockWidth + 1, blockHeight + 1, 1000, 1000, 1000);
419
420    // Test bottom-right pixel
421    const int maxBlockX = ((w-1) / blockWidth) & 0x1;
422    const int maxBlockY = ((w-1) / blockHeight) & 0x1;
423    unsigned short maxR = (maxBlockX == maxBlockY) ? 1000 : 200;
424    unsigned short maxG = maxBlockY ? 1000: 200;
425    unsigned short maxB = maxBlockX ? 1000: 200;
426    checkPixel(buf, w-1, h-1, maxR, maxG, maxB);
427}
428
429void checkAnyBuffer(const CpuConsumer::LockedBuffer &buf, int format) {
430    switch (format) {
431        case HAL_PIXEL_FORMAT_RAW_SENSOR:
432            checkBayerRawBuffer(buf);
433            break;
434        case HAL_PIXEL_FORMAT_Y8:
435            checkGreyscaleBuffer<uint8_t>(buf);
436            break;
437        case HAL_PIXEL_FORMAT_Y16:
438            checkGreyscaleBuffer<uint16_t>(buf);
439            break;
440        case HAL_PIXEL_FORMAT_RGBA_8888:
441            checkRgba8888Buffer(buf);
442            break;
443    }
444}
445
446void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
447        const android_native_rect_t& rect);
448
449void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride);
450
451void fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r,
452        uint8_t g, uint8_t b, uint8_t a);
453
454// Configures the ANativeWindow producer-side interface based on test parameters
455void configureANW(const sp<ANativeWindow>& anw,
456        const CpuConsumerTestParams& params,
457        int maxBufferSlack) {
458    status_t err;
459    err = native_window_set_buffers_geometry(anw.get(),
460            params.width, params.height, params.format);
461    ASSERT_NO_ERROR(err, "set_buffers_geometry error: ");
462
463    err = native_window_set_usage(anw.get(),
464            GRALLOC_USAGE_SW_WRITE_OFTEN);
465    ASSERT_NO_ERROR(err, "set_usage error: ");
466
467    int minUndequeuedBuffers;
468    err = anw.get()->query(anw.get(),
469            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
470            &minUndequeuedBuffers);
471    ASSERT_NO_ERROR(err, "query error: ");
472
473    ALOGVV("Setting buffer count to %d",
474            maxBufferSlack + 1 + minUndequeuedBuffers);
475    err = native_window_set_buffer_count(anw.get(),
476            maxBufferSlack + 1 + minUndequeuedBuffers);
477    ASSERT_NO_ERROR(err, "set_buffer_count error: ");
478
479}
480
481// Produce one frame of image data; assumes format and resolution configuration
482// is already done.
483void produceOneFrame(const sp<ANativeWindow>& anw,
484        const CpuConsumerTestParams& params,
485        int64_t timestamp, uint32_t *stride) {
486    status_t err;
487    ANativeWindowBuffer* anb;
488    ALOGVV("Dequeue buffer from %p", anw.get());
489    err = native_window_dequeue_buffer_and_wait(anw.get(), &anb);
490    ASSERT_NO_ERROR(err, "dequeueBuffer error: ");
491
492    ASSERT_TRUE(anb != NULL);
493
494    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
495
496    *stride = buf->getStride();
497    uint8_t* img = NULL;
498
499    ALOGVV("Lock buffer from %p for write", anw.get());
500    err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
501    ASSERT_NO_ERROR(err, "lock error: ");
502
503    switch (params.format) {
504        case HAL_PIXEL_FORMAT_YV12:
505            fillYV12Buffer(img, params.width, params.height, *stride);
506            break;
507        case HAL_PIXEL_FORMAT_RAW_SENSOR:
508            fillBayerRawBuffer(img, params.width, params.height, buf->getStride());
509            break;
510        case HAL_PIXEL_FORMAT_Y8:
511            fillGreyscaleBuffer<uint8_t>(img, params.width, params.height,
512                                         buf->getStride(), /*bpp*/8);
513            break;
514        case HAL_PIXEL_FORMAT_Y16:
515            fillGreyscaleBuffer<uint16_t>((uint16_t*)img, params.width,
516                                          params.height, buf->getStride(),
517                                          /*bpp*/16);
518            break;
519        case HAL_PIXEL_FORMAT_RGBA_8888:
520            fillRgba8888Buffer(img, params.width, params.height, buf->getStride());
521            break;
522        default:
523            FAIL() << "Unknown pixel format under test!";
524            break;
525    }
526    ALOGVV("Unlock buffer from %p", anw.get());
527    err = buf->unlock();
528    ASSERT_NO_ERROR(err, "unlock error: ");
529
530    ALOGVV("Set timestamp to %p", anw.get());
531    err = native_window_set_buffers_timestamp(anw.get(), timestamp);
532    ASSERT_NO_ERROR(err, "set_buffers_timestamp error: ");
533
534    ALOGVV("Queue buffer to %p", anw.get());
535    err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), -1);
536    ASSERT_NO_ERROR(err, "queueBuffer error:");
537};
538
539// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
540// supported on all devices.
541TEST_P(CpuConsumerTest, FromCpuSingle) {
542    status_t err;
543    CpuConsumerTestParams params = GetParam();
544
545    // Set up
546
547    ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, 1));
548
549    // Produce
550
551    const int64_t time = 12345678L;
552    uint32_t stride;
553    ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time,
554                    &stride));
555
556    // Consume
557
558    CpuConsumer::LockedBuffer b;
559    err = mCC->lockNextBuffer(&b);
560    ASSERT_NO_ERROR(err, "getNextBuffer error: ");
561
562    ASSERT_TRUE(b.data != NULL);
563    EXPECT_EQ(params.width,  b.width);
564    EXPECT_EQ(params.height, b.height);
565    EXPECT_EQ(params.format, b.format);
566    EXPECT_EQ(stride, b.stride);
567    EXPECT_EQ(time, b.timestamp);
568
569    checkAnyBuffer(b, GetParam().format);
570    mCC->unlockBuffer(b);
571}
572
573// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
574// supported on all devices.
575TEST_P(CpuConsumerTest, FromCpuManyInQueue) {
576    status_t err;
577    CpuConsumerTestParams params = GetParam();
578
579    const int numInQueue = 5;
580    // Set up
581
582    ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, numInQueue));
583
584    // Produce
585
586    const int64_t time[numInQueue] = { 1L, 2L, 3L, 4L, 5L};
587    uint32_t stride[numInQueue];
588
589    for (int i = 0; i < numInQueue; i++) {
590        ALOGV("Producing frame %d", i);
591        ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time[i],
592                        &stride[i]));
593    }
594
595    // Consume
596
597    for (int i = 0; i < numInQueue; i++) {
598        ALOGV("Consuming frame %d", i);
599        CpuConsumer::LockedBuffer b;
600        err = mCC->lockNextBuffer(&b);
601        ASSERT_NO_ERROR(err, "getNextBuffer error: ");
602
603        ASSERT_TRUE(b.data != NULL);
604        EXPECT_EQ(params.width,  b.width);
605        EXPECT_EQ(params.height, b.height);
606        EXPECT_EQ(params.format, b.format);
607        EXPECT_EQ(stride[i], b.stride);
608        EXPECT_EQ(time[i], b.timestamp);
609
610        checkAnyBuffer(b, GetParam().format);
611
612        mCC->unlockBuffer(b);
613    }
614}
615
616// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
617// supported on all devices.
618TEST_P(CpuConsumerTest, FromCpuLockMax) {
619    status_t err;
620    CpuConsumerTestParams params = GetParam();
621
622    // Set up
623
624    ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, params.maxLockedBuffers + 1));
625
626    // Produce
627
628    const int64_t time = 1234L;
629    uint32_t stride;
630
631    for (int i = 0; i < params.maxLockedBuffers + 1; i++) {
632        ALOGV("Producing frame %d", i);
633        ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time,
634                        &stride));
635    }
636
637    // Consume
638
639    CpuConsumer::LockedBuffer *b = new CpuConsumer::LockedBuffer[params.maxLockedBuffers];
640    for (int i = 0; i < params.maxLockedBuffers; i++) {
641        ALOGV("Locking frame %d", i);
642        err = mCC->lockNextBuffer(&b[i]);
643        ASSERT_NO_ERROR(err, "getNextBuffer error: ");
644
645        ASSERT_TRUE(b[i].data != NULL);
646        EXPECT_EQ(params.width,  b[i].width);
647        EXPECT_EQ(params.height, b[i].height);
648        EXPECT_EQ(params.format, b[i].format);
649        EXPECT_EQ(stride, b[i].stride);
650        EXPECT_EQ(time, b[i].timestamp);
651
652        checkAnyBuffer(b[i], GetParam().format);
653    }
654
655    ALOGV("Locking frame %d (too many)", params.maxLockedBuffers);
656    CpuConsumer::LockedBuffer bTooMuch;
657    err = mCC->lockNextBuffer(&bTooMuch);
658    ASSERT_TRUE(err == INVALID_OPERATION) << "Allowing too many locks";
659
660    ALOGV("Unlocking frame 0");
661    err = mCC->unlockBuffer(b[0]);
662    ASSERT_NO_ERROR(err, "Could not unlock buffer 0: ");
663
664    ALOGV("Locking frame %d (should work now)", params.maxLockedBuffers);
665    err = mCC->lockNextBuffer(&bTooMuch);
666    ASSERT_NO_ERROR(err, "Did not allow new lock after unlock");
667
668    ASSERT_TRUE(bTooMuch.data != NULL);
669    EXPECT_EQ(params.width,  bTooMuch.width);
670    EXPECT_EQ(params.height, bTooMuch.height);
671    EXPECT_EQ(params.format, bTooMuch.format);
672    EXPECT_EQ(stride, bTooMuch.stride);
673    EXPECT_EQ(time, bTooMuch.timestamp);
674
675    checkAnyBuffer(bTooMuch, GetParam().format);
676
677    ALOGV("Unlocking extra buffer");
678    err = mCC->unlockBuffer(bTooMuch);
679    ASSERT_NO_ERROR(err, "Could not unlock extra buffer: ");
680
681    ALOGV("Locking frame %d (no more available)", params.maxLockedBuffers + 1);
682    err = mCC->lockNextBuffer(&b[0]);
683    ASSERT_EQ(BAD_VALUE, err) << "Not out of buffers somehow";
684
685    for (int i = 1; i < params.maxLockedBuffers; i++) {
686        mCC->unlockBuffer(b[i]);
687    }
688
689    delete[] b;
690
691}
692
693CpuConsumerTestParams y8TestSets[] = {
694    { 512,   512, 1, HAL_PIXEL_FORMAT_Y8},
695    { 512,   512, 3, HAL_PIXEL_FORMAT_Y8},
696    { 2608, 1960, 1, HAL_PIXEL_FORMAT_Y8},
697    { 2608, 1960, 3, HAL_PIXEL_FORMAT_Y8},
698    { 100,   100, 1, HAL_PIXEL_FORMAT_Y8},
699    { 100,   100, 3, HAL_PIXEL_FORMAT_Y8},
700};
701
702CpuConsumerTestParams y16TestSets[] = {
703    { 512,   512, 1, HAL_PIXEL_FORMAT_Y16},
704    { 512,   512, 3, HAL_PIXEL_FORMAT_Y16},
705    { 2608, 1960, 1, HAL_PIXEL_FORMAT_Y16},
706    { 2608, 1960, 3, HAL_PIXEL_FORMAT_Y16},
707    { 100,   100, 1, HAL_PIXEL_FORMAT_Y16},
708    { 100,   100, 3, HAL_PIXEL_FORMAT_Y16},
709};
710
711CpuConsumerTestParams rawTestSets[] = {
712    { 512,   512, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
713    { 512,   512, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
714    { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
715    { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
716    { 100,   100, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
717    { 100,   100, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
718};
719
720CpuConsumerTestParams rgba8888TestSets[] = {
721    { 512,   512, 1, HAL_PIXEL_FORMAT_RGBA_8888},
722    { 512,   512, 3, HAL_PIXEL_FORMAT_RGBA_8888},
723    { 2608, 1960, 1, HAL_PIXEL_FORMAT_RGBA_8888},
724    { 2608, 1960, 3, HAL_PIXEL_FORMAT_RGBA_8888},
725    { 100,   100, 1, HAL_PIXEL_FORMAT_RGBA_8888},
726    { 100,   100, 3, HAL_PIXEL_FORMAT_RGBA_8888},
727};
728
729#if CPU_CONSUMER_TEST_FORMAT_Y8
730INSTANTIATE_TEST_CASE_P(Y8Tests,
731        CpuConsumerTest,
732        ::testing::ValuesIn(y8TestSets));
733#endif
734
735#if CPU_CONSUMER_TEST_FORMAT_Y16
736INSTANTIATE_TEST_CASE_P(Y16Tests,
737        CpuConsumerTest,
738        ::testing::ValuesIn(y16TestSets));
739#endif
740
741#if CPU_CONSUMER_TEST_FORMAT_RAW
742INSTANTIATE_TEST_CASE_P(RawTests,
743        CpuConsumerTest,
744        ::testing::ValuesIn(rawTestSets));
745#endif
746
747#if CPU_CONSUMER_TEST_FORMAT_RGBA_8888
748INSTANTIATE_TEST_CASE_P(Rgba8888Tests,
749        CpuConsumerTest,
750        ::testing::ValuesIn(rgba8888TestSets));
751#endif
752
753
754
755} // namespace android
756