| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 31 |     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), | 
 | 32 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | f8cebe5 | 2015-04-20 12:09:38 -0700 | [diff] [blame] | 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)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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)); | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 43 |     ASSERT_TRUE(anb != nullptr); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 44 |  | 
| Mathias Agopian | f543e5a | 2017-04-03 17:16:41 -0700 | [diff] [blame] | 45 |     sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 46 |  | 
 | 47 |     // Fill the buffer with the a checkerboard pattern | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 48 |     uint8_t* img = nullptr; | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 81 |     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), | 
 | 82 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | f8cebe5 | 2015-04-20 12:09:38 -0700 | [diff] [blame] | 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)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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)); | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 93 |     ASSERT_TRUE(anb != nullptr); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 94 |  | 
| Mathias Agopian | f543e5a | 2017-04-03 17:16:41 -0700 | [diff] [blame] | 95 |     sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 96 |  | 
 | 97 |     // Fill the buffer with the a checkerboard pattern | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 98 |     uint8_t* img = nullptr; | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Kalle Raita | e3747fd | 2016-08-02 16:19:15 -0700 | [diff] [blame] | 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)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 125 | } | 
 | 126 |  | 
 | 127 | TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) { | 
 | 128 |     const int texWidth = 64; | 
 | 129 |     const int texHeight = 66; | 
 | 130 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 131 |     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), | 
 | 132 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | f8cebe5 | 2015-04-20 12:09:38 -0700 | [diff] [blame] | 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)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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)); | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 158 |         ASSERT_TRUE(anb != nullptr); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 159 |  | 
| Mathias Agopian | f543e5a | 2017-04-03 17:16:41 -0700 | [diff] [blame] | 160 |         sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 161 |  | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 162 |         uint8_t* img = nullptr; | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 199 |     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), | 
 | 200 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | f8cebe5 | 2015-04-20 12:09:38 -0700 | [diff] [blame] | 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)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |                 } | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 237 |                 if (anb == nullptr) { | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 238 |                     return false; | 
 | 239 |                 } | 
 | 240 |  | 
| Mathias Agopian | f543e5a | 2017-04-03 17:16:41 -0700 | [diff] [blame] | 241 |                 sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 251 |                 uint8_t* img = nullptr; | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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)); | 
| Brian Carlstrom | 83b1e68 | 2016-03-12 16:07:59 -0800 | [diff] [blame] | 298 |     pt->run("ProducerThread"); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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; | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 343 |     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), | 
 | 344 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | f8cebe5 | 2015-04-20 12:09:38 -0700 | [diff] [blame] | 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)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 389 |     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), | 
 | 390 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | f8cebe5 | 2015-04-20 12:09:38 -0700 | [diff] [blame] | 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)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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: | 
| Chih-Hung Hsieh | d9cdadb | 2016-05-03 14:00:39 -0700 | [diff] [blame] | 439 |         explicit ProducerThread(const sp<ANativeWindow>& anw): | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 440 |                 mANW(anw) { | 
 | 441 |         } | 
 | 442 |  | 
 | 443 |         virtual ~ProducerThread() { | 
 | 444 |         } | 
 | 445 |  | 
 | 446 |         virtual bool threadLoop() { | 
 | 447 |             ANativeWindowBuffer* anb; | 
 | 448 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 449 |             if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) != | 
 | 450 |                     NO_ERROR) { | 
 | 451 |                 return false; | 
 | 452 |             } | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |                 } | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 460 |                 if (anb == nullptr) { | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 461 |                     return false; | 
 | 462 |                 } | 
 | 463 |                 if (mANW->queueBuffer(mANW.get(), anb, -1) | 
 | 464 |                         != NO_ERROR) { | 
 | 465 |                     return false; | 
 | 466 |                 } | 
 | 467 |             } | 
 | 468 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 469 |             if (native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU) | 
 | 470 |                     != NO_ERROR) { | 
 | 471 |                 return false; | 
 | 472 |             } | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 473 |  | 
 | 474 |             return false; | 
 | 475 |         } | 
 | 476 |  | 
 | 477 |     private: | 
 | 478 |         sp<ANativeWindow> mANW; | 
 | 479 |     }; | 
 | 480 |  | 
 | 481 |     sp<DisconnectWaiter> dw(new DisconnectWaiter()); | 
| Dan Stoza | 5603a2f | 2014-04-07 13:41:37 -0700 | [diff] [blame] | 482 |     mConsumer->consumerConnect(dw, false); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 483 |  | 
 | 484 |  | 
 | 485 |     sp<Thread> pt(new ProducerThread(mANW)); | 
| Brian Carlstrom | 83b1e68 | 2016-03-12 16:07:59 -0800 | [diff] [blame] | 486 |     pt->run("ProducerThread"); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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(), | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 506 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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(), | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 520 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 521 |     ASSERT_EQ(OK, native_window_api_connect(mANW.get(), | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 522 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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(), | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 532 |             NATIVE_WINDOW_API_CPU)); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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: | 
| Chih-Hung Hsieh | d9cdadb | 2016-05-03 14:00:39 -0700 | [diff] [blame] | 622 |         explicit ProducerThread(const sp<ANativeWindow>& anw): | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 634 |             if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) != | 
 | 635 |                     NO_ERROR) { | 
 | 636 |                 return false; | 
 | 637 |             } | 
 | 638 |  | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 639 |             // Frame 1 | 
 | 640 |             if (native_window_dequeue_buffer_and_wait(mANW.get(), | 
 | 641 |                     &anb) != NO_ERROR) { | 
 | 642 |                 return false; | 
 | 643 |             } | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 644 |             if (anb == nullptr) { | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |             } | 
| Yi Kong | a03e044 | 2018-07-17 11:16:57 -0700 | [diff] [blame] | 657 |             if (anb == nullptr) { | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 682 |     sp<Thread> pt(new ProducerThread(mANW)); | 
| Brian Carlstrom | 83b1e68 | 2016-03-12 16:07:59 -0800 | [diff] [blame] | 683 |     pt->run("ProducerThread"); | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |  | 
| Pablo Ceballos | 583b1b3 | 2015-09-03 18:23:52 -0700 | [diff] [blame] | 703 |     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), | 
 | 704 |             NATIVE_WINDOW_API_CPU)); | 
 | 705 |  | 
| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 |