| Dan Stoza | cb1fcde | 2013-12-03 12:37:36 -0800 | [diff] [blame] | 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 | } // namespace android |