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