xref: /aosp_15_r20/external/angle/src/tests/capture_tests/CapturedTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2023 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "util/random_utils.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "util/test_utils.h"
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker namespace
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker class CapturedTest : public ANGLETest<>
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker   protected:
CapturedTest()21*8975f5c5SAndroid Build Coastguard Worker     CapturedTest()
22*8975f5c5SAndroid Build Coastguard Worker     {
23*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(128);
24*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(128);
25*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
26*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
27*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
28*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
29*8975f5c5SAndroid Build Coastguard Worker         setConfigDepthBits(24);
30*8975f5c5SAndroid Build Coastguard Worker         setConfigStencilBits(8);
31*8975f5c5SAndroid Build Coastguard Worker     }
32*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()33*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
34*8975f5c5SAndroid Build Coastguard Worker     {
35*8975f5c5SAndroid Build Coastguard Worker         // Calls not captured because we setup Start frame to MEC.
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker         // TODO: why are these framebuffers not showing up in the capture?
38*8975f5c5SAndroid Build Coastguard Worker 
39*8975f5c5SAndroid Build Coastguard Worker         mFBOs.resize(2, 0);
40*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(2, mFBOs.data());
41*8975f5c5SAndroid Build Coastguard Worker     }
42*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()43*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
44*8975f5c5SAndroid Build Coastguard Worker     {
45*8975f5c5SAndroid Build Coastguard Worker         // Not reached during capture as we hit the End frame earlier.
46*8975f5c5SAndroid Build Coastguard Worker 
47*8975f5c5SAndroid Build Coastguard Worker         if (!mFBOs.empty())
48*8975f5c5SAndroid Build Coastguard Worker         {
49*8975f5c5SAndroid Build Coastguard Worker             glDeleteFramebuffers(static_cast<GLsizei>(mFBOs.size()), mFBOs.data());
50*8975f5c5SAndroid Build Coastguard Worker         }
51*8975f5c5SAndroid Build Coastguard Worker     }
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLuint> mFBOs;
54*8975f5c5SAndroid Build Coastguard Worker };
55*8975f5c5SAndroid Build Coastguard Worker 
56*8975f5c5SAndroid Build Coastguard Worker class MultiFrame
57*8975f5c5SAndroid Build Coastguard Worker {
58*8975f5c5SAndroid Build Coastguard Worker   public:
testSetUp()59*8975f5c5SAndroid Build Coastguard Worker     void testSetUp()
60*8975f5c5SAndroid Build Coastguard Worker     {
61*8975f5c5SAndroid Build Coastguard Worker         constexpr char kInactiveVS[] = R"(precision highp float;
62*8975f5c5SAndroid Build Coastguard Worker void main(void) {
63*8975f5c5SAndroid Build Coastguard Worker    gl_Position = vec4(0.5, 0.5, 0.5, 1.0);
64*8975f5c5SAndroid Build Coastguard Worker })";
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker         static constexpr char kInactiveDeferredVS[] = R"(attribute vec4 a_position;
67*8975f5c5SAndroid Build Coastguard Worker attribute vec2 a_texCoord;
68*8975f5c5SAndroid Build Coastguard Worker varying vec2 v_texCoord;
69*8975f5c5SAndroid Build Coastguard Worker void main()
70*8975f5c5SAndroid Build Coastguard Worker {
71*8975f5c5SAndroid Build Coastguard Worker     gl_Position = a_position;
72*8975f5c5SAndroid Build Coastguard Worker     v_texCoord = a_texCoord;
73*8975f5c5SAndroid Build Coastguard Worker })";
74*8975f5c5SAndroid Build Coastguard Worker 
75*8975f5c5SAndroid Build Coastguard Worker         static constexpr char kInactiveDeferredFS[] = R"(precision mediump float;
76*8975f5c5SAndroid Build Coastguard Worker varying vec2 v_texCoord;
77*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D s_texture;
78*8975f5c5SAndroid Build Coastguard Worker void main()
79*8975f5c5SAndroid Build Coastguard Worker {
80*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = vec4(0.4, 0.4, 0.4, 1.0);
81*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = texture2D(s_texture, v_texCoord);
82*8975f5c5SAndroid Build Coastguard Worker })";
83*8975f5c5SAndroid Build Coastguard Worker 
84*8975f5c5SAndroid Build Coastguard Worker         static constexpr char kActiveDeferredVS[] = R"(attribute vec4 a_position;
85*8975f5c5SAndroid Build Coastguard Worker attribute vec2 a_texCoord;
86*8975f5c5SAndroid Build Coastguard Worker varying vec2 v_texCoord;
87*8975f5c5SAndroid Build Coastguard Worker void main()
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker     gl_Position = a_position;
90*8975f5c5SAndroid Build Coastguard Worker     v_texCoord = a_texCoord;
91*8975f5c5SAndroid Build Coastguard Worker })";
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker         // Create shaders, program but defer compiling & linking, use before capture starts
94*8975f5c5SAndroid Build Coastguard Worker         // (Inactive)
95*8975f5c5SAndroid Build Coastguard Worker         lateLinkTestVertShaderInactive                   = glCreateShader(GL_VERTEX_SHADER);
96*8975f5c5SAndroid Build Coastguard Worker         const char *lateLinkTestVsSourceArrayInactive[1] = {kInactiveDeferredVS};
97*8975f5c5SAndroid Build Coastguard Worker         glShaderSource(lateLinkTestVertShaderInactive, 1, lateLinkTestVsSourceArrayInactive, 0);
98*8975f5c5SAndroid Build Coastguard Worker         lateLinkTestFragShaderInactive                   = glCreateShader(GL_FRAGMENT_SHADER);
99*8975f5c5SAndroid Build Coastguard Worker         const char *lateLinkTestFsSourceArrayInactive[1] = {kInactiveDeferredFS};
100*8975f5c5SAndroid Build Coastguard Worker         glShaderSource(lateLinkTestFragShaderInactive, 1, lateLinkTestFsSourceArrayInactive, 0);
101*8975f5c5SAndroid Build Coastguard Worker         lateLinkTestProgramInactive = glCreateProgram();
102*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(lateLinkTestProgramInactive, lateLinkTestVertShaderInactive);
103*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(lateLinkTestProgramInactive, lateLinkTestFragShaderInactive);
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker         // Create inactive program having shader shared with deferred linked program
106*8975f5c5SAndroid Build Coastguard Worker         glCompileShader(lateLinkTestVertShaderInactive);
107*8975f5c5SAndroid Build Coastguard Worker         glCompileShader(lateLinkTestFragShaderInactive);
108*8975f5c5SAndroid Build Coastguard Worker         glLinkProgram(lateLinkTestProgramInactive);
109*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
110*8975f5c5SAndroid Build Coastguard Worker 
111*8975f5c5SAndroid Build Coastguard Worker         // Create vertex shader and program but defer compiling & linking until capture time
112*8975f5c5SAndroid Build Coastguard Worker         // (Active) Use fragment shader attached to inactive program
113*8975f5c5SAndroid Build Coastguard Worker         lateLinkTestVertShaderActive                   = glCreateShader(GL_VERTEX_SHADER);
114*8975f5c5SAndroid Build Coastguard Worker         const char *lateLinkTestVsSourceArrayActive[1] = {kActiveDeferredVS};
115*8975f5c5SAndroid Build Coastguard Worker         glShaderSource(lateLinkTestVertShaderActive, 1, lateLinkTestVsSourceArrayActive, 0);
116*8975f5c5SAndroid Build Coastguard Worker         lateLinkTestProgramActive = glCreateProgram();
117*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(lateLinkTestProgramActive, lateLinkTestVertShaderActive);
118*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(lateLinkTestProgramActive, lateLinkTestFragShaderInactive);
119*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker         // Create shader that is unused during capture
122*8975f5c5SAndroid Build Coastguard Worker         inactiveProgram                    = glCreateProgram();
123*8975f5c5SAndroid Build Coastguard Worker         inactiveShader                     = glCreateShader(GL_VERTEX_SHADER);
124*8975f5c5SAndroid Build Coastguard Worker         const char *inactiveSourceArray[1] = {kInactiveVS};
125*8975f5c5SAndroid Build Coastguard Worker         glShaderSource(inactiveShader, 1, inactiveSourceArray, 0);
126*8975f5c5SAndroid Build Coastguard Worker         glCompileShader(inactiveShader);
127*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(inactiveProgram, inactiveShader);
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker         // Create Shader Program before capture begins to use during capture
130*8975f5c5SAndroid Build Coastguard Worker         activeBeforeProgram                = glCreateProgram();
131*8975f5c5SAndroid Build Coastguard Worker         activeBeforeVertShader             = glCreateShader(GL_VERTEX_SHADER);
132*8975f5c5SAndroid Build Coastguard Worker         activeBeforeFragShader             = glCreateShader(GL_FRAGMENT_SHADER);
133*8975f5c5SAndroid Build Coastguard Worker         const char *activeVsSourceArray[1] = {kActiveVS};
134*8975f5c5SAndroid Build Coastguard Worker         glShaderSource(activeBeforeVertShader, 1, activeVsSourceArray, 0);
135*8975f5c5SAndroid Build Coastguard Worker         glCompileShader(activeBeforeVertShader);
136*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(activeBeforeProgram, activeBeforeVertShader);
137*8975f5c5SAndroid Build Coastguard Worker         const char *activeFsSourceArray[1] = {kActiveFS};
138*8975f5c5SAndroid Build Coastguard Worker         glShaderSource(activeBeforeFragShader, 1, activeFsSourceArray, 0);
139*8975f5c5SAndroid Build Coastguard Worker         glCompileShader(activeBeforeFragShader);
140*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(activeBeforeProgram, activeBeforeFragShader);
141*8975f5c5SAndroid Build Coastguard Worker         glLinkProgram(activeBeforeProgram);
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker         // Get the attr/sampler locations
144*8975f5c5SAndroid Build Coastguard Worker         mPositionLoc = glGetAttribLocation(activeBeforeProgram, "a_position");
145*8975f5c5SAndroid Build Coastguard Worker         mTexCoordLoc = glGetAttribLocation(activeBeforeProgram, "a_texCoord");
146*8975f5c5SAndroid Build Coastguard Worker         mSamplerLoc  = glGetUniformLocation(activeBeforeProgram, "s_texture");
147*8975f5c5SAndroid Build Coastguard Worker         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker         // Bind the texture object before capture begins
150*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &textureNeverBound);
151*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &textureBoundBeforeCapture);
152*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, textureBoundBeforeCapture);
153*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
154*8975f5c5SAndroid Build Coastguard Worker 
155*8975f5c5SAndroid Build Coastguard Worker         const size_t width                 = 2;
156*8975f5c5SAndroid Build Coastguard Worker         const size_t height                = 2;
157*8975f5c5SAndroid Build Coastguard Worker         GLubyte pixels[width * height * 3] = {
158*8975f5c5SAndroid Build Coastguard Worker             255, 0,   0,    // Red
159*8975f5c5SAndroid Build Coastguard Worker             0,   255, 0,    // Green
160*8975f5c5SAndroid Build Coastguard Worker             0,   0,   255,  // Blue
161*8975f5c5SAndroid Build Coastguard Worker             255, 255, 0,    // Yellow
162*8975f5c5SAndroid Build Coastguard Worker         };
163*8975f5c5SAndroid Build Coastguard Worker         // Populate the pre-capture bound texture
164*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
165*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
166*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
167*8975f5c5SAndroid Build Coastguard Worker     }
168*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()169*8975f5c5SAndroid Build Coastguard Worker     void testTearDown()
170*8975f5c5SAndroid Build Coastguard Worker     {
171*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &textureNeverBound);
172*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &textureBoundBeforeCapture);
173*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(inactiveProgram);
174*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(activeBeforeProgram);
175*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(inactiveShader);
176*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(activeBeforeVertShader);
177*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(activeBeforeFragShader);
178*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(lateLinkTestProgramInactive);
179*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(lateLinkTestProgramActive);
180*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(lateLinkTestVertShaderInactive);
181*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(lateLinkTestFragShaderInactive);
182*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(lateLinkTestVertShaderActive);
183*8975f5c5SAndroid Build Coastguard Worker     }
184*8975f5c5SAndroid Build Coastguard Worker 
185*8975f5c5SAndroid Build Coastguard Worker     static constexpr char kActiveVS[] = R"(attribute vec4 a_position;
186*8975f5c5SAndroid Build Coastguard Worker attribute vec2 a_texCoord;
187*8975f5c5SAndroid Build Coastguard Worker varying vec2 v_texCoord;
188*8975f5c5SAndroid Build Coastguard Worker void main()
189*8975f5c5SAndroid Build Coastguard Worker {
190*8975f5c5SAndroid Build Coastguard Worker     gl_Position = a_position;
191*8975f5c5SAndroid Build Coastguard Worker     v_texCoord = a_texCoord;
192*8975f5c5SAndroid Build Coastguard Worker })";
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker     static constexpr char kActiveFS[] = R"(precision mediump float;
195*8975f5c5SAndroid Build Coastguard Worker varying vec2 v_texCoord;
196*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D s_texture;
197*8975f5c5SAndroid Build Coastguard Worker void main()
198*8975f5c5SAndroid Build Coastguard Worker {
199*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = texture2D(s_texture, v_texCoord);
200*8975f5c5SAndroid Build Coastguard Worker })";
201*8975f5c5SAndroid Build Coastguard Worker 
202*8975f5c5SAndroid Build Coastguard Worker     void frame1();
203*8975f5c5SAndroid Build Coastguard Worker     void frame2();
204*8975f5c5SAndroid Build Coastguard Worker     void frame3();
205*8975f5c5SAndroid Build Coastguard Worker     void frame4();
206*8975f5c5SAndroid Build Coastguard Worker 
207*8975f5c5SAndroid Build Coastguard Worker     // For testing deferred compile/link
208*8975f5c5SAndroid Build Coastguard Worker     GLuint lateLinkTestVertShaderInactive;
209*8975f5c5SAndroid Build Coastguard Worker     GLuint lateLinkTestFragShaderInactive;
210*8975f5c5SAndroid Build Coastguard Worker     GLuint lateLinkTestProgramInactive;
211*8975f5c5SAndroid Build Coastguard Worker     GLuint lateLinkTestVertShaderActive;
212*8975f5c5SAndroid Build Coastguard Worker     GLuint lateLinkTestProgramActive;
213*8975f5c5SAndroid Build Coastguard Worker 
214*8975f5c5SAndroid Build Coastguard Worker     GLuint inactiveProgram;
215*8975f5c5SAndroid Build Coastguard Worker     GLuint inactiveShader;
216*8975f5c5SAndroid Build Coastguard Worker 
217*8975f5c5SAndroid Build Coastguard Worker     GLuint activeBeforeProgram;
218*8975f5c5SAndroid Build Coastguard Worker     GLuint activeBeforeVertShader;
219*8975f5c5SAndroid Build Coastguard Worker     GLuint activeBeforeFragShader;
220*8975f5c5SAndroid Build Coastguard Worker 
221*8975f5c5SAndroid Build Coastguard Worker     GLuint textureNeverBound;
222*8975f5c5SAndroid Build Coastguard Worker     GLuint textureBoundBeforeCapture;
223*8975f5c5SAndroid Build Coastguard Worker     GLuint mPositionLoc;
224*8975f5c5SAndroid Build Coastguard Worker     GLuint mTexCoordLoc;
225*8975f5c5SAndroid Build Coastguard Worker     GLint mSamplerLoc;
226*8975f5c5SAndroid Build Coastguard Worker };
227*8975f5c5SAndroid Build Coastguard Worker 
frame1()228*8975f5c5SAndroid Build Coastguard Worker void MultiFrame::frame1()
229*8975f5c5SAndroid Build Coastguard Worker {
230*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.25f, 0.5f, 0.5f, 0.5f);
231*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
232*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 128, 1.0);
233*8975f5c5SAndroid Build Coastguard Worker 
234*8975f5c5SAndroid Build Coastguard Worker     static GLfloat vertices[] = {
235*8975f5c5SAndroid Build Coastguard Worker         -0.75f, 0.25f,  0.0f,  // Position 0
236*8975f5c5SAndroid Build Coastguard Worker         0.0f,   0.0f,          // TexCoord 0
237*8975f5c5SAndroid Build Coastguard Worker         -0.75f, -0.75f, 0.0f,  // Position 1
238*8975f5c5SAndroid Build Coastguard Worker         0.0f,   1.0f,          // TexCoord 1
239*8975f5c5SAndroid Build Coastguard Worker         0.25f,  -0.75f, 0.0f,  // Position 2
240*8975f5c5SAndroid Build Coastguard Worker         1.0f,   1.0f,          // TexCoord 2
241*8975f5c5SAndroid Build Coastguard Worker         0.25f,  0.25f,  0.0f,  // Position 3
242*8975f5c5SAndroid Build Coastguard Worker         1.0f,   0.0f           // TexCoord 3
243*8975f5c5SAndroid Build Coastguard Worker     };
244*8975f5c5SAndroid Build Coastguard Worker 
245*8975f5c5SAndroid Build Coastguard Worker     GLushort indices[] = {0, 1, 2, 0, 2, 3};
246*8975f5c5SAndroid Build Coastguard Worker 
247*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
248*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(activeBeforeProgram);
249*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices);
250*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices + 3);
251*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(mPositionLoc);
252*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(mTexCoordLoc);
253*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mSamplerLoc, 0);
254*8975f5c5SAndroid Build Coastguard Worker 
255*8975f5c5SAndroid Build Coastguard Worker     // Draw without binding texture during capture
256*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
257*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(20, 20, 0, 0, 255, 255);
258*8975f5c5SAndroid Build Coastguard Worker 
259*8975f5c5SAndroid Build Coastguard Worker     glDeleteVertexArrays(1, &mPositionLoc);
260*8975f5c5SAndroid Build Coastguard Worker     glDeleteVertexArrays(1, &mTexCoordLoc);
261*8975f5c5SAndroid Build Coastguard Worker }
262*8975f5c5SAndroid Build Coastguard Worker 
frame2()263*8975f5c5SAndroid Build Coastguard Worker void MultiFrame::frame2()
264*8975f5c5SAndroid Build Coastguard Worker {
265*8975f5c5SAndroid Build Coastguard Worker     // Draw using texture created and bound during capture
266*8975f5c5SAndroid Build Coastguard Worker 
267*8975f5c5SAndroid Build Coastguard Worker     GLuint activeDuringProgram;
268*8975f5c5SAndroid Build Coastguard Worker     GLuint activeDuringVertShader;
269*8975f5c5SAndroid Build Coastguard Worker     GLuint activeDuringFragShader;
270*8975f5c5SAndroid Build Coastguard Worker     GLuint positionLoc;
271*8975f5c5SAndroid Build Coastguard Worker     GLuint texCoordLoc;
272*8975f5c5SAndroid Build Coastguard Worker     GLuint textureBoundDuringCapture;
273*8975f5c5SAndroid Build Coastguard Worker     GLint samplerLoc;
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker     activeDuringProgram                = glCreateProgram();
276*8975f5c5SAndroid Build Coastguard Worker     activeDuringVertShader             = glCreateShader(GL_VERTEX_SHADER);
277*8975f5c5SAndroid Build Coastguard Worker     activeDuringFragShader             = glCreateShader(GL_FRAGMENT_SHADER);
278*8975f5c5SAndroid Build Coastguard Worker     const char *activeVsSourceArray[1] = {kActiveVS};
279*8975f5c5SAndroid Build Coastguard Worker     glShaderSource(activeDuringVertShader, 1, activeVsSourceArray, 0);
280*8975f5c5SAndroid Build Coastguard Worker     glCompileShader(activeDuringVertShader);
281*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(activeDuringProgram, activeDuringVertShader);
282*8975f5c5SAndroid Build Coastguard Worker     const char *activeFsSourceArray[1] = {kActiveFS};
283*8975f5c5SAndroid Build Coastguard Worker     glShaderSource(activeDuringFragShader, 1, activeFsSourceArray, 0);
284*8975f5c5SAndroid Build Coastguard Worker     glCompileShader(activeDuringFragShader);
285*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(activeDuringProgram, activeDuringFragShader);
286*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(activeDuringProgram);
287*8975f5c5SAndroid Build Coastguard Worker 
288*8975f5c5SAndroid Build Coastguard Worker     // Get the attr/sampler locations
289*8975f5c5SAndroid Build Coastguard Worker     positionLoc = glGetAttribLocation(activeDuringProgram, "a_position");
290*8975f5c5SAndroid Build Coastguard Worker     texCoordLoc = glGetAttribLocation(activeDuringProgram, "a_texCoord");
291*8975f5c5SAndroid Build Coastguard Worker     samplerLoc  = glGetUniformLocation(activeDuringProgram, "s_texture");
292*8975f5c5SAndroid Build Coastguard Worker     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
293*8975f5c5SAndroid Build Coastguard Worker 
294*8975f5c5SAndroid Build Coastguard Worker     // Bind the texture object during capture
295*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &textureBoundDuringCapture);
296*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, textureBoundDuringCapture);
297*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
298*8975f5c5SAndroid Build Coastguard Worker 
299*8975f5c5SAndroid Build Coastguard Worker     const size_t width                 = 2;
300*8975f5c5SAndroid Build Coastguard Worker     const size_t height                = 2;
301*8975f5c5SAndroid Build Coastguard Worker     GLubyte pixels[width * height * 3] = {
302*8975f5c5SAndroid Build Coastguard Worker         255, 255, 0,    // Yellow
303*8975f5c5SAndroid Build Coastguard Worker         0,   0,   255,  // Blue
304*8975f5c5SAndroid Build Coastguard Worker         0,   255, 0,    // Green
305*8975f5c5SAndroid Build Coastguard Worker         255, 0,   0,    // Red
306*8975f5c5SAndroid Build Coastguard Worker     };
307*8975f5c5SAndroid Build Coastguard Worker 
308*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
309*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
310*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
311*8975f5c5SAndroid Build Coastguard Worker 
312*8975f5c5SAndroid Build Coastguard Worker     static GLfloat vertices[] = {
313*8975f5c5SAndroid Build Coastguard Worker         -0.25f, 0.75f,  0.0f,  // Position 0
314*8975f5c5SAndroid Build Coastguard Worker         0.0f,   0.0f,          // TexCoord 0
315*8975f5c5SAndroid Build Coastguard Worker         -0.25f, -0.25f, 0.0f,  // Position 1
316*8975f5c5SAndroid Build Coastguard Worker         0.0f,   1.0f,          // TexCoord 1
317*8975f5c5SAndroid Build Coastguard Worker         0.75f,  -0.25f, 0.0f,  // Position 2
318*8975f5c5SAndroid Build Coastguard Worker         1.0f,   1.0f,          // TexCoord 2
319*8975f5c5SAndroid Build Coastguard Worker         0.75f,  0.75f,  0.0f,  // Position 3
320*8975f5c5SAndroid Build Coastguard Worker         1.0f,   0.0f           // TexCoord 3
321*8975f5c5SAndroid Build Coastguard Worker     };
322*8975f5c5SAndroid Build Coastguard Worker     GLushort indices[] = {0, 1, 2, 0, 2, 3};
323*8975f5c5SAndroid Build Coastguard Worker 
324*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
325*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(activeDuringProgram);
326*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices);
327*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices + 3);
328*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(positionLoc);
329*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(texCoordLoc);
330*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(samplerLoc, 0);
331*8975f5c5SAndroid Build Coastguard Worker 
332*8975f5c5SAndroid Build Coastguard Worker     // Draw using texture bound during capture
333*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
334*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(108, 108, 0, 0, 255, 255);
335*8975f5c5SAndroid Build Coastguard Worker 
336*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &textureBoundDuringCapture);
337*8975f5c5SAndroid Build Coastguard Worker     glDeleteVertexArrays(1, &positionLoc);
338*8975f5c5SAndroid Build Coastguard Worker     glDeleteVertexArrays(1, &texCoordLoc);
339*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(activeDuringProgram);
340*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(activeDuringVertShader);
341*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(activeDuringFragShader);
342*8975f5c5SAndroid Build Coastguard Worker }
343*8975f5c5SAndroid Build Coastguard Worker 
frame3()344*8975f5c5SAndroid Build Coastguard Worker void MultiFrame::frame3()
345*8975f5c5SAndroid Build Coastguard Worker {
346*8975f5c5SAndroid Build Coastguard Worker     // TODO: using local objects (with RAII helpers) here that create and destroy objects within the
347*8975f5c5SAndroid Build Coastguard Worker     // frame. Maybe move some of this to test Setup.
348*8975f5c5SAndroid Build Coastguard Worker 
349*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(precision highp float;
350*8975f5c5SAndroid Build Coastguard Worker attribute vec3 attr1;
351*8975f5c5SAndroid Build Coastguard Worker void main(void) {
352*8975f5c5SAndroid Build Coastguard Worker    gl_Position = vec4(attr1, 1.0);
353*8975f5c5SAndroid Build Coastguard Worker })";
354*8975f5c5SAndroid Build Coastguard Worker 
355*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(precision highp float;
356*8975f5c5SAndroid Build Coastguard Worker void main(void) {
357*8975f5c5SAndroid Build Coastguard Worker    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
358*8975f5c5SAndroid Build Coastguard Worker })";
359*8975f5c5SAndroid Build Coastguard Worker 
360*8975f5c5SAndroid Build Coastguard Worker     GLBuffer emptyBuffer;
361*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, emptyBuffer);
362*8975f5c5SAndroid Build Coastguard Worker 
363*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVS, kFS);
364*8975f5c5SAndroid Build Coastguard Worker     glBindAttribLocation(program, 0, "attr1");
365*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
366*8975f5c5SAndroid Build Coastguard Worker     ASSERT_TRUE(CheckLinkStatusAndReturnProgram(program, true));
367*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
368*8975f5c5SAndroid Build Coastguard Worker 
369*8975f5c5SAndroid Build Coastguard Worker     // Use non-existing attribute 1.
370*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(1);
371*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(1, 3, GL_UNSIGNED_BYTE, false, 1, 0);
372*8975f5c5SAndroid Build Coastguard Worker 
373*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 3);
374*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
375*8975f5c5SAndroid Build Coastguard Worker 
376*8975f5c5SAndroid Build Coastguard Worker     // Note: RAII destructors called here causing additional GL calls.
377*8975f5c5SAndroid Build Coastguard Worker }
378*8975f5c5SAndroid Build Coastguard Worker 
frame4()379*8975f5c5SAndroid Build Coastguard Worker void MultiFrame::frame4()
380*8975f5c5SAndroid Build Coastguard Worker {
381*8975f5c5SAndroid Build Coastguard Worker     GLuint positionLoc;
382*8975f5c5SAndroid Build Coastguard Worker     GLuint texCoordLoc;
383*8975f5c5SAndroid Build Coastguard Worker     GLuint lateLinkTestTexture;
384*8975f5c5SAndroid Build Coastguard Worker     GLint samplerLoc;
385*8975f5c5SAndroid Build Coastguard Worker 
386*8975f5c5SAndroid Build Coastguard Worker     // Deferred compile/link
387*8975f5c5SAndroid Build Coastguard Worker     glCompileShader(lateLinkTestVertShaderActive);
388*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(lateLinkTestProgramActive);
389*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
390*8975f5c5SAndroid Build Coastguard Worker 
391*8975f5c5SAndroid Build Coastguard Worker     // Get the attr/sampler locations
392*8975f5c5SAndroid Build Coastguard Worker     positionLoc = glGetAttribLocation(lateLinkTestProgramActive, "a_position");
393*8975f5c5SAndroid Build Coastguard Worker     texCoordLoc = glGetAttribLocation(lateLinkTestProgramActive, "a_texCoord");
394*8975f5c5SAndroid Build Coastguard Worker     samplerLoc  = glGetUniformLocation(lateLinkTestProgramActive, "s_texture");
395*8975f5c5SAndroid Build Coastguard Worker     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
396*8975f5c5SAndroid Build Coastguard Worker 
397*8975f5c5SAndroid Build Coastguard Worker     // Bind the texture object during capture
398*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &lateLinkTestTexture);
399*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, lateLinkTestTexture);
400*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
401*8975f5c5SAndroid Build Coastguard Worker 
402*8975f5c5SAndroid Build Coastguard Worker     const size_t width                 = 2;
403*8975f5c5SAndroid Build Coastguard Worker     const size_t height                = 2;
404*8975f5c5SAndroid Build Coastguard Worker     GLubyte pixels[width * height * 3] = {
405*8975f5c5SAndroid Build Coastguard Worker         255, 255, 0,    // Yellow
406*8975f5c5SAndroid Build Coastguard Worker         0,   0,   255,  // Blue
407*8975f5c5SAndroid Build Coastguard Worker         0,   255, 0,    // Green
408*8975f5c5SAndroid Build Coastguard Worker         255, 0,   0,    // Red
409*8975f5c5SAndroid Build Coastguard Worker     };
410*8975f5c5SAndroid Build Coastguard Worker 
411*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
412*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
413*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
414*8975f5c5SAndroid Build Coastguard Worker 
415*8975f5c5SAndroid Build Coastguard Worker     static GLfloat vertices[] = {
416*8975f5c5SAndroid Build Coastguard Worker         -0.25f, 0.75f,  0.0f,  // Position 0
417*8975f5c5SAndroid Build Coastguard Worker         0.0f,   0.0f,          // TexCoord 0
418*8975f5c5SAndroid Build Coastguard Worker         -0.25f, -0.25f, 0.0f,  // Position 1
419*8975f5c5SAndroid Build Coastguard Worker         0.0f,   1.0f,          // TexCoord 1
420*8975f5c5SAndroid Build Coastguard Worker         0.75f,  -0.25f, 0.0f,  // Position 2
421*8975f5c5SAndroid Build Coastguard Worker         1.0f,   1.0f,          // TexCoord 2
422*8975f5c5SAndroid Build Coastguard Worker         0.75f,  0.75f,  0.0f,  // Position 3
423*8975f5c5SAndroid Build Coastguard Worker         1.0f,   0.0f           // TexCoord 3
424*8975f5c5SAndroid Build Coastguard Worker     };
425*8975f5c5SAndroid Build Coastguard Worker     GLushort indices[] = {0, 1, 2, 0, 2, 3};
426*8975f5c5SAndroid Build Coastguard Worker 
427*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
428*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(lateLinkTestProgramActive);
429*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices);
430*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices + 3);
431*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(positionLoc);
432*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(texCoordLoc);
433*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(samplerLoc, 0);
434*8975f5c5SAndroid Build Coastguard Worker 
435*8975f5c5SAndroid Build Coastguard Worker     // Draw shaders & program created before capture
436*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
437*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(108, 108, 0, 0, 255, 255);
438*8975f5c5SAndroid Build Coastguard Worker 
439*8975f5c5SAndroid Build Coastguard Worker     // Add an invalid call so it shows up in capture as a comment.
440*8975f5c5SAndroid Build Coastguard Worker     // This is unrelated to the rest of the frame, but needs a home.
441*8975f5c5SAndroid Build Coastguard Worker     GLuint nonExistentBinding = 666;
442*8975f5c5SAndroid Build Coastguard Worker     GLuint nonExistentTexture = 777;
443*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(nonExistentBinding, nonExistentTexture);
444*8975f5c5SAndroid Build Coastguard Worker     glGetError();
445*8975f5c5SAndroid Build Coastguard Worker 
446*8975f5c5SAndroid Build Coastguard Worker     // Another unrelated change
447*8975f5c5SAndroid Build Coastguard Worker     // Bind a PIXEL_UNPACK_BUFFER buffer so it gets cleared in Reset
448*8975f5c5SAndroid Build Coastguard Worker     GLBuffer unpackBuffer;
449*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
450*8975f5c5SAndroid Build Coastguard Worker }
451*8975f5c5SAndroid Build Coastguard Worker 
452*8975f5c5SAndroid Build Coastguard Worker // Test captured by capture_tests.py
TEST_P(CapturedTest,MultiFrame)453*8975f5c5SAndroid Build Coastguard Worker TEST_P(CapturedTest, MultiFrame)
454*8975f5c5SAndroid Build Coastguard Worker {
455*8975f5c5SAndroid Build Coastguard Worker     MultiFrame multiFrame;
456*8975f5c5SAndroid Build Coastguard Worker     multiFrame.testSetUp();
457*8975f5c5SAndroid Build Coastguard Worker 
458*8975f5c5SAndroid Build Coastguard Worker     // Swap before the first frame so that setup gets its own frame
459*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
460*8975f5c5SAndroid Build Coastguard Worker     multiFrame.frame1();
461*8975f5c5SAndroid Build Coastguard Worker 
462*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
463*8975f5c5SAndroid Build Coastguard Worker     multiFrame.frame2();
464*8975f5c5SAndroid Build Coastguard Worker 
465*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
466*8975f5c5SAndroid Build Coastguard Worker     multiFrame.frame3();
467*8975f5c5SAndroid Build Coastguard Worker 
468*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
469*8975f5c5SAndroid Build Coastguard Worker     multiFrame.frame4();
470*8975f5c5SAndroid Build Coastguard Worker 
471*8975f5c5SAndroid Build Coastguard Worker     // Empty frames to reach capture end.
472*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++)
473*8975f5c5SAndroid Build Coastguard Worker     {
474*8975f5c5SAndroid Build Coastguard Worker         swapBuffers();
475*8975f5c5SAndroid Build Coastguard Worker     }
476*8975f5c5SAndroid Build Coastguard Worker     // Note: test teardown adds an additonal swap in
477*8975f5c5SAndroid Build Coastguard Worker     // ANGLETestBase::ANGLETestPreTearDown() when --angle-per-test-capture-label
478*8975f5c5SAndroid Build Coastguard Worker 
479*8975f5c5SAndroid Build Coastguard Worker     multiFrame.testTearDown();
480*8975f5c5SAndroid Build Coastguard Worker }
481*8975f5c5SAndroid Build Coastguard Worker 
482*8975f5c5SAndroid Build Coastguard Worker // Draw using two textures using multiple glActiveTexture calls, ensure they are correctly Reset
TEST_P(CapturedTest,ActiveTextures)483*8975f5c5SAndroid Build Coastguard Worker TEST_P(CapturedTest, ActiveTextures)
484*8975f5c5SAndroid Build Coastguard Worker {
485*8975f5c5SAndroid Build Coastguard Worker     static constexpr char kVS[] = R"(attribute vec4 a_position;
486*8975f5c5SAndroid Build Coastguard Worker attribute vec2 a_texCoord;
487*8975f5c5SAndroid Build Coastguard Worker varying vec2 v_texCoord;
488*8975f5c5SAndroid Build Coastguard Worker void main()
489*8975f5c5SAndroid Build Coastguard Worker {
490*8975f5c5SAndroid Build Coastguard Worker     gl_Position = a_position;
491*8975f5c5SAndroid Build Coastguard Worker     v_texCoord = a_texCoord;
492*8975f5c5SAndroid Build Coastguard Worker })";
493*8975f5c5SAndroid Build Coastguard Worker 
494*8975f5c5SAndroid Build Coastguard Worker     static constexpr char kFS[] = R"(precision mediump float;
495*8975f5c5SAndroid Build Coastguard Worker varying vec2 v_texCoord;
496*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D s_texture1;
497*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D s_texture2;
498*8975f5c5SAndroid Build Coastguard Worker void main()
499*8975f5c5SAndroid Build Coastguard Worker {
500*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = texture2D(s_texture1, v_texCoord) + texture2D(s_texture2, v_texCoord);
501*8975f5c5SAndroid Build Coastguard Worker })";
502*8975f5c5SAndroid Build Coastguard Worker 
503*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVS, kFS);
504*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
505*8975f5c5SAndroid Build Coastguard Worker 
506*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
507*8975f5c5SAndroid Build Coastguard Worker 
508*8975f5c5SAndroid Build Coastguard Worker     // Set the sampler uniforms
509*8975f5c5SAndroid Build Coastguard Worker     GLint samplerLoc1 = glGetUniformLocation(program, "s_texture1");
510*8975f5c5SAndroid Build Coastguard Worker     GLint samplerLoc2 = glGetUniformLocation(program, "s_texture2");
511*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(samplerLoc1, 0);
512*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(samplerLoc2, 1);
513*8975f5c5SAndroid Build Coastguard Worker 
514*8975f5c5SAndroid Build Coastguard Worker     // Bind the texture objects before capture begins
515*8975f5c5SAndroid Build Coastguard Worker     constexpr const GLsizei kSize = 4;
516*8975f5c5SAndroid Build Coastguard Worker 
517*8975f5c5SAndroid Build Coastguard Worker     GLTexture redTexture;
518*8975f5c5SAndroid Build Coastguard Worker     GLTexture greenTexture;
519*8975f5c5SAndroid Build Coastguard Worker     GLTexture blueTexture;
520*8975f5c5SAndroid Build Coastguard Worker 
521*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLColor> kRedData(kSize * kSize, GLColor::red);
522*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLColor> kGreenData(kSize * kSize, GLColor::green);
523*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLColor> kBlueData(kSize * kSize, GLColor::blue);
524*8975f5c5SAndroid Build Coastguard Worker 
525*8975f5c5SAndroid Build Coastguard Worker     // Red texture
526*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, redTexture);
527*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
528*8975f5c5SAndroid Build Coastguard Worker                  kRedData.data());
529*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
530*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
531*8975f5c5SAndroid Build Coastguard Worker 
532*8975f5c5SAndroid Build Coastguard Worker     // Green texture
533*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, greenTexture);
534*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
535*8975f5c5SAndroid Build Coastguard Worker                  kGreenData.data());
536*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
537*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
538*8975f5c5SAndroid Build Coastguard Worker 
539*8975f5c5SAndroid Build Coastguard Worker     // Blue texture
540*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, blueTexture);
541*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
542*8975f5c5SAndroid Build Coastguard Worker                  kBlueData.data());
543*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
544*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
545*8975f5c5SAndroid Build Coastguard Worker 
546*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
547*8975f5c5SAndroid Build Coastguard Worker 
548*8975f5c5SAndroid Build Coastguard Worker     // First run the program with red and green active
549*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
550*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, redTexture);
551*8975f5c5SAndroid Build Coastguard Worker 
552*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE1);
553*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, greenTexture);
554*8975f5c5SAndroid Build Coastguard Worker 
555*8975f5c5SAndroid Build Coastguard Worker     // Trigger MEC
556*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
557*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
558*8975f5c5SAndroid Build Coastguard Worker 
559*8975f5c5SAndroid Build Coastguard Worker     // Draw and verify results
560*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, "a_position", 0.5f);
561*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
562*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(0, 0, 255, 255, 0, 255);
563*8975f5c5SAndroid Build Coastguard Worker 
564*8975f5c5SAndroid Build Coastguard Worker     // Change the active textures to green and blue
565*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
566*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, greenTexture);
567*8975f5c5SAndroid Build Coastguard Worker 
568*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE1);
569*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, blueTexture);
570*8975f5c5SAndroid Build Coastguard Worker 
571*8975f5c5SAndroid Build Coastguard Worker     // Draw and verify results
572*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, "a_position", 0.5f);
573*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
574*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(0, 0, 0, 255, 255, 255);
575*8975f5c5SAndroid Build Coastguard Worker 
576*8975f5c5SAndroid Build Coastguard Worker     // Modify the green texture to ensure we bind the right index in Reset
577*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLColor> kWhiteData(kSize * kSize, GLColor::white);
578*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
579*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, greenTexture);
580*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
581*8975f5c5SAndroid Build Coastguard Worker                  kWhiteData.data());
582*8975f5c5SAndroid Build Coastguard Worker 
583*8975f5c5SAndroid Build Coastguard Worker     // Empty frames to reach capture end.
584*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++)
585*8975f5c5SAndroid Build Coastguard Worker     {
586*8975f5c5SAndroid Build Coastguard Worker         swapBuffers();
587*8975f5c5SAndroid Build Coastguard Worker     }
588*8975f5c5SAndroid Build Coastguard Worker }
589*8975f5c5SAndroid Build Coastguard Worker 
590*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CapturedTest);
591*8975f5c5SAndroid Build Coastguard Worker // Capture is only supported on the Vulkan backend
592*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(CapturedTest, ES3_VULKAN());
593*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
594