Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2011 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 "SurfaceTextureGL_test"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include "SurfaceTextureGL.h"
     21 
     22 #include "DisconnectWaiter.h"
     23 #include "FillBuffer.h"
     24 
     25 namespace android {
     26 
     27 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
     28     const int texWidth = 64;
     29     const int texHeight = 66;
     30 
     31     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
     32             NATIVE_WINDOW_API_CPU));
     33     ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
     34             texWidth, texHeight));
     35     ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
     36             HAL_PIXEL_FORMAT_YV12));
     37     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
     38             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
     39 
     40     ANativeWindowBuffer* anb;
     41     ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
     42             &anb));
     43     ASSERT_TRUE(anb != NULL);
     44 
     45     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
     46 
     47     // Fill the buffer with the a checkerboard pattern
     48     uint8_t* img = NULL;
     49     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
     50     fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
     51     buf->unlock();
     52     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
     53             -1));
     54 
     55     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
     56 
     57     glClearColor(0.2, 0.2, 0.2, 0.2);
     58     glClear(GL_COLOR_BUFFER_BIT);
     59 
     60     glViewport(0, 0, texWidth, texHeight);
     61     drawTexture();
     62 
     63     EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255, 3));
     64     EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255, 3));
     65     EXPECT_TRUE(checkPixel(63, 65,   0, 133,   0, 255, 3));
     66     EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255, 3));
     67 
     68     EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255, 3));
     69     EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255, 3));
     70     EXPECT_TRUE(checkPixel(52, 51,  98, 255,  73, 255, 3));
     71     EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255, 3));
     72     EXPECT_TRUE(checkPixel(31,  9, 107,  24,  87, 255, 3));
     73     EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255, 3));
     74     EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255, 3));
     75 }
     76 
     77 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
     78     const int texWidth = 64;
     79     const int texHeight = 64;
     80 
     81     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
     82             NATIVE_WINDOW_API_CPU));
     83     ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
     84             texWidth, texHeight));
     85     ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
     86             HAL_PIXEL_FORMAT_YV12));
     87     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
     88             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
     89 
     90     ANativeWindowBuffer* anb;
     91     ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
     92             &anb));
     93     ASSERT_TRUE(anb != NULL);
     94 
     95     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
     96 
     97     // Fill the buffer with the a checkerboard pattern
     98     uint8_t* img = NULL;
     99     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    100     fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
    101     buf->unlock();
    102     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
    103             -1));
    104 
    105     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    106 
    107     glClearColor(0.2, 0.2, 0.2, 0.2);
    108     glClear(GL_COLOR_BUFFER_BIT);
    109 
    110     glViewport(0, 0, texWidth, texHeight);
    111     drawTexture();
    112 
    113     EXPECT_TRUE(checkPixel( 0,  0,   0, 133,   0, 255));
    114     EXPECT_TRUE(checkPixel(63,  0, 255, 127, 255, 255));
    115     EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
    116     EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
    117 
    118     EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255, 3));
    119     EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255, 3));
    120     EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255, 3));
    121     EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255, 3));
    122     EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255, 3));
    123     EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255, 3));
    124     EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255, 3));
    125 }
    126 
    127 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
    128     const int texWidth = 64;
    129     const int texHeight = 66;
    130 
    131     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
    132             NATIVE_WINDOW_API_CPU));
    133     ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
    134             texWidth, texHeight));
    135     ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
    136             HAL_PIXEL_FORMAT_YV12));
    137     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    138             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    139 
    140     android_native_rect_t crops[] = {
    141         {4, 6, 22, 36},
    142         {0, 6, 22, 36},
    143         {4, 0, 22, 36},
    144         {4, 6, texWidth, 36},
    145         {4, 6, 22, texHeight},
    146     };
    147 
    148     for (int i = 0; i < 5; i++) {
    149         const android_native_rect_t& crop(crops[i]);
    150         SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
    151                 crop.left, crop.top, crop.right, crop.bottom).string());
    152 
    153         ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
    154 
    155         ANativeWindowBuffer* anb;
    156         ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    157                 &anb));
    158         ASSERT_TRUE(anb != NULL);
    159 
    160         sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    161 
    162         uint8_t* img = NULL;
    163         buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    164         fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
    165         buf->unlock();
    166         ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
    167                 buf->getNativeBuffer(), -1));
    168 
    169         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    170 
    171         glClearColor(0.2, 0.2, 0.2, 0.2);
    172         glClear(GL_COLOR_BUFFER_BIT);
    173 
    174         glViewport(0, 0, 64, 64);
    175         drawTexture();
    176 
    177         EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
    178         EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
    179         EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
    180         EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
    181 
    182         EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
    183         EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
    184         EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
    185         EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
    186         EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
    187         EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
    188         EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
    189     }
    190 }
    191 
    192 // This test is intended to catch synchronization bugs between the CPU-written
    193 // and GPU-read buffers.
    194 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
    195     enum { texWidth = 16 };
    196     enum { texHeight = 16 };
    197     enum { numFrames = 1024 };
    198 
    199     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
    200             NATIVE_WINDOW_API_CPU));
    201     ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
    202             texWidth, texHeight));
    203     ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
    204             HAL_PIXEL_FORMAT_YV12));
    205     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    206             GRALLOC_USAGE_SW_WRITE_OFTEN));
    207 
    208     struct TestPixel {
    209         int x;
    210         int y;
    211     };
    212     const TestPixel testPixels[] = {
    213         {  4, 11 },
    214         { 12, 14 },
    215         {  7,  2 },
    216     };
    217     enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
    218 
    219     class ProducerThread : public Thread {
    220     public:
    221         ProducerThread(const sp<ANativeWindow>& anw,
    222                 const TestPixel* testPixels):
    223                 mANW(anw),
    224                 mTestPixels(testPixels) {
    225         }
    226 
    227         virtual ~ProducerThread() {
    228         }
    229 
    230         virtual bool threadLoop() {
    231             for (int i = 0; i < numFrames; i++) {
    232                 ANativeWindowBuffer* anb;
    233                 if (native_window_dequeue_buffer_and_wait(mANW.get(),
    234                         &anb) != NO_ERROR) {
    235                     return false;
    236                 }
    237                 if (anb == NULL) {
    238                     return false;
    239                 }
    240 
    241                 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    242 
    243                 const int yuvTexOffsetY = 0;
    244                 int stride = buf->getStride();
    245                 int yuvTexStrideY = stride;
    246                 int yuvTexOffsetV = yuvTexStrideY * texHeight;
    247                 int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
    248                 int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
    249                 int yuvTexStrideU = yuvTexStrideV;
    250 
    251                 uint8_t* img = NULL;
    252                 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    253 
    254                 // Gray out all the test pixels first, so we're more likely to
    255                 // see a failure if GL is still texturing from the buffer we
    256                 // just dequeued.
    257                 for (int j = 0; j < numTestPixels; j++) {
    258                     int x = mTestPixels[j].x;
    259                     int y = mTestPixels[j].y;
    260                     uint8_t value = 128;
    261                     img[y*stride + x] = value;
    262                 }
    263 
    264                 // Fill the buffer with gray.
    265                 for (int y = 0; y < texHeight; y++) {
    266                     for (int x = 0; x < texWidth; x++) {
    267                         img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
    268                         img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
    269                         img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
    270                     }
    271                 }
    272 
    273                 // Set the test pixels to either white or black.
    274                 for (int j = 0; j < numTestPixels; j++) {
    275                     int x = mTestPixels[j].x;
    276                     int y = mTestPixels[j].y;
    277                     uint8_t value = 0;
    278                     if (j == (i % numTestPixels)) {
    279                         value = 255;
    280                     }
    281                     img[y*stride + x] = value;
    282                 }
    283 
    284                 buf->unlock();
    285                 if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), -1)
    286                         != NO_ERROR) {
    287                     return false;
    288                 }
    289             }
    290             return false;
    291         }
    292 
    293         sp<ANativeWindow> mANW;
    294         const TestPixel* mTestPixels;
    295     };
    296 
    297     sp<Thread> pt(new ProducerThread(mANW, testPixels));
    298     pt->run("ProducerThread");
    299 
    300     glViewport(0, 0, texWidth, texHeight);
    301 
    302     glClearColor(0.2, 0.2, 0.2, 0.2);
    303     glClear(GL_COLOR_BUFFER_BIT);
    304 
    305     // We wait for the first two frames up front so that the producer will be
    306     // likely to dequeue the buffer that's currently being textured from.
    307     mFW->waitForFrame();
    308     mFW->waitForFrame();
    309 
    310     for (int i = 0; i < numFrames; i++) {
    311         SCOPED_TRACE(String8::format("frame %d", i).string());
    312 
    313         // We must wait for each frame to come in because if we ever do an
    314         // updateTexImage call that doesn't consume a newly available buffer
    315         // then the producer and consumer will get out of sync, which will cause
    316         // a deadlock.
    317         if (i > 1) {
    318             mFW->waitForFrame();
    319         }
    320         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    321         drawTexture();
    322 
    323         for (int j = 0; j < numTestPixels; j++) {
    324             int x = testPixels[j].x;
    325             int y = testPixels[j].y;
    326             uint8_t value = 0;
    327             if (j == (i % numTestPixels)) {
    328                 // We must y-invert the texture coords
    329                 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
    330             } else {
    331                 // We must y-invert the texture coords
    332                 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
    333             }
    334         }
    335     }
    336 
    337     pt->requestExitAndWait();
    338 }
    339 
    340 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
    341     const int texWidth = 64;
    342     const int texHeight = 66;
    343 
    344     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
    345             NATIVE_WINDOW_API_CPU));
    346     ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
    347             texWidth, texHeight));
    348     ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
    349             HAL_PIXEL_FORMAT_RGBA_8888));
    350     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    351             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    352 
    353     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    354 
    355     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    356 
    357     glClearColor(0.2, 0.2, 0.2, 0.2);
    358     glClear(GL_COLOR_BUFFER_BIT);
    359 
    360     glViewport(0, 0, texWidth, texHeight);
    361     drawTexture();
    362 
    363     EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
    364     EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
    365     EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231));
    366     EXPECT_TRUE(checkPixel( 0, 65,  35,  35,  35,  35));
    367 
    368     EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
    369     EXPECT_TRUE(checkPixel(23, 65, 231,  35, 231,  35));
    370     EXPECT_TRUE(checkPixel(19, 40,  35, 231,  35,  35));
    371     EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
    372     EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
    373     EXPECT_TRUE(checkPixel(37, 34,  35, 231, 231, 231));
    374     EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
    375     EXPECT_TRUE(checkPixel(37, 47, 231,  35, 231, 231));
    376     EXPECT_TRUE(checkPixel(25, 38,  35,  35,  35,  35));
    377     EXPECT_TRUE(checkPixel(49,  6,  35, 231,  35,  35));
    378     EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
    379     EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231));
    380     EXPECT_TRUE(checkPixel(10,  6,  35,  35, 231, 231));
    381     EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
    382     EXPECT_TRUE(checkPixel(55, 28,  35,  35, 231,  35));
    383     EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
    384 }
    385 
    386 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
    387     const int texWidth = 64;
    388     const int texHeight = 64;
    389 
    390     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
    391             NATIVE_WINDOW_API_CPU));
    392     ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
    393             texWidth, texHeight));
    394     ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
    395             HAL_PIXEL_FORMAT_RGBA_8888));
    396     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    397             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    398 
    399     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    400 
    401     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    402 
    403     glClearColor(0.2, 0.2, 0.2, 0.2);
    404     glClear(GL_COLOR_BUFFER_BIT);
    405 
    406     glViewport(0, 0, texWidth, texHeight);
    407     drawTexture();
    408 
    409     EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
    410     EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
    411     EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
    412     EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
    413 
    414     EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
    415     EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
    416     EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
    417     EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
    418     EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
    419     EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
    420     EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
    421     EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
    422     EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
    423     EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
    424     EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
    425     EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
    426     EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
    427     EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
    428     EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
    429     EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
    430 }
    431 
    432 // Tests if GLConsumer and BufferQueue are robust enough
    433 // to handle a special case where updateTexImage is called
    434 // in the middle of disconnect.  This ordering is enforced
    435 // by blocking in the disconnect callback.
    436 TEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
    437 
    438     class ProducerThread : public Thread {
    439     public:
    440         ProducerThread(const sp<ANativeWindow>& anw):
    441                 mANW(anw) {
    442         }
    443 
    444         virtual ~ProducerThread() {
    445         }
    446 
    447         virtual bool threadLoop() {
    448             ANativeWindowBuffer* anb;
    449 
    450             if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) !=
    451                     NO_ERROR) {
    452                 return false;
    453             }
    454 
    455             for (int numFrames =0 ; numFrames < 2; numFrames ++) {
    456 
    457                 if (native_window_dequeue_buffer_and_wait(mANW.get(),
    458                         &anb) != NO_ERROR) {
    459                     return false;
    460                 }
    461                 if (anb == NULL) {
    462                     return false;
    463                 }
    464                 if (mANW->queueBuffer(mANW.get(), anb, -1)
    465                         != NO_ERROR) {
    466                     return false;
    467                 }
    468             }
    469 
    470             if (native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU)
    471                     != NO_ERROR) {
    472                 return false;
    473             }
    474 
    475             return false;
    476         }
    477 
    478     private:
    479         sp<ANativeWindow> mANW;
    480     };
    481 
    482     sp<DisconnectWaiter> dw(new DisconnectWaiter());
    483     mConsumer->consumerConnect(dw, false);
    484 
    485 
    486     sp<Thread> pt(new ProducerThread(mANW));
    487     pt->run("ProducerThread");
    488 
    489     // eat a frame so GLConsumer will own an at least one slot
    490     dw->waitForFrame();
    491     EXPECT_EQ(OK,mST->updateTexImage());
    492 
    493     dw->waitForFrame();
    494     // Could fail here as GLConsumer thinks it still owns the slot
    495     // but bufferQueue has released all slots
    496     EXPECT_EQ(OK,mST->updateTexImage());
    497 
    498     dw->finishDisconnect();
    499 }
    500 
    501 
    502 // This test ensures that the GLConsumer clears the mCurrentTexture
    503 // when it is disconnected and reconnected.  Otherwise it will
    504 // attempt to release a buffer that it does not owned
    505 TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
    506     ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
    507             NATIVE_WINDOW_API_CPU));
    508 
    509     ANativeWindowBuffer *anb;
    510 
    511     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    512     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    513 
    514     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    515     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    516 
    517     EXPECT_EQ(OK,mST->updateTexImage());
    518     EXPECT_EQ(OK,mST->updateTexImage());
    519 
    520     ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
    521             NATIVE_WINDOW_API_CPU));
    522     ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
    523             NATIVE_WINDOW_API_CPU));
    524 
    525     EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    526     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    527 
    528     // Will fail here if mCurrentTexture is not cleared properly
    529     mFW->waitForFrame();
    530     EXPECT_EQ(OK,mST->updateTexImage());
    531 
    532     ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
    533             NATIVE_WINDOW_API_CPU));
    534 }
    535 
    536 TEST_F(SurfaceTextureGLTest, ScaleToWindowMode) {
    537     ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
    538         NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
    539 
    540     // The producer image size
    541     ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
    542 
    543     // The consumer image size (16 x 9) ratio
    544     mST->setDefaultBufferSize(1280, 720);
    545 
    546     ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
    547             NATIVE_WINDOW_API_CPU));
    548 
    549     ANativeWindowBuffer *anb;
    550 
    551     android_native_rect_t odd = {23, 78, 123, 477};
    552     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &odd));
    553     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    554     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    555     mFW->waitForFrame();
    556     EXPECT_EQ(OK, mST->updateTexImage());
    557     Rect r = mST->getCurrentCrop();
    558     assertRectEq(Rect(23, 78, 123, 477), r);
    559 
    560     ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
    561             NATIVE_WINDOW_API_CPU));
    562 }
    563 
    564 // This test ensures the scaling mode does the right thing
    565 // ie NATIVE_WINDOW_SCALING_MODE_CROP should crop
    566 // the image such that it has the same aspect ratio as the
    567 // default buffer size
    568 TEST_F(SurfaceTextureGLTest, CroppedScalingMode) {
    569     ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
    570         NATIVE_WINDOW_SCALING_MODE_SCALE_CROP));
    571 
    572     // The producer image size
    573     ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
    574 
    575     // The consumer image size (16 x 9) ratio
    576     mST->setDefaultBufferSize(1280, 720);
    577 
    578     native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU);
    579 
    580     ANativeWindowBuffer *anb;
    581 
    582     // The crop is in the shape of (320, 180) === 16 x 9
    583     android_native_rect_t standard = {10, 20, 330, 200};
    584     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &standard));
    585     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    586     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    587     mFW->waitForFrame();
    588     EXPECT_EQ(OK, mST->updateTexImage());
    589     Rect r = mST->getCurrentCrop();
    590     // crop should be the same as crop (same aspect ratio)
    591     assertRectEq(Rect(10, 20, 330, 200), r);
    592 
    593     // make this wider then desired aspect 239 x 100 (2.39:1)
    594     android_native_rect_t wide = {20, 30, 259, 130};
    595     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &wide));
    596     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    597     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    598     mFW->waitForFrame();
    599     EXPECT_EQ(OK, mST->updateTexImage());
    600     r = mST->getCurrentCrop();
    601     // crop should be the same height, but have cropped left and right borders
    602     // offset is 30.6 px L+, R-
    603     assertRectEq(Rect(51, 30, 228, 130), r);
    604 
    605     // This image is taller then desired aspect 400 x 300 (4:3)
    606     android_native_rect_t narrow = {0, 0, 400, 300};
    607     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &narrow));
    608     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    609     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    610     mFW->waitForFrame();
    611     EXPECT_EQ(OK, mST->updateTexImage());
    612     r = mST->getCurrentCrop();
    613     // crop should be the same width, but have cropped top and bottom borders
    614     // offset is 37.5 px
    615     assertRectEq(Rect(0, 37, 400, 262), r);
    616 
    617     native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
    618 }
    619 
    620 TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
    621     class ProducerThread : public Thread {
    622     public:
    623         ProducerThread(const sp<ANativeWindow>& anw):
    624                 mANW(anw),
    625                 mDequeueError(NO_ERROR) {
    626         }
    627 
    628         virtual ~ProducerThread() {
    629         }
    630 
    631         virtual bool threadLoop() {
    632             Mutex::Autolock lock(mMutex);
    633             ANativeWindowBuffer* anb;
    634 
    635             if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) !=
    636                     NO_ERROR) {
    637                 return false;
    638             }
    639 
    640             // Frame 1
    641             if (native_window_dequeue_buffer_and_wait(mANW.get(),
    642                     &anb) != NO_ERROR) {
    643                 return false;
    644             }
    645             if (anb == NULL) {
    646                 return false;
    647             }
    648             if (mANW->queueBuffer(mANW.get(), anb, -1)
    649                     != NO_ERROR) {
    650                 return false;
    651             }
    652 
    653             // Frame 2
    654             if (native_window_dequeue_buffer_and_wait(mANW.get(),
    655                     &anb) != NO_ERROR) {
    656                 return false;
    657             }
    658             if (anb == NULL) {
    659                 return false;
    660             }
    661             if (mANW->queueBuffer(mANW.get(), anb, -1)
    662                     != NO_ERROR) {
    663                 return false;
    664             }
    665 
    666             // Frame 3 - error expected
    667             mDequeueError = native_window_dequeue_buffer_and_wait(mANW.get(),
    668                 &anb);
    669             return false;
    670         }
    671 
    672         status_t getDequeueError() {
    673             Mutex::Autolock lock(mMutex);
    674             return mDequeueError;
    675         }
    676 
    677     private:
    678         sp<ANativeWindow> mANW;
    679         status_t mDequeueError;
    680         Mutex mMutex;
    681     };
    682 
    683     sp<Thread> pt(new ProducerThread(mANW));
    684     pt->run("ProducerThread");
    685 
    686     mFW->waitForFrame();
    687     mFW->waitForFrame();
    688 
    689     // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
    690     // block waiting for a buffer to become available.
    691     usleep(100000);
    692 
    693     mST->abandon();
    694 
    695     pt->requestExitAndWait();
    696     ASSERT_EQ(NO_INIT,
    697             reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
    698 }
    699 
    700 TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
    701     int texHeight = 16;
    702     ANativeWindowBuffer* anb;
    703 
    704     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
    705             NATIVE_WINDOW_API_CPU));
    706 
    707     GLint maxTextureSize;
    708     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
    709 
    710     // make sure it works with small textures
    711     mST->setDefaultBufferSize(16, texHeight);
    712     EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    713             &anb));
    714     EXPECT_EQ(16, anb->width);
    715     EXPECT_EQ(texHeight, anb->height);
    716     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
    717     EXPECT_EQ(NO_ERROR, mST->updateTexImage());
    718 
    719     // make sure it works with GL_MAX_TEXTURE_SIZE
    720     mST->setDefaultBufferSize(maxTextureSize, texHeight);
    721     EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    722             &anb));
    723     EXPECT_EQ(maxTextureSize, anb->width);
    724     EXPECT_EQ(texHeight, anb->height);
    725     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
    726     EXPECT_EQ(NO_ERROR, mST->updateTexImage());
    727 
    728     // make sure it fails with GL_MAX_TEXTURE_SIZE+1
    729     mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
    730     EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    731             &anb));
    732     EXPECT_EQ(maxTextureSize+1, anb->width);
    733     EXPECT_EQ(texHeight, anb->height);
    734     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
    735     ASSERT_NE(NO_ERROR, mST->updateTexImage());
    736 }
    737 
    738 } // namespace android
    739