• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SurfaceTextureClient_test"
18 //#define LOG_NDEBUG 0
19 
20 #include <EGL/egl.h>
21 #include <GLES2/gl2.h>
22 
23 #include <gtest/gtest.h>
24 #include <gui/GLConsumer.h>
25 #include <gui/Surface.h>
26 #include <system/graphics.h>
27 #include <utils/Log.h>
28 #include <utils/Thread.h>
29 
30 namespace android {
31 
32 class SurfaceTextureClientTest : public ::testing::Test {
33 protected:
SurfaceTextureClientTest()34     SurfaceTextureClientTest():
35             mEglDisplay(EGL_NO_DISPLAY),
36             mEglSurface(EGL_NO_SURFACE),
37             mEglContext(EGL_NO_CONTEXT) {
38     }
39 
SetUp()40     virtual void SetUp() {
41         const ::testing::TestInfo* const testInfo =
42             ::testing::UnitTest::GetInstance()->current_test_info();
43         ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
44                 testInfo->name());
45 
46         sp<IGraphicBufferProducer> producer;
47         sp<IGraphicBufferConsumer> consumer;
48         BufferQueue::createBufferQueue(&producer, &consumer);
49         mST = new GLConsumer(consumer, 123, GLConsumer::TEXTURE_EXTERNAL, true,
50                 false);
51         mSTC = new Surface(producer);
52         mANW = mSTC;
53 
54         // We need a valid GL context so we can test updateTexImage()
55         // This initializes EGL and create a dummy GL context with a
56         // pbuffer render target.
57         mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
58         ASSERT_EQ(EGL_SUCCESS, eglGetError());
59         ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
60 
61         EGLint majorVersion, minorVersion;
62         EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
63         ASSERT_EQ(EGL_SUCCESS, eglGetError());
64 
65         EGLConfig myConfig;
66         EGLint numConfigs = 0;
67         EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(),
68                 &myConfig, 1, &numConfigs));
69         ASSERT_EQ(EGL_SUCCESS, eglGetError());
70 
71         mEglConfig = myConfig;
72         EGLint pbufferAttribs[] = {
73             EGL_WIDTH, 16,
74             EGL_HEIGHT, 16,
75             EGL_NONE };
76         mEglSurface = eglCreatePbufferSurface(mEglDisplay, myConfig, pbufferAttribs);
77         ASSERT_EQ(EGL_SUCCESS, eglGetError());
78         ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
79 
80         mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT, 0);
81         ASSERT_EQ(EGL_SUCCESS, eglGetError());
82         ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
83 
84         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
85         ASSERT_EQ(EGL_SUCCESS, eglGetError());
86     }
87 
TearDown()88     virtual void TearDown() {
89         mST.clear();
90         mSTC.clear();
91         mANW.clear();
92 
93         eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
94         eglDestroyContext(mEglDisplay, mEglContext);
95         eglDestroySurface(mEglDisplay, mEglSurface);
96         eglTerminate(mEglDisplay);
97 
98         const ::testing::TestInfo* const testInfo =
99             ::testing::UnitTest::GetInstance()->current_test_info();
100         ALOGV("End test:   %s.%s", testInfo->test_case_name(),
101                 testInfo->name());
102     }
103 
getConfigAttribs()104     virtual EGLint const* getConfigAttribs() {
105         static EGLint sDefaultConfigAttribs[] = {
106             EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
107             EGL_NONE
108         };
109 
110         return sDefaultConfigAttribs;
111     }
112 
113     sp<GLConsumer> mST;
114     sp<Surface> mSTC;
115     sp<ANativeWindow> mANW;
116 
117     EGLDisplay mEglDisplay;
118     EGLSurface mEglSurface;
119     EGLContext mEglContext;
120     EGLConfig  mEglConfig;
121 };
122 
TEST_F(SurfaceTextureClientTest,GetISurfaceTextureIsNotNull)123 TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) {
124     sp<IGraphicBufferProducer> ist(mSTC->getIGraphicBufferProducer());
125     ASSERT_TRUE(ist != NULL);
126 }
127 
TEST_F(SurfaceTextureClientTest,QueuesToWindowCompositorIsFalse)128 TEST_F(SurfaceTextureClientTest, QueuesToWindowCompositorIsFalse) {
129     int result = -123;
130     int err = mANW->query(mANW.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
131             &result);
132     EXPECT_EQ(NO_ERROR, err);
133     EXPECT_EQ(0, result);
134 }
135 
TEST_F(SurfaceTextureClientTest,ConcreteTypeIsSurfaceTextureClient)136 TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) {
137     int result = -123;
138     int err = mANW->query(mANW.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
139     EXPECT_EQ(NO_ERROR, err);
140     EXPECT_EQ(NATIVE_WINDOW_SURFACE, result);
141 }
142 
TEST_F(SurfaceTextureClientTest,EglCreateWindowSurfaceSucceeds)143 TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) {
144     EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
145     ASSERT_EQ(EGL_SUCCESS, eglGetError());
146     ASSERT_NE(EGL_NO_DISPLAY, dpy);
147 
148     EGLint majorVersion;
149     EGLint minorVersion;
150     EXPECT_TRUE(eglInitialize(dpy, &majorVersion, &minorVersion));
151     ASSERT_EQ(EGL_SUCCESS, eglGetError());
152 
153     EGLConfig myConfig = {0};
154     EGLint numConfigs = 0;
155     EGLint configAttribs[] = {
156         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
157         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
158         EGL_RED_SIZE, 8,
159         EGL_GREEN_SIZE, 8,
160         EGL_BLUE_SIZE, 8,
161         EGL_ALPHA_SIZE, 8,
162         EGL_DEPTH_SIZE, 16,
163         EGL_STENCIL_SIZE, 8,
164         EGL_NONE };
165     EXPECT_TRUE(eglChooseConfig(dpy, configAttribs, &myConfig, 1,
166             &numConfigs));
167     ASSERT_EQ(EGL_SUCCESS, eglGetError());
168 
169     EGLSurface eglSurface = eglCreateWindowSurface(dpy, myConfig, mANW.get(),
170             NULL);
171     EXPECT_NE(EGL_NO_SURFACE, eglSurface);
172     EXPECT_EQ(EGL_SUCCESS, eglGetError());
173 
174     if (eglSurface != EGL_NO_SURFACE) {
175         eglDestroySurface(dpy, eglSurface);
176     }
177 
178     eglTerminate(dpy);
179 }
180 
TEST_F(SurfaceTextureClientTest,EglSwapBuffersAbandonErrorIsEglBadSurface)181 TEST_F(SurfaceTextureClientTest, EglSwapBuffersAbandonErrorIsEglBadSurface) {
182 
183     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, mANW.get(), NULL);
184     EXPECT_NE(EGL_NO_SURFACE, eglSurface);
185     EXPECT_EQ(EGL_SUCCESS, eglGetError());
186 
187     EGLBoolean success = eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
188     EXPECT_TRUE(success);
189 
190     glClear(GL_COLOR_BUFFER_BIT);
191     success = eglSwapBuffers(mEglDisplay, eglSurface);
192     EXPECT_TRUE(success);
193 
194     mST->abandon();
195 
196     glClear(GL_COLOR_BUFFER_BIT);
197     success = eglSwapBuffers(mEglDisplay, eglSurface);
198     EXPECT_FALSE(success);
199     EXPECT_EQ(EGL_BAD_SURFACE, eglGetError());
200 
201     success = eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
202     ASSERT_TRUE(success);
203 
204     if (eglSurface != EGL_NO_SURFACE) {
205         eglDestroySurface(mEglDisplay, eglSurface);
206     }
207 }
208 
TEST_F(SurfaceTextureClientTest,BufferGeometryInvalidSizesFail)209 TEST_F(SurfaceTextureClientTest, BufferGeometryInvalidSizesFail) {
210     EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1,  0,  0));
211     EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0, -1,  0));
212     EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0,  0, -1));
213     EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, -1,  0));
214     EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0,  8,  0));
215     EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  8,  0,  0));
216 }
217 
TEST_F(SurfaceTextureClientTest,DefaultGeometryValues)218 TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
219     ANativeWindowBuffer* buf;
220     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
221     EXPECT_EQ(1, buf->width);
222     EXPECT_EQ(1, buf->height);
223     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
224     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
225 }
226 
TEST_F(SurfaceTextureClientTest,BufferGeometryCanBeSet)227 TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
228     ANativeWindowBuffer* buf;
229     EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, PIXEL_FORMAT_RGB_565));
230     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
231     EXPECT_EQ(16, buf->width);
232     EXPECT_EQ(8, buf->height);
233     EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
234     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
235 }
236 
TEST_F(SurfaceTextureClientTest,BufferGeometryDefaultSizeSetFormat)237 TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
238     ANativeWindowBuffer* buf;
239     EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
240     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
241     EXPECT_EQ(1, buf->width);
242     EXPECT_EQ(1, buf->height);
243     EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
244     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
245 }
246 
TEST_F(SurfaceTextureClientTest,BufferGeometrySetSizeDefaultFormat)247 TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
248     ANativeWindowBuffer* buf;
249     EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
250     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
251     EXPECT_EQ(16, buf->width);
252     EXPECT_EQ(8, buf->height);
253     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
254     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
255 }
256 
TEST_F(SurfaceTextureClientTest,BufferGeometrySizeCanBeUnset)257 TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
258     ANativeWindowBuffer* buf;
259     EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
260     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
261     EXPECT_EQ(16, buf->width);
262     EXPECT_EQ(8, buf->height);
263     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
264     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
265     EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, 0));
266     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
267     EXPECT_EQ(1, buf->width);
268     EXPECT_EQ(1, buf->height);
269     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
270     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
271 }
272 
TEST_F(SurfaceTextureClientTest,BufferGeometrySizeCanBeChangedWithoutFormat)273 TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) {
274     ANativeWindowBuffer* buf;
275     EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
276     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
277     EXPECT_EQ(1, buf->width);
278     EXPECT_EQ(1, buf->height);
279     EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
280     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
281     EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
282     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
283     EXPECT_EQ(16, buf->width);
284     EXPECT_EQ(8, buf->height);
285     EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
286     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
287 }
288 
TEST_F(SurfaceTextureClientTest,SurfaceTextureSetDefaultSize)289 TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSize) {
290     sp<GLConsumer> st(mST);
291     ANativeWindowBuffer* buf;
292     EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
293     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
294     EXPECT_EQ(16, buf->width);
295     EXPECT_EQ(8, buf->height);
296     EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
297     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
298 }
299 
TEST_F(SurfaceTextureClientTest,SurfaceTextureSetDefaultSizeAfterDequeue)300 TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeAfterDequeue) {
301     ANativeWindowBuffer* buf[2];
302     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
303     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
304     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
305     EXPECT_NE(buf[0], buf[1]);
306     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
307     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1], -1));
308     EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8));
309     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
310     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
311     EXPECT_NE(buf[0], buf[1]);
312     EXPECT_EQ(16, buf[0]->width);
313     EXPECT_EQ(16, buf[1]->width);
314     EXPECT_EQ(8, buf[0]->height);
315     EXPECT_EQ(8, buf[1]->height);
316     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
317     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1], -1));
318 }
319 
TEST_F(SurfaceTextureClientTest,SurfaceTextureSetDefaultSizeVsGeometry)320 TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
321     ANativeWindowBuffer* buf[2];
322     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
323     EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8));
324     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
325     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
326     EXPECT_NE(buf[0], buf[1]);
327     EXPECT_EQ(16, buf[0]->width);
328     EXPECT_EQ(16, buf[1]->width);
329     EXPECT_EQ(8, buf[0]->height);
330     EXPECT_EQ(8, buf[1]->height);
331     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
332     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1], -1));
333     EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 12, 24, 0));
334     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
335     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
336     EXPECT_NE(buf[0], buf[1]);
337     EXPECT_EQ(12, buf[0]->width);
338     EXPECT_EQ(12, buf[1]->width);
339     EXPECT_EQ(24, buf[0]->height);
340     EXPECT_EQ(24, buf[1]->height);
341     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
342     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1], -1));
343 }
344 
TEST_F(SurfaceTextureClientTest,SurfaceTextureTooManyUpdateTexImage)345 TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
346     android_native_buffer_t* buf[3];
347     ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 0));
348     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
349 
350     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
351     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
352     EXPECT_EQ(OK, mST->updateTexImage());
353     EXPECT_EQ(OK, mST->updateTexImage());
354 
355     ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1));
356     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
357 
358     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
359     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
360     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
361     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
362 
363     EXPECT_EQ(OK, mST->updateTexImage());
364     EXPECT_EQ(OK, mST->updateTexImage());
365     EXPECT_EQ(OK, mST->updateTexImage());
366 }
367 
TEST_F(SurfaceTextureClientTest,SurfaceTextureSyncModeSlowRetire)368 TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) {
369     android_native_buffer_t* buf[3];
370     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
371     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
372     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
373     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
374     EXPECT_NE(buf[0], buf[1]);
375     EXPECT_NE(buf[1], buf[2]);
376     EXPECT_NE(buf[2], buf[0]);
377     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
378     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
379     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
380     EXPECT_EQ(OK, mST->updateTexImage());
381     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
382     EXPECT_EQ(OK, mST->updateTexImage());
383     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
384     EXPECT_EQ(OK, mST->updateTexImage());
385     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
386 }
387 
TEST_F(SurfaceTextureClientTest,SurfaceTextureSyncModeFastRetire)388 TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
389     android_native_buffer_t* buf[3];
390     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
391     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
392     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
393     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
394     EXPECT_NE(buf[0], buf[1]);
395     EXPECT_NE(buf[1], buf[2]);
396     EXPECT_NE(buf[2], buf[0]);
397     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
398     EXPECT_EQ(OK, mST->updateTexImage());
399     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
400     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
401     EXPECT_EQ(OK, mST->updateTexImage());
402     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
403     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
404     EXPECT_EQ(OK, mST->updateTexImage());
405     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
406 }
407 
TEST_F(SurfaceTextureClientTest,SurfaceTextureSyncModeDQQR)408 TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
409     android_native_buffer_t* buf[3];
410     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
411 
412     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
413     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
414     EXPECT_EQ(OK, mST->updateTexImage());
415     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
416 
417     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
418     EXPECT_NE(buf[0], buf[1]);
419     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
420     EXPECT_EQ(OK, mST->updateTexImage());
421     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
422 
423     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
424     EXPECT_NE(buf[1], buf[2]);
425     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
426     EXPECT_EQ(OK, mST->updateTexImage());
427     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
428 }
429 
430 // XXX: We currently have no hardware that properly handles dequeuing the
431 // buffer that is currently bound to the texture.
TEST_F(SurfaceTextureClientTest,DISABLED_SurfaceTextureSyncModeDequeueCurrent)432 TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) {
433     android_native_buffer_t* buf[3];
434     android_native_buffer_t* firstBuf;
435     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
436     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &firstBuf));
437     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf, -1));
438     EXPECT_EQ(OK, mST->updateTexImage());
439     EXPECT_EQ(mST->getCurrentBuffer().get(), firstBuf);
440     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
441     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
442     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
443     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
444     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
445     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
446     EXPECT_NE(buf[0], buf[1]);
447     EXPECT_NE(buf[1], buf[2]);
448     EXPECT_NE(buf[2], buf[0]);
449     EXPECT_EQ(firstBuf, buf[2]);
450 }
451 
TEST_F(SurfaceTextureClientTest,SurfaceTextureSyncModeMinUndequeued)452 TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
453     android_native_buffer_t* buf[3];
454     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
455 
456     // We should be able to dequeue all the buffers before we've queued mANWy.
457     EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
458     EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
459     EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
460 
461     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2], -1));
462     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
463 
464     EXPECT_EQ(OK, mST->updateTexImage());
465     EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
466 
467     EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
468 
469     // Once we've queued a buffer, however we should not be able to dequeue more
470     // than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case.
471     EXPECT_EQ(-EBUSY, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
472 
473     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
474     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2], -1));
475 }
476 
TEST_F(SurfaceTextureClientTest,SetCropCropsCrop)477 TEST_F(SurfaceTextureClientTest, SetCropCropsCrop) {
478     android_native_rect_t rect = {-2, -13, 40, 18};
479     native_window_set_crop(mANW.get(), &rect);
480 
481     ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 4, 4));
482 
483     android_native_buffer_t* buf;
484     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
485     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf, -1));
486     ASSERT_EQ(OK, mST->updateTexImage());
487 
488     Rect crop = mST->getCurrentCrop();
489     EXPECT_EQ(0, crop.left);
490     EXPECT_EQ(0, crop.top);
491     EXPECT_EQ(4, crop.right);
492     EXPECT_EQ(4, crop.bottom);
493 }
494 
495 // XXX: This is not expected to pass until the synchronization hacks are removed
496 // from the SurfaceTexture class.
TEST_F(SurfaceTextureClientTest,DISABLED_SurfaceTextureSyncModeWaitRetire)497 TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) {
498     class MyThread : public Thread {
499         sp<GLConsumer> mST;
500         EGLContext ctx;
501         EGLSurface sur;
502         EGLDisplay dpy;
503         bool mBufferRetired;
504         Mutex mLock;
505         virtual bool threadLoop() {
506             eglMakeCurrent(dpy, sur, sur, ctx);
507             usleep(20000);
508             Mutex::Autolock _l(mLock);
509             mST->updateTexImage();
510             mBufferRetired = true;
511             eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
512             return false;
513         }
514     public:
515         MyThread(const sp<GLConsumer>& mST)
516             : mST(mST), mBufferRetired(false) {
517             ctx = eglGetCurrentContext();
518             sur = eglGetCurrentSurface(EGL_DRAW);
519             dpy = eglGetCurrentDisplay();
520             eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
521         }
522         ~MyThread() {
523             eglMakeCurrent(dpy, sur, sur, ctx);
524         }
525         void bufferDequeued() {
526             Mutex::Autolock _l(mLock);
527             EXPECT_EQ(true, mBufferRetired);
528         }
529     };
530 
531     android_native_buffer_t* buf[3];
532     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
533     // dequeue/queue/update so we have a current buffer
534     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
535     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
536     mST->updateTexImage();
537 
538     MyThread* thread = new MyThread(mST);
539     sp<Thread> threadBase(thread);
540 
541     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
542     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
543     thread->run();
544     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
545     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
546     //ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
547     //ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
548     thread->bufferDequeued();
549     thread->requestExitAndWait();
550 }
551 
TEST_F(SurfaceTextureClientTest,GetTransformMatrixReturnsVerticalFlip)552 TEST_F(SurfaceTextureClientTest, GetTransformMatrixReturnsVerticalFlip) {
553     android_native_buffer_t* buf[3];
554     float mtx[16] = {};
555     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
556     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
557     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
558     ASSERT_EQ(OK, mST->updateTexImage());
559     mST->getTransformMatrix(mtx);
560 
561     EXPECT_EQ(1.f, mtx[0]);
562     EXPECT_EQ(0.f, mtx[1]);
563     EXPECT_EQ(0.f, mtx[2]);
564     EXPECT_EQ(0.f, mtx[3]);
565 
566     EXPECT_EQ(0.f, mtx[4]);
567     EXPECT_EQ(-1.f, mtx[5]);
568     EXPECT_EQ(0.f, mtx[6]);
569     EXPECT_EQ(0.f, mtx[7]);
570 
571     EXPECT_EQ(0.f, mtx[8]);
572     EXPECT_EQ(0.f, mtx[9]);
573     EXPECT_EQ(1.f, mtx[10]);
574     EXPECT_EQ(0.f, mtx[11]);
575 
576     EXPECT_EQ(0.f, mtx[12]);
577     EXPECT_EQ(1.f, mtx[13]);
578     EXPECT_EQ(0.f, mtx[14]);
579     EXPECT_EQ(1.f, mtx[15]);
580 }
581 
TEST_F(SurfaceTextureClientTest,GetTransformMatrixSucceedsAfterFreeingBuffers)582 TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffers) {
583     android_native_buffer_t* buf[3];
584     float mtx[16] = {};
585     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
586     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
587     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
588     ASSERT_EQ(OK, mST->updateTexImage());
589     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
590     mST->getTransformMatrix(mtx);
591 
592     EXPECT_EQ(1.f, mtx[0]);
593     EXPECT_EQ(0.f, mtx[1]);
594     EXPECT_EQ(0.f, mtx[2]);
595     EXPECT_EQ(0.f, mtx[3]);
596 
597     EXPECT_EQ(0.f, mtx[4]);
598     EXPECT_EQ(-1.f, mtx[5]);
599     EXPECT_EQ(0.f, mtx[6]);
600     EXPECT_EQ(0.f, mtx[7]);
601 
602     EXPECT_EQ(0.f, mtx[8]);
603     EXPECT_EQ(0.f, mtx[9]);
604     EXPECT_EQ(1.f, mtx[10]);
605     EXPECT_EQ(0.f, mtx[11]);
606 
607     EXPECT_EQ(0.f, mtx[12]);
608     EXPECT_EQ(1.f, mtx[13]);
609     EXPECT_EQ(0.f, mtx[14]);
610     EXPECT_EQ(1.f, mtx[15]);
611 }
612 
TEST_F(SurfaceTextureClientTest,GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop)613 TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop) {
614     android_native_buffer_t* buf[3];
615     float mtx[16] = {};
616     android_native_rect_t crop;
617     crop.left = 0;
618     crop.top = 0;
619     crop.right = 5;
620     crop.bottom = 5;
621 
622     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
623     ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0));
624     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
625     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop));
626     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
627     ASSERT_EQ(OK, mST->updateTexImage());
628     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
629     mST->getTransformMatrix(mtx);
630 
631     // This accounts for the .5 texel shrink for each edge that's included in the
632     // transform matrix to avoid texturing outside the crop region.
633     EXPECT_EQ(0.5, mtx[0]);
634     EXPECT_EQ(0.f, mtx[1]);
635     EXPECT_EQ(0.f, mtx[2]);
636     EXPECT_EQ(0.f, mtx[3]);
637 
638     EXPECT_EQ(0.f, mtx[4]);
639     EXPECT_EQ(-0.5, mtx[5]);
640     EXPECT_EQ(0.f, mtx[6]);
641     EXPECT_EQ(0.f, mtx[7]);
642 
643     EXPECT_EQ(0.f, mtx[8]);
644     EXPECT_EQ(0.f, mtx[9]);
645     EXPECT_EQ(1.f, mtx[10]);
646     EXPECT_EQ(0.f, mtx[11]);
647 
648     EXPECT_EQ(0.0625f, mtx[12]);
649     EXPECT_EQ(0.5625f, mtx[13]);
650     EXPECT_EQ(0.f, mtx[14]);
651     EXPECT_EQ(1.f, mtx[15]);
652 }
653 
654 // This test verifies that the buffer format can be queried immediately after
655 // it is set.
TEST_F(SurfaceTextureClientTest,QueryFormatAfterSettingWorks)656 TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) {
657     sp<ANativeWindow> anw(mSTC);
658     int fmts[] = {
659         // RGBA_8888 should not come first, as it's the default
660         HAL_PIXEL_FORMAT_RGBX_8888,
661         HAL_PIXEL_FORMAT_RGBA_8888,
662         HAL_PIXEL_FORMAT_RGB_888,
663         HAL_PIXEL_FORMAT_RGB_565,
664         HAL_PIXEL_FORMAT_BGRA_8888,
665         HAL_PIXEL_FORMAT_YV12,
666     };
667 
668     const int numFmts = (sizeof(fmts) / sizeof(fmts[0]));
669     for (int i = 0; i < numFmts; i++) {
670       int fmt = -1;
671       ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i]));
672       ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt));
673       EXPECT_EQ(fmts[i], fmt);
674     }
675 }
676 
677 class MultiSurfaceTextureClientTest : public ::testing::Test {
678 
679 public:
MultiSurfaceTextureClientTest()680     MultiSurfaceTextureClientTest() :
681             mEglDisplay(EGL_NO_DISPLAY),
682             mEglContext(EGL_NO_CONTEXT) {
683         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
684             mEglSurfaces[i] = EGL_NO_CONTEXT;
685         }
686     }
687 
688 protected:
689 
690     enum { NUM_SURFACE_TEXTURES = 32 };
691 
SetUp()692     virtual void SetUp() {
693         mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
694         ASSERT_EQ(EGL_SUCCESS, eglGetError());
695         ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
696 
697         EGLint majorVersion, minorVersion;
698         EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
699         ASSERT_EQ(EGL_SUCCESS, eglGetError());
700 
701         EGLConfig myConfig;
702         EGLint numConfigs = 0;
703         EGLint configAttribs[] = {
704             EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
705             EGL_NONE
706         };
707         EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &myConfig, 1,
708                 &numConfigs));
709         ASSERT_EQ(EGL_SUCCESS, eglGetError());
710 
711         mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT,
712                 0);
713         ASSERT_EQ(EGL_SUCCESS, eglGetError());
714         ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
715 
716         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
717             sp<IGraphicBufferProducer> producer;
718             sp<IGraphicBufferConsumer> consumer;
719             BufferQueue::createBufferQueue(&producer, &consumer);
720             sp<GLConsumer> st(new GLConsumer(consumer, i,
721                     GLConsumer::TEXTURE_EXTERNAL, true, false));
722             sp<Surface> stc(new Surface(producer));
723             mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
724                     static_cast<ANativeWindow*>(stc.get()), NULL);
725             ASSERT_EQ(EGL_SUCCESS, eglGetError());
726             ASSERT_NE(EGL_NO_SURFACE, mEglSurfaces[i]);
727         }
728     }
729 
TearDown()730     virtual void TearDown() {
731         eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
732                 EGL_NO_CONTEXT);
733 
734         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
735             if (mEglSurfaces[i] != EGL_NO_SURFACE) {
736                 eglDestroySurface(mEglDisplay, mEglSurfaces[i]);
737             }
738         }
739 
740         if (mEglContext != EGL_NO_CONTEXT) {
741             eglDestroyContext(mEglDisplay, mEglContext);
742         }
743 
744         if (mEglDisplay != EGL_NO_DISPLAY) {
745             eglTerminate(mEglDisplay);
746         }
747     }
748 
749     EGLDisplay mEglDisplay;
750     EGLSurface mEglSurfaces[NUM_SURFACE_TEXTURES];
751     EGLContext mEglContext;
752 };
753 
754 // XXX: This test is disabled because it causes a hang on some devices.  See bug
755 // 5015672.
TEST_F(MultiSurfaceTextureClientTest,DISABLED_MakeCurrentBetweenSurfacesWorks)756 TEST_F(MultiSurfaceTextureClientTest, DISABLED_MakeCurrentBetweenSurfacesWorks) {
757     for (int iter = 0; iter < 8; iter++) {
758         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
759             eglMakeCurrent(mEglDisplay, mEglSurfaces[i], mEglSurfaces[i],
760                     mEglContext);
761             glClear(GL_COLOR_BUFFER_BIT);
762             eglSwapBuffers(mEglDisplay, mEglSurfaces[i]);
763         }
764     }
765 }
766 
767 } // namespace android
768