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