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