Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2013 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 "SurfaceTextureMultiContextGL_test"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include "SurfaceTextureMultiContextGL.h"
     21 
     22 #include "FillBuffer.h"
     23 
     24 #include <GLES/glext.h>
     25 
     26 namespace android {
     27 
     28 TEST_F(SurfaceTextureMultiContextGLTest, UpdateFromMultipleContextsFails) {
     29     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
     30 
     31     // Latch the texture contents on the primary context.
     32     mFW->waitForFrame();
     33     ASSERT_EQ(OK, mST->updateTexImage());
     34 
     35     // Attempt to latch the texture on the secondary context.
     36     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
     37             mSecondEglContext));
     38     ASSERT_EQ(EGL_SUCCESS, eglGetError());
     39     ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
     40 }
     41 
     42 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextSucceeds) {
     43     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
     44 
     45     // Latch the texture contents on the primary context.
     46     mFW->waitForFrame();
     47     ASSERT_EQ(OK, mST->updateTexImage());
     48 
     49     // Detach from the primary context.
     50     ASSERT_EQ(OK, mST->detachFromContext());
     51 
     52     // Check that the GL texture was deleted.
     53     EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
     54 }
     55 
     56 TEST_F(SurfaceTextureMultiContextGLTest,
     57         DetachFromContextSucceedsAfterProducerDisconnect) {
     58     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
     59 
     60     // Latch the texture contents on the primary context.
     61     mFW->waitForFrame();
     62     ASSERT_EQ(OK, mST->updateTexImage());
     63 
     64     // Detach from the primary context.
     65     native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
     66     ASSERT_EQ(OK, mST->detachFromContext());
     67 
     68     // Check that the GL texture was deleted.
     69     EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
     70 }
     71 
     72 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenAbandoned) {
     73     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
     74 
     75     // Latch the texture contents on the primary context.
     76     mFW->waitForFrame();
     77     ASSERT_EQ(OK, mST->updateTexImage());
     78 
     79     // Attempt to detach from the primary context.
     80     mST->abandon();
     81     ASSERT_EQ(NO_INIT, mST->detachFromContext());
     82 }
     83 
     84 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenDetached) {
     85     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
     86 
     87     // Latch the texture contents on the primary context.
     88     mFW->waitForFrame();
     89     ASSERT_EQ(OK, mST->updateTexImage());
     90 
     91     // Detach from the primary context.
     92     ASSERT_EQ(OK, mST->detachFromContext());
     93 
     94     // Attempt to detach from the primary context again.
     95     ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
     96 }
     97 
     98 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoDisplay) {
     99     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    100 
    101     // Latch the texture contents on the primary context.
    102     mFW->waitForFrame();
    103     ASSERT_EQ(OK, mST->updateTexImage());
    104 
    105     // Make there be no current display.
    106     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
    107             EGL_NO_CONTEXT));
    108     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    109 
    110     // Attempt to detach from the primary context.
    111     ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
    112 }
    113 
    114 TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoContext) {
    115     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    116 
    117     // Latch the texture contents on the primary context.
    118     mFW->waitForFrame();
    119     ASSERT_EQ(OK, mST->updateTexImage());
    120 
    121     // Make current context be incorrect.
    122     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    123             mSecondEglContext));
    124     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    125 
    126     // Attempt to detach from the primary context.
    127     ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
    128 }
    129 
    130 TEST_F(SurfaceTextureMultiContextGLTest, UpdateTexImageFailsWhenDetached) {
    131     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    132 
    133     // Detach from the primary context.
    134     ASSERT_EQ(OK, mST->detachFromContext());
    135 
    136     // Attempt to latch the texture contents on the primary context.
    137     mFW->waitForFrame();
    138     ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
    139 }
    140 
    141 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceeds) {
    142     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    143 
    144     // Latch the texture contents on the primary context.
    145     mFW->waitForFrame();
    146     ASSERT_EQ(OK, mST->updateTexImage());
    147 
    148     // Detach from the primary context.
    149     ASSERT_EQ(OK, mST->detachFromContext());
    150 
    151     // Attach to the secondary context.
    152     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    153             mSecondEglContext));
    154     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
    155 
    156     // Verify that the texture object was created and bound.
    157     GLint texBinding = -1;
    158     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
    159     EXPECT_EQ(SECOND_TEX_ID, texBinding);
    160 
    161     // Try to use the texture from the secondary context.
    162     glClearColor(0.2, 0.2, 0.2, 0.2);
    163     glClear(GL_COLOR_BUFFER_BIT);
    164     glViewport(0, 0, 1, 1);
    165     mSecondTextureRenderer->drawTexture();
    166     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
    167     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    168 }
    169 
    170 TEST_F(SurfaceTextureMultiContextGLTest,
    171         AttachToContextSucceedsAfterProducerDisconnect) {
    172     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    173 
    174     // Latch the texture contents on the primary context.
    175     mFW->waitForFrame();
    176     ASSERT_EQ(OK, mST->updateTexImage());
    177 
    178     // Detach from the primary context.
    179     native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
    180     ASSERT_EQ(OK, mST->detachFromContext());
    181 
    182     // Attach to the secondary context.
    183     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    184             mSecondEglContext));
    185     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
    186 
    187     // Verify that the texture object was created and bound.
    188     GLint texBinding = -1;
    189     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
    190     EXPECT_EQ(SECOND_TEX_ID, texBinding);
    191 
    192     // Try to use the texture from the secondary context.
    193     glClearColor(0.2, 0.2, 0.2, 0.2);
    194     glClear(GL_COLOR_BUFFER_BIT);
    195     glViewport(0, 0, 1, 1);
    196     mSecondTextureRenderer->drawTexture();
    197     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    198     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
    199 }
    200 
    201 TEST_F(SurfaceTextureMultiContextGLTest,
    202         AttachToContextSucceedsBeforeUpdateTexImage) {
    203     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    204 
    205     // Detach from the primary context.
    206     native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
    207     ASSERT_EQ(OK, mST->detachFromContext());
    208 
    209     // Attach to the secondary context.
    210     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    211             mSecondEglContext));
    212     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
    213 
    214     // Verify that the texture object was created and bound.
    215     GLint texBinding = -1;
    216     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
    217     EXPECT_EQ(SECOND_TEX_ID, texBinding);
    218 
    219     // Latch the texture contents on the primary context.
    220     mFW->waitForFrame();
    221     ASSERT_EQ(OK, mST->updateTexImage());
    222 
    223     // Try to use the texture from the secondary context.
    224     glClearColor(0.2, 0.2, 0.2, 0.2);
    225     glClear(GL_COLOR_BUFFER_BIT);
    226     glViewport(0, 0, 1, 1);
    227     mSecondTextureRenderer->drawTexture();
    228     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    229     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
    230 }
    231 
    232 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAbandoned) {
    233     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    234 
    235     // Latch the texture contents on the primary context.
    236     mFW->waitForFrame();
    237     ASSERT_EQ(OK, mST->updateTexImage());
    238 
    239     // Detach from the primary context.
    240     ASSERT_EQ(OK, mST->detachFromContext());
    241 
    242     // Attempt to attach to the secondary context.
    243     mST->abandon();
    244 
    245     // Attempt to attach to the primary context.
    246     ASSERT_EQ(NO_INIT, mST->attachToContext(SECOND_TEX_ID));
    247 }
    248 
    249 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAttached) {
    250     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    251 
    252     // Latch the texture contents on the primary context.
    253     mFW->waitForFrame();
    254     ASSERT_EQ(OK, mST->updateTexImage());
    255 
    256     // Attempt to attach to the primary context.
    257     ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
    258 }
    259 
    260 TEST_F(SurfaceTextureMultiContextGLTest,
    261         AttachToContextFailsWhenAttachedBeforeUpdateTexImage) {
    262     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    263 
    264     // Attempt to attach to the primary context.
    265     ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
    266 }
    267 
    268 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWithNoDisplay) {
    269     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    270 
    271     // Latch the texture contents on the primary context.
    272     mFW->waitForFrame();
    273     ASSERT_EQ(OK, mST->updateTexImage());
    274 
    275     // Detach from the primary context.
    276     ASSERT_EQ(OK, mST->detachFromContext());
    277 
    278     // Make there be no current display.
    279     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
    280             EGL_NO_CONTEXT));
    281     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    282 
    283     // Attempt to attach with no context current.
    284     ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
    285 }
    286 
    287 TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceedsTwice) {
    288     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    289 
    290     // Latch the texture contents on the primary context.
    291     mFW->waitForFrame();
    292     ASSERT_EQ(OK, mST->updateTexImage());
    293 
    294     // Detach from the primary context.
    295     ASSERT_EQ(OK, mST->detachFromContext());
    296 
    297     // Attach to the secondary context.
    298     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    299             mSecondEglContext));
    300     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
    301 
    302     // Detach from the secondary context.
    303     ASSERT_EQ(OK, mST->detachFromContext());
    304 
    305     // Attach to the tertiary context.
    306     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    307             mThirdEglContext));
    308     ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
    309 
    310     // Verify that the texture object was created and bound.
    311     GLint texBinding = -1;
    312     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
    313     EXPECT_EQ(THIRD_TEX_ID, texBinding);
    314 
    315     // Try to use the texture from the tertiary context.
    316     glClearColor(0.2, 0.2, 0.2, 0.2);
    317     glClear(GL_COLOR_BUFFER_BIT);
    318     glViewport(0, 0, 1, 1);
    319     mThirdTextureRenderer->drawTexture();
    320     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    321     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
    322 }
    323 
    324 TEST_F(SurfaceTextureMultiContextGLTest,
    325         AttachToContextSucceedsTwiceBeforeUpdateTexImage) {
    326     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    327 
    328     // Detach from the primary context.
    329     ASSERT_EQ(OK, mST->detachFromContext());
    330 
    331     // Attach to the secondary context.
    332     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    333             mSecondEglContext));
    334     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
    335 
    336     // Detach from the secondary context.
    337     ASSERT_EQ(OK, mST->detachFromContext());
    338 
    339     // Attach to the tertiary context.
    340     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    341             mThirdEglContext));
    342     ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
    343 
    344     // Verify that the texture object was created and bound.
    345     GLint texBinding = -1;
    346     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
    347     EXPECT_EQ(THIRD_TEX_ID, texBinding);
    348 
    349     // Latch the texture contents on the tertiary context.
    350     mFW->waitForFrame();
    351     ASSERT_EQ(OK, mST->updateTexImage());
    352 
    353     // Try to use the texture from the tertiary context.
    354     glClearColor(0.2, 0.2, 0.2, 0.2);
    355     glClear(GL_COLOR_BUFFER_BIT);
    356     glViewport(0, 0, 1, 1);
    357     mThirdTextureRenderer->drawTexture();
    358     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    359     ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
    360 }
    361 
    362 TEST_F(SurfaceTextureMultiContextGLTest,
    363         UpdateTexImageSucceedsForBufferConsumedBeforeDetach) {
    364     ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
    365 
    366     // produce two frames and consume them both on the primary context
    367     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    368     mFW->waitForFrame();
    369     ASSERT_EQ(OK, mST->updateTexImage());
    370 
    371     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    372     mFW->waitForFrame();
    373     ASSERT_EQ(OK, mST->updateTexImage());
    374 
    375     // produce one more frame
    376     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    377 
    378     // Detach from the primary context and attach to the secondary context
    379     ASSERT_EQ(OK, mST->detachFromContext());
    380     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    381             mSecondEglContext));
    382     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
    383 
    384     // Consume final frame on secondary context
    385     mFW->waitForFrame();
    386     ASSERT_EQ(OK, mST->updateTexImage());
    387 }
    388 
    389 TEST_F(SurfaceTextureMultiContextGLTest,
    390        AttachAfterDisplayTerminatedSucceeds) {
    391     ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
    392 
    393     // produce two frames and consume them both on the primary context
    394     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    395     mFW->waitForFrame();
    396     ASSERT_EQ(OK, mST->updateTexImage());
    397 
    398     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    399     mFW->waitForFrame();
    400     ASSERT_EQ(OK, mST->updateTexImage());
    401 
    402     // produce one more frame
    403     ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    404 
    405     // Detach from the primary context.
    406     ASSERT_EQ(OK, mST->releaseTexImage());
    407     ASSERT_EQ(OK, mST->detachFromContext());
    408 
    409     // Terminate and then initialize the display. All contexts, surfaces
    410     // and images are invalid at this point.
    411     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    412     ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
    413     EGLint majorVersion = 0;
    414     EGLint minorVersion = 0;
    415     EXPECT_TRUE(eglTerminate(display));
    416     EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
    417     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    418 
    419     // The surface is invalid so create it again.
    420     EGLint pbufferAttribs[] = {
    421         EGL_WIDTH, 64,
    422         EGL_HEIGHT, 64,
    423         EGL_NONE };
    424     mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
    425             pbufferAttribs);
    426 
    427     // The second context is invalid so create it again.
    428     mSecondEglContext = eglCreateContext(mEglDisplay, mGlConfig,
    429             EGL_NO_CONTEXT, getContextAttribs());
    430     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    431     ASSERT_NE(EGL_NO_CONTEXT, mSecondEglContext);
    432 
    433     ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    434             mSecondEglContext));
    435     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    436 
    437     // Now attach to and consume final frame on secondary context.
    438     ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
    439     mFW->waitForFrame();
    440     ASSERT_EQ(OK, mST->updateTexImage());
    441 }
    442 
    443 
    444 } // namespace android
    445