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