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