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