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 != nullptr);
     44 
     45     sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
     46 
     47     // Fill the buffer with the a checkerboard pattern
     48     uint8_t* img = nullptr;
     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 != nullptr);
     94 
     95     sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
     96 
     97     // Fill the buffer with the a checkerboard pattern
     98     uint8_t* img = nullptr;
     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 != nullptr);
    159 
    160         sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
    161 
    162         uint8_t* img = nullptr;
    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 == nullptr) {
    238                     return false;
    239                 }
    240 
    241                 sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
    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 = nullptr;
    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             if (j == (i % numTestPixels)) {
    327                 // We must y-invert the texture coords
    328                 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
    329             } else {
    330                 // We must y-invert the texture coords
    331                 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
    332             }
    333         }
    334     }
    335 
    336     pt->requestExitAndWait();
    337 }
    338 
    339 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
    340     const int texWidth = 64;
    341     const int texHeight = 66;
    342 
    343     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
    344             NATIVE_WINDOW_API_CPU));
    345     ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
    346             texWidth, texHeight));
    347     ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
    348             HAL_PIXEL_FORMAT_RGBA_8888));
    349     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    350             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    351 
    352     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    353 
    354     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    355 
    356     glClearColor(0.2, 0.2, 0.2, 0.2);
    357     glClear(GL_COLOR_BUFFER_BIT);
    358 
    359     glViewport(0, 0, texWidth, texHeight);
    360     drawTexture();
    361 
    362     EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
    363     EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
    364     EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231));
    365     EXPECT_TRUE(checkPixel( 0, 65,  35,  35,  35,  35));
    366 
    367     EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
    368     EXPECT_TRUE(checkPixel(23, 65, 231,  35, 231,  35));
    369     EXPECT_TRUE(checkPixel(19, 40,  35, 231,  35,  35));
    370     EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
    371     EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
    372     EXPECT_TRUE(checkPixel(37, 34,  35, 231, 231, 231));
    373     EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
    374     EXPECT_TRUE(checkPixel(37, 47, 231,  35, 231, 231));
    375     EXPECT_TRUE(checkPixel(25, 38,  35,  35,  35,  35));
    376     EXPECT_TRUE(checkPixel(49,  6,  35, 231,  35,  35));
    377     EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
    378     EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231));
    379     EXPECT_TRUE(checkPixel(10,  6,  35,  35, 231, 231));
    380     EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
    381     EXPECT_TRUE(checkPixel(55, 28,  35,  35, 231,  35));
    382     EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
    383 }
    384 
    385 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
    386     const int texWidth = 64;
    387     const int texHeight = 64;
    388 
    389     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
    390             NATIVE_WINDOW_API_CPU));
    391     ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
    392             texWidth, texHeight));
    393     ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
    394             HAL_PIXEL_FORMAT_RGBA_8888));
    395     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    396             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    397 
    398     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    399 
    400     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    401 
    402     glClearColor(0.2, 0.2, 0.2, 0.2);
    403     glClear(GL_COLOR_BUFFER_BIT);
    404 
    405     glViewport(0, 0, texWidth, texHeight);
    406     drawTexture();
    407 
    408     EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
    409     EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
    410     EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
    411     EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
    412 
    413     EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
    414     EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
    415     EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
    416     EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
    417     EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
    418     EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
    419     EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
    420     EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
    421     EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
    422     EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
    423     EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
    424     EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
    425     EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
    426     EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
    427     EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
    428     EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
    429 }
    430 
    431 // Tests if GLConsumer and BufferQueue are robust enough
    432 // to handle a special case where updateTexImage is called
    433 // in the middle of disconnect.  This ordering is enforced
    434 // by blocking in the disconnect callback.
    435 TEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
    436 
    437     class ProducerThread : public Thread {
    438     public:
    439         explicit ProducerThread(const sp<ANativeWindow>& anw):
    440                 mANW(anw) {
    441         }
    442 
    443         virtual ~ProducerThread() {
    444         }
    445 
    446         virtual bool threadLoop() {
    447             ANativeWindowBuffer* anb;
    448 
    449             if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) !=
    450                     NO_ERROR) {
    451                 return false;
    452             }
    453 
    454             for (int numFrames =0 ; numFrames < 2; numFrames ++) {
    455 
    456                 if (native_window_dequeue_buffer_and_wait(mANW.get(),
    457                         &anb) != NO_ERROR) {
    458                     return false;
    459                 }
    460                 if (anb == nullptr) {
    461                     return false;
    462                 }
    463                 if (mANW->queueBuffer(mANW.get(), anb, -1)
    464                         != NO_ERROR) {
    465                     return false;
    466                 }
    467             }
    468 
    469             if (native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU)
    470                     != NO_ERROR) {
    471                 return false;
    472             }
    473 
    474             return false;
    475         }
    476 
    477     private:
    478         sp<ANativeWindow> mANW;
    479     };
    480 
    481     sp<DisconnectWaiter> dw(new DisconnectWaiter());
    482     mConsumer->consumerConnect(dw, false);
    483 
    484 
    485     sp<Thread> pt(new ProducerThread(mANW));
    486     pt->run("ProducerThread");
    487 
    488     // eat a frame so GLConsumer will own an at least one slot
    489     dw->waitForFrame();
    490     EXPECT_EQ(OK,mST->updateTexImage());
    491 
    492     dw->waitForFrame();
    493     // Could fail here as GLConsumer thinks it still owns the slot
    494     // but bufferQueue has released all slots
    495     EXPECT_EQ(OK,mST->updateTexImage());
    496 
    497     dw->finishDisconnect();
    498 }
    499 
    500 
    501 // This test ensures that the GLConsumer clears the mCurrentTexture
    502 // when it is disconnected and reconnected.  Otherwise it will
    503 // attempt to release a buffer that it does not owned
    504 TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
    505     ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
    506             NATIVE_WINDOW_API_CPU));
    507 
    508     ANativeWindowBuffer *anb;
    509 
    510     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    511     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    512 
    513     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    514     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    515 
    516     EXPECT_EQ(OK,mST->updateTexImage());
    517     EXPECT_EQ(OK,mST->updateTexImage());
    518 
    519     ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
    520             NATIVE_WINDOW_API_CPU));
    521     ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
    522             NATIVE_WINDOW_API_CPU));
    523 
    524     EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    525     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    526 
    527     // Will fail here if mCurrentTexture is not cleared properly
    528     mFW->waitForFrame();
    529     EXPECT_EQ(OK,mST->updateTexImage());
    530 
    531     ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
    532             NATIVE_WINDOW_API_CPU));
    533 }
    534 
    535 TEST_F(SurfaceTextureGLTest, ScaleToWindowMode) {
    536     ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
    537         NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
    538 
    539     // The producer image size
    540     ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
    541 
    542     // The consumer image size (16 x 9) ratio
    543     mST->setDefaultBufferSize(1280, 720);
    544 
    545     ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
    546             NATIVE_WINDOW_API_CPU));
    547 
    548     ANativeWindowBuffer *anb;
    549 
    550     android_native_rect_t odd = {23, 78, 123, 477};
    551     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &odd));
    552     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    553     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    554     mFW->waitForFrame();
    555     EXPECT_EQ(OK, mST->updateTexImage());
    556     Rect r = mST->getCurrentCrop();
    557     assertRectEq(Rect(23, 78, 123, 477), r);
    558 
    559     ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
    560             NATIVE_WINDOW_API_CPU));
    561 }
    562 
    563 // This test ensures the scaling mode does the right thing
    564 // ie NATIVE_WINDOW_SCALING_MODE_CROP should crop
    565 // the image such that it has the same aspect ratio as the
    566 // default buffer size
    567 TEST_F(SurfaceTextureGLTest, CroppedScalingMode) {
    568     ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
    569         NATIVE_WINDOW_SCALING_MODE_SCALE_CROP));
    570 
    571     // The producer image size
    572     ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
    573 
    574     // The consumer image size (16 x 9) ratio
    575     mST->setDefaultBufferSize(1280, 720);
    576 
    577     native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU);
    578 
    579     ANativeWindowBuffer *anb;
    580 
    581     // The crop is in the shape of (320, 180) === 16 x 9
    582     android_native_rect_t standard = {10, 20, 330, 200};
    583     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &standard));
    584     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    585     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    586     mFW->waitForFrame();
    587     EXPECT_EQ(OK, mST->updateTexImage());
    588     Rect r = mST->getCurrentCrop();
    589     // crop should be the same as crop (same aspect ratio)
    590     assertRectEq(Rect(10, 20, 330, 200), r);
    591 
    592     // make this wider then desired aspect 239 x 100 (2.39:1)
    593     android_native_rect_t wide = {20, 30, 259, 130};
    594     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &wide));
    595     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    596     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    597     mFW->waitForFrame();
    598     EXPECT_EQ(OK, mST->updateTexImage());
    599     r = mST->getCurrentCrop();
    600     // crop should be the same height, but have cropped left and right borders
    601     // offset is 30.6 px L+, R-
    602     assertRectEq(Rect(51, 30, 228, 130), r);
    603 
    604     // This image is taller then desired aspect 400 x 300 (4:3)
    605     android_native_rect_t narrow = {0, 0, 400, 300};
    606     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &narrow));
    607     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
    608     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
    609     mFW->waitForFrame();
    610     EXPECT_EQ(OK, mST->updateTexImage());
    611     r = mST->getCurrentCrop();
    612     // crop should be the same width, but have cropped top and bottom borders
    613     // offset is 37.5 px
    614     assertRectEq(Rect(0, 37, 400, 262), r);
    615 
    616     native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
    617 }
    618 
    619 TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
    620     class ProducerThread : public Thread {
    621     public:
    622         explicit ProducerThread(const sp<ANativeWindow>& anw):
    623                 mANW(anw),
    624                 mDequeueError(NO_ERROR) {
    625         }
    626 
    627         virtual ~ProducerThread() {
    628         }
    629 
    630         virtual bool threadLoop() {
    631             Mutex::Autolock lock(mMutex);
    632             ANativeWindowBuffer* anb;
    633 
    634             if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) !=
    635                     NO_ERROR) {
    636                 return false;
    637             }
    638 
    639             // Frame 1
    640             if (native_window_dequeue_buffer_and_wait(mANW.get(),
    641                     &anb) != NO_ERROR) {
    642                 return false;
    643             }
    644             if (anb == nullptr) {
    645                 return false;
    646             }
    647             if (mANW->queueBuffer(mANW.get(), anb, -1)
    648                     != NO_ERROR) {
    649                 return false;
    650             }
    651 
    652             // Frame 2
    653             if (native_window_dequeue_buffer_and_wait(mANW.get(),
    654                     &anb) != NO_ERROR) {
    655                 return false;
    656             }
    657             if (anb == nullptr) {
    658                 return false;
    659             }
    660             if (mANW->queueBuffer(mANW.get(), anb, -1)
    661                     != NO_ERROR) {
    662                 return false;
    663             }
    664 
    665             // Frame 3 - error expected
    666             mDequeueError = native_window_dequeue_buffer_and_wait(mANW.get(),
    667                 &anb);
    668             return false;
    669         }
    670 
    671         status_t getDequeueError() {
    672             Mutex::Autolock lock(mMutex);
    673             return mDequeueError;
    674         }
    675 
    676     private:
    677         sp<ANativeWindow> mANW;
    678         status_t mDequeueError;
    679         Mutex mMutex;
    680     };
    681 
    682     sp<Thread> pt(new ProducerThread(mANW));
    683     pt->run("ProducerThread");
    684 
    685     mFW->waitForFrame();
    686     mFW->waitForFrame();
    687 
    688     // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
    689     // block waiting for a buffer to become available.
    690     usleep(100000);
    691 
    692     mST->abandon();
    693 
    694     pt->requestExitAndWait();
    695     ASSERT_EQ(NO_INIT,
    696             reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
    697 }
    698 
    699 TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
    700     int texHeight = 16;
    701     ANativeWindowBuffer* anb;
    702 
    703     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
    704             NATIVE_WINDOW_API_CPU));
    705 
    706     GLint maxTextureSize;
    707     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
    708 
    709     // make sure it works with small textures
    710     mST->setDefaultBufferSize(16, texHeight);
    711     EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    712             &anb));
    713     EXPECT_EQ(16, anb->width);
    714     EXPECT_EQ(texHeight, anb->height);
    715     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
    716     EXPECT_EQ(NO_ERROR, mST->updateTexImage());
    717 
    718     // make sure it works with GL_MAX_TEXTURE_SIZE
    719     mST->setDefaultBufferSize(maxTextureSize, texHeight);
    720     EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    721             &anb));
    722     EXPECT_EQ(maxTextureSize, anb->width);
    723     EXPECT_EQ(texHeight, anb->height);
    724     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
    725     EXPECT_EQ(NO_ERROR, mST->updateTexImage());
    726 
    727     // make sure it fails with GL_MAX_TEXTURE_SIZE+1
    728     mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
    729     EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    730             &anb));
    731     EXPECT_EQ(maxTextureSize+1, anb->width);
    732     EXPECT_EQ(texHeight, anb->height);
    733     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
    734     ASSERT_NE(NO_ERROR, mST->updateTexImage());
    735 }
    736 
    737 } // namespace android
    738