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