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