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 "SurfaceTexture_test"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include <gtest/gtest.h>
     21 #include <gui/GLConsumer.h>
     22 #include <ui/GraphicBuffer.h>
     23 #include <utils/String8.h>
     24 #include <utils/threads.h>
     25 
     26 #include <gui/ISurfaceComposer.h>
     27 #include <gui/Surface.h>
     28 #include <gui/SurfaceComposerClient.h>
     29 
     30 #include <EGL/egl.h>
     31 #include <EGL/eglext.h>
     32 #include <GLES/gl.h>
     33 #include <GLES/glext.h>
     34 #include <GLES2/gl2.h>
     35 #include <GLES2/gl2ext.h>
     36 
     37 #include <ui/FramebufferNativeWindow.h>
     38 #include <utils/UniquePtr.h>
     39 #include <android/native_window.h>
     40 
     41 namespace android {
     42 
     43 class GLTest : public ::testing::Test {
     44 protected:
     45 
     46     GLTest():
     47             mEglDisplay(EGL_NO_DISPLAY),
     48             mEglSurface(EGL_NO_SURFACE),
     49             mEglContext(EGL_NO_CONTEXT) {
     50     }
     51 
     52     virtual void SetUp() {
     53         const ::testing::TestInfo* const testInfo =
     54             ::testing::UnitTest::GetInstance()->current_test_info();
     55         ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
     56                 testInfo->name());
     57 
     58         mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     59         ASSERT_EQ(EGL_SUCCESS, eglGetError());
     60         ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
     61 
     62         EGLint majorVersion;
     63         EGLint minorVersion;
     64         EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
     65         ASSERT_EQ(EGL_SUCCESS, eglGetError());
     66         RecordProperty("EglVersionMajor", majorVersion);
     67         RecordProperty("EglVersionMajor", minorVersion);
     68 
     69         EGLint numConfigs = 0;
     70         EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
     71                 1, &numConfigs));
     72         ASSERT_EQ(EGL_SUCCESS, eglGetError());
     73 
     74         char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
     75         if (displaySecsEnv != NULL) {
     76             mDisplaySecs = atoi(displaySecsEnv);
     77             if (mDisplaySecs < 0) {
     78                 mDisplaySecs = 0;
     79             }
     80         } else {
     81             mDisplaySecs = 0;
     82         }
     83 
     84         if (mDisplaySecs > 0) {
     85             mComposerClient = new SurfaceComposerClient;
     86             ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
     87 
     88             mSurfaceControl = mComposerClient->createSurface(
     89                     String8("Test Surface"),
     90                     getSurfaceWidth(), getSurfaceHeight(),
     91                     PIXEL_FORMAT_RGB_888, 0);
     92 
     93             ASSERT_TRUE(mSurfaceControl != NULL);
     94             ASSERT_TRUE(mSurfaceControl->isValid());
     95 
     96             SurfaceComposerClient::openGlobalTransaction();
     97             ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
     98             ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
     99             SurfaceComposerClient::closeGlobalTransaction();
    100 
    101             sp<ANativeWindow> window = mSurfaceControl->getSurface();
    102             mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
    103                     window.get(), NULL);
    104         } else {
    105             EGLint pbufferAttribs[] = {
    106                 EGL_WIDTH, getSurfaceWidth(),
    107                 EGL_HEIGHT, getSurfaceHeight(),
    108                 EGL_NONE };
    109 
    110             mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
    111                     pbufferAttribs);
    112         }
    113         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    114         ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
    115 
    116         mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
    117                 getContextAttribs());
    118         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    119         ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
    120 
    121         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    122                 mEglContext));
    123         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    124 
    125         EGLint w, h;
    126         EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
    127         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    128         EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
    129         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    130         RecordProperty("EglSurfaceWidth", w);
    131         RecordProperty("EglSurfaceHeight", h);
    132 
    133         glViewport(0, 0, w, h);
    134         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    135     }
    136 
    137     virtual void TearDown() {
    138         // Display the result
    139         if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
    140             eglSwapBuffers(mEglDisplay, mEglSurface);
    141             sleep(mDisplaySecs);
    142         }
    143 
    144         if (mComposerClient != NULL) {
    145             mComposerClient->dispose();
    146         }
    147         if (mEglContext != EGL_NO_CONTEXT) {
    148             eglDestroyContext(mEglDisplay, mEglContext);
    149         }
    150         if (mEglSurface != EGL_NO_SURFACE) {
    151             eglDestroySurface(mEglDisplay, mEglSurface);
    152         }
    153         if (mEglDisplay != EGL_NO_DISPLAY) {
    154             eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
    155                     EGL_NO_CONTEXT);
    156             eglTerminate(mEglDisplay);
    157         }
    158         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    159 
    160         const ::testing::TestInfo* const testInfo =
    161             ::testing::UnitTest::GetInstance()->current_test_info();
    162         ALOGV("End test:   %s.%s", testInfo->test_case_name(),
    163                 testInfo->name());
    164     }
    165 
    166     virtual EGLint const* getConfigAttribs() {
    167         static EGLint sDefaultConfigAttribs[] = {
    168             EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    169             EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    170             EGL_RED_SIZE, 8,
    171             EGL_GREEN_SIZE, 8,
    172             EGL_BLUE_SIZE, 8,
    173             EGL_ALPHA_SIZE, 8,
    174             EGL_DEPTH_SIZE, 16,
    175             EGL_STENCIL_SIZE, 8,
    176             EGL_NONE };
    177 
    178         return sDefaultConfigAttribs;
    179     }
    180 
    181     virtual EGLint const* getContextAttribs() {
    182         static EGLint sDefaultContextAttribs[] = {
    183             EGL_CONTEXT_CLIENT_VERSION, 2,
    184             EGL_NONE };
    185 
    186         return sDefaultContextAttribs;
    187     }
    188 
    189     virtual EGLint getSurfaceWidth() {
    190         return 512;
    191     }
    192 
    193     virtual EGLint getSurfaceHeight() {
    194         return 512;
    195     }
    196 
    197     ::testing::AssertionResult checkPixel(int x, int y, int r,
    198             int g, int b, int a, int tolerance=2) {
    199         GLubyte pixel[4];
    200         String8 msg;
    201         glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
    202         GLenum err = glGetError();
    203         if (err != GL_NO_ERROR) {
    204             msg += String8::format("error reading pixel: %#x", err);
    205             while ((err = glGetError()) != GL_NO_ERROR) {
    206                 msg += String8::format(", %#x", err);
    207             }
    208             return ::testing::AssertionFailure(
    209                     ::testing::Message(msg.string()));
    210         }
    211         if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
    212             msg += String8::format("r(%d isn't %d)", pixel[0], r);
    213         }
    214         if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
    215             if (!msg.isEmpty()) {
    216                 msg += " ";
    217             }
    218             msg += String8::format("g(%d isn't %d)", pixel[1], g);
    219         }
    220         if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
    221             if (!msg.isEmpty()) {
    222                 msg += " ";
    223             }
    224             msg += String8::format("b(%d isn't %d)", pixel[2], b);
    225         }
    226         if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
    227             if (!msg.isEmpty()) {
    228                 msg += " ";
    229             }
    230             msg += String8::format("a(%d isn't %d)", pixel[3], a);
    231         }
    232         if (!msg.isEmpty()) {
    233             return ::testing::AssertionFailure(
    234                     ::testing::Message(msg.string()));
    235         } else {
    236             return ::testing::AssertionSuccess();
    237         }
    238     }
    239 
    240     ::testing::AssertionResult assertRectEq(const Rect &r1,
    241         const Rect &r2, int tolerance=1) {
    242 
    243         String8 msg;
    244 
    245         if (abs(r1.left - r2.left) > tolerance) {
    246             msg += String8::format("left(%d isn't %d)", r1.left, r2.left);
    247         }
    248         if (abs(r1.top - r2.top) > tolerance) {
    249             if (!msg.isEmpty()) {
    250                 msg += " ";
    251             }
    252             msg += String8::format("top(%d isn't %d)", r1.top, r2.top);
    253         }
    254         if (abs(r1.right - r2.right) > tolerance) {
    255             if (!msg.isEmpty()) {
    256                 msg += " ";
    257             }
    258             msg += String8::format("right(%d isn't %d)", r1.right, r2.right);
    259         }
    260         if (abs(r1.bottom - r2.bottom) > tolerance) {
    261             if (!msg.isEmpty()) {
    262                 msg += " ";
    263             }
    264             msg += String8::format("bottom(%d isn't %d)", r1.bottom, r2.bottom);
    265         }
    266         if (!msg.isEmpty()) {
    267             msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]",
    268                 r1.left, r1.top, r1.right, r1.bottom,
    269                 r2.left, r2.top, r2.right, r2.bottom);
    270             fprintf(stderr, "assertRectEq: %s\n", msg.string());
    271             return ::testing::AssertionFailure(
    272                     ::testing::Message(msg.string()));
    273         } else {
    274             return ::testing::AssertionSuccess();
    275         }
    276     }
    277 
    278     int mDisplaySecs;
    279     sp<SurfaceComposerClient> mComposerClient;
    280     sp<SurfaceControl> mSurfaceControl;
    281 
    282     EGLDisplay mEglDisplay;
    283     EGLSurface mEglSurface;
    284     EGLContext mEglContext;
    285     EGLConfig  mGlConfig;
    286 };
    287 
    288 static void loadShader(GLenum shaderType, const char* pSource,
    289         GLuint* outShader) {
    290     GLuint shader = glCreateShader(shaderType);
    291     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    292     if (shader) {
    293         glShaderSource(shader, 1, &pSource, NULL);
    294         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    295         glCompileShader(shader);
    296         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    297         GLint compiled = 0;
    298         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
    299         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    300         if (!compiled) {
    301             GLint infoLen = 0;
    302             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
    303             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    304             if (infoLen) {
    305                 char* buf = (char*) malloc(infoLen);
    306                 if (buf) {
    307                     glGetShaderInfoLog(shader, infoLen, NULL, buf);
    308                     printf("Shader compile log:\n%s\n", buf);
    309                     free(buf);
    310                     FAIL();
    311                 }
    312             } else {
    313                 char* buf = (char*) malloc(0x1000);
    314                 if (buf) {
    315                     glGetShaderInfoLog(shader, 0x1000, NULL, buf);
    316                     printf("Shader compile log:\n%s\n", buf);
    317                     free(buf);
    318                     FAIL();
    319                 }
    320             }
    321             glDeleteShader(shader);
    322             shader = 0;
    323         }
    324     }
    325     ASSERT_TRUE(shader != 0);
    326     *outShader = shader;
    327 }
    328 
    329 static void createProgram(const char* pVertexSource,
    330         const char* pFragmentSource, GLuint* outPgm) {
    331     GLuint vertexShader, fragmentShader;
    332     {
    333         SCOPED_TRACE("compiling vertex shader");
    334         ASSERT_NO_FATAL_FAILURE(loadShader(GL_VERTEX_SHADER, pVertexSource,
    335                 &vertexShader));
    336     }
    337     {
    338         SCOPED_TRACE("compiling fragment shader");
    339         ASSERT_NO_FATAL_FAILURE(loadShader(GL_FRAGMENT_SHADER, pFragmentSource,
    340                 &fragmentShader));
    341     }
    342 
    343     GLuint program = glCreateProgram();
    344     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    345     if (program) {
    346         glAttachShader(program, vertexShader);
    347         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    348         glAttachShader(program, fragmentShader);
    349         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    350         glLinkProgram(program);
    351         GLint linkStatus = GL_FALSE;
    352         glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
    353         if (linkStatus != GL_TRUE) {
    354             GLint bufLength = 0;
    355             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
    356             if (bufLength) {
    357                 char* buf = (char*) malloc(bufLength);
    358                 if (buf) {
    359                     glGetProgramInfoLog(program, bufLength, NULL, buf);
    360                     printf("Program link log:\n%s\n", buf);
    361                     free(buf);
    362                     FAIL();
    363                 }
    364             }
    365             glDeleteProgram(program);
    366             program = 0;
    367         }
    368     }
    369     glDeleteShader(vertexShader);
    370     glDeleteShader(fragmentShader);
    371     ASSERT_TRUE(program != 0);
    372     *outPgm = program;
    373 }
    374 
    375 static int abs(int value) {
    376     return value > 0 ? value : -value;
    377 }
    378 
    379 
    380 // XXX: Code above this point should live elsewhere
    381 
    382 class MultiTextureConsumerTest : public GLTest {
    383 protected:
    384     enum { TEX_ID = 123 };
    385 
    386     virtual void SetUp() {
    387         GLTest::SetUp();
    388         sp<BufferQueue> bq = new BufferQueue();
    389         mGlConsumer = new GLConsumer(bq, TEX_ID);
    390         mSurface = new Surface(bq);
    391         mANW = mSurface.get();
    392 
    393     }
    394     virtual void TearDown() {
    395         GLTest::TearDown();
    396     }
    397     virtual EGLint const* getContextAttribs() {
    398         return NULL;
    399     }
    400     virtual EGLint const* getConfigAttribs() {
    401         static EGLint sDefaultConfigAttribs[] = {
    402             EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    403             EGL_RED_SIZE, 8,
    404             EGL_GREEN_SIZE, 8,
    405             EGL_BLUE_SIZE, 8,
    406             EGL_ALPHA_SIZE, 8,
    407             EGL_NONE };
    408 
    409         return sDefaultConfigAttribs;
    410     }
    411     sp<GLConsumer> mGlConsumer;
    412     sp<Surface> mSurface;
    413     ANativeWindow* mANW;
    414 };
    415 
    416 
    417 TEST_F(MultiTextureConsumerTest, EGLImageTargetWorks) {
    418     ANativeWindow_Buffer buffer;
    419 
    420     ASSERT_EQ(native_window_set_usage(mANW, GRALLOC_USAGE_SW_WRITE_OFTEN), NO_ERROR);
    421     ASSERT_EQ(native_window_set_buffers_format(mANW, HAL_PIXEL_FORMAT_RGBA_8888), NO_ERROR);
    422 
    423     glShadeModel(GL_FLAT);
    424     glDisable(GL_DITHER);
    425     glDisable(GL_CULL_FACE);
    426     glViewport(0, 0, getSurfaceWidth(), getSurfaceHeight());
    427     glOrthof(0, getSurfaceWidth(), 0, getSurfaceHeight(), 0, 1);
    428     glEnableClientState(GL_VERTEX_ARRAY);
    429     glColor4f(1, 1, 1, 1);
    430 
    431     glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
    432     glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    433     glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    434     glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    435     glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    436 
    437     uint32_t texel = 0x80808080;
    438     glBindTexture(GL_TEXTURE_2D, TEX_ID+1);
    439     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texel);
    440     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    441     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    442     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    443     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    444 
    445     glActiveTexture(GL_TEXTURE1);
    446     glBindTexture(GL_TEXTURE_2D, TEX_ID+1);
    447     glEnable(GL_TEXTURE_2D);
    448     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    449 
    450     glActiveTexture(GL_TEXTURE0);
    451     glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
    452     glEnable(GL_TEXTURE_EXTERNAL_OES);
    453     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    454 
    455     glClear(GL_COLOR_BUFFER_BIT);
    456     for (int i=0 ; i<8 ; i++) {
    457         mSurface->lock(&buffer, NULL);
    458         memset(buffer.bits, (i&7) * 0x20, buffer.stride * buffer.height * 4);
    459         mSurface->unlockAndPost();
    460 
    461         mGlConsumer->updateTexImage();
    462 
    463         GLfloat vertices[][2] = { {i*16.0f, 0}, {(i+1)*16.0f, 0}, {(i+1)*16.0f, 16.0f}, {i*16.0f, 16.0f} };
    464         glVertexPointer(2, GL_FLOAT, 0, vertices);
    465         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    466 
    467         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    468     }
    469 
    470     for (int i=0 ; i<8 ; i++) {
    471         EXPECT_TRUE(checkPixel(i*16 + 8,  8, i*16, i*16, i*16, i*16, 0));
    472     }
    473 }
    474 
    475 
    476 
    477 class SurfaceTextureGLTest : public GLTest {
    478 protected:
    479     enum { TEX_ID = 123 };
    480 
    481     virtual void SetUp() {
    482         GLTest::SetUp();
    483         sp<BufferQueue> bq = new BufferQueue();
    484         mBQ = bq;
    485         mST = new GLConsumer(bq, TEX_ID);
    486         mSTC = new Surface(bq);
    487         mANW = mSTC;
    488         mTextureRenderer = new TextureRenderer(TEX_ID, mST);
    489         ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp());
    490         mFW = new FrameWaiter;
    491         mST->setFrameAvailableListener(mFW);
    492     }
    493 
    494     virtual void TearDown() {
    495         mANW.clear();
    496         mSTC.clear();
    497         mST.clear();
    498         GLTest::TearDown();
    499     }
    500 
    501     void drawTexture() {
    502         mTextureRenderer->drawTexture();
    503     }
    504 
    505     class TextureRenderer: public RefBase {
    506     public:
    507         TextureRenderer(GLuint texName, const sp<GLConsumer>& st):
    508                 mTexName(texName),
    509                 mST(st) {
    510         }
    511 
    512         void SetUp() {
    513             const char vsrc[] =
    514                 "attribute vec4 vPosition;\n"
    515                 "varying vec2 texCoords;\n"
    516                 "uniform mat4 texMatrix;\n"
    517                 "void main() {\n"
    518                 "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
    519                 "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
    520                 "  gl_Position = vPosition;\n"
    521                 "}\n";
    522 
    523             const char fsrc[] =
    524                 "#extension GL_OES_EGL_image_external : require\n"
    525                 "precision mediump float;\n"
    526                 "uniform samplerExternalOES texSampler;\n"
    527                 "varying vec2 texCoords;\n"
    528                 "void main() {\n"
    529                 "  gl_FragColor = texture2D(texSampler, texCoords);\n"
    530                 "}\n";
    531 
    532             {
    533                 SCOPED_TRACE("creating shader program");
    534                 ASSERT_NO_FATAL_FAILURE(createProgram(vsrc, fsrc, &mPgm));
    535             }
    536 
    537             mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
    538             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    539             ASSERT_NE(-1, mPositionHandle);
    540             mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
    541             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    542             ASSERT_NE(-1, mTexSamplerHandle);
    543             mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
    544             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    545             ASSERT_NE(-1, mTexMatrixHandle);
    546         }
    547 
    548         // drawTexture draws the GLConsumer over the entire GL viewport.
    549         void drawTexture() {
    550             static const GLfloat triangleVertices[] = {
    551                 -1.0f, 1.0f,
    552                 -1.0f, -1.0f,
    553                 1.0f, -1.0f,
    554                 1.0f, 1.0f,
    555             };
    556 
    557             glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
    558                     triangleVertices);
    559             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    560             glEnableVertexAttribArray(mPositionHandle);
    561             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    562 
    563             glUseProgram(mPgm);
    564             glUniform1i(mTexSamplerHandle, 0);
    565             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    566             glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName);
    567             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    568 
    569             // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
    570             // they're setting the defautls for that target, but when hacking
    571             // things to use GL_TEXTURE_2D they are needed to achieve the same
    572             // behavior.
    573             glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
    574                     GL_LINEAR);
    575             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    576             glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
    577                     GL_LINEAR);
    578             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    579             glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
    580                     GL_CLAMP_TO_EDGE);
    581             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    582             glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
    583                     GL_CLAMP_TO_EDGE);
    584             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    585 
    586             GLfloat texMatrix[16];
    587             mST->getTransformMatrix(texMatrix);
    588             glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
    589 
    590             glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    591             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    592         }
    593 
    594         GLuint mTexName;
    595         sp<GLConsumer> mST;
    596         GLuint mPgm;
    597         GLint mPositionHandle;
    598         GLint mTexSamplerHandle;
    599         GLint mTexMatrixHandle;
    600     };
    601 
    602     class FrameWaiter : public GLConsumer::FrameAvailableListener {
    603     public:
    604         FrameWaiter():
    605                 mPendingFrames(0) {
    606         }
    607 
    608         void waitForFrame() {
    609             Mutex::Autolock lock(mMutex);
    610             while (mPendingFrames == 0) {
    611                 mCondition.wait(mMutex);
    612             }
    613             mPendingFrames--;
    614         }
    615 
    616         virtual void onFrameAvailable() {
    617             Mutex::Autolock lock(mMutex);
    618             mPendingFrames++;
    619             mCondition.signal();
    620         }
    621 
    622         int mPendingFrames;
    623         Mutex mMutex;
    624         Condition mCondition;
    625     };
    626 
    627     // Note that GLConsumer will lose the notifications
    628     // onBuffersReleased and onFrameAvailable as there is currently
    629     // no way to forward the events.  This DisconnectWaiter will not let the
    630     // disconnect finish until finishDisconnect() is called.  It will
    631     // also block until a disconnect is called
    632     class DisconnectWaiter : public BnConsumerListener {
    633     public:
    634         DisconnectWaiter () :
    635             mWaitForDisconnect(false),
    636             mPendingFrames(0) {
    637         }
    638 
    639         void waitForFrame() {
    640             Mutex::Autolock lock(mMutex);
    641             while (mPendingFrames == 0) {
    642                 mFrameCondition.wait(mMutex);
    643             }
    644             mPendingFrames--;
    645         }
    646 
    647         virtual void onFrameAvailable() {
    648             Mutex::Autolock lock(mMutex);
    649             mPendingFrames++;
    650             mFrameCondition.signal();
    651         }
    652 
    653         virtual void onBuffersReleased() {
    654             Mutex::Autolock lock(mMutex);
    655             while (!mWaitForDisconnect) {
    656                 mDisconnectCondition.wait(mMutex);
    657             }
    658         }
    659 
    660         void finishDisconnect() {
    661             Mutex::Autolock lock(mMutex);
    662             mWaitForDisconnect = true;
    663             mDisconnectCondition.signal();
    664         }
    665 
    666     private:
    667         Mutex mMutex;
    668 
    669         bool mWaitForDisconnect;
    670         Condition mDisconnectCondition;
    671 
    672         int mPendingFrames;
    673         Condition mFrameCondition;
    674     };
    675 
    676     sp<BufferQueue> mBQ;
    677     sp<GLConsumer> mST;
    678     sp<Surface> mSTC;
    679     sp<ANativeWindow> mANW;
    680     sp<TextureRenderer> mTextureRenderer;
    681     sp<FrameWaiter> mFW;
    682 };
    683 
    684 // Fill a YV12 buffer with a multi-colored checkerboard pattern
    685 void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
    686     const int blockWidth = w > 16 ? w / 16 : 1;
    687     const int blockHeight = h > 16 ? h / 16 : 1;
    688     const int yuvTexOffsetY = 0;
    689     int yuvTexStrideY = stride;
    690     int yuvTexOffsetV = yuvTexStrideY * h;
    691     int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
    692     int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
    693     int yuvTexStrideU = yuvTexStrideV;
    694     for (int x = 0; x < w; x++) {
    695         for (int y = 0; y < h; y++) {
    696             int parityX = (x / blockWidth) & 1;
    697             int parityY = (y / blockHeight) & 1;
    698             unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
    699             buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
    700             if (x < w / 2 && y < h / 2) {
    701                 buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
    702                 if (x * 2 < w / 2 && y * 2 < h / 2) {
    703                     buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
    704                     buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
    705                     buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
    706                     buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
    707                         intensity;
    708                 }
    709             }
    710         }
    711     }
    712 }
    713 
    714 // Fill a YV12 buffer with red outside a given rectangle and green inside it.
    715 void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
    716         const android_native_rect_t& rect) {
    717     const int yuvTexOffsetY = 0;
    718     int yuvTexStrideY = stride;
    719     int yuvTexOffsetV = yuvTexStrideY * h;
    720     int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
    721     int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
    722     int yuvTexStrideU = yuvTexStrideV;
    723     for (int x = 0; x < w; x++) {
    724         for (int y = 0; y < h; y++) {
    725             bool inside = rect.left <= x && x < rect.right &&
    726                     rect.top <= y && y < rect.bottom;
    727             buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
    728             if (x < w / 2 && y < h / 2) {
    729                 bool inside = rect.left <= 2*x && 2*x < rect.right &&
    730                         rect.top <= 2*y && 2*y < rect.bottom;
    731                 buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
    732                 buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
    733                         inside ? 16 : 255;
    734             }
    735         }
    736     }
    737 }
    738 
    739 void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
    740     const size_t PIXEL_SIZE = 4;
    741     for (int x = 0; x < w; x++) {
    742         for (int y = 0; y < h; y++) {
    743             off_t offset = (y * stride + x) * PIXEL_SIZE;
    744             for (int c = 0; c < 4; c++) {
    745                 int parityX = (x / (1 << (c+2))) & 1;
    746                 int parityY = (y / (1 << (c+2))) & 1;
    747                 buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
    748             }
    749         }
    750     }
    751 }
    752 
    753 void fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r,
    754         uint8_t g, uint8_t b, uint8_t a) {
    755     const size_t PIXEL_SIZE = 4;
    756     for (int y = 0; y < h; y++) {
    757         for (int x = 0; x < h; x++) {
    758             off_t offset = (y * stride + x) * PIXEL_SIZE;
    759             buf[offset + 0] = r;
    760             buf[offset + 1] = g;
    761             buf[offset + 2] = b;
    762             buf[offset + 3] = a;
    763         }
    764     }
    765 }
    766 
    767 // Produce a single RGBA8 frame by filling a buffer with a checkerboard pattern
    768 // using the CPU.  This assumes that the ANativeWindow is already configured to
    769 // allow this to be done (e.g. the format is set to RGBA8).
    770 //
    771 // Calls to this function should be wrapped in an ASSERT_NO_FATAL_FAILURE().
    772 void produceOneRGBA8Frame(const sp<ANativeWindow>& anw) {
    773     android_native_buffer_t* anb;
    774     ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(),
    775             &anb));
    776     ASSERT_TRUE(anb != NULL);
    777 
    778     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    779 
    780     uint8_t* img = NULL;
    781     ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
    782             (void**)(&img)));
    783     fillRGBA8Buffer(img, buf->getWidth(), buf->getHeight(), buf->getStride());
    784     ASSERT_EQ(NO_ERROR, buf->unlock());
    785     ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf->getNativeBuffer(),
    786             -1));
    787 }
    788 
    789 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
    790     const int texWidth = 64;
    791     const int texHeight = 66;
    792 
    793     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    794             texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
    795     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    796             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    797 
    798     ANativeWindowBuffer* anb;
    799     ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    800             &anb));
    801     ASSERT_TRUE(anb != NULL);
    802 
    803     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    804 
    805     // Fill the buffer with the a checkerboard pattern
    806     uint8_t* img = NULL;
    807     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    808     fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
    809     buf->unlock();
    810     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
    811             -1));
    812 
    813     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    814 
    815     glClearColor(0.2, 0.2, 0.2, 0.2);
    816     glClear(GL_COLOR_BUFFER_BIT);
    817 
    818     glViewport(0, 0, texWidth, texHeight);
    819     drawTexture();
    820 
    821     EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255, 3));
    822     EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255, 3));
    823     EXPECT_TRUE(checkPixel(63, 65,   0, 133,   0, 255, 3));
    824     EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255, 3));
    825 
    826     EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255, 3));
    827     EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255, 3));
    828     EXPECT_TRUE(checkPixel(52, 51,  98, 255,  73, 255, 3));
    829     EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255, 3));
    830     EXPECT_TRUE(checkPixel(31,  9, 107,  24,  87, 255, 3));
    831     EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255, 3));
    832     EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255, 3));
    833 }
    834 
    835 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
    836     const int texWidth = 64;
    837     const int texHeight = 64;
    838 
    839     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    840             texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
    841     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    842             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    843 
    844     ANativeWindowBuffer* anb;
    845     ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    846             &anb));
    847     ASSERT_TRUE(anb != NULL);
    848 
    849     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    850 
    851     // Fill the buffer with the a checkerboard pattern
    852     uint8_t* img = NULL;
    853     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    854     fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
    855     buf->unlock();
    856     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
    857             -1));
    858 
    859     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    860 
    861     glClearColor(0.2, 0.2, 0.2, 0.2);
    862     glClear(GL_COLOR_BUFFER_BIT);
    863 
    864     glViewport(0, 0, texWidth, texHeight);
    865     drawTexture();
    866 
    867     EXPECT_TRUE(checkPixel( 0,  0,   0, 133,   0, 255));
    868     EXPECT_TRUE(checkPixel(63,  0, 255, 127, 255, 255));
    869     EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
    870     EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
    871 
    872     EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255));
    873     EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255));
    874     EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255));
    875     EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
    876     EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255));
    877     EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255));
    878     EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
    879 }
    880 
    881 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
    882     const int texWidth = 64;
    883     const int texHeight = 66;
    884 
    885     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    886             texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
    887     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    888             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    889 
    890     android_native_rect_t crops[] = {
    891         {4, 6, 22, 36},
    892         {0, 6, 22, 36},
    893         {4, 0, 22, 36},
    894         {4, 6, texWidth, 36},
    895         {4, 6, 22, texHeight},
    896     };
    897 
    898     for (int i = 0; i < 5; i++) {
    899         const android_native_rect_t& crop(crops[i]);
    900         SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
    901                 crop.left, crop.top, crop.right, crop.bottom).string());
    902 
    903         ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
    904 
    905         ANativeWindowBuffer* anb;
    906         ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
    907                 &anb));
    908         ASSERT_TRUE(anb != NULL);
    909 
    910         sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    911 
    912         uint8_t* img = NULL;
    913         buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    914         fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
    915         buf->unlock();
    916         ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
    917                 buf->getNativeBuffer(), -1));
    918 
    919         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
    920 
    921         glClearColor(0.2, 0.2, 0.2, 0.2);
    922         glClear(GL_COLOR_BUFFER_BIT);
    923 
    924         glViewport(0, 0, 64, 64);
    925         drawTexture();
    926 
    927         EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
    928         EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
    929         EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
    930         EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
    931 
    932         EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
    933         EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
    934         EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
    935         EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
    936         EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
    937         EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
    938         EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
    939     }
    940 }
    941 
    942 // This test is intended to catch synchronization bugs between the CPU-written
    943 // and GPU-read buffers.
    944 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
    945     enum { texWidth = 16 };
    946     enum { texHeight = 16 };
    947     enum { numFrames = 1024 };
    948 
    949     ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
    950     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    951             texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
    952     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    953             GRALLOC_USAGE_SW_WRITE_OFTEN));
    954 
    955     struct TestPixel {
    956         int x;
    957         int y;
    958     };
    959     const TestPixel testPixels[] = {
    960         {  4, 11 },
    961         { 12, 14 },
    962         {  7,  2 },
    963     };
    964     enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
    965 
    966     class ProducerThread : public Thread {
    967     public:
    968         ProducerThread(const sp<ANativeWindow>& anw,
    969                 const TestPixel* testPixels):
    970                 mANW(anw),
    971                 mTestPixels(testPixels) {
    972         }
    973 
    974         virtual ~ProducerThread() {
    975         }
    976 
    977         virtual bool threadLoop() {
    978             for (int i = 0; i < numFrames; i++) {
    979                 ANativeWindowBuffer* anb;
    980                 if (native_window_dequeue_buffer_and_wait(mANW.get(),
    981                         &anb) != NO_ERROR) {
    982                     return false;
    983                 }
    984                 if (anb == NULL) {
    985                     return false;
    986                 }
    987 
    988                 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    989 
    990                 const int yuvTexOffsetY = 0;
    991                 int stride = buf->getStride();
    992                 int yuvTexStrideY = stride;
    993                 int yuvTexOffsetV = yuvTexStrideY * texHeight;
    994                 int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
    995                 int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
    996                 int yuvTexStrideU = yuvTexStrideV;
    997 
    998                 uint8_t* img = NULL;
    999                 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
   1000 
   1001                 // Gray out all the test pixels first, so we're more likely to
   1002                 // see a failure if GL is still texturing from the buffer we
   1003                 // just dequeued.
   1004                 for (int j = 0; j < numTestPixels; j++) {
   1005                     int x = mTestPixels[j].x;
   1006                     int y = mTestPixels[j].y;
   1007                     uint8_t value = 128;
   1008                     img[y*stride + x] = value;
   1009                 }
   1010 
   1011                 // Fill the buffer with gray.
   1012                 for (int y = 0; y < texHeight; y++) {
   1013                     for (int x = 0; x < texWidth; x++) {
   1014                         img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
   1015                         img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
   1016                         img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
   1017                     }
   1018                 }
   1019 
   1020                 // Set the test pixels to either white or black.
   1021                 for (int j = 0; j < numTestPixels; j++) {
   1022                     int x = mTestPixels[j].x;
   1023                     int y = mTestPixels[j].y;
   1024                     uint8_t value = 0;
   1025                     if (j == (i % numTestPixels)) {
   1026                         value = 255;
   1027                     }
   1028                     img[y*stride + x] = value;
   1029                 }
   1030 
   1031                 buf->unlock();
   1032                 if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), -1)
   1033                         != NO_ERROR) {
   1034                     return false;
   1035                 }
   1036             }
   1037             return false;
   1038         }
   1039 
   1040         sp<ANativeWindow> mANW;
   1041         const TestPixel* mTestPixels;
   1042     };
   1043 
   1044     sp<Thread> pt(new ProducerThread(mANW, testPixels));
   1045     pt->run();
   1046 
   1047     glViewport(0, 0, texWidth, texHeight);
   1048 
   1049     glClearColor(0.2, 0.2, 0.2, 0.2);
   1050     glClear(GL_COLOR_BUFFER_BIT);
   1051 
   1052     // We wait for the first two frames up front so that the producer will be
   1053     // likely to dequeue the buffer that's currently being textured from.
   1054     mFW->waitForFrame();
   1055     mFW->waitForFrame();
   1056 
   1057     for (int i = 0; i < numFrames; i++) {
   1058         SCOPED_TRACE(String8::format("frame %d", i).string());
   1059 
   1060         // We must wait for each frame to come in because if we ever do an
   1061         // updateTexImage call that doesn't consume a newly available buffer
   1062         // then the producer and consumer will get out of sync, which will cause
   1063         // a deadlock.
   1064         if (i > 1) {
   1065             mFW->waitForFrame();
   1066         }
   1067         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1068         drawTexture();
   1069 
   1070         for (int j = 0; j < numTestPixels; j++) {
   1071             int x = testPixels[j].x;
   1072             int y = testPixels[j].y;
   1073             uint8_t value = 0;
   1074             if (j == (i % numTestPixels)) {
   1075                 // We must y-invert the texture coords
   1076                 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
   1077             } else {
   1078                 // We must y-invert the texture coords
   1079                 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
   1080             }
   1081         }
   1082     }
   1083 
   1084     pt->requestExitAndWait();
   1085 }
   1086 
   1087 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
   1088     const int texWidth = 64;
   1089     const int texHeight = 66;
   1090 
   1091     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
   1092             texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
   1093     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
   1094             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
   1095 
   1096     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   1097 
   1098     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1099 
   1100     glClearColor(0.2, 0.2, 0.2, 0.2);
   1101     glClear(GL_COLOR_BUFFER_BIT);
   1102 
   1103     glViewport(0, 0, texWidth, texHeight);
   1104     drawTexture();
   1105 
   1106     EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
   1107     EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
   1108     EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231));
   1109     EXPECT_TRUE(checkPixel( 0, 65,  35,  35,  35,  35));
   1110 
   1111     EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
   1112     EXPECT_TRUE(checkPixel(23, 65, 231,  35, 231,  35));
   1113     EXPECT_TRUE(checkPixel(19, 40,  35, 231,  35,  35));
   1114     EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
   1115     EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
   1116     EXPECT_TRUE(checkPixel(37, 34,  35, 231, 231, 231));
   1117     EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
   1118     EXPECT_TRUE(checkPixel(37, 47, 231,  35, 231, 231));
   1119     EXPECT_TRUE(checkPixel(25, 38,  35,  35,  35,  35));
   1120     EXPECT_TRUE(checkPixel(49,  6,  35, 231,  35,  35));
   1121     EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
   1122     EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231));
   1123     EXPECT_TRUE(checkPixel(10,  6,  35,  35, 231, 231));
   1124     EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
   1125     EXPECT_TRUE(checkPixel(55, 28,  35,  35, 231,  35));
   1126     EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
   1127 }
   1128 
   1129 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
   1130     const int texWidth = 64;
   1131     const int texHeight = 64;
   1132 
   1133     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
   1134             texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
   1135     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
   1136             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
   1137 
   1138     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   1139 
   1140     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1141 
   1142     glClearColor(0.2, 0.2, 0.2, 0.2);
   1143     glClear(GL_COLOR_BUFFER_BIT);
   1144 
   1145     glViewport(0, 0, texWidth, texHeight);
   1146     drawTexture();
   1147 
   1148     EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
   1149     EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
   1150     EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
   1151     EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
   1152 
   1153     EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
   1154     EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
   1155     EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
   1156     EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
   1157     EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
   1158     EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
   1159     EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
   1160     EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
   1161     EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
   1162     EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
   1163     EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
   1164     EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
   1165     EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
   1166     EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
   1167     EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
   1168     EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
   1169 }
   1170 
   1171 // Tests if GLConsumer and BufferQueue are robust enough
   1172 // to handle a special case where updateTexImage is called
   1173 // in the middle of disconnect.  This ordering is enforced
   1174 // by blocking in the disconnect callback.
   1175 TEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
   1176 
   1177     class ProducerThread : public Thread {
   1178     public:
   1179         ProducerThread(const sp<ANativeWindow>& anw):
   1180                 mANW(anw) {
   1181         }
   1182 
   1183         virtual ~ProducerThread() {
   1184         }
   1185 
   1186         virtual bool threadLoop() {
   1187             ANativeWindowBuffer* anb;
   1188 
   1189             native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_EGL);
   1190 
   1191             for (int numFrames =0 ; numFrames < 2; numFrames ++) {
   1192 
   1193                 if (native_window_dequeue_buffer_and_wait(mANW.get(),
   1194                         &anb) != NO_ERROR) {
   1195                     return false;
   1196                 }
   1197                 if (anb == NULL) {
   1198                     return false;
   1199                 }
   1200                 if (mANW->queueBuffer(mANW.get(), anb, -1)
   1201                         != NO_ERROR) {
   1202                     return false;
   1203                 }
   1204             }
   1205 
   1206             native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL);
   1207 
   1208             return false;
   1209         }
   1210 
   1211     private:
   1212         sp<ANativeWindow> mANW;
   1213     };
   1214 
   1215     sp<DisconnectWaiter> dw(new DisconnectWaiter());
   1216     mBQ->consumerConnect(dw, false);
   1217 
   1218 
   1219     sp<Thread> pt(new ProducerThread(mANW));
   1220     pt->run();
   1221 
   1222     // eat a frame so GLConsumer will own an at least one slot
   1223     dw->waitForFrame();
   1224     EXPECT_EQ(OK,mST->updateTexImage());
   1225 
   1226     dw->waitForFrame();
   1227     // Could fail here as GLConsumer thinks it still owns the slot
   1228     // but bufferQueue has released all slots
   1229     EXPECT_EQ(OK,mST->updateTexImage());
   1230 
   1231     dw->finishDisconnect();
   1232 }
   1233 
   1234 
   1235 // This test ensures that the GLConsumer clears the mCurrentTexture
   1236 // when it is disconnected and reconnected.  Otherwise it will
   1237 // attempt to release a buffer that it does not owned
   1238 TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
   1239     ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
   1240             NATIVE_WINDOW_API_EGL));
   1241 
   1242     ANativeWindowBuffer *anb;
   1243 
   1244     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
   1245     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
   1246 
   1247     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
   1248     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
   1249 
   1250     EXPECT_EQ(OK,mST->updateTexImage());
   1251     EXPECT_EQ(OK,mST->updateTexImage());
   1252 
   1253     ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
   1254             NATIVE_WINDOW_API_EGL));
   1255     ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
   1256             NATIVE_WINDOW_API_EGL));
   1257 
   1258     EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
   1259     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
   1260 
   1261     // Will fail here if mCurrentTexture is not cleared properly
   1262     mFW->waitForFrame();
   1263     EXPECT_EQ(OK,mST->updateTexImage());
   1264 
   1265     ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
   1266             NATIVE_WINDOW_API_EGL));
   1267 }
   1268 
   1269 TEST_F(SurfaceTextureGLTest, ScaleToWindowMode) {
   1270     ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
   1271         NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
   1272 
   1273     // The producer image size
   1274     ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
   1275 
   1276     // The consumer image size (16 x 9) ratio
   1277     mST->setDefaultBufferSize(1280, 720);
   1278 
   1279     ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
   1280             NATIVE_WINDOW_API_CPU));
   1281 
   1282     ANativeWindowBuffer *anb;
   1283 
   1284     android_native_rect_t odd = {23, 78, 123, 477};
   1285     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &odd));
   1286     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
   1287     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
   1288     mFW->waitForFrame();
   1289     EXPECT_EQ(OK, mST->updateTexImage());
   1290     Rect r = mST->getCurrentCrop();
   1291     assertRectEq(Rect(23, 78, 123, 477), r);
   1292 
   1293     ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
   1294             NATIVE_WINDOW_API_CPU));
   1295 }
   1296 
   1297 // This test ensures the scaling mode does the right thing
   1298 // ie NATIVE_WINDOW_SCALING_MODE_CROP should crop
   1299 // the image such that it has the same aspect ratio as the
   1300 // default buffer size
   1301 TEST_F(SurfaceTextureGLTest, CroppedScalingMode) {
   1302     ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
   1303         NATIVE_WINDOW_SCALING_MODE_SCALE_CROP));
   1304 
   1305     // The producer image size
   1306     ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
   1307 
   1308     // The consumer image size (16 x 9) ratio
   1309     mST->setDefaultBufferSize(1280, 720);
   1310 
   1311     native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU);
   1312 
   1313     ANativeWindowBuffer *anb;
   1314 
   1315     // The crop is in the shape of (320, 180) === 16 x 9
   1316     android_native_rect_t standard = {10, 20, 330, 200};
   1317     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &standard));
   1318     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
   1319     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
   1320     mFW->waitForFrame();
   1321     EXPECT_EQ(OK, mST->updateTexImage());
   1322     Rect r = mST->getCurrentCrop();
   1323     // crop should be the same as crop (same aspect ratio)
   1324     assertRectEq(Rect(10, 20, 330, 200), r);
   1325 
   1326     // make this wider then desired aspect 239 x 100 (2.39:1)
   1327     android_native_rect_t wide = {20, 30, 259, 130};
   1328     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &wide));
   1329     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
   1330     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
   1331     mFW->waitForFrame();
   1332     EXPECT_EQ(OK, mST->updateTexImage());
   1333     r = mST->getCurrentCrop();
   1334     // crop should be the same height, but have cropped left and right borders
   1335     // offset is 30.6 px L+, R-
   1336     assertRectEq(Rect(51, 30, 228, 130), r);
   1337 
   1338     // This image is taller then desired aspect 400 x 300 (4:3)
   1339     android_native_rect_t narrow = {0, 0, 400, 300};
   1340     ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &narrow));
   1341     EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
   1342     EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
   1343     mFW->waitForFrame();
   1344     EXPECT_EQ(OK, mST->updateTexImage());
   1345     r = mST->getCurrentCrop();
   1346     // crop should be the same width, but have cropped top and bottom borders
   1347     // offset is 37.5 px
   1348     assertRectEq(Rect(0, 37, 400, 262), r);
   1349 
   1350     native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
   1351 }
   1352 
   1353 TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
   1354     class ProducerThread : public Thread {
   1355     public:
   1356         ProducerThread(const sp<ANativeWindow>& anw):
   1357                 mANW(anw),
   1358                 mDequeueError(NO_ERROR) {
   1359         }
   1360 
   1361         virtual ~ProducerThread() {
   1362         }
   1363 
   1364         virtual bool threadLoop() {
   1365             Mutex::Autolock lock(mMutex);
   1366             ANativeWindowBuffer* anb;
   1367 
   1368             // Frame 1
   1369             if (native_window_dequeue_buffer_and_wait(mANW.get(),
   1370                     &anb) != NO_ERROR) {
   1371                 return false;
   1372             }
   1373             if (anb == NULL) {
   1374                 return false;
   1375             }
   1376             if (mANW->queueBuffer(mANW.get(), anb, -1)
   1377                     != NO_ERROR) {
   1378                 return false;
   1379             }
   1380 
   1381             // Frame 2
   1382             if (native_window_dequeue_buffer_and_wait(mANW.get(),
   1383                     &anb) != NO_ERROR) {
   1384                 return false;
   1385             }
   1386             if (anb == NULL) {
   1387                 return false;
   1388             }
   1389             if (mANW->queueBuffer(mANW.get(), anb, -1)
   1390                     != NO_ERROR) {
   1391                 return false;
   1392             }
   1393 
   1394             // Frame 3 - error expected
   1395             mDequeueError = native_window_dequeue_buffer_and_wait(mANW.get(),
   1396                 &anb);
   1397             return false;
   1398         }
   1399 
   1400         status_t getDequeueError() {
   1401             Mutex::Autolock lock(mMutex);
   1402             return mDequeueError;
   1403         }
   1404 
   1405     private:
   1406         sp<ANativeWindow> mANW;
   1407         status_t mDequeueError;
   1408         Mutex mMutex;
   1409     };
   1410 
   1411     ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
   1412 
   1413     sp<Thread> pt(new ProducerThread(mANW));
   1414     pt->run();
   1415 
   1416     mFW->waitForFrame();
   1417     mFW->waitForFrame();
   1418 
   1419     // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
   1420     // block waiting for a buffer to become available.
   1421     usleep(100000);
   1422 
   1423     mST->abandon();
   1424 
   1425     pt->requestExitAndWait();
   1426     ASSERT_EQ(NO_INIT,
   1427             reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
   1428 }
   1429 
   1430 TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
   1431     int texHeight = 16;
   1432     ANativeWindowBuffer* anb;
   1433 
   1434     GLint maxTextureSize;
   1435     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
   1436 
   1437     // make sure it works with small textures
   1438     mST->setDefaultBufferSize(16, texHeight);
   1439     EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
   1440             &anb));
   1441     EXPECT_EQ(16, anb->width);
   1442     EXPECT_EQ(texHeight, anb->height);
   1443     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
   1444     EXPECT_EQ(NO_ERROR, mST->updateTexImage());
   1445 
   1446     // make sure it works with GL_MAX_TEXTURE_SIZE
   1447     mST->setDefaultBufferSize(maxTextureSize, texHeight);
   1448     EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
   1449             &anb));
   1450     EXPECT_EQ(maxTextureSize, anb->width);
   1451     EXPECT_EQ(texHeight, anb->height);
   1452     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
   1453     EXPECT_EQ(NO_ERROR, mST->updateTexImage());
   1454 
   1455     // make sure it fails with GL_MAX_TEXTURE_SIZE+1
   1456     mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
   1457     EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
   1458             &anb));
   1459     EXPECT_EQ(maxTextureSize+1, anb->width);
   1460     EXPECT_EQ(texHeight, anb->height);
   1461     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
   1462     ASSERT_NE(NO_ERROR, mST->updateTexImage());
   1463 }
   1464 
   1465 /*
   1466  * This test fixture is for testing GL -> GL texture streaming.  It creates an
   1467  * EGLSurface and an EGLContext for the image producer to use.
   1468  */
   1469 class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
   1470 protected:
   1471     SurfaceTextureGLToGLTest():
   1472             mProducerEglSurface(EGL_NO_SURFACE),
   1473             mProducerEglContext(EGL_NO_CONTEXT) {
   1474     }
   1475 
   1476     virtual void SetUp() {
   1477         SurfaceTextureGLTest::SetUp();
   1478 
   1479         mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
   1480                 mANW.get(), NULL);
   1481         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1482         ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
   1483 
   1484         mProducerEglContext = eglCreateContext(mEglDisplay, mGlConfig,
   1485                 EGL_NO_CONTEXT, getContextAttribs());
   1486         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1487         ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
   1488     }
   1489 
   1490     virtual void TearDown() {
   1491         if (mProducerEglContext != EGL_NO_CONTEXT) {
   1492             eglDestroyContext(mEglDisplay, mProducerEglContext);
   1493         }
   1494         if (mProducerEglSurface != EGL_NO_SURFACE) {
   1495             eglDestroySurface(mEglDisplay, mProducerEglSurface);
   1496         }
   1497         SurfaceTextureGLTest::TearDown();
   1498     }
   1499 
   1500     EGLSurface mProducerEglSurface;
   1501     EGLContext mProducerEglContext;
   1502 };
   1503 
   1504 TEST_F(SurfaceTextureGLToGLTest, TransformHintGetsRespected) {
   1505     const uint32_t texWidth = 32;
   1506     const uint32_t texHeight = 64;
   1507 
   1508     mST->setDefaultBufferSize(texWidth, texHeight);
   1509     mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
   1510 
   1511     // This test requires 3 buffers to avoid deadlock because we're
   1512     // both producer and consumer, and only using one thread.
   1513     mST->setDefaultMaxBufferCount(3);
   1514 
   1515     // Do the producer side of things
   1516     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1517             mProducerEglSurface, mProducerEglContext));
   1518     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1519 
   1520     // Start a buffer with our chosen size and transform hint moving
   1521     // through the system.
   1522     glClear(GL_COLOR_BUFFER_BIT);  // give the driver something to do
   1523     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1524     mST->updateTexImage();  // consume it
   1525     // Swap again.
   1526     glClear(GL_COLOR_BUFFER_BIT);
   1527     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1528     mST->updateTexImage();
   1529 
   1530     // The current buffer should either show the effects of the transform
   1531     // hint (in the form of an inverse transform), or show that the
   1532     // transform hint has been ignored.
   1533     sp<GraphicBuffer> buf = mST->getCurrentBuffer();
   1534     if (mST->getCurrentTransform() == NATIVE_WINDOW_TRANSFORM_ROT_270) {
   1535         ASSERT_EQ(texWidth, buf->getHeight());
   1536         ASSERT_EQ(texHeight, buf->getWidth());
   1537     } else {
   1538         ASSERT_EQ(texWidth, buf->getWidth());
   1539         ASSERT_EQ(texHeight, buf->getHeight());
   1540     }
   1541 
   1542     // Reset the transform hint and confirm that it takes.
   1543     mST->setTransformHint(0);
   1544     glClear(GL_COLOR_BUFFER_BIT);
   1545     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1546     mST->updateTexImage();
   1547     glClear(GL_COLOR_BUFFER_BIT);
   1548     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1549     mST->updateTexImage();
   1550 
   1551     buf = mST->getCurrentBuffer();
   1552     ASSERT_EQ((uint32_t) 0, mST->getCurrentTransform());
   1553     ASSERT_EQ(texWidth, buf->getWidth());
   1554     ASSERT_EQ(texHeight, buf->getHeight());
   1555 }
   1556 
   1557 TEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
   1558     const int texWidth = 64;
   1559     const int texHeight = 64;
   1560 
   1561     mST->setDefaultBufferSize(texWidth, texHeight);
   1562 
   1563     // This test requires 3 buffers to complete run on a single thread.
   1564     mST->setDefaultMaxBufferCount(3);
   1565 
   1566     // Do the producer side of things
   1567     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1568             mProducerEglSurface, mProducerEglContext));
   1569     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1570 
   1571     // This is needed to ensure we pick up a buffer of the correct size.
   1572     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1573 
   1574     glClearColor(0.6, 0.6, 0.6, 0.6);
   1575     glClear(GL_COLOR_BUFFER_BIT);
   1576 
   1577     glEnable(GL_SCISSOR_TEST);
   1578     glScissor(4, 4, 4, 4);
   1579     glClearColor(1.0, 0.0, 0.0, 1.0);
   1580     glClear(GL_COLOR_BUFFER_BIT);
   1581 
   1582     glScissor(24, 48, 4, 4);
   1583     glClearColor(0.0, 1.0, 0.0, 1.0);
   1584     glClear(GL_COLOR_BUFFER_BIT);
   1585 
   1586     glScissor(37, 17, 4, 4);
   1587     glClearColor(0.0, 0.0, 1.0, 1.0);
   1588     glClear(GL_COLOR_BUFFER_BIT);
   1589 
   1590     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1591 
   1592     // Do the consumer side of things
   1593     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1594             mEglContext));
   1595     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1596 
   1597     glDisable(GL_SCISSOR_TEST);
   1598 
   1599     // Skip the first frame, which was empty
   1600     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1601     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1602 
   1603     glClearColor(0.2, 0.2, 0.2, 0.2);
   1604     glClear(GL_COLOR_BUFFER_BIT);
   1605 
   1606     glViewport(0, 0, texWidth, texHeight);
   1607     drawTexture();
   1608 
   1609     EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
   1610     EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
   1611     EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
   1612     EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
   1613 
   1614     EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
   1615     EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
   1616     EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
   1617     EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
   1618     EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
   1619     EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
   1620     EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
   1621     EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
   1622     EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
   1623     EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
   1624     EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
   1625     EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
   1626     EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
   1627     EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
   1628     EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
   1629     EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
   1630 }
   1631 
   1632 TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) {
   1633     sp<GraphicBuffer> buffers[2];
   1634 
   1635     // This test requires async mode to run on a single thread.
   1636     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1637             mProducerEglSurface, mProducerEglContext));
   1638     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1639     EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
   1640     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1641 
   1642     for (int i = 0; i < 2; i++) {
   1643         // Produce a frame
   1644         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1645                 mProducerEglSurface, mProducerEglContext));
   1646         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1647         glClear(GL_COLOR_BUFFER_BIT);
   1648         eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1649 
   1650         // Consume a frame
   1651         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1652                 mEglContext));
   1653         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1654         mFW->waitForFrame();
   1655         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1656         buffers[i] = mST->getCurrentBuffer();
   1657     }
   1658 
   1659     // Destroy the GL texture object to release its ref on buffers[2].
   1660     GLuint texID = TEX_ID;
   1661     glDeleteTextures(1, &texID);
   1662 
   1663     // Destroy the EGLSurface
   1664     EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
   1665     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1666     mProducerEglSurface = EGL_NO_SURFACE;
   1667 
   1668     // This test should have the only reference to buffer 0.
   1669     EXPECT_EQ(1, buffers[0]->getStrongCount());
   1670 
   1671     // The GLConsumer should hold a single reference to buffer 1 in its
   1672     // mCurrentBuffer member.  All of the references in the slots should have
   1673     // been released.
   1674     EXPECT_EQ(2, buffers[1]->getStrongCount());
   1675 }
   1676 
   1677 TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
   1678     sp<GraphicBuffer> buffers[3];
   1679 
   1680     // This test requires async mode to run on a single thread.
   1681     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1682             mProducerEglSurface, mProducerEglContext));
   1683     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1684     EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
   1685     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1686 
   1687     for (int i = 0; i < 3; i++) {
   1688         // Produce a frame
   1689         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1690                 mProducerEglSurface, mProducerEglContext));
   1691         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1692         glClear(GL_COLOR_BUFFER_BIT);
   1693         EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
   1694         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1695 
   1696         // Consume a frame
   1697         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1698                 mEglContext));
   1699         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1700         mFW->waitForFrame();
   1701         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1702         buffers[i] = mST->getCurrentBuffer();
   1703     }
   1704 
   1705     // Abandon the GLConsumer, releasing the ref that the GLConsumer has
   1706     // on buffers[2].
   1707     mST->abandon();
   1708 
   1709     // Destroy the GL texture object to release its ref on buffers[2].
   1710     GLuint texID = TEX_ID;
   1711     glDeleteTextures(1, &texID);
   1712 
   1713     // Destroy the EGLSurface.
   1714     EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
   1715     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1716     mProducerEglSurface = EGL_NO_SURFACE;
   1717 
   1718     EXPECT_EQ(1, buffers[0]->getStrongCount());
   1719     EXPECT_EQ(1, buffers[1]->getStrongCount());
   1720 
   1721     // Depending on how lazily the GL driver dequeues buffers, we may end up
   1722     // with either two or three total buffers.  If there are three, make sure
   1723     // the last one was properly down-ref'd.
   1724     if (buffers[2] != buffers[0]) {
   1725         EXPECT_EQ(1, buffers[2]->getStrongCount());
   1726     }
   1727 }
   1728 
   1729 TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentBeforeConsumerDeathUnrefsBuffers) {
   1730     sp<GraphicBuffer> buffer;
   1731 
   1732     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1733             mProducerEglSurface, mProducerEglContext));
   1734 
   1735     // Produce a frame
   1736     glClear(GL_COLOR_BUFFER_BIT);
   1737     EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
   1738     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1739 
   1740     // Destroy the EGLSurface.
   1741     EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
   1742     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1743     mProducerEglSurface = EGL_NO_SURFACE;
   1744     mSTC.clear();
   1745     mANW.clear();
   1746     mTextureRenderer.clear();
   1747 
   1748     // Consume a frame
   1749     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1750     buffer = mST->getCurrentBuffer();
   1751 
   1752     // Destroy the GL texture object to release its ref
   1753     GLuint texID = TEX_ID;
   1754     glDeleteTextures(1, &texID);
   1755 
   1756     // make un-current, all references to buffer should be gone
   1757     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
   1758             EGL_NO_SURFACE, EGL_NO_CONTEXT));
   1759 
   1760     // Destroy consumer
   1761     mST.clear();
   1762 
   1763     EXPECT_EQ(1, buffer->getStrongCount());
   1764 }
   1765 
   1766 TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentAfterConsumerDeathUnrefsBuffers) {
   1767     sp<GraphicBuffer> buffer;
   1768 
   1769     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1770             mProducerEglSurface, mProducerEglContext));
   1771 
   1772     // Produce a frame
   1773     glClear(GL_COLOR_BUFFER_BIT);
   1774     EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
   1775     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1776 
   1777     // Destroy the EGLSurface.
   1778     EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
   1779     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1780     mProducerEglSurface = EGL_NO_SURFACE;
   1781     mSTC.clear();
   1782     mANW.clear();
   1783     mTextureRenderer.clear();
   1784 
   1785     // Consume a frame
   1786     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1787     buffer = mST->getCurrentBuffer();
   1788 
   1789     // Destroy the GL texture object to release its ref
   1790     GLuint texID = TEX_ID;
   1791     glDeleteTextures(1, &texID);
   1792 
   1793     // Destroy consumer
   1794     mST.clear();
   1795 
   1796     // make un-current, all references to buffer should be gone
   1797     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
   1798             EGL_NO_SURFACE, EGL_NO_CONTEXT));
   1799 
   1800     EXPECT_EQ(1, buffer->getStrongCount());
   1801 }
   1802 
   1803 TEST_F(SurfaceTextureGLToGLTest, TexturingFromUserSizedGLFilledBuffer) {
   1804     enum { texWidth = 64 };
   1805     enum { texHeight = 64 };
   1806 
   1807     // This test requires 3 buffers to complete run on a single thread.
   1808     mST->setDefaultMaxBufferCount(3);
   1809 
   1810     // Set the user buffer size.
   1811     native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
   1812 
   1813     // Do the producer side of things
   1814     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1815             mProducerEglSurface, mProducerEglContext));
   1816     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1817 
   1818     // This is needed to ensure we pick up a buffer of the correct size.
   1819     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1820 
   1821     glClearColor(0.6, 0.6, 0.6, 0.6);
   1822     glClear(GL_COLOR_BUFFER_BIT);
   1823 
   1824     glEnable(GL_SCISSOR_TEST);
   1825     glScissor(4, 4, 1, 1);
   1826     glClearColor(1.0, 0.0, 0.0, 1.0);
   1827     glClear(GL_COLOR_BUFFER_BIT);
   1828 
   1829     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1830 
   1831     // Do the consumer side of things
   1832     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1833             mEglContext));
   1834     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1835 
   1836     glDisable(GL_SCISSOR_TEST);
   1837 
   1838     // Skip the first frame, which was empty
   1839     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1840     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1841 
   1842     glClearColor(0.2, 0.2, 0.2, 0.2);
   1843     glClear(GL_COLOR_BUFFER_BIT);
   1844 
   1845     glViewport(0, 0, texWidth, texHeight);
   1846     drawTexture();
   1847 
   1848     EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
   1849     EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
   1850     EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
   1851     EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
   1852 
   1853     EXPECT_TRUE(checkPixel( 4,  4, 255,   0,   0, 255));
   1854     EXPECT_TRUE(checkPixel( 5,  5, 153, 153, 153, 153));
   1855     EXPECT_TRUE(checkPixel( 3,  3, 153, 153, 153, 153));
   1856     EXPECT_TRUE(checkPixel(45, 52, 153, 153, 153, 153));
   1857     EXPECT_TRUE(checkPixel(12, 36, 153, 153, 153, 153));
   1858 }
   1859 
   1860 TEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedUserSizedGLFilledBuffer) {
   1861     enum { texWidth = 64 };
   1862     enum { texHeight = 16 };
   1863 
   1864     // This test requires 3 buffers to complete run on a single thread.
   1865     mST->setDefaultMaxBufferCount(3);
   1866 
   1867     // Set the transform hint.
   1868     mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
   1869 
   1870     // Set the user buffer size.
   1871     native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
   1872 
   1873     // Do the producer side of things
   1874     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1875             mProducerEglSurface, mProducerEglContext));
   1876     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1877 
   1878     // This is needed to ensure we pick up a buffer of the correct size and the
   1879     // new rotation hint.
   1880     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1881 
   1882     glClearColor(0.6, 0.6, 0.6, 0.6);
   1883     glClear(GL_COLOR_BUFFER_BIT);
   1884 
   1885     glEnable(GL_SCISSOR_TEST);
   1886     glScissor(24, 4, 1, 1);
   1887     glClearColor(1.0, 0.0, 0.0, 1.0);
   1888     glClear(GL_COLOR_BUFFER_BIT);
   1889 
   1890     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1891 
   1892     // Do the consumer side of things
   1893     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1894             mEglContext));
   1895     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1896 
   1897     glDisable(GL_SCISSOR_TEST);
   1898 
   1899     // Skip the first frame, which was empty
   1900     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1901     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1902 
   1903     glClearColor(0.2, 0.2, 0.2, 0.2);
   1904     glClear(GL_COLOR_BUFFER_BIT);
   1905 
   1906     glViewport(0, 0, texWidth, texHeight);
   1907     drawTexture();
   1908 
   1909     EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
   1910     EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
   1911     EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
   1912     EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
   1913 
   1914     EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
   1915     EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
   1916     EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
   1917     EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
   1918     EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
   1919 }
   1920 
   1921 TEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedGLFilledBuffer) {
   1922     enum { texWidth = 64 };
   1923     enum { texHeight = 16 };
   1924 
   1925     // This test requires 3 buffers to complete run on a single thread.
   1926     mST->setDefaultMaxBufferCount(3);
   1927 
   1928     // Set the transform hint.
   1929     mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
   1930 
   1931     // Set the default buffer size.
   1932     mST->setDefaultBufferSize(texWidth, texHeight);
   1933 
   1934     // Do the producer side of things
   1935     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1936             mProducerEglSurface, mProducerEglContext));
   1937     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1938 
   1939     // This is needed to ensure we pick up a buffer of the correct size and the
   1940     // new rotation hint.
   1941     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1942 
   1943     glClearColor(0.6, 0.6, 0.6, 0.6);
   1944     glClear(GL_COLOR_BUFFER_BIT);
   1945 
   1946     glEnable(GL_SCISSOR_TEST);
   1947     glScissor(24, 4, 1, 1);
   1948     glClearColor(1.0, 0.0, 0.0, 1.0);
   1949     glClear(GL_COLOR_BUFFER_BIT);
   1950 
   1951     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1952 
   1953     // Do the consumer side of things
   1954     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1955             mEglContext));
   1956     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1957 
   1958     glDisable(GL_SCISSOR_TEST);
   1959 
   1960     // Skip the first frame, which was empty
   1961     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1962     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1963 
   1964     glClearColor(0.2, 0.2, 0.2, 0.2);
   1965     glClear(GL_COLOR_BUFFER_BIT);
   1966 
   1967     glViewport(0, 0, texWidth, texHeight);
   1968     drawTexture();
   1969 
   1970     EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
   1971     EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
   1972     EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
   1973     EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
   1974 
   1975     EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
   1976     EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
   1977     EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
   1978     EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
   1979     EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
   1980 }
   1981 
   1982 /*
   1983  * This test fixture is for testing GL -> GL texture streaming from one thread
   1984  * to another.  It contains functionality to create a producer thread that will
   1985  * perform GL rendering to an ANativeWindow that feeds frames to a
   1986  * GLConsumer.  Additionally it supports interlocking the producer and
   1987  * consumer threads so that a specific sequence of calls can be
   1988  * deterministically created by the test.
   1989  *
   1990  * The intended usage is as follows:
   1991  *
   1992  * TEST_F(...) {
   1993  *     class PT : public ProducerThread {
   1994  *         virtual void render() {
   1995  *             ...
   1996  *             swapBuffers();
   1997  *         }
   1998  *     };
   1999  *
   2000  *     runProducerThread(new PT());
   2001  *
   2002  *     // The order of these calls will vary from test to test and may include
   2003  *     // multiple frames and additional operations (e.g. GL rendering from the
   2004  *     // texture).
   2005  *     fc->waitForFrame();
   2006  *     mST->updateTexImage();
   2007  *     fc->finishFrame();
   2008  * }
   2009  *
   2010  */
   2011 class SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest {
   2012 protected:
   2013 
   2014     // ProducerThread is an abstract base class to simplify the creation of
   2015     // OpenGL ES frame producer threads.
   2016     class ProducerThread : public Thread {
   2017     public:
   2018         virtual ~ProducerThread() {
   2019         }
   2020 
   2021         void setEglObjects(EGLDisplay producerEglDisplay,
   2022                 EGLSurface producerEglSurface,
   2023                 EGLContext producerEglContext) {
   2024             mProducerEglDisplay = producerEglDisplay;
   2025             mProducerEglSurface = producerEglSurface;
   2026             mProducerEglContext = producerEglContext;
   2027         }
   2028 
   2029         virtual bool threadLoop() {
   2030             eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface,
   2031                     mProducerEglSurface, mProducerEglContext);
   2032             render();
   2033             eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
   2034                     EGL_NO_CONTEXT);
   2035             return false;
   2036         }
   2037 
   2038     protected:
   2039         virtual void render() = 0;
   2040 
   2041         void swapBuffers() {
   2042             eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface);
   2043         }
   2044 
   2045         EGLDisplay mProducerEglDisplay;
   2046         EGLSurface mProducerEglSurface;
   2047         EGLContext mProducerEglContext;
   2048     };
   2049 
   2050     // FrameCondition is a utility class for interlocking between the producer
   2051     // and consumer threads.  The FrameCondition object should be created and
   2052     // destroyed in the consumer thread only.  The consumer thread should set
   2053     // the FrameCondition as the FrameAvailableListener of the GLConsumer,
   2054     // and should call both waitForFrame and finishFrame once for each expected
   2055     // frame.
   2056     //
   2057     // This interlocking relies on the fact that onFrameAvailable gets called
   2058     // synchronously from GLConsumer::queueBuffer.
   2059     class FrameCondition : public GLConsumer::FrameAvailableListener {
   2060     public:
   2061         FrameCondition():
   2062                 mFrameAvailable(false),
   2063                 mFrameFinished(false) {
   2064         }
   2065 
   2066         // waitForFrame waits for the next frame to arrive.  This should be
   2067         // called from the consumer thread once for every frame expected by the
   2068         // test.
   2069         void waitForFrame() {
   2070             Mutex::Autolock lock(mMutex);
   2071             ALOGV("+waitForFrame");
   2072             while (!mFrameAvailable) {
   2073                 mFrameAvailableCondition.wait(mMutex);
   2074             }
   2075             mFrameAvailable = false;
   2076             ALOGV("-waitForFrame");
   2077         }
   2078 
   2079         // Allow the producer to return from its swapBuffers call and continue
   2080         // on to produce the next frame.  This should be called by the consumer
   2081         // thread once for every frame expected by the test.
   2082         void finishFrame() {
   2083             Mutex::Autolock lock(mMutex);
   2084             ALOGV("+finishFrame");
   2085             mFrameFinished = true;
   2086             mFrameFinishCondition.signal();
   2087             ALOGV("-finishFrame");
   2088         }
   2089 
   2090         // This should be called by GLConsumer on the producer thread.
   2091         virtual void onFrameAvailable() {
   2092             Mutex::Autolock lock(mMutex);
   2093             ALOGV("+onFrameAvailable");
   2094             mFrameAvailable = true;
   2095             mFrameAvailableCondition.signal();
   2096             while (!mFrameFinished) {
   2097                 mFrameFinishCondition.wait(mMutex);
   2098             }
   2099             mFrameFinished = false;
   2100             ALOGV("-onFrameAvailable");
   2101         }
   2102 
   2103     protected:
   2104         bool mFrameAvailable;
   2105         bool mFrameFinished;
   2106 
   2107         Mutex mMutex;
   2108         Condition mFrameAvailableCondition;
   2109         Condition mFrameFinishCondition;
   2110     };
   2111 
   2112     virtual void SetUp() {
   2113         SurfaceTextureGLToGLTest::SetUp();
   2114         mFC = new FrameCondition();
   2115         mST->setFrameAvailableListener(mFC);
   2116     }
   2117 
   2118     virtual void TearDown() {
   2119         if (mProducerThread != NULL) {
   2120             mProducerThread->requestExitAndWait();
   2121         }
   2122         mProducerThread.clear();
   2123         mFC.clear();
   2124         SurfaceTextureGLToGLTest::TearDown();
   2125     }
   2126 
   2127     void runProducerThread(const sp<ProducerThread> producerThread) {
   2128         ASSERT_TRUE(mProducerThread == NULL);
   2129         mProducerThread = producerThread;
   2130         producerThread->setEglObjects(mEglDisplay, mProducerEglSurface,
   2131                 mProducerEglContext);
   2132         producerThread->run();
   2133     }
   2134 
   2135     sp<ProducerThread> mProducerThread;
   2136     sp<FrameCondition> mFC;
   2137 };
   2138 
   2139 TEST_F(SurfaceTextureGLThreadToGLTest,
   2140         UpdateTexImageBeforeFrameFinishedCompletes) {
   2141     class PT : public ProducerThread {
   2142         virtual void render() {
   2143             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   2144             glClear(GL_COLOR_BUFFER_BIT);
   2145             swapBuffers();
   2146         }
   2147     };
   2148 
   2149     runProducerThread(new PT());
   2150 
   2151     mFC->waitForFrame();
   2152     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2153     mFC->finishFrame();
   2154 
   2155     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
   2156 }
   2157 
   2158 TEST_F(SurfaceTextureGLThreadToGLTest,
   2159         UpdateTexImageAfterFrameFinishedCompletes) {
   2160     class PT : public ProducerThread {
   2161         virtual void render() {
   2162             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   2163             glClear(GL_COLOR_BUFFER_BIT);
   2164             swapBuffers();
   2165         }
   2166     };
   2167 
   2168     runProducerThread(new PT());
   2169 
   2170     mFC->waitForFrame();
   2171     mFC->finishFrame();
   2172     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2173 
   2174     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
   2175 }
   2176 
   2177 TEST_F(SurfaceTextureGLThreadToGLTest,
   2178         RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
   2179     enum { NUM_ITERATIONS = 1024 };
   2180 
   2181     class PT : public ProducerThread {
   2182         virtual void render() {
   2183             for (int i = 0; i < NUM_ITERATIONS; i++) {
   2184                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   2185                 glClear(GL_COLOR_BUFFER_BIT);
   2186                 ALOGV("+swapBuffers");
   2187                 swapBuffers();
   2188                 ALOGV("-swapBuffers");
   2189             }
   2190         }
   2191     };
   2192 
   2193     runProducerThread(new PT());
   2194 
   2195     for (int i = 0; i < NUM_ITERATIONS; i++) {
   2196         mFC->waitForFrame();
   2197         ALOGV("+updateTexImage");
   2198         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2199         ALOGV("-updateTexImage");
   2200         mFC->finishFrame();
   2201 
   2202         // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
   2203     }
   2204 }
   2205 
   2206 TEST_F(SurfaceTextureGLThreadToGLTest,
   2207         RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
   2208     enum { NUM_ITERATIONS = 1024 };
   2209 
   2210     class PT : public ProducerThread {
   2211         virtual void render() {
   2212             for (int i = 0; i < NUM_ITERATIONS; i++) {
   2213                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   2214                 glClear(GL_COLOR_BUFFER_BIT);
   2215                 ALOGV("+swapBuffers");
   2216                 swapBuffers();
   2217                 ALOGV("-swapBuffers");
   2218             }
   2219         }
   2220     };
   2221 
   2222     runProducerThread(new PT());
   2223 
   2224     for (int i = 0; i < NUM_ITERATIONS; i++) {
   2225         mFC->waitForFrame();
   2226         mFC->finishFrame();
   2227         ALOGV("+updateTexImage");
   2228         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2229         ALOGV("-updateTexImage");
   2230 
   2231         // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
   2232     }
   2233 }
   2234 
   2235 // XXX: This test is disabled because it is currently hanging on some devices.
   2236 TEST_F(SurfaceTextureGLThreadToGLTest,
   2237         DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
   2238     enum { NUM_ITERATIONS = 64 };
   2239 
   2240     class PT : public ProducerThread {
   2241         virtual void render() {
   2242             for (int i = 0; i < NUM_ITERATIONS; i++) {
   2243                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   2244                 glClear(GL_COLOR_BUFFER_BIT);
   2245                 ALOGV("+swapBuffers");
   2246                 swapBuffers();
   2247                 ALOGV("-swapBuffers");
   2248             }
   2249         }
   2250     };
   2251 
   2252     ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
   2253 
   2254     runProducerThread(new PT());
   2255 
   2256     // Allow three frames to be rendered and queued before starting the
   2257     // rendering in this thread.  For the latter two frames we don't call
   2258     // updateTexImage so the next dequeue from the producer thread will block
   2259     // waiting for a frame to become available.
   2260     mFC->waitForFrame();
   2261     mFC->finishFrame();
   2262 
   2263     // We must call updateTexImage to consume the first frame so that the
   2264     // SurfaceTexture is able to reduce the buffer count to 2.  This is because
   2265     // the GL driver may dequeue a buffer when the EGLSurface is created, and
   2266     // that happens before we call setDefaultMaxBufferCount.  It's possible that the
   2267     // driver does not dequeue a buffer at EGLSurface creation time, so we
   2268     // cannot rely on this to cause the second dequeueBuffer call to block.
   2269     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2270 
   2271     mFC->waitForFrame();
   2272     mFC->finishFrame();
   2273     mFC->waitForFrame();
   2274     mFC->finishFrame();
   2275 
   2276     // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
   2277     // block waiting for a buffer to become available.
   2278     usleep(100000);
   2279 
   2280     // Render and present a number of images.  This thread should not be blocked
   2281     // by the fact that the producer thread is blocking in dequeue.
   2282     for (int i = 0; i < NUM_ITERATIONS; i++) {
   2283         glClear(GL_COLOR_BUFFER_BIT);
   2284         eglSwapBuffers(mEglDisplay, mEglSurface);
   2285     }
   2286 
   2287     // Consume the two pending buffers to unblock the producer thread.
   2288     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2289     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2290 
   2291     // Consume the remaining buffers from the producer thread.
   2292     for (int i = 0; i < NUM_ITERATIONS-3; i++) {
   2293         mFC->waitForFrame();
   2294         mFC->finishFrame();
   2295         ALOGV("+updateTexImage");
   2296         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2297         ALOGV("-updateTexImage");
   2298     }
   2299 }
   2300 
   2301 class SurfaceTextureFBOTest : public SurfaceTextureGLTest {
   2302 protected:
   2303 
   2304     virtual void SetUp() {
   2305         SurfaceTextureGLTest::SetUp();
   2306 
   2307         glGenFramebuffers(1, &mFbo);
   2308         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   2309 
   2310         glGenTextures(1, &mFboTex);
   2311         glBindTexture(GL_TEXTURE_2D, mFboTex);
   2312         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSurfaceWidth(),
   2313                 getSurfaceHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
   2314         glBindTexture(GL_TEXTURE_2D, 0);
   2315         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   2316 
   2317         glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
   2318         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
   2319                 GL_TEXTURE_2D, mFboTex, 0);
   2320         glBindFramebuffer(GL_FRAMEBUFFER, 0);
   2321         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   2322     }
   2323 
   2324     virtual void TearDown() {
   2325         SurfaceTextureGLTest::TearDown();
   2326 
   2327         glDeleteTextures(1, &mFboTex);
   2328         glDeleteFramebuffers(1, &mFbo);
   2329     }
   2330 
   2331     GLuint mFbo;
   2332     GLuint mFboTex;
   2333 };
   2334 
   2335 // This test is intended to verify that proper synchronization is done when
   2336 // rendering into an FBO.
   2337 TEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
   2338     const int texWidth = 64;
   2339     const int texHeight = 64;
   2340 
   2341     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
   2342             texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
   2343     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
   2344             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
   2345 
   2346     android_native_buffer_t* anb;
   2347     ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
   2348             &anb));
   2349     ASSERT_TRUE(anb != NULL);
   2350 
   2351     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
   2352 
   2353     // Fill the buffer with green
   2354     uint8_t* img = NULL;
   2355     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
   2356     fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255,
   2357             0, 255);
   2358     buf->unlock();
   2359     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
   2360             -1));
   2361 
   2362     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2363 
   2364     glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
   2365     drawTexture();
   2366     glBindFramebuffer(GL_FRAMEBUFFER, 0);
   2367 
   2368     for (int i = 0; i < 4; i++) {
   2369         SCOPED_TRACE(String8::format("frame %d", i).string());
   2370 
   2371         ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
   2372                 &anb));
   2373         ASSERT_TRUE(anb != NULL);
   2374 
   2375         buf = new GraphicBuffer(anb, false);
   2376 
   2377         // Fill the buffer with red
   2378         ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
   2379                 (void**)(&img)));
   2380         fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0,
   2381                 0, 255);
   2382         ASSERT_EQ(NO_ERROR, buf->unlock());
   2383         ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
   2384                 buf->getNativeBuffer(), -1));
   2385 
   2386         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   2387 
   2388         drawTexture();
   2389 
   2390         EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255));
   2391     }
   2392 
   2393     glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
   2394 
   2395     EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255));
   2396 }
   2397 
   2398 class SurfaceTextureMultiContextGLTest : public SurfaceTextureGLTest {
   2399 protected:
   2400     enum { SECOND_TEX_ID = 123 };
   2401     enum { THIRD_TEX_ID = 456 };
   2402 
   2403     SurfaceTextureMultiContextGLTest():
   2404             mSecondEglContext(EGL_NO_CONTEXT) {
   2405     }
   2406 
   2407     virtual void SetUp() {
   2408         SurfaceTextureGLTest::SetUp();
   2409 
   2410         // Set up the secondary context and texture renderer.
   2411         mSecondEglContext = eglCreateContext(mEglDisplay, mGlConfig,
   2412                 EGL_NO_CONTEXT, getContextAttribs());
   2413         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   2414         ASSERT_NE(EGL_NO_CONTEXT, mSecondEglContext);
   2415 
   2416         ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2417                 mSecondEglContext));
   2418         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   2419         mSecondTextureRenderer = new TextureRenderer(SECOND_TEX_ID, mST);
   2420         ASSERT_NO_FATAL_FAILURE(mSecondTextureRenderer->SetUp());
   2421 
   2422         // Set up the tertiary context and texture renderer.
   2423         mThirdEglContext = eglCreateContext(mEglDisplay, mGlConfig,
   2424                 EGL_NO_CONTEXT, getContextAttribs());
   2425         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   2426         ASSERT_NE(EGL_NO_CONTEXT, mThirdEglContext);
   2427 
   2428         ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2429                 mThirdEglContext));
   2430         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   2431         mThirdTextureRenderer = new TextureRenderer(THIRD_TEX_ID, mST);
   2432         ASSERT_NO_FATAL_FAILURE(mThirdTextureRenderer->SetUp());
   2433 
   2434         // Switch back to the primary context to start the tests.
   2435         ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2436                 mEglContext));
   2437     }
   2438 
   2439     virtual void TearDown() {
   2440         if (mThirdEglContext != EGL_NO_CONTEXT) {
   2441             eglDestroyContext(mEglDisplay, mThirdEglContext);
   2442         }
   2443         if (mSecondEglContext != EGL_NO_CONTEXT) {
   2444             eglDestroyContext(mEglDisplay, mSecondEglContext);
   2445         }
   2446         SurfaceTextureGLTest::TearDown();
   2447     }
   2448 
   2449     EGLContext mSecondEglContext;
   2450     sp<TextureRenderer> mSecondTextureRenderer;
   2451 
   2452     EGLContext mThirdEglContext;
   2453     sp<TextureRenderer> mThirdTextureRenderer;
   2454 };
   2455 
   2456 TEST_F(SurfaceTextureMultiContextGLTest, UpdateFromMultipleContextsFails) {
   2457     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2458 
   2459     // Latch the texture contents on the primary context.
   2460     mFW->waitForFrame();
   2461     ASSERT_EQ(OK, mST->updateTexImage());
   2462 
   2463     // Attempt to latch the texture on the secondary context.
   2464     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2465             mSecondEglContext));
   2466     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   2467     ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
   2468 }
   2469 
   2470 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextSucceeds) {
   2471     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2472 
   2473     // Latch the texture contents on the primary context.
   2474     mFW->waitForFrame();
   2475     ASSERT_EQ(OK, mST->updateTexImage());
   2476 
   2477     // Detach from the primary context.
   2478     ASSERT_EQ(OK, mST->detachFromContext());
   2479 
   2480     // Check that the GL texture was deleted.
   2481     EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
   2482 }
   2483 
   2484 TEST_F(SurfaceTextureMultiContextGLTest,
   2485         DetachFromContextSucceedsAfterProducerDisconnect) {
   2486     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2487 
   2488     // Latch the texture contents on the primary context.
   2489     mFW->waitForFrame();
   2490     ASSERT_EQ(OK, mST->updateTexImage());
   2491 
   2492     // Detach from the primary context.
   2493     native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
   2494     ASSERT_EQ(OK, mST->detachFromContext());
   2495 
   2496     // Check that the GL texture was deleted.
   2497     EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
   2498 }
   2499 
   2500 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenAbandoned) {
   2501     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2502 
   2503     // Latch the texture contents on the primary context.
   2504     mFW->waitForFrame();
   2505     ASSERT_EQ(OK, mST->updateTexImage());
   2506 
   2507     // Attempt to detach from the primary context.
   2508     mST->abandon();
   2509     ASSERT_EQ(NO_INIT, mST->detachFromContext());
   2510 }
   2511 
   2512 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenDetached) {
   2513     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2514 
   2515     // Latch the texture contents on the primary context.
   2516     mFW->waitForFrame();
   2517     ASSERT_EQ(OK, mST->updateTexImage());
   2518 
   2519     // Detach from the primary context.
   2520     ASSERT_EQ(OK, mST->detachFromContext());
   2521 
   2522     // Attempt to detach from the primary context again.
   2523     ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
   2524 }
   2525 
   2526 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoDisplay) {
   2527     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2528 
   2529     // Latch the texture contents on the primary context.
   2530     mFW->waitForFrame();
   2531     ASSERT_EQ(OK, mST->updateTexImage());
   2532 
   2533     // Make there be no current display.
   2534     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
   2535             EGL_NO_CONTEXT));
   2536     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   2537 
   2538     // Attempt to detach from the primary context.
   2539     ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
   2540 }
   2541 
   2542 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoContext) {
   2543     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2544 
   2545     // Latch the texture contents on the primary context.
   2546     mFW->waitForFrame();
   2547     ASSERT_EQ(OK, mST->updateTexImage());
   2548 
   2549     // Make current context be incorrect.
   2550     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2551             mSecondEglContext));
   2552     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   2553 
   2554     // Attempt to detach from the primary context.
   2555     ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
   2556 }
   2557 
   2558 TEST_F(SurfaceTextureMultiContextGLTest, UpdateTexImageFailsWhenDetached) {
   2559     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2560 
   2561     // Detach from the primary context.
   2562     ASSERT_EQ(OK, mST->detachFromContext());
   2563 
   2564     // Attempt to latch the texture contents on the primary context.
   2565     mFW->waitForFrame();
   2566     ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
   2567 }
   2568 
   2569 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceeds) {
   2570     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2571 
   2572     // Latch the texture contents on the primary context.
   2573     mFW->waitForFrame();
   2574     ASSERT_EQ(OK, mST->updateTexImage());
   2575 
   2576     // Detach from the primary context.
   2577     ASSERT_EQ(OK, mST->detachFromContext());
   2578 
   2579     // Attach to the secondary context.
   2580     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2581             mSecondEglContext));
   2582     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
   2583 
   2584     // Verify that the texture object was created and bound.
   2585     GLint texBinding = -1;
   2586     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
   2587     EXPECT_EQ(SECOND_TEX_ID, texBinding);
   2588 
   2589     // Try to use the texture from the secondary context.
   2590     glClearColor(0.2, 0.2, 0.2, 0.2);
   2591     glClear(GL_COLOR_BUFFER_BIT);
   2592     glViewport(0, 0, 1, 1);
   2593     mSecondTextureRenderer->drawTexture();
   2594     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
   2595     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   2596 }
   2597 
   2598 TEST_F(SurfaceTextureMultiContextGLTest,
   2599         AttachToContextSucceedsAfterProducerDisconnect) {
   2600     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2601 
   2602     // Latch the texture contents on the primary context.
   2603     mFW->waitForFrame();
   2604     ASSERT_EQ(OK, mST->updateTexImage());
   2605 
   2606     // Detach from the primary context.
   2607     native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
   2608     ASSERT_EQ(OK, mST->detachFromContext());
   2609 
   2610     // Attach to the secondary context.
   2611     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2612             mSecondEglContext));
   2613     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
   2614 
   2615     // Verify that the texture object was created and bound.
   2616     GLint texBinding = -1;
   2617     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
   2618     EXPECT_EQ(SECOND_TEX_ID, texBinding);
   2619 
   2620     // Try to use the texture from the secondary context.
   2621     glClearColor(0.2, 0.2, 0.2, 0.2);
   2622     glClear(GL_COLOR_BUFFER_BIT);
   2623     glViewport(0, 0, 1, 1);
   2624     mSecondTextureRenderer->drawTexture();
   2625     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   2626     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
   2627 }
   2628 
   2629 TEST_F(SurfaceTextureMultiContextGLTest,
   2630         AttachToContextSucceedsBeforeUpdateTexImage) {
   2631     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2632 
   2633     // Detach from the primary context.
   2634     native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
   2635     ASSERT_EQ(OK, mST->detachFromContext());
   2636 
   2637     // Attach to the secondary context.
   2638     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2639             mSecondEglContext));
   2640     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
   2641 
   2642     // Verify that the texture object was created and bound.
   2643     GLint texBinding = -1;
   2644     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
   2645     EXPECT_EQ(SECOND_TEX_ID, texBinding);
   2646 
   2647     // Latch the texture contents on the primary context.
   2648     mFW->waitForFrame();
   2649     ASSERT_EQ(OK, mST->updateTexImage());
   2650 
   2651     // Try to use the texture from the secondary context.
   2652     glClearColor(0.2, 0.2, 0.2, 0.2);
   2653     glClear(GL_COLOR_BUFFER_BIT);
   2654     glViewport(0, 0, 1, 1);
   2655     mSecondTextureRenderer->drawTexture();
   2656     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   2657     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
   2658 }
   2659 
   2660 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAbandoned) {
   2661     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2662 
   2663     // Latch the texture contents on the primary context.
   2664     mFW->waitForFrame();
   2665     ASSERT_EQ(OK, mST->updateTexImage());
   2666 
   2667     // Detach from the primary context.
   2668     ASSERT_EQ(OK, mST->detachFromContext());
   2669 
   2670     // Attempt to attach to the secondary context.
   2671     mST->abandon();
   2672 
   2673     // Attempt to attach to the primary context.
   2674     ASSERT_EQ(NO_INIT, mST->attachToContext(SECOND_TEX_ID));
   2675 }
   2676 
   2677 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAttached) {
   2678     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2679 
   2680     // Latch the texture contents on the primary context.
   2681     mFW->waitForFrame();
   2682     ASSERT_EQ(OK, mST->updateTexImage());
   2683 
   2684     // Attempt to attach to the primary context.
   2685     ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
   2686 }
   2687 
   2688 TEST_F(SurfaceTextureMultiContextGLTest,
   2689         AttachToContextFailsWhenAttachedBeforeUpdateTexImage) {
   2690     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2691 
   2692     // Attempt to attach to the primary context.
   2693     ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
   2694 }
   2695 
   2696 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWithNoDisplay) {
   2697     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2698 
   2699     // Latch the texture contents on the primary context.
   2700     mFW->waitForFrame();
   2701     ASSERT_EQ(OK, mST->updateTexImage());
   2702 
   2703     // Detach from the primary context.
   2704     ASSERT_EQ(OK, mST->detachFromContext());
   2705 
   2706     // Make there be no current display.
   2707     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
   2708             EGL_NO_CONTEXT));
   2709     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   2710 
   2711     // Attempt to attach with no context current.
   2712     ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
   2713 }
   2714 
   2715 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceedsTwice) {
   2716     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2717 
   2718     // Latch the texture contents on the primary context.
   2719     mFW->waitForFrame();
   2720     ASSERT_EQ(OK, mST->updateTexImage());
   2721 
   2722     // Detach from the primary context.
   2723     ASSERT_EQ(OK, mST->detachFromContext());
   2724 
   2725     // Attach to the secondary context.
   2726     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2727             mSecondEglContext));
   2728     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
   2729 
   2730     // Detach from the secondary context.
   2731     ASSERT_EQ(OK, mST->detachFromContext());
   2732 
   2733     // Attach to the tertiary context.
   2734     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2735             mThirdEglContext));
   2736     ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
   2737 
   2738     // Verify that the texture object was created and bound.
   2739     GLint texBinding = -1;
   2740     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
   2741     EXPECT_EQ(THIRD_TEX_ID, texBinding);
   2742 
   2743     // Try to use the texture from the tertiary context.
   2744     glClearColor(0.2, 0.2, 0.2, 0.2);
   2745     glClear(GL_COLOR_BUFFER_BIT);
   2746     glViewport(0, 0, 1, 1);
   2747     mThirdTextureRenderer->drawTexture();
   2748     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   2749     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
   2750 }
   2751 
   2752 TEST_F(SurfaceTextureMultiContextGLTest,
   2753         AttachToContextSucceedsTwiceBeforeUpdateTexImage) {
   2754     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2755 
   2756     // Detach from the primary context.
   2757     ASSERT_EQ(OK, mST->detachFromContext());
   2758 
   2759     // Attach to the secondary context.
   2760     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2761             mSecondEglContext));
   2762     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
   2763 
   2764     // Detach from the secondary context.
   2765     ASSERT_EQ(OK, mST->detachFromContext());
   2766 
   2767     // Attach to the tertiary context.
   2768     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2769             mThirdEglContext));
   2770     ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
   2771 
   2772     // Verify that the texture object was created and bound.
   2773     GLint texBinding = -1;
   2774     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
   2775     EXPECT_EQ(THIRD_TEX_ID, texBinding);
   2776 
   2777     // Latch the texture contents on the tertiary context.
   2778     mFW->waitForFrame();
   2779     ASSERT_EQ(OK, mST->updateTexImage());
   2780 
   2781     // Try to use the texture from the tertiary context.
   2782     glClearColor(0.2, 0.2, 0.2, 0.2);
   2783     glClear(GL_COLOR_BUFFER_BIT);
   2784     glViewport(0, 0, 1, 1);
   2785     mThirdTextureRenderer->drawTexture();
   2786     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   2787     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
   2788 }
   2789 
   2790 TEST_F(SurfaceTextureMultiContextGLTest,
   2791         UpdateTexImageSucceedsForBufferConsumedBeforeDetach) {
   2792     ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
   2793 
   2794     // produce two frames and consume them both on the primary context
   2795     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2796     mFW->waitForFrame();
   2797     ASSERT_EQ(OK, mST->updateTexImage());
   2798 
   2799     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2800     mFW->waitForFrame();
   2801     ASSERT_EQ(OK, mST->updateTexImage());
   2802 
   2803     // produce one more frame
   2804     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
   2805 
   2806     // Detach from the primary context and attach to the secondary context
   2807     ASSERT_EQ(OK, mST->detachFromContext());
   2808     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   2809             mSecondEglContext));
   2810     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
   2811 
   2812     // Consume final frame on secondary context
   2813     mFW->waitForFrame();
   2814     ASSERT_EQ(OK, mST->updateTexImage());
   2815 }
   2816 
   2817 } // namespace android
   2818