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