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 
TEST_F(SurfaceTextureGLTest,TexturingFromCpuFilledYV12BufferNpot)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 
TEST_F(SurfaceTextureGLTest,TexturingFromCpuFilledYV12BufferPow2)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 
TEST_F(SurfaceTextureGLTest,TexturingFromCpuFilledYV12BufferWithCrop)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 }", crop.left, crop.top,
151                                      crop.right, crop.bottom)
152                              .c_str());
153 
154         ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
155 
156         ANativeWindowBuffer* anb;
157         ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
158                 &anb));
159         ASSERT_TRUE(anb != nullptr);
160 
161         sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
162 
163         uint8_t* img = nullptr;
164         buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
165         fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
166         buf->unlock();
167         ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
168                 buf->getNativeBuffer(), -1));
169 
170         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
171 
172         glClearColor(0.2, 0.2, 0.2, 0.2);
173         glClear(GL_COLOR_BUFFER_BIT);
174 
175         glViewport(0, 0, 64, 64);
176         drawTexture();
177 
178         EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
179         EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
180         EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
181         EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
182 
183         EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
184         EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
185         EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
186         EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
187         EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
188         EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
189         EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
190     }
191 }
192 
193 // This test is intended to catch synchronization bugs between the CPU-written
194 // and GPU-read buffers.
TEST_F(SurfaceTextureGLTest,TexturingFromCpuFilledYV12BuffersRepeatedly)195 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
196     enum { texWidth = 16 };
197     enum { texHeight = 16 };
198     enum { numFrames = 1024 };
199 
200     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(),
201             NATIVE_WINDOW_API_CPU));
202     ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
203             texWidth, texHeight));
204     ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
205             HAL_PIXEL_FORMAT_YV12));
206     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
207             GRALLOC_USAGE_SW_WRITE_OFTEN));
208 
209     struct TestPixel {
210         int x;
211         int y;
212     };
213     const TestPixel testPixels[] = {
214         {  4, 11 },
215         { 12, 14 },
216         {  7,  2 },
217     };
218     enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
219 
220     class ProducerThread : public Thread {
221     public:
222         ProducerThread(const sp<ANativeWindow>& anw,
223                 const TestPixel* testPixels):
224                 mANW(anw),
225                 mTestPixels(testPixels) {
226         }
227 
228         virtual ~ProducerThread() {
229         }
230 
231         virtual bool threadLoop() {
232             for (int i = 0; i < numFrames; i++) {
233                 ANativeWindowBuffer* anb;
234                 if (native_window_dequeue_buffer_and_wait(mANW.get(),
235                         &anb) != NO_ERROR) {
236                     return false;
237                 }
238                 if (anb == nullptr) {
239                     return false;
240                 }
241 
242                 sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
243 
244                 const int yuvTexOffsetY = 0;
245                 int stride = buf->getStride();
246                 int yuvTexStrideY = stride;
247                 int yuvTexOffsetV = yuvTexStrideY * texHeight;
248                 int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
249                 int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
250                 int yuvTexStrideU = yuvTexStrideV;
251 
252                 uint8_t* img = nullptr;
253                 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
254 
255                 // Gray out all the test pixels first, so we're more likely to
256                 // see a failure if GL is still texturing from the buffer we
257                 // just dequeued.
258                 for (int j = 0; j < numTestPixels; j++) {
259                     int x = mTestPixels[j].x;
260                     int y = mTestPixels[j].y;
261                     uint8_t value = 128;
262                     img[y*stride + x] = value;
263                 }
264 
265                 // Fill the buffer with gray.
266                 for (int y = 0; y < texHeight; y++) {
267                     for (int x = 0; x < texWidth; x++) {
268                         img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
269                         img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
270                         img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
271                     }
272                 }
273 
274                 // Set the test pixels to either white or black.
275                 for (int j = 0; j < numTestPixels; j++) {
276                     int x = mTestPixels[j].x;
277                     int y = mTestPixels[j].y;
278                     uint8_t value = 0;
279                     if (j == (i % numTestPixels)) {
280                         value = 255;
281                     }
282                     img[y*stride + x] = value;
283                 }
284 
285                 buf->unlock();
286                 if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), -1)
287                         != NO_ERROR) {
288                     return false;
289                 }
290             }
291             return false;
292         }
293 
294         sp<ANativeWindow> mANW;
295         const TestPixel* mTestPixels;
296     };
297 
298     sp<Thread> pt(new ProducerThread(mANW, testPixels));
299     pt->run("ProducerThread");
300 
301     glViewport(0, 0, texWidth, texHeight);
302 
303     glClearColor(0.2, 0.2, 0.2, 0.2);
304     glClear(GL_COLOR_BUFFER_BIT);
305 
306     // We wait for the first two frames up front so that the producer will be
307     // likely to dequeue the buffer that's currently being textured from.
308     mFW->waitForFrame();
309     mFW->waitForFrame();
310 
311     for (int i = 0; i < numFrames; i++) {
312         SCOPED_TRACE(String8::format("frame %d", i).c_str());
313 
314         // We must wait for each frame to come in because if we ever do an
315         // updateTexImage call that doesn't consume a newly available buffer
316         // then the producer and consumer will get out of sync, which will cause
317         // a deadlock.
318         if (i > 1) {
319             mFW->waitForFrame();
320         }
321         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
322         drawTexture();
323 
324         for (int j = 0; j < numTestPixels; j++) {
325             int x = testPixels[j].x;
326             int y = testPixels[j].y;
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 
TEST_F(SurfaceTextureGLTest,TexturingFromCpuFilledRGBABufferNpot)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 
TEST_F(SurfaceTextureGLTest,TexturingFromCpuFilledRGBABufferPow2)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.
TEST_F(SurfaceTextureGLTest,DisconnectStressTest)436 TEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
437 
438     class ProducerThread : public Thread {
439     public:
440         explicit 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 == nullptr) {
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
TEST_F(SurfaceTextureGLTest,DisconnectClearsCurrentTexture)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 
TEST_F(SurfaceTextureGLTest,ScaleToWindowMode)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
TEST_F(SurfaceTextureGLTest,CroppedScalingMode)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 
TEST_F(SurfaceTextureGLTest,AbandonUnblocksDequeueBuffer)620 TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
621     class ProducerThread : public Thread {
622     public:
623         explicit 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 == nullptr) {
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 == nullptr) {
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 
TEST_F(SurfaceTextureGLTest,InvalidWidthOrHeightFails)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