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