Home | History | Annotate | Download | only in tests
      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:
     37     SurfaceTextureClientTest():
     38             mEglDisplay(EGL_NO_DISPLAY),
     39             mEglSurface(EGL_NO_SURFACE),
     40             mEglContext(EGL_NO_CONTEXT),
     41             mEglConfig(NULL) {
     42     }
     43 
     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, 0);
     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 
     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 
    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 
    127 TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) {
    128     sp<IGraphicBufferProducer> ist(mSTC->getIGraphicBufferProducer());
    129     ASSERT_TRUE(ist != NULL);
    130 }
    131 
    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 
    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 
    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 = {0};
    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             NULL);
    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 
    185 TEST_F(SurfaceTextureClientTest, EglSwapBuffersAbandonErrorIsEglBadSurface) {
    186 
    187     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, mANW.get(), NULL);
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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.
    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 
    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 
    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.
    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         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 
    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 
    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 
    639 TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop) {
    640     // Query to see if the image crop extension exists
    641     EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    642     const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS);
    643     size_t cropExtLen = strlen(CROP_EXT_STR);
    644     size_t extsLen = strlen(exts);
    645     bool equal = !strcmp(CROP_EXT_STR, exts);
    646     bool atStart = !strncmp(CROP_EXT_STR " ", exts, cropExtLen+1);
    647     bool atEnd = (cropExtLen+1) < extsLen &&
    648             !strcmp(" " CROP_EXT_STR, exts + extsLen - (cropExtLen+1));
    649     bool inMiddle = strstr(exts, " " CROP_EXT_STR " ");
    650     bool hasEglAndroidImageCrop = equal || atStart || atEnd || inMiddle;
    651 
    652     android_native_buffer_t* buf[3];
    653     float mtx[16] = {};
    654     android_native_rect_t crop;
    655     crop.left = 0;
    656     crop.top = 0;
    657     crop.right = 5;
    658     crop.bottom = 5;
    659 
    660     ASSERT_EQ(OK, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
    661     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
    662     ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 8, 8));
    663     ASSERT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
    664     ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
    665     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop));
    666     ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
    667     ASSERT_EQ(OK, mST->updateTexImage());
    668     ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
    669     mST->getTransformMatrix(mtx);
    670 
    671     // If the egl image crop extension is not present, this accounts for the
    672     // .5 texel shrink for each edge that's included in the transform matrix
    673     // to avoid texturing outside the crop region. Otherwise the crop is not
    674     // included in the transform matrix.
    675     EXPECT_EQ(hasEglAndroidImageCrop ? 1 : 0.5, mtx[0]);
    676     EXPECT_EQ(0.f, mtx[1]);
    677     EXPECT_EQ(0.f, mtx[2]);
    678     EXPECT_EQ(0.f, mtx[3]);
    679 
    680     EXPECT_EQ(0.f, mtx[4]);
    681     EXPECT_EQ(hasEglAndroidImageCrop ? -1 : -0.5, mtx[5]);
    682     EXPECT_EQ(0.f, mtx[6]);
    683     EXPECT_EQ(0.f, mtx[7]);
    684 
    685     EXPECT_EQ(0.f, mtx[8]);
    686     EXPECT_EQ(0.f, mtx[9]);
    687     EXPECT_EQ(1.f, mtx[10]);
    688     EXPECT_EQ(0.f, mtx[11]);
    689 
    690     EXPECT_EQ(hasEglAndroidImageCrop ? 0 : 0.0625f, mtx[12]);
    691     EXPECT_EQ(hasEglAndroidImageCrop ? 1 : 0.5625f, mtx[13]);
    692     EXPECT_EQ(0.f, mtx[14]);
    693     EXPECT_EQ(1.f, mtx[15]);
    694 }
    695 
    696 // This test verifies that the buffer format can be queried immediately after
    697 // it is set.
    698 TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) {
    699     sp<ANativeWindow> anw(mSTC);
    700     int fmts[] = {
    701         // RGBA_8888 should not come first, as it's the default
    702         HAL_PIXEL_FORMAT_RGBX_8888,
    703         HAL_PIXEL_FORMAT_RGBA_8888,
    704         HAL_PIXEL_FORMAT_RGB_888,
    705         HAL_PIXEL_FORMAT_RGB_565,
    706         HAL_PIXEL_FORMAT_BGRA_8888,
    707         HAL_PIXEL_FORMAT_YV12,
    708     };
    709 
    710     const int numFmts = (sizeof(fmts) / sizeof(fmts[0]));
    711     for (int i = 0; i < numFmts; i++) {
    712       int fmt = -1;
    713       ASSERT_EQ(OK, native_window_set_buffers_dimensions(anw.get(), 0, 0));
    714       ASSERT_EQ(OK, native_window_set_buffers_format(anw.get(), fmts[i]));
    715       ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt));
    716       EXPECT_EQ(fmts[i], fmt);
    717     }
    718 }
    719 
    720 class MultiSurfaceTextureClientTest : public ::testing::Test {
    721 
    722 public:
    723     MultiSurfaceTextureClientTest() :
    724             mEglDisplay(EGL_NO_DISPLAY),
    725             mEglContext(EGL_NO_CONTEXT) {
    726         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
    727             mEglSurfaces[i] = EGL_NO_CONTEXT;
    728         }
    729     }
    730 
    731 protected:
    732 
    733     enum { NUM_SURFACE_TEXTURES = 32 };
    734 
    735     virtual void SetUp() {
    736         mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    737         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    738         ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
    739 
    740         EGLint majorVersion, minorVersion;
    741         EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
    742         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    743 
    744         EGLConfig myConfig;
    745         EGLint numConfigs = 0;
    746         EGLint configAttribs[] = {
    747             EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    748             EGL_NONE
    749         };
    750         EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &myConfig, 1,
    751                 &numConfigs));
    752         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    753 
    754         mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT,
    755                 0);
    756         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    757         ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
    758 
    759         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
    760             sp<IGraphicBufferProducer> producer;
    761             sp<IGraphicBufferConsumer> consumer;
    762             BufferQueue::createBufferQueue(&producer, &consumer);
    763             sp<GLConsumer> st(new GLConsumer(consumer, i,
    764                     GLConsumer::TEXTURE_EXTERNAL, true, false));
    765             sp<Surface> stc(new Surface(producer));
    766             mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
    767                     static_cast<ANativeWindow*>(stc.get()), NULL);
    768             ASSERT_EQ(EGL_SUCCESS, eglGetError());
    769             ASSERT_NE(EGL_NO_SURFACE, mEglSurfaces[i]);
    770         }
    771     }
    772 
    773     virtual void TearDown() {
    774         eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
    775                 EGL_NO_CONTEXT);
    776 
    777         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
    778             if (mEglSurfaces[i] != EGL_NO_SURFACE) {
    779                 eglDestroySurface(mEglDisplay, mEglSurfaces[i]);
    780             }
    781         }
    782 
    783         if (mEglContext != EGL_NO_CONTEXT) {
    784             eglDestroyContext(mEglDisplay, mEglContext);
    785         }
    786 
    787         if (mEglDisplay != EGL_NO_DISPLAY) {
    788             eglTerminate(mEglDisplay);
    789         }
    790     }
    791 
    792     EGLDisplay mEglDisplay;
    793     EGLSurface mEglSurfaces[NUM_SURFACE_TEXTURES];
    794     EGLContext mEglContext;
    795 };
    796 
    797 // XXX: This test is disabled because it causes a hang on some devices.  See bug
    798 // 5015672.
    799 TEST_F(MultiSurfaceTextureClientTest, DISABLED_MakeCurrentBetweenSurfacesWorks) {
    800     for (int iter = 0; iter < 8; iter++) {
    801         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
    802             eglMakeCurrent(mEglDisplay, mEglSurfaces[i], mEglSurfaces[i],
    803                     mEglContext);
    804             glClear(GL_COLOR_BUFFER_BIT);
    805             eglSwapBuffers(mEglDisplay, mEglSurfaces[i]);
    806         }
    807     }
    808 }
    809 
    810 } // namespace android
    811