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/SurfaceTexture.h>
     22 #include <gui/SurfaceTextureClient.h>
     23 #include <ui/GraphicBuffer.h>
     24 #include <utils/String8.h>
     25 #include <utils/threads.h>
     26 
     27 #include <surfaceflinger/ISurfaceComposer.h>
     28 #include <surfaceflinger/Surface.h>
     29 #include <surfaceflinger/SurfaceComposerClient.h>
     30 
     31 #include <EGL/egl.h>
     32 #include <EGL/eglext.h>
     33 #include <GLES2/gl2.h>
     34 #include <GLES2/gl2ext.h>
     35 
     36 #include <ui/FramebufferNativeWindow.h>
     37 
     38 namespace android {
     39 
     40 class GLTest : public ::testing::Test {
     41 protected:
     42 
     43     GLTest():
     44             mEglDisplay(EGL_NO_DISPLAY),
     45             mEglSurface(EGL_NO_SURFACE),
     46             mEglContext(EGL_NO_CONTEXT) {
     47     }
     48 
     49     virtual void SetUp() {
     50         mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     51         ASSERT_EQ(EGL_SUCCESS, eglGetError());
     52         ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
     53 
     54         EGLint majorVersion;
     55         EGLint minorVersion;
     56         EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
     57         ASSERT_EQ(EGL_SUCCESS, eglGetError());
     58         RecordProperty("EglVersionMajor", majorVersion);
     59         RecordProperty("EglVersionMajor", minorVersion);
     60 
     61         EGLint numConfigs = 0;
     62         EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
     63                 1, &numConfigs));
     64         ASSERT_EQ(EGL_SUCCESS, eglGetError());
     65 
     66         char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
     67         if (displaySecsEnv != NULL) {
     68             mDisplaySecs = atoi(displaySecsEnv);
     69             if (mDisplaySecs < 0) {
     70                 mDisplaySecs = 0;
     71             }
     72         } else {
     73             mDisplaySecs = 0;
     74         }
     75 
     76         if (mDisplaySecs > 0) {
     77             mComposerClient = new SurfaceComposerClient;
     78             ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
     79 
     80             mSurfaceControl = mComposerClient->createSurface(
     81                     String8("Test Surface"), 0,
     82                     getSurfaceWidth(), getSurfaceHeight(),
     83                     PIXEL_FORMAT_RGB_888, 0);
     84 
     85             ASSERT_TRUE(mSurfaceControl != NULL);
     86             ASSERT_TRUE(mSurfaceControl->isValid());
     87 
     88             SurfaceComposerClient::openGlobalTransaction();
     89             ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
     90             ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
     91             SurfaceComposerClient::closeGlobalTransaction();
     92 
     93             sp<ANativeWindow> window = mSurfaceControl->getSurface();
     94             mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
     95                     window.get(), NULL);
     96         } else {
     97             EGLint pbufferAttribs[] = {
     98                 EGL_WIDTH, getSurfaceWidth(),
     99                 EGL_HEIGHT, getSurfaceHeight(),
    100                 EGL_NONE };
    101 
    102             mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
    103                     pbufferAttribs);
    104         }
    105         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    106         ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
    107 
    108         mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
    109                 getContextAttribs());
    110         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    111         ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
    112 
    113         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    114                 mEglContext));
    115         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    116 
    117         EGLint w, h;
    118         EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
    119         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    120         EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
    121         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    122         RecordProperty("EglSurfaceWidth", w);
    123         RecordProperty("EglSurfaceHeight", h);
    124 
    125         glViewport(0, 0, w, h);
    126         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    127     }
    128 
    129     virtual void TearDown() {
    130         // Display the result
    131         if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
    132             eglSwapBuffers(mEglDisplay, mEglSurface);
    133             sleep(mDisplaySecs);
    134         }
    135 
    136         if (mComposerClient != NULL) {
    137             mComposerClient->dispose();
    138         }
    139         if (mEglContext != EGL_NO_CONTEXT) {
    140             eglDestroyContext(mEglDisplay, mEglContext);
    141         }
    142         if (mEglSurface != EGL_NO_SURFACE) {
    143             eglDestroySurface(mEglDisplay, mEglSurface);
    144         }
    145         if (mEglDisplay != EGL_NO_DISPLAY) {
    146             eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
    147                     EGL_NO_CONTEXT);
    148             eglTerminate(mEglDisplay);
    149         }
    150         ASSERT_EQ(EGL_SUCCESS, eglGetError());
    151     }
    152 
    153     virtual EGLint const* getConfigAttribs() {
    154         static EGLint sDefaultConfigAttribs[] = {
    155             EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    156             EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    157             EGL_RED_SIZE, 8,
    158             EGL_GREEN_SIZE, 8,
    159             EGL_BLUE_SIZE, 8,
    160             EGL_ALPHA_SIZE, 8,
    161             EGL_DEPTH_SIZE, 16,
    162             EGL_STENCIL_SIZE, 8,
    163             EGL_NONE };
    164 
    165         return sDefaultConfigAttribs;
    166     }
    167 
    168     virtual EGLint const* getContextAttribs() {
    169         static EGLint sDefaultContextAttribs[] = {
    170             EGL_CONTEXT_CLIENT_VERSION, 2,
    171             EGL_NONE };
    172 
    173         return sDefaultContextAttribs;
    174     }
    175 
    176     virtual EGLint getSurfaceWidth() {
    177         return 512;
    178     }
    179 
    180     virtual EGLint getSurfaceHeight() {
    181         return 512;
    182     }
    183 
    184     void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader) {
    185         GLuint shader = glCreateShader(shaderType);
    186         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    187         if (shader) {
    188             glShaderSource(shader, 1, &pSource, NULL);
    189             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    190             glCompileShader(shader);
    191             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    192             GLint compiled = 0;
    193             glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
    194             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    195             if (!compiled) {
    196                 GLint infoLen = 0;
    197                 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
    198                 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    199                 if (infoLen) {
    200                     char* buf = (char*) malloc(infoLen);
    201                     if (buf) {
    202                         glGetShaderInfoLog(shader, infoLen, NULL, buf);
    203                         printf("Shader compile log:\n%s\n", buf);
    204                         free(buf);
    205                         FAIL();
    206                     }
    207                 } else {
    208                     char* buf = (char*) malloc(0x1000);
    209                     if (buf) {
    210                         glGetShaderInfoLog(shader, 0x1000, NULL, buf);
    211                         printf("Shader compile log:\n%s\n", buf);
    212                         free(buf);
    213                         FAIL();
    214                     }
    215                 }
    216                 glDeleteShader(shader);
    217                 shader = 0;
    218             }
    219         }
    220         ASSERT_TRUE(shader != 0);
    221         *outShader = shader;
    222     }
    223 
    224     void createProgram(const char* pVertexSource, const char* pFragmentSource,
    225             GLuint* outPgm) {
    226         GLuint vertexShader, fragmentShader;
    227         {
    228             SCOPED_TRACE("compiling vertex shader");
    229             loadShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader);
    230             if (HasFatalFailure()) {
    231                 return;
    232             }
    233         }
    234         {
    235             SCOPED_TRACE("compiling fragment shader");
    236             loadShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader);
    237             if (HasFatalFailure()) {
    238                 return;
    239             }
    240         }
    241 
    242         GLuint program = glCreateProgram();
    243         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    244         if (program) {
    245             glAttachShader(program, vertexShader);
    246             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    247             glAttachShader(program, fragmentShader);
    248             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    249             glLinkProgram(program);
    250             GLint linkStatus = GL_FALSE;
    251             glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
    252             if (linkStatus != GL_TRUE) {
    253                 GLint bufLength = 0;
    254                 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
    255                 if (bufLength) {
    256                     char* buf = (char*) malloc(bufLength);
    257                     if (buf) {
    258                         glGetProgramInfoLog(program, bufLength, NULL, buf);
    259                         printf("Program link log:\n%s\n", buf);
    260                         free(buf);
    261                         FAIL();
    262                     }
    263                 }
    264                 glDeleteProgram(program);
    265                 program = 0;
    266             }
    267         }
    268         glDeleteShader(vertexShader);
    269         glDeleteShader(fragmentShader);
    270         ASSERT_TRUE(program != 0);
    271         *outPgm = program;
    272     }
    273 
    274     static int abs(int value) {
    275         return value > 0 ? value : -value;
    276     }
    277 
    278     ::testing::AssertionResult checkPixel(int x, int y, int r,
    279             int g, int b, int a, int tolerance=2) {
    280         GLubyte pixel[4];
    281         String8 msg;
    282         glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
    283         GLenum err = glGetError();
    284         if (err != GL_NO_ERROR) {
    285             msg += String8::format("error reading pixel: %#x", err);
    286             while ((err = glGetError()) != GL_NO_ERROR) {
    287                 msg += String8::format(", %#x", err);
    288             }
    289             fprintf(stderr, "pixel check failure: %s\n", msg.string());
    290             return ::testing::AssertionFailure(
    291                     ::testing::Message(msg.string()));
    292         }
    293         if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
    294             msg += String8::format("r(%d isn't %d)", pixel[0], r);
    295         }
    296         if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
    297             if (!msg.isEmpty()) {
    298                 msg += " ";
    299             }
    300             msg += String8::format("g(%d isn't %d)", pixel[1], g);
    301         }
    302         if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
    303             if (!msg.isEmpty()) {
    304                 msg += " ";
    305             }
    306             msg += String8::format("b(%d isn't %d)", pixel[2], b);
    307         }
    308         if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
    309             if (!msg.isEmpty()) {
    310                 msg += " ";
    311             }
    312             msg += String8::format("a(%d isn't %d)", pixel[3], a);
    313         }
    314         if (!msg.isEmpty()) {
    315             fprintf(stderr, "pixel check failure: %s\n", msg.string());
    316             return ::testing::AssertionFailure(
    317                     ::testing::Message(msg.string()));
    318         } else {
    319             return ::testing::AssertionSuccess();
    320         }
    321     }
    322 
    323     int mDisplaySecs;
    324     sp<SurfaceComposerClient> mComposerClient;
    325     sp<SurfaceControl> mSurfaceControl;
    326 
    327     EGLDisplay mEglDisplay;
    328     EGLSurface mEglSurface;
    329     EGLContext mEglContext;
    330     EGLConfig  mGlConfig;
    331 };
    332 
    333 // XXX: Code above this point should live elsewhere
    334 
    335 class SurfaceTextureGLTest : public GLTest {
    336 protected:
    337     enum { TEX_ID = 123 };
    338 
    339     virtual void SetUp() {
    340         GLTest::SetUp();
    341         mST = new SurfaceTexture(TEX_ID);
    342         mSTC = new SurfaceTextureClient(mST);
    343         mANW = mSTC;
    344 
    345         const char vsrc[] =
    346             "attribute vec4 vPosition;\n"
    347             "varying vec2 texCoords;\n"
    348             "uniform mat4 texMatrix;\n"
    349             "void main() {\n"
    350             "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
    351             "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
    352             "  gl_Position = vPosition;\n"
    353             "}\n";
    354 
    355         const char fsrc[] =
    356             "#extension GL_OES_EGL_image_external : require\n"
    357             "precision mediump float;\n"
    358             "uniform samplerExternalOES texSampler;\n"
    359             "varying vec2 texCoords;\n"
    360             "void main() {\n"
    361             "  gl_FragColor = texture2D(texSampler, texCoords);\n"
    362             "}\n";
    363 
    364         {
    365             SCOPED_TRACE("creating shader program");
    366             createProgram(vsrc, fsrc, &mPgm);
    367             if (HasFatalFailure()) {
    368                 return;
    369             }
    370         }
    371 
    372         mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
    373         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    374         ASSERT_NE(-1, mPositionHandle);
    375         mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
    376         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    377         ASSERT_NE(-1, mTexSamplerHandle);
    378         mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
    379         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    380         ASSERT_NE(-1, mTexMatrixHandle);
    381     }
    382 
    383     virtual void TearDown() {
    384         mANW.clear();
    385         mSTC.clear();
    386         mST.clear();
    387         GLTest::TearDown();
    388     }
    389 
    390     // drawTexture draws the SurfaceTexture over the entire GL viewport.
    391     void drawTexture() {
    392         const GLfloat triangleVertices[] = {
    393             -1.0f, 1.0f,
    394             -1.0f, -1.0f,
    395             1.0f, -1.0f,
    396             1.0f, 1.0f,
    397         };
    398 
    399         glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
    400                 triangleVertices);
    401         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    402         glEnableVertexAttribArray(mPositionHandle);
    403         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    404 
    405         glUseProgram(mPgm);
    406         glUniform1i(mTexSamplerHandle, 0);
    407         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    408         glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
    409         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    410 
    411         // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
    412         // they're setting the defautls for that target, but when hacking things
    413         // to use GL_TEXTURE_2D they are needed to achieve the same behavior.
    414         glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
    415                 GL_LINEAR);
    416         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    417         glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
    418                 GL_LINEAR);
    419         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    420         glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
    421                 GL_CLAMP_TO_EDGE);
    422         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    423         glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
    424                 GL_CLAMP_TO_EDGE);
    425         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    426 
    427         GLfloat texMatrix[16];
    428         mST->getTransformMatrix(texMatrix);
    429         glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
    430 
    431         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    432         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    433     }
    434 
    435     class FrameWaiter : public SurfaceTexture::FrameAvailableListener {
    436     public:
    437         FrameWaiter():
    438                 mPendingFrames(0) {
    439         }
    440 
    441         void waitForFrame() {
    442             Mutex::Autolock lock(mMutex);
    443             while (mPendingFrames == 0) {
    444                 mCondition.wait(mMutex);
    445             }
    446             mPendingFrames--;
    447         }
    448 
    449         virtual void onFrameAvailable() {
    450             Mutex::Autolock lock(mMutex);
    451             mPendingFrames++;
    452             mCondition.signal();
    453         }
    454 
    455         int mPendingFrames;
    456         Mutex mMutex;
    457         Condition mCondition;
    458     };
    459 
    460     sp<SurfaceTexture> mST;
    461     sp<SurfaceTextureClient> mSTC;
    462     sp<ANativeWindow> mANW;
    463 
    464     GLuint mPgm;
    465     GLint mPositionHandle;
    466     GLint mTexSamplerHandle;
    467     GLint mTexMatrixHandle;
    468 };
    469 
    470 // Fill a YV12 buffer with a multi-colored checkerboard pattern
    471 void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
    472     const int blockWidth = w > 16 ? w / 16 : 1;
    473     const int blockHeight = h > 16 ? h / 16 : 1;
    474     const int yuvTexOffsetY = 0;
    475     int yuvTexStrideY = stride;
    476     int yuvTexOffsetV = yuvTexStrideY * h;
    477     int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
    478     int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
    479     int yuvTexStrideU = yuvTexStrideV;
    480     for (int x = 0; x < w; x++) {
    481         for (int y = 0; y < h; y++) {
    482             int parityX = (x / blockWidth) & 1;
    483             int parityY = (y / blockHeight) & 1;
    484             unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
    485             buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
    486             if (x < w / 2 && y < h / 2) {
    487                 buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
    488                 if (x * 2 < w / 2 && y * 2 < h / 2) {
    489                     buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
    490                     buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
    491                     buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
    492                     buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
    493                         intensity;
    494                 }
    495             }
    496         }
    497     }
    498 }
    499 
    500 // Fill a YV12 buffer with red outside a given rectangle and green inside it.
    501 void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
    502         const android_native_rect_t& rect) {
    503     const int yuvTexOffsetY = 0;
    504     int yuvTexStrideY = stride;
    505     int yuvTexOffsetV = yuvTexStrideY * h;
    506     int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
    507     int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
    508     int yuvTexStrideU = yuvTexStrideV;
    509     for (int x = 0; x < w; x++) {
    510         for (int y = 0; y < h; y++) {
    511             bool inside = rect.left <= x && x < rect.right &&
    512                     rect.top <= y && y < rect.bottom;
    513             buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
    514             if (x < w / 2 && y < h / 2) {
    515                 bool inside = rect.left <= 2*x && 2*x < rect.right &&
    516                         rect.top <= 2*y && 2*y < rect.bottom;
    517                 buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
    518                 buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
    519                         inside ? 16 : 255;
    520             }
    521         }
    522     }
    523 }
    524 
    525 void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
    526     const size_t PIXEL_SIZE = 4;
    527     for (int x = 0; x < w; x++) {
    528         for (int y = 0; y < h; y++) {
    529             off_t offset = (y * stride + x) * PIXEL_SIZE;
    530             for (int c = 0; c < 4; c++) {
    531                 int parityX = (x / (1 << (c+2))) & 1;
    532                 int parityY = (y / (1 << (c+2))) & 1;
    533                 buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
    534             }
    535         }
    536     }
    537 }
    538 
    539 void fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r,
    540         uint8_t g, uint8_t b, uint8_t a) {
    541     const size_t PIXEL_SIZE = 4;
    542     for (int y = 0; y < h; y++) {
    543         for (int x = 0; x < h; x++) {
    544             off_t offset = (y * stride + x) * PIXEL_SIZE;
    545             buf[offset + 0] = r;
    546             buf[offset + 1] = g;
    547             buf[offset + 2] = b;
    548             buf[offset + 3] = a;
    549         }
    550     }
    551 }
    552 
    553 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
    554     const int texWidth = 64;
    555     const int texHeight = 66;
    556 
    557     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    558             texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
    559     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    560             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    561 
    562     ANativeWindowBuffer* anb;
    563     ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
    564     ASSERT_TRUE(anb != NULL);
    565 
    566     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    567     ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
    568 
    569     // Fill the buffer with the a checkerboard pattern
    570     uint8_t* img = NULL;
    571     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    572     fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
    573     buf->unlock();
    574     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
    575 
    576     mST->updateTexImage();
    577 
    578     glClearColor(0.2, 0.2, 0.2, 0.2);
    579     glClear(GL_COLOR_BUFFER_BIT);
    580 
    581     glViewport(0, 0, texWidth, texHeight);
    582     drawTexture();
    583 
    584     EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255));
    585     EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255));
    586     EXPECT_TRUE(checkPixel(63, 65,   0, 133,   0, 255));
    587     EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255));
    588 
    589     EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255));
    590     EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255));
    591     EXPECT_TRUE(checkPixel(52, 51,  98, 255,  73, 255));
    592     EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255));
    593     EXPECT_TRUE(checkPixel(31,  9, 107,  24,  87, 255));
    594     EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255));
    595     EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255));
    596 }
    597 
    598 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
    599     const int texWidth = 64;
    600     const int texHeight = 64;
    601 
    602     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    603             texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
    604     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    605             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    606 
    607     ANativeWindowBuffer* anb;
    608     ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
    609     ASSERT_TRUE(anb != NULL);
    610 
    611     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    612     ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
    613 
    614     // Fill the buffer with the a checkerboard pattern
    615     uint8_t* img = NULL;
    616     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    617     fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
    618     buf->unlock();
    619     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
    620 
    621     mST->updateTexImage();
    622 
    623     glClearColor(0.2, 0.2, 0.2, 0.2);
    624     glClear(GL_COLOR_BUFFER_BIT);
    625 
    626     glViewport(0, 0, texWidth, texHeight);
    627     drawTexture();
    628 
    629     EXPECT_TRUE(checkPixel( 0,  0,   0, 133,   0, 255));
    630     EXPECT_TRUE(checkPixel(63,  0, 255, 127, 255, 255));
    631     EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
    632     EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
    633 
    634     EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255));
    635     EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255));
    636     EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255));
    637     EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
    638     EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255));
    639     EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255));
    640     EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
    641 }
    642 
    643 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
    644     const int texWidth = 64;
    645     const int texHeight = 66;
    646 
    647     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    648             texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
    649     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    650             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    651 
    652     android_native_rect_t crops[] = {
    653         {4, 6, 22, 36},
    654         {0, 6, 22, 36},
    655         {4, 0, 22, 36},
    656         {4, 6, texWidth, 36},
    657         {4, 6, 22, texHeight},
    658     };
    659 
    660     for (int i = 0; i < 5; i++) {
    661         const android_native_rect_t& crop(crops[i]);
    662         SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
    663                 crop.left, crop.top, crop.right, crop.bottom).string());
    664 
    665         ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
    666 
    667         ANativeWindowBuffer* anb;
    668         ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
    669         ASSERT_TRUE(anb != NULL);
    670 
    671         sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    672         ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(),
    673                 buf->getNativeBuffer()));
    674 
    675         uint8_t* img = NULL;
    676         buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    677         fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
    678         buf->unlock();
    679         ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
    680                 buf->getNativeBuffer()));
    681 
    682         mST->updateTexImage();
    683 
    684         glClearColor(0.2, 0.2, 0.2, 0.2);
    685         glClear(GL_COLOR_BUFFER_BIT);
    686 
    687         glViewport(0, 0, 64, 64);
    688         drawTexture();
    689 
    690         EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
    691         EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
    692         EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
    693         EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
    694 
    695         EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
    696         EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
    697         EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
    698         EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
    699         EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
    700         EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
    701         EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
    702     }
    703 }
    704 
    705 // This test is intended to catch synchronization bugs between the CPU-written
    706 // and GPU-read buffers.
    707 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
    708     enum { texWidth = 16 };
    709     enum { texHeight = 16 };
    710     enum { numFrames = 1024 };
    711 
    712     ASSERT_EQ(NO_ERROR, mST->setSynchronousMode(true));
    713     ASSERT_EQ(NO_ERROR, mST->setBufferCountServer(2));
    714     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    715             texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
    716     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    717             GRALLOC_USAGE_SW_WRITE_OFTEN));
    718 
    719     struct TestPixel {
    720         int x;
    721         int y;
    722     };
    723     const TestPixel testPixels[] = {
    724         {  4, 11 },
    725         { 12, 14 },
    726         {  7,  2 },
    727     };
    728     enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
    729 
    730     class ProducerThread : public Thread {
    731     public:
    732         ProducerThread(const sp<ANativeWindow>& anw,
    733                 const TestPixel* testPixels):
    734                 mANW(anw),
    735                 mTestPixels(testPixels) {
    736         }
    737 
    738         virtual ~ProducerThread() {
    739         }
    740 
    741         virtual bool threadLoop() {
    742             for (int i = 0; i < numFrames; i++) {
    743                 ANativeWindowBuffer* anb;
    744                 if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
    745                     return false;
    746                 }
    747                 if (anb == NULL) {
    748                     return false;
    749                 }
    750 
    751                 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    752                 if (mANW->lockBuffer(mANW.get(), buf->getNativeBuffer())
    753                         != NO_ERROR) {
    754                     return false;
    755                 }
    756 
    757                 const int yuvTexOffsetY = 0;
    758                 int stride = buf->getStride();
    759                 int yuvTexStrideY = stride;
    760                 int yuvTexOffsetV = yuvTexStrideY * texHeight;
    761                 int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
    762                 int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
    763                 int yuvTexStrideU = yuvTexStrideV;
    764 
    765                 uint8_t* img = NULL;
    766                 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    767 
    768                 // Gray out all the test pixels first, so we're more likely to
    769                 // see a failure if GL is still texturing from the buffer we
    770                 // just dequeued.
    771                 for (int j = 0; j < numTestPixels; j++) {
    772                     int x = mTestPixels[j].x;
    773                     int y = mTestPixels[j].y;
    774                     uint8_t value = 128;
    775                     img[y*stride + x] = value;
    776                 }
    777 
    778                 // Fill the buffer with gray.
    779                 for (int y = 0; y < texHeight; y++) {
    780                     for (int x = 0; x < texWidth; x++) {
    781                         img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
    782                         img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
    783                         img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
    784                     }
    785                 }
    786 
    787                 // Set the test pixels to either white or black.
    788                 for (int j = 0; j < numTestPixels; j++) {
    789                     int x = mTestPixels[j].x;
    790                     int y = mTestPixels[j].y;
    791                     uint8_t value = 0;
    792                     if (j == (i % numTestPixels)) {
    793                         value = 255;
    794                     }
    795                     img[y*stride + x] = value;
    796                 }
    797 
    798                 buf->unlock();
    799                 if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer())
    800                         != NO_ERROR) {
    801                     return false;
    802                 }
    803             }
    804             return false;
    805         }
    806 
    807         sp<ANativeWindow> mANW;
    808         const TestPixel* mTestPixels;
    809     };
    810 
    811     sp<FrameWaiter> fw(new FrameWaiter);
    812     mST->setFrameAvailableListener(fw);
    813 
    814     sp<Thread> pt(new ProducerThread(mANW, testPixels));
    815     pt->run();
    816 
    817     glViewport(0, 0, texWidth, texHeight);
    818 
    819     glClearColor(0.2, 0.2, 0.2, 0.2);
    820     glClear(GL_COLOR_BUFFER_BIT);
    821 
    822     // We wait for the first two frames up front so that the producer will be
    823     // likely to dequeue the buffer that's currently being textured from.
    824     fw->waitForFrame();
    825     fw->waitForFrame();
    826 
    827     for (int i = 0; i < numFrames; i++) {
    828         SCOPED_TRACE(String8::format("frame %d", i).string());
    829 
    830         // We must wait for each frame to come in because if we ever do an
    831         // updateTexImage call that doesn't consume a newly available buffer
    832         // then the producer and consumer will get out of sync, which will cause
    833         // a deadlock.
    834         if (i > 1) {
    835             fw->waitForFrame();
    836         }
    837         mST->updateTexImage();
    838         drawTexture();
    839 
    840         for (int j = 0; j < numTestPixels; j++) {
    841             int x = testPixels[j].x;
    842             int y = testPixels[j].y;
    843             uint8_t value = 0;
    844             if (j == (i % numTestPixels)) {
    845                 // We must y-invert the texture coords
    846                 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
    847             } else {
    848                 // We must y-invert the texture coords
    849                 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
    850             }
    851         }
    852     }
    853 
    854     pt->requestExitAndWait();
    855 }
    856 
    857 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
    858     const int texWidth = 64;
    859     const int texHeight = 66;
    860 
    861     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    862             texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
    863     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    864             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    865 
    866     android_native_buffer_t* anb;
    867     ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
    868     ASSERT_TRUE(anb != NULL);
    869 
    870     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    871     ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
    872 
    873     // Fill the buffer with the a checkerboard pattern
    874     uint8_t* img = NULL;
    875     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    876     fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride());
    877     buf->unlock();
    878     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
    879 
    880     mST->updateTexImage();
    881 
    882     glClearColor(0.2, 0.2, 0.2, 0.2);
    883     glClear(GL_COLOR_BUFFER_BIT);
    884 
    885     glViewport(0, 0, texWidth, texHeight);
    886     drawTexture();
    887 
    888     EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
    889     EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
    890     EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231));
    891     EXPECT_TRUE(checkPixel( 0, 65,  35,  35,  35,  35));
    892 
    893     EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
    894     EXPECT_TRUE(checkPixel(23, 65, 231,  35, 231,  35));
    895     EXPECT_TRUE(checkPixel(19, 40,  35, 231,  35,  35));
    896     EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
    897     EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
    898     EXPECT_TRUE(checkPixel(37, 34,  35, 231, 231, 231));
    899     EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
    900     EXPECT_TRUE(checkPixel(37, 47, 231,  35, 231, 231));
    901     EXPECT_TRUE(checkPixel(25, 38,  35,  35,  35,  35));
    902     EXPECT_TRUE(checkPixel(49,  6,  35, 231,  35,  35));
    903     EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
    904     EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231));
    905     EXPECT_TRUE(checkPixel(10,  6,  35,  35, 231, 231));
    906     EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
    907     EXPECT_TRUE(checkPixel(55, 28,  35,  35, 231,  35));
    908     EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
    909 }
    910 
    911 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
    912     const int texWidth = 64;
    913     const int texHeight = 64;
    914 
    915     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    916             texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
    917     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    918             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
    919 
    920     android_native_buffer_t* anb;
    921     ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
    922     ASSERT_TRUE(anb != NULL);
    923 
    924     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
    925     ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
    926 
    927     // Fill the buffer with the a checkerboard pattern
    928     uint8_t* img = NULL;
    929     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    930     fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride());
    931     buf->unlock();
    932     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
    933 
    934     mST->updateTexImage();
    935 
    936     glClearColor(0.2, 0.2, 0.2, 0.2);
    937     glClear(GL_COLOR_BUFFER_BIT);
    938 
    939     glViewport(0, 0, texWidth, texHeight);
    940     drawTexture();
    941 
    942     EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
    943     EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
    944     EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
    945     EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
    946 
    947     EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
    948     EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
    949     EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
    950     EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
    951     EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
    952     EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
    953     EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
    954     EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
    955     EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
    956     EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
    957     EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
    958     EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
    959     EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
    960     EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
    961     EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
    962     EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
    963 }
    964 
    965 TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
    966     class ProducerThread : public Thread {
    967     public:
    968         ProducerThread(const sp<ANativeWindow>& anw):
    969                 mANW(anw),
    970                 mDequeueError(NO_ERROR) {
    971         }
    972 
    973         virtual ~ProducerThread() {
    974         }
    975 
    976         virtual bool threadLoop() {
    977             Mutex::Autolock lock(mMutex);
    978             ANativeWindowBuffer* anb;
    979 
    980             // Frame 1
    981             if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
    982                 return false;
    983             }
    984             if (anb == NULL) {
    985                 return false;
    986             }
    987             if (mANW->queueBuffer(mANW.get(), anb)
    988                     != NO_ERROR) {
    989                 return false;
    990             }
    991 
    992             // Frame 2
    993             if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
    994                 return false;
    995             }
    996             if (anb == NULL) {
    997                 return false;
    998             }
    999             if (mANW->queueBuffer(mANW.get(), anb)
   1000                     != NO_ERROR) {
   1001                 return false;
   1002             }
   1003 
   1004             // Frame 3 - error expected
   1005             mDequeueError = mANW->dequeueBuffer(mANW.get(), &anb);
   1006             return false;
   1007         }
   1008 
   1009         status_t getDequeueError() {
   1010             Mutex::Autolock lock(mMutex);
   1011             return mDequeueError;
   1012         }
   1013 
   1014     private:
   1015         sp<ANativeWindow> mANW;
   1016         status_t mDequeueError;
   1017         Mutex mMutex;
   1018     };
   1019 
   1020     sp<FrameWaiter> fw(new FrameWaiter);
   1021     mST->setFrameAvailableListener(fw);
   1022     ASSERT_EQ(OK, mST->setSynchronousMode(true));
   1023     ASSERT_EQ(OK, mST->setBufferCountServer(2));
   1024 
   1025     sp<Thread> pt(new ProducerThread(mANW));
   1026     pt->run();
   1027 
   1028     fw->waitForFrame();
   1029     fw->waitForFrame();
   1030 
   1031     // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
   1032     // block waiting for a buffer to become available.
   1033     usleep(100000);
   1034 
   1035     mST->abandon();
   1036 
   1037     pt->requestExitAndWait();
   1038     ASSERT_EQ(NO_INIT,
   1039             reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
   1040 }
   1041 
   1042 TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
   1043     int texHeight = 16;
   1044     ANativeWindowBuffer* anb;
   1045 
   1046     GLint maxTextureSize;
   1047     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
   1048 
   1049     // make sure it works with small textures
   1050     mST->setDefaultBufferSize(16, texHeight);
   1051     EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
   1052     EXPECT_EQ(16, anb->width);
   1053     EXPECT_EQ(texHeight, anb->height);
   1054     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
   1055     EXPECT_EQ(NO_ERROR, mST->updateTexImage());
   1056 
   1057     // make sure it works with GL_MAX_TEXTURE_SIZE
   1058     mST->setDefaultBufferSize(maxTextureSize, texHeight);
   1059     EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
   1060     EXPECT_EQ(maxTextureSize, anb->width);
   1061     EXPECT_EQ(texHeight, anb->height);
   1062     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
   1063     EXPECT_EQ(NO_ERROR, mST->updateTexImage());
   1064 
   1065     // make sure it fails with GL_MAX_TEXTURE_SIZE+1
   1066     mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
   1067     EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
   1068     EXPECT_EQ(maxTextureSize+1, anb->width);
   1069     EXPECT_EQ(texHeight, anb->height);
   1070     EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
   1071     ASSERT_NE(NO_ERROR, mST->updateTexImage());
   1072 }
   1073 
   1074 /*
   1075  * This test fixture is for testing GL -> GL texture streaming.  It creates an
   1076  * EGLSurface and an EGLContext for the image producer to use.
   1077  */
   1078 class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
   1079 protected:
   1080     SurfaceTextureGLToGLTest():
   1081             mProducerEglSurface(EGL_NO_SURFACE),
   1082             mProducerEglContext(EGL_NO_CONTEXT) {
   1083     }
   1084 
   1085     virtual void SetUp() {
   1086         SurfaceTextureGLTest::SetUp();
   1087 
   1088         EGLConfig myConfig = {0};
   1089         EGLint numConfigs = 0;
   1090         EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
   1091                 1, &numConfigs));
   1092         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1093 
   1094         mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
   1095                 mANW.get(), NULL);
   1096         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1097         ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
   1098 
   1099         mProducerEglContext = eglCreateContext(mEglDisplay, myConfig,
   1100                 EGL_NO_CONTEXT, getContextAttribs());
   1101         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1102         ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
   1103     }
   1104 
   1105     virtual void TearDown() {
   1106         if (mProducerEglContext != EGL_NO_CONTEXT) {
   1107             eglDestroyContext(mEglDisplay, mProducerEglContext);
   1108         }
   1109         if (mProducerEglSurface != EGL_NO_SURFACE) {
   1110             eglDestroySurface(mEglDisplay, mProducerEglSurface);
   1111         }
   1112         SurfaceTextureGLTest::TearDown();
   1113     }
   1114 
   1115     EGLSurface mProducerEglSurface;
   1116     EGLContext mProducerEglContext;
   1117 };
   1118 
   1119 TEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
   1120     const int texWidth = 64;
   1121     const int texHeight = 64;
   1122 
   1123     mST->setDefaultBufferSize(texWidth, texHeight);
   1124 
   1125     // Do the producer side of things
   1126     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1127             mProducerEglSurface, mProducerEglContext));
   1128     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1129 
   1130     // This is needed to ensure we pick up a buffer of the correct size.
   1131     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1132 
   1133     glClearColor(0.6, 0.6, 0.6, 0.6);
   1134     glClear(GL_COLOR_BUFFER_BIT);
   1135 
   1136     glEnable(GL_SCISSOR_TEST);
   1137     glScissor(4, 4, 4, 4);
   1138     glClearColor(1.0, 0.0, 0.0, 1.0);
   1139     glClear(GL_COLOR_BUFFER_BIT);
   1140 
   1141     glScissor(24, 48, 4, 4);
   1142     glClearColor(0.0, 1.0, 0.0, 1.0);
   1143     glClear(GL_COLOR_BUFFER_BIT);
   1144 
   1145     glScissor(37, 17, 4, 4);
   1146     glClearColor(0.0, 0.0, 1.0, 1.0);
   1147     glClear(GL_COLOR_BUFFER_BIT);
   1148 
   1149     eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1150 
   1151     // Do the consumer side of things
   1152     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1153             mEglContext));
   1154     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1155 
   1156     glDisable(GL_SCISSOR_TEST);
   1157 
   1158     mST->updateTexImage(); // Skip the first frame, which was empty
   1159     mST->updateTexImage();
   1160 
   1161     glClearColor(0.2, 0.2, 0.2, 0.2);
   1162     glClear(GL_COLOR_BUFFER_BIT);
   1163 
   1164     glViewport(0, 0, texWidth, texHeight);
   1165     drawTexture();
   1166 
   1167     EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
   1168     EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
   1169     EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
   1170     EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
   1171 
   1172     EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
   1173     EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
   1174     EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
   1175     EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
   1176     EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
   1177     EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
   1178     EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
   1179     EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
   1180     EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
   1181     EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
   1182     EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
   1183     EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
   1184     EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
   1185     EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
   1186     EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
   1187     EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
   1188 }
   1189 
   1190 TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) {
   1191     sp<GraphicBuffer> buffers[3];
   1192 
   1193     // This test requires async mode to run on a single thread.
   1194     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1195             mProducerEglSurface, mProducerEglContext));
   1196     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1197     EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
   1198     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1199 
   1200     for (int i = 0; i < 3; i++) {
   1201         // Produce a frame
   1202         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1203                 mProducerEglSurface, mProducerEglContext));
   1204         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1205         glClear(GL_COLOR_BUFFER_BIT);
   1206         eglSwapBuffers(mEglDisplay, mProducerEglSurface);
   1207 
   1208         // Consume a frame
   1209         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1210                 mEglContext));
   1211         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1212         mST->updateTexImage();
   1213         buffers[i] = mST->getCurrentBuffer();
   1214     }
   1215 
   1216     // Destroy the GL texture object to release its ref on buffers[2].
   1217     GLuint texID = TEX_ID;
   1218     glDeleteTextures(1, &texID);
   1219 
   1220     // Destroy the EGLSurface
   1221     EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
   1222     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1223 
   1224     // Release the ref that the SurfaceTexture has on buffers[2].
   1225     mST->abandon();
   1226 
   1227     EXPECT_EQ(1, buffers[0]->getStrongCount());
   1228     EXPECT_EQ(1, buffers[1]->getStrongCount());
   1229 
   1230     // Depending on how lazily the GL driver dequeues buffers, we may end up
   1231     // with either two or three total buffers.  If there are three, make sure
   1232     // the last one was properly down-ref'd.
   1233     if (buffers[2] != buffers[0]) {
   1234         EXPECT_EQ(1, buffers[2]->getStrongCount());
   1235     }
   1236 }
   1237 
   1238 TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
   1239     sp<GraphicBuffer> buffers[3];
   1240 
   1241     // This test requires async mode to run on a single thread.
   1242     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1243             mProducerEglSurface, mProducerEglContext));
   1244     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1245     EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
   1246     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1247 
   1248     for (int i = 0; i < 3; i++) {
   1249         // Produce a frame
   1250         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1251                 mProducerEglSurface, mProducerEglContext));
   1252         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1253         glClear(GL_COLOR_BUFFER_BIT);
   1254         EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
   1255         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1256 
   1257         // Consume a frame
   1258         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1259                 mEglContext));
   1260         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1261         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1262         buffers[i] = mST->getCurrentBuffer();
   1263     }
   1264 
   1265     // Abandon the SurfaceTexture, releasing the ref that the SurfaceTexture has
   1266     // on buffers[2].
   1267     mST->abandon();
   1268 
   1269     // Destroy the GL texture object to release its ref on buffers[2].
   1270     GLuint texID = TEX_ID;
   1271     glDeleteTextures(1, &texID);
   1272 
   1273     // Destroy the EGLSurface.
   1274     EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
   1275     ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1276 
   1277     EXPECT_EQ(1, buffers[0]->getStrongCount());
   1278     EXPECT_EQ(1, buffers[1]->getStrongCount());
   1279 
   1280     // Depending on how lazily the GL driver dequeues buffers, we may end up
   1281     // with either two or three total buffers.  If there are three, make sure
   1282     // the last one was properly down-ref'd.
   1283     if (buffers[2] != buffers[0]) {
   1284         EXPECT_EQ(1, buffers[2]->getStrongCount());
   1285     }
   1286 }
   1287 
   1288 TEST_F(SurfaceTextureGLToGLTest, EglSurfaceDefaultsToSynchronousMode) {
   1289     // This test requires 3 buffers to run on a single thread.
   1290     mST->setBufferCountServer(3);
   1291 
   1292     ASSERT_TRUE(mST->isSynchronousMode());
   1293 
   1294     for (int i = 0; i < 10; i++) {
   1295         // Produce a frame
   1296         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
   1297                 mProducerEglSurface, mProducerEglContext));
   1298         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1299         glClear(GL_COLOR_BUFFER_BIT);
   1300         EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
   1301         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1302 
   1303         // Consume a frame
   1304         EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
   1305                 mEglContext));
   1306         ASSERT_EQ(EGL_SUCCESS, eglGetError());
   1307         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1308     }
   1309 
   1310     ASSERT_TRUE(mST->isSynchronousMode());
   1311 }
   1312 
   1313 /*
   1314  * This test fixture is for testing GL -> GL texture streaming from one thread
   1315  * to another.  It contains functionality to create a producer thread that will
   1316  * perform GL rendering to an ANativeWindow that feeds frames to a
   1317  * SurfaceTexture.  Additionally it supports interlocking the producer and
   1318  * consumer threads so that a specific sequence of calls can be
   1319  * deterministically created by the test.
   1320  *
   1321  * The intended usage is as follows:
   1322  *
   1323  * TEST_F(...) {
   1324  *     class PT : public ProducerThread {
   1325  *         virtual void render() {
   1326  *             ...
   1327  *             swapBuffers();
   1328  *         }
   1329  *     };
   1330  *
   1331  *     runProducerThread(new PT());
   1332  *
   1333  *     // The order of these calls will vary from test to test and may include
   1334  *     // multiple frames and additional operations (e.g. GL rendering from the
   1335  *     // texture).
   1336  *     fc->waitForFrame();
   1337  *     mST->updateTexImage();
   1338  *     fc->finishFrame();
   1339  * }
   1340  *
   1341  */
   1342 class SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest {
   1343 protected:
   1344 
   1345     // ProducerThread is an abstract base class to simplify the creation of
   1346     // OpenGL ES frame producer threads.
   1347     class ProducerThread : public Thread {
   1348     public:
   1349         virtual ~ProducerThread() {
   1350         }
   1351 
   1352         void setEglObjects(EGLDisplay producerEglDisplay,
   1353                 EGLSurface producerEglSurface,
   1354                 EGLContext producerEglContext) {
   1355             mProducerEglDisplay = producerEglDisplay;
   1356             mProducerEglSurface = producerEglSurface;
   1357             mProducerEglContext = producerEglContext;
   1358         }
   1359 
   1360         virtual bool threadLoop() {
   1361             eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface,
   1362                     mProducerEglSurface, mProducerEglContext);
   1363             render();
   1364             eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
   1365                     EGL_NO_CONTEXT);
   1366             return false;
   1367         }
   1368 
   1369     protected:
   1370         virtual void render() = 0;
   1371 
   1372         void swapBuffers() {
   1373             eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface);
   1374         }
   1375 
   1376         EGLDisplay mProducerEglDisplay;
   1377         EGLSurface mProducerEglSurface;
   1378         EGLContext mProducerEglContext;
   1379     };
   1380 
   1381     // FrameCondition is a utility class for interlocking between the producer
   1382     // and consumer threads.  The FrameCondition object should be created and
   1383     // destroyed in the consumer thread only.  The consumer thread should set
   1384     // the FrameCondition as the FrameAvailableListener of the SurfaceTexture,
   1385     // and should call both waitForFrame and finishFrame once for each expected
   1386     // frame.
   1387     //
   1388     // This interlocking relies on the fact that onFrameAvailable gets called
   1389     // synchronously from SurfaceTexture::queueBuffer.
   1390     class FrameCondition : public SurfaceTexture::FrameAvailableListener {
   1391     public:
   1392         FrameCondition():
   1393                 mFrameAvailable(false),
   1394                 mFrameFinished(false) {
   1395         }
   1396 
   1397         // waitForFrame waits for the next frame to arrive.  This should be
   1398         // called from the consumer thread once for every frame expected by the
   1399         // test.
   1400         void waitForFrame() {
   1401             Mutex::Autolock lock(mMutex);
   1402             LOGV("+waitForFrame");
   1403             while (!mFrameAvailable) {
   1404                 mFrameAvailableCondition.wait(mMutex);
   1405             }
   1406             mFrameAvailable = false;
   1407             LOGV("-waitForFrame");
   1408         }
   1409 
   1410         // Allow the producer to return from its swapBuffers call and continue
   1411         // on to produce the next frame.  This should be called by the consumer
   1412         // thread once for every frame expected by the test.
   1413         void finishFrame() {
   1414             Mutex::Autolock lock(mMutex);
   1415             LOGV("+finishFrame");
   1416             mFrameFinished = true;
   1417             mFrameFinishCondition.signal();
   1418             LOGV("-finishFrame");
   1419         }
   1420 
   1421         // This should be called by SurfaceTexture on the producer thread.
   1422         virtual void onFrameAvailable() {
   1423             Mutex::Autolock lock(mMutex);
   1424             LOGV("+onFrameAvailable");
   1425             mFrameAvailable = true;
   1426             mFrameAvailableCondition.signal();
   1427             while (!mFrameFinished) {
   1428                 mFrameFinishCondition.wait(mMutex);
   1429             }
   1430             mFrameFinished = false;
   1431             LOGV("-onFrameAvailable");
   1432         }
   1433 
   1434     protected:
   1435         bool mFrameAvailable;
   1436         bool mFrameFinished;
   1437 
   1438         Mutex mMutex;
   1439         Condition mFrameAvailableCondition;
   1440         Condition mFrameFinishCondition;
   1441     };
   1442 
   1443     virtual void SetUp() {
   1444         SurfaceTextureGLToGLTest::SetUp();
   1445         mFC = new FrameCondition();
   1446         mST->setFrameAvailableListener(mFC);
   1447     }
   1448 
   1449     virtual void TearDown() {
   1450         if (mProducerThread != NULL) {
   1451             mProducerThread->requestExitAndWait();
   1452         }
   1453         mProducerThread.clear();
   1454         mFC.clear();
   1455         SurfaceTextureGLToGLTest::TearDown();
   1456     }
   1457 
   1458     void runProducerThread(const sp<ProducerThread> producerThread) {
   1459         ASSERT_TRUE(mProducerThread == NULL);
   1460         mProducerThread = producerThread;
   1461         producerThread->setEglObjects(mEglDisplay, mProducerEglSurface,
   1462                 mProducerEglContext);
   1463         producerThread->run();
   1464     }
   1465 
   1466     sp<ProducerThread> mProducerThread;
   1467     sp<FrameCondition> mFC;
   1468 };
   1469 
   1470 TEST_F(SurfaceTextureGLThreadToGLTest,
   1471         UpdateTexImageBeforeFrameFinishedCompletes) {
   1472     class PT : public ProducerThread {
   1473         virtual void render() {
   1474             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   1475             glClear(GL_COLOR_BUFFER_BIT);
   1476             swapBuffers();
   1477         }
   1478     };
   1479 
   1480     runProducerThread(new PT());
   1481 
   1482     mFC->waitForFrame();
   1483     mST->updateTexImage();
   1484     mFC->finishFrame();
   1485 
   1486     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
   1487 }
   1488 
   1489 TEST_F(SurfaceTextureGLThreadToGLTest,
   1490         UpdateTexImageAfterFrameFinishedCompletes) {
   1491     class PT : public ProducerThread {
   1492         virtual void render() {
   1493             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   1494             glClear(GL_COLOR_BUFFER_BIT);
   1495             swapBuffers();
   1496         }
   1497     };
   1498 
   1499     runProducerThread(new PT());
   1500 
   1501     mFC->waitForFrame();
   1502     mFC->finishFrame();
   1503     mST->updateTexImage();
   1504 
   1505     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
   1506 }
   1507 
   1508 TEST_F(SurfaceTextureGLThreadToGLTest,
   1509         RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
   1510     enum { NUM_ITERATIONS = 1024 };
   1511 
   1512     class PT : public ProducerThread {
   1513         virtual void render() {
   1514             for (int i = 0; i < NUM_ITERATIONS; i++) {
   1515                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   1516                 glClear(GL_COLOR_BUFFER_BIT);
   1517                 LOGV("+swapBuffers");
   1518                 swapBuffers();
   1519                 LOGV("-swapBuffers");
   1520             }
   1521         }
   1522     };
   1523 
   1524     runProducerThread(new PT());
   1525 
   1526     for (int i = 0; i < NUM_ITERATIONS; i++) {
   1527         mFC->waitForFrame();
   1528         LOGV("+updateTexImage");
   1529         mST->updateTexImage();
   1530         LOGV("-updateTexImage");
   1531         mFC->finishFrame();
   1532 
   1533         // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
   1534     }
   1535 }
   1536 
   1537 TEST_F(SurfaceTextureGLThreadToGLTest,
   1538         RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
   1539     enum { NUM_ITERATIONS = 1024 };
   1540 
   1541     class PT : public ProducerThread {
   1542         virtual void render() {
   1543             for (int i = 0; i < NUM_ITERATIONS; i++) {
   1544                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   1545                 glClear(GL_COLOR_BUFFER_BIT);
   1546                 LOGV("+swapBuffers");
   1547                 swapBuffers();
   1548                 LOGV("-swapBuffers");
   1549             }
   1550         }
   1551     };
   1552 
   1553     runProducerThread(new PT());
   1554 
   1555     for (int i = 0; i < NUM_ITERATIONS; i++) {
   1556         mFC->waitForFrame();
   1557         mFC->finishFrame();
   1558         LOGV("+updateTexImage");
   1559         mST->updateTexImage();
   1560         LOGV("-updateTexImage");
   1561 
   1562         // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
   1563     }
   1564 }
   1565 
   1566 // XXX: This test is disabled because it is currently hanging on some devices.
   1567 TEST_F(SurfaceTextureGLThreadToGLTest,
   1568         DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
   1569     enum { NUM_ITERATIONS = 64 };
   1570 
   1571     class PT : public ProducerThread {
   1572         virtual void render() {
   1573             for (int i = 0; i < NUM_ITERATIONS; i++) {
   1574                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
   1575                 glClear(GL_COLOR_BUFFER_BIT);
   1576                 LOGV("+swapBuffers");
   1577                 swapBuffers();
   1578                 LOGV("-swapBuffers");
   1579             }
   1580         }
   1581     };
   1582 
   1583     ASSERT_EQ(OK, mST->setSynchronousMode(true));
   1584     ASSERT_EQ(OK, mST->setBufferCountServer(2));
   1585 
   1586     runProducerThread(new PT());
   1587 
   1588     // Allow three frames to be rendered and queued before starting the
   1589     // rendering in this thread.  For the latter two frames we don't call
   1590     // updateTexImage so the next dequeue from the producer thread will block
   1591     // waiting for a frame to become available.
   1592     mFC->waitForFrame();
   1593     mFC->finishFrame();
   1594 
   1595     // We must call updateTexImage to consume the first frame so that the
   1596     // SurfaceTexture is able to reduce the buffer count to 2.  This is because
   1597     // the GL driver may dequeue a buffer when the EGLSurface is created, and
   1598     // that happens before we call setBufferCountServer.  It's possible that the
   1599     // driver does not dequeue a buffer at EGLSurface creation time, so we
   1600     // cannot rely on this to cause the second dequeueBuffer call to block.
   1601     mST->updateTexImage();
   1602 
   1603     mFC->waitForFrame();
   1604     mFC->finishFrame();
   1605     mFC->waitForFrame();
   1606     mFC->finishFrame();
   1607 
   1608     // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
   1609     // block waiting for a buffer to become available.
   1610     usleep(100000);
   1611 
   1612     // Render and present a number of images.  This thread should not be blocked
   1613     // by the fact that the producer thread is blocking in dequeue.
   1614     for (int i = 0; i < NUM_ITERATIONS; i++) {
   1615         glClear(GL_COLOR_BUFFER_BIT);
   1616         eglSwapBuffers(mEglDisplay, mEglSurface);
   1617     }
   1618 
   1619     // Consume the two pending buffers to unblock the producer thread.
   1620     mST->updateTexImage();
   1621     mST->updateTexImage();
   1622 
   1623     // Consume the remaining buffers from the producer thread.
   1624     for (int i = 0; i < NUM_ITERATIONS-3; i++) {
   1625         mFC->waitForFrame();
   1626         mFC->finishFrame();
   1627         LOGV("+updateTexImage");
   1628         mST->updateTexImage();
   1629         LOGV("-updateTexImage");
   1630     }
   1631 }
   1632 
   1633 class SurfaceTextureFBOTest : public SurfaceTextureGLTest {
   1634 protected:
   1635 
   1636     virtual void SetUp() {
   1637         SurfaceTextureGLTest::SetUp();
   1638 
   1639         glGenFramebuffers(1, &mFbo);
   1640         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   1641 
   1642         glGenTextures(1, &mFboTex);
   1643         glBindTexture(GL_TEXTURE_2D, mFboTex);
   1644         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSurfaceWidth(),
   1645                 getSurfaceHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
   1646         glBindTexture(GL_TEXTURE_2D, 0);
   1647         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   1648 
   1649         glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
   1650         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
   1651                 GL_TEXTURE_2D, mFboTex, 0);
   1652         glBindFramebuffer(GL_FRAMEBUFFER, 0);
   1653         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
   1654     }
   1655 
   1656     virtual void TearDown() {
   1657         SurfaceTextureGLTest::TearDown();
   1658 
   1659         glDeleteTextures(1, &mFboTex);
   1660         glDeleteFramebuffers(1, &mFbo);
   1661     }
   1662 
   1663     GLuint mFbo;
   1664     GLuint mFboTex;
   1665 };
   1666 
   1667 // This test is intended to verify that proper synchronization is done when
   1668 // rendering into an FBO.
   1669 TEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
   1670     const int texWidth = 64;
   1671     const int texHeight = 64;
   1672 
   1673     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
   1674             texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
   1675     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
   1676             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
   1677 
   1678     android_native_buffer_t* anb;
   1679     ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
   1680     ASSERT_TRUE(anb != NULL);
   1681 
   1682     sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
   1683     ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
   1684 
   1685     // Fill the buffer with green
   1686     uint8_t* img = NULL;
   1687     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
   1688     fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255,
   1689             0, 255);
   1690     buf->unlock();
   1691     ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
   1692 
   1693     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1694 
   1695     glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
   1696     drawTexture();
   1697     glBindFramebuffer(GL_FRAMEBUFFER, 0);
   1698 
   1699     for (int i = 0; i < 4; i++) {
   1700         SCOPED_TRACE(String8::format("frame %d", i).string());
   1701 
   1702         ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
   1703         ASSERT_TRUE(anb != NULL);
   1704 
   1705         buf = new GraphicBuffer(anb, false);
   1706         ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(),
   1707                 buf->getNativeBuffer()));
   1708 
   1709         // Fill the buffer with red
   1710         ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
   1711                 (void**)(&img)));
   1712         fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0,
   1713                 0, 255);
   1714         ASSERT_EQ(NO_ERROR, buf->unlock());
   1715         ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
   1716                 buf->getNativeBuffer()));
   1717 
   1718         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
   1719 
   1720         drawTexture();
   1721 
   1722         EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255));
   1723     }
   1724 
   1725     glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
   1726 
   1727     EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255));
   1728 }
   1729 
   1730 } // namespace android
   1731