xref: /aosp_15_r20/external/angle/src/tests/gl_tests/SimpleOperationTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // SimpleOperationTest:
7 //   Basic GL commands such as linking a program, initializing a buffer, etc.
8 
9 #include "test_utils/ANGLETest.h"
10 
11 #include <vector>
12 
13 #include "test_utils/gl_raii.h"
14 #include "util/EGLWindow.h"
15 #include "util/random_utils.h"
16 
17 using namespace angle;
18 
19 namespace
20 {
21 constexpr char kBasicVertexShader[] =
22     R"(attribute vec3 position;
23 void main()
24 {
25     gl_Position = vec4(position, 1);
26 })";
27 
28 constexpr char kGreenFragmentShader[] =
29     R"(void main()
30 {
31     gl_FragColor = vec4(0, 1, 0, 1);
32 })";
33 
34 class SimpleOperationTest : public ANGLETest<>
35 {
36   protected:
SimpleOperationTest()37     SimpleOperationTest()
38     {
39         setWindowWidth(128);
40         setWindowHeight(128);
41         setConfigRedBits(8);
42         setConfigGreenBits(8);
43         setConfigBlueBits(8);
44         setConfigAlphaBits(8);
45     }
46 
47     void verifyBuffer(const std::vector<uint8_t> &data, GLenum binding);
48 
49     template <typename T>
50     void testDrawElementsLineLoopUsingClientSideMemory(GLenum indexType,
51                                                        int windowWidth,
52                                                        int windowHeight);
53 };
54 
55 class SimpleOperationTest31 : public SimpleOperationTest
56 {};
57 
verifyBuffer(const std::vector<uint8_t> & data,GLenum binding)58 void SimpleOperationTest::verifyBuffer(const std::vector<uint8_t> &data, GLenum binding)
59 {
60     if (!IsGLExtensionEnabled("GL_EXT_map_buffer_range"))
61     {
62         return;
63     }
64 
65     uint8_t *mapPointer =
66         static_cast<uint8_t *>(glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 1024, GL_MAP_READ_BIT));
67     ASSERT_GL_NO_ERROR();
68 
69     std::vector<uint8_t> readbackData(data.size());
70     memcpy(readbackData.data(), mapPointer, data.size());
71     glUnmapBufferOES(GL_ARRAY_BUFFER);
72 
73     EXPECT_EQ(data, readbackData);
74 }
75 
76 // Validates if culling rasterization states work. Simply draws a quad with
77 // cull face enabled and make sure we still render correctly.
TEST_P(SimpleOperationTest,CullFaceEnabledState)78 TEST_P(SimpleOperationTest, CullFaceEnabledState)
79 {
80     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
81     glUseProgram(program);
82 
83     glClear(GL_COLOR_BUFFER_BIT);
84     glEnable(GL_CULL_FACE);
85 
86     drawQuad(program, "position", 0.0f, 1.0f, true);
87 
88     ASSERT_GL_NO_ERROR();
89 
90     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
91 }
92 
93 // Validates if culling rasterization states work. Simply draws a quad with
94 // cull face enabled with cullface front and make sure the face have not been rendered.
TEST_P(SimpleOperationTest,CullFaceFrontEnabledState)95 TEST_P(SimpleOperationTest, CullFaceFrontEnabledState)
96 {
97     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
98     glUseProgram(program);
99 
100     glClear(GL_COLOR_BUFFER_BIT);
101     glEnable(GL_CULL_FACE);
102 
103     // Should make the quad disappear since we draw it front facing.
104     glCullFace(GL_FRONT);
105 
106     drawQuad(program, "position", 0.0f, 1.0f, true);
107 
108     ASSERT_GL_NO_ERROR();
109 
110     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
111 }
112 
113 // Validates if blending render states work. Simply draws twice and verify the color have been
114 // added in the final output.
TEST_P(SimpleOperationTest,BlendingRenderState)115 TEST_P(SimpleOperationTest, BlendingRenderState)
116 {
117     // The precision when blending isn't perfect and some tests fail with a color of 254 instead
118     // of 255 on the green component. This is why we need 0.51 green instead of .5
119     constexpr char halfGreenFragmentShader[] =
120         R"(void main()
121 {
122     gl_FragColor = vec4(0, 0.51, 0, 1);
123 })";
124 
125     ANGLE_GL_PROGRAM(program, kBasicVertexShader, halfGreenFragmentShader);
126     glUseProgram(program);
127 
128     glClear(GL_COLOR_BUFFER_BIT);
129     glEnable(GL_BLEND);
130     glBlendFunc(GL_ONE, GL_ONE);
131     glBlendEquation(GL_FUNC_ADD);
132 
133     auto vertices = GetQuadVertices();
134 
135     const GLint positionLocation = glGetAttribLocation(program, "position");
136     ASSERT_NE(-1, positionLocation);
137 
138     GLBuffer vertexBuffer;
139     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
140     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
141                  GL_STATIC_DRAW);
142     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
143 
144     glEnableVertexAttribArray(positionLocation);
145 
146     // Drawing a quad once will give 0.51 green, but if we enable blending
147     // with additive function we should end up with full green of 1.0 with
148     // a clamping func of 1.0.
149     glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vertices.size()));
150     glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vertices.size()));
151 
152     ASSERT_GL_NO_ERROR();
153 
154     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
155 }
156 
157 // Tests getting the GL_BLEND_EQUATION integer
TEST_P(SimpleOperationTest,BlendEquationGetInteger)158 TEST_P(SimpleOperationTest, BlendEquationGetInteger)
159 {
160     glEnable(GL_BLEND);
161     glBlendFunc(GL_ONE, GL_ONE);
162 
163     constexpr std::array<GLenum, 5> equations = {GL_FUNC_ADD, GL_FUNC_SUBTRACT,
164                                                  GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX};
165 
166     for (GLenum equation : equations)
167     {
168         glBlendEquation(equation);
169 
170         GLint currentEquation;
171         glGetIntegerv(GL_BLEND_EQUATION, &currentEquation);
172         ASSERT_GL_NO_ERROR();
173 
174         EXPECT_EQ(currentEquation, static_cast<GLint>(equation));
175     }
176 }
177 
TEST_P(SimpleOperationTest,CompileVertexShader)178 TEST_P(SimpleOperationTest, CompileVertexShader)
179 {
180     GLuint shader = CompileShader(GL_VERTEX_SHADER, kBasicVertexShader);
181     EXPECT_NE(shader, 0u);
182     glDeleteShader(shader);
183 
184     ASSERT_GL_NO_ERROR();
185 }
186 
TEST_P(SimpleOperationTest,CompileFragmentShaderSingleVaryingInput)187 TEST_P(SimpleOperationTest, CompileFragmentShaderSingleVaryingInput)
188 {
189     constexpr char kFS[] = R"(precision mediump float;
190 varying vec4 v_input;
191 void main()
192 {
193     gl_FragColor = v_input;
194 })";
195 
196     GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
197     EXPECT_NE(shader, 0u);
198     glDeleteShader(shader);
199 
200     ASSERT_GL_NO_ERROR();
201 }
202 
203 // Covers a simple bug in Vulkan to do with dependencies between the Surface and the default
204 // Framebuffer.
TEST_P(SimpleOperationTest,ClearAndSwap)205 TEST_P(SimpleOperationTest, ClearAndSwap)
206 {
207     glClearColor(1.0, 0.0, 0.0, 1.0);
208     glClear(GL_COLOR_BUFFER_BIT);
209     swapBuffers();
210 
211     // Can't check the pixel result after the swap, and checking the pixel result affects the
212     // behaviour of the test on the Vulkan back-end, so don't bother checking correctness.
213     ASSERT_GL_NO_ERROR();
214     ASSERT_FALSE(getGLWindow()->hasError());
215 }
216 
217 // Simple case of setting a scissor, enabled or disabled.
TEST_P(SimpleOperationTest,ScissorTest)218 TEST_P(SimpleOperationTest, ScissorTest)
219 {
220     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
221 
222     glClear(GL_COLOR_BUFFER_BIT);
223     glEnable(GL_SCISSOR_TEST);
224     glScissor(getWindowWidth() / 4, getWindowHeight() / 4, getWindowWidth() / 2,
225               getWindowHeight() / 2);
226 
227     // Fill the whole screen with a quad.
228     drawQuad(program, "position", 0.0f, 1.0f, true);
229 
230     ASSERT_GL_NO_ERROR();
231 
232     // Test outside the scissor test, pitch black.
233     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
234 
235     // Test inside, green of the fragment shader.
236     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
237 }
238 
TEST_P(SimpleOperationTest,LinkProgramShadersNoInputs)239 TEST_P(SimpleOperationTest, LinkProgramShadersNoInputs)
240 {
241     constexpr char kVS[] = "void main() { gl_Position = vec4(1.0, 1.0, 1.0, 1.0); }";
242     constexpr char kFS[] = "void main() { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); }";
243 
244     ANGLE_GL_PROGRAM(program, kVS, kFS);
245     ASSERT_GL_NO_ERROR();
246 }
247 
TEST_P(SimpleOperationTest,LinkProgramWithUniforms)248 TEST_P(SimpleOperationTest, LinkProgramWithUniforms)
249 {
250     constexpr char kVS[] = R"(void main()
251 {
252     gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
253 })";
254     constexpr char kFS[] = R"(precision mediump float;
255 uniform vec4 u_input;
256 void main()
257 {
258     gl_FragColor = u_input;
259 })";
260 
261     ANGLE_GL_PROGRAM(program, kVS, kFS);
262 
263     const GLint uniformLoc = glGetUniformLocation(program, "u_input");
264     EXPECT_NE(-1, uniformLoc);
265 
266     ASSERT_GL_NO_ERROR();
267 }
268 
TEST_P(SimpleOperationTest,LinkProgramWithAttributes)269 TEST_P(SimpleOperationTest, LinkProgramWithAttributes)
270 {
271     constexpr char kVS[] = R"(attribute vec4 a_input;
272 void main()
273 {
274     gl_Position = a_input;
275 })";
276 
277     ANGLE_GL_PROGRAM(program, kVS, kGreenFragmentShader);
278 
279     const GLint attribLoc = glGetAttribLocation(program, "a_input");
280     EXPECT_NE(-1, attribLoc);
281 
282     ASSERT_GL_NO_ERROR();
283 }
284 
TEST_P(SimpleOperationTest,BufferDataWithData)285 TEST_P(SimpleOperationTest, BufferDataWithData)
286 {
287     GLBuffer buffer;
288     glBindBuffer(GL_ARRAY_BUFFER, buffer);
289 
290     std::vector<uint8_t> data(1024);
291     FillVectorWithRandomUBytes(&data);
292     glBufferData(GL_ARRAY_BUFFER, data.size(), &data[0], GL_STATIC_DRAW);
293 
294     verifyBuffer(data, GL_ARRAY_BUFFER);
295 
296     ASSERT_GL_NO_ERROR();
297 }
298 
TEST_P(SimpleOperationTest,BufferDataWithNoData)299 TEST_P(SimpleOperationTest, BufferDataWithNoData)
300 {
301     GLBuffer buffer;
302     glBindBuffer(GL_ARRAY_BUFFER, buffer);
303     glBufferData(GL_ARRAY_BUFFER, 1024, nullptr, GL_STATIC_DRAW);
304 
305     ASSERT_GL_NO_ERROR();
306 }
307 
TEST_P(SimpleOperationTest,BufferSubData)308 TEST_P(SimpleOperationTest, BufferSubData)
309 {
310     GLBuffer buffer;
311     glBindBuffer(GL_ARRAY_BUFFER, buffer);
312 
313     constexpr size_t bufferSize = 1024;
314     std::vector<uint8_t> data(bufferSize);
315     FillVectorWithRandomUBytes(&data);
316 
317     glBufferData(GL_ARRAY_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
318 
319     constexpr size_t subDataCount = 16;
320     constexpr size_t sliceSize    = bufferSize / subDataCount;
321     for (size_t i = 0; i < subDataCount; i++)
322     {
323         size_t offset = i * sliceSize;
324         glBufferSubData(GL_ARRAY_BUFFER, offset, sliceSize, &data[offset]);
325     }
326 
327     verifyBuffer(data, GL_ARRAY_BUFFER);
328 
329     ASSERT_GL_NO_ERROR();
330 }
331 
332 // Simple quad test.
TEST_P(SimpleOperationTest,DrawQuad)333 TEST_P(SimpleOperationTest, DrawQuad)
334 {
335     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
336 
337     drawQuad(program, "position", 0.5f, 1.0f, true);
338 
339     ASSERT_GL_NO_ERROR();
340 
341     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
342 }
343 
344 // Simple quad test with data in client memory, not vertex buffer.
TEST_P(SimpleOperationTest,DrawQuadFromClientMemory)345 TEST_P(SimpleOperationTest, DrawQuadFromClientMemory)
346 {
347     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
348 
349     drawQuad(program, "position", 0.5f, 1.0f, false);
350 
351     ASSERT_GL_NO_ERROR();
352 
353     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
354 }
355 
356 // Simple double quad test.
TEST_P(SimpleOperationTest,DrawQuadTwice)357 TEST_P(SimpleOperationTest, DrawQuadTwice)
358 {
359     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
360 
361     drawQuad(program, "position", 0.5f, 1.0f, true);
362     drawQuad(program, "position", 0.5f, 1.0f, true);
363 
364     ASSERT_GL_NO_ERROR();
365 
366     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
367 }
368 
369 // Simple line test.
TEST_P(SimpleOperationTest,DrawLine)370 TEST_P(SimpleOperationTest, DrawLine)
371 {
372     // We assume in the test the width and height are equal and we are tracing
373     // the line from bottom left to top right. Verify that all pixels along that line
374     // have been traced with green.
375     ASSERT_EQ(getWindowWidth(), getWindowHeight());
376 
377     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
378     glUseProgram(program);
379 
380     std::vector<Vector3> vertices = {{-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}};
381 
382     const GLint positionLocation = glGetAttribLocation(program, "position");
383     ASSERT_NE(-1, positionLocation);
384 
385     GLBuffer vertexBuffer;
386     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
387     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
388                  GL_STATIC_DRAW);
389     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
390     glEnableVertexAttribArray(positionLocation);
391 
392     glClear(GL_COLOR_BUFFER_BIT);
393     glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(vertices.size()));
394 
395     glDisableVertexAttribArray(positionLocation);
396 
397     ASSERT_GL_NO_ERROR();
398 
399     for (int x = 0; x < getWindowWidth(); x++)
400     {
401         EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
402     }
403 }
404 
405 // Simple line test that will use a very large offset in the vertex attributes.
TEST_P(SimpleOperationTest,DrawLineWithLargeAttribPointerOffset)406 TEST_P(SimpleOperationTest, DrawLineWithLargeAttribPointerOffset)
407 {
408     // We assume in the test the width and height are equal and we are tracing
409     // the line from bottom left to top right. Verify that all pixels along that line
410     // have been traced with green.
411     ASSERT_EQ(getWindowWidth(), getWindowHeight());
412 
413     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
414     glUseProgram(program);
415 
416     int kOffset = 3315;
417     std::vector<Vector3> vertices(kOffset);
418     Vector3 vector1{-1.0f, -1.0f, 0.0f};
419     Vector3 vector2{1.0f, 1.0f, 0.0f};
420     vertices.emplace_back(vector1);
421     vertices.emplace_back(vector2);
422 
423     const GLint positionLocation = glGetAttribLocation(program, "position");
424     ASSERT_NE(-1, positionLocation);
425 
426     GLBuffer vertexBuffer;
427     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
428     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
429                  GL_STATIC_DRAW);
430     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0,
431                           reinterpret_cast<const void *>(kOffset * sizeof(vertices[0])));
432     glEnableVertexAttribArray(positionLocation);
433 
434     glClear(GL_COLOR_BUFFER_BIT);
435     glDrawArrays(GL_LINES, 0, 2);
436 
437     glDisableVertexAttribArray(positionLocation);
438 
439     ASSERT_GL_NO_ERROR();
440 
441     for (auto x = 0; x < getWindowWidth(); x++)
442     {
443         EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
444     }
445 }
446 
447 // Simple line strip test.
TEST_P(SimpleOperationTest,DrawLineStrip)448 TEST_P(SimpleOperationTest, DrawLineStrip)
449 {
450     // We assume in the test the width and height are equal and we are tracing
451     // the line from bottom left to center, then from center to bottom right.
452     // Verify that all pixels along these lines have been traced with green.
453     ASSERT_EQ(getWindowWidth(), getWindowHeight());
454 
455     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
456     glUseProgram(program);
457 
458     auto vertices =
459         std::vector<Vector3>{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {1.0f, -1.0f, 0.0f}};
460 
461     const GLint positionLocation = glGetAttribLocation(program, "position");
462     ASSERT_NE(-1, positionLocation);
463 
464     GLBuffer vertexBuffer;
465     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
466     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
467                  GL_STATIC_DRAW);
468     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
469 
470     glEnableVertexAttribArray(positionLocation);
471 
472     glClear(GL_COLOR_BUFFER_BIT);
473     glDrawArrays(GL_LINE_STRIP, 0, static_cast<GLsizei>(vertices.size()));
474 
475     ASSERT_GL_NO_ERROR();
476 
477     const auto centerX = getWindowWidth() / 2;
478     const auto centerY = getWindowHeight() / 2;
479 
480     for (auto x = 0; x < centerX; x++)
481     {
482         EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
483     }
484 
485     for (auto x = centerX, y = centerY - 1; x < getWindowWidth() && y >= 0; x++, y--)
486     {
487         EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
488     }
489 }
490 
491 class TriangleFanDrawTest : public SimpleOperationTest
492 {
493   protected:
testSetUp()494     void testSetUp() override
495     {
496         // We assume in the test the width and height are equal and we are tracing
497         // 2 triangles to cover half the surface like this:
498         ASSERT_EQ(getWindowWidth(), getWindowHeight());
499 
500         mProgram.makeRaster(kBasicVertexShader, kGreenFragmentShader);
501         ASSERT_TRUE(mProgram.valid());
502         glUseProgram(mProgram);
503 
504         const GLint positionLocation = glGetAttribLocation(mProgram, "position");
505         ASSERT_NE(-1, positionLocation);
506 
507         glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
508         glBufferData(GL_ARRAY_BUFFER, sizeof(mVertices[0]) * mVertices.size(), mVertices.data(),
509                      GL_STATIC_DRAW);
510         glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
511         glEnableVertexAttribArray(positionLocation);
512 
513         glClearColor(1, 0, 0, 1);
514         glClear(GL_COLOR_BUFFER_BIT);
515     }
516 
readPixels()517     void readPixels()
518     {
519         if (mReadPixels.empty())
520         {
521             mReadPixels.resize(getWindowWidth() * getWindowWidth());
522         }
523 
524         glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
525                      mReadPixels.data());
526         EXPECT_GL_NO_ERROR();
527     }
528 
verifyPixelAt(int x,int y,const GLColor & expected)529     void verifyPixelAt(int x, int y, const GLColor &expected)
530     {
531         EXPECT_EQ(mReadPixels[y * getWindowWidth() + x], expected);
532     }
533 
verifyTriangles()534     void verifyTriangles()
535     {
536         readPixels();
537 
538         // Check 4 lines accross de triangles to make sure we filled it.
539         // Don't check every pixel as it would slow down our tests.
540         for (auto x = 0; x < getWindowWidth(); x++)
541         {
542             verifyPixelAt(x, x, GLColor::green);
543         }
544 
545         for (auto x = getWindowWidth() / 3, y = 0; x < getWindowWidth(); x++, y++)
546         {
547             verifyPixelAt(x, y, GLColor::green);
548         }
549 
550         for (auto x = getWindowWidth() / 2, y = 0; x < getWindowWidth(); x++, y++)
551         {
552             verifyPixelAt(x, y, GLColor::green);
553         }
554 
555         for (auto x = (getWindowWidth() / 4) * 3, y = 0; x < getWindowWidth(); x++, y++)
556         {
557             verifyPixelAt(x, y, GLColor::green);
558         }
559 
560         // Area outside triangles
561         for (auto x = 0; x < getWindowWidth() - 2; x++)
562         {
563             verifyPixelAt(x, x + 2, GLColor::red);
564         }
565     }
566 
567     const std::vector<Vector3> mVertices = {{0.0f, 0.0f, 0.0f},
568                                             {-1.0f, -1.0f, 0.0f},
569                                             {0.0f, -1.0f, 0.0f},
570                                             {1.0f, -1.0f, 0.0f},
571                                             {1.0f, 1.0f, 0.0f}};
572 
573     GLBuffer mVertexBuffer;
574     GLProgram mProgram;
575 
576     std::vector<GLColor> mReadPixels;
577 };
578 
579 // Simple triangle fans test.
TEST_P(TriangleFanDrawTest,DrawTriangleFan)580 TEST_P(TriangleFanDrawTest, DrawTriangleFan)
581 {
582     glClear(GL_COLOR_BUFFER_BIT);
583     glDrawArrays(GL_TRIANGLE_FAN, 0, static_cast<GLsizei>(mVertices.size()));
584 
585     EXPECT_GL_NO_ERROR();
586 
587     verifyTriangles();
588 }
589 
590 // Triangle fans test with index buffer.
TEST_P(TriangleFanDrawTest,DrawTriangleFanElements)591 TEST_P(TriangleFanDrawTest, DrawTriangleFanElements)
592 {
593     std::vector<GLubyte> indices = {0, 1, 2, 3, 4};
594 
595     GLBuffer indexBuffer;
596     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
597     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
598                  GL_STATIC_DRAW);
599 
600     glClear(GL_COLOR_BUFFER_BIT);
601     glDrawElements(GL_TRIANGLE_FAN, static_cast<GLsizei>(indices.size()), GL_UNSIGNED_BYTE, 0);
602 
603     EXPECT_GL_NO_ERROR();
604 
605     verifyTriangles();
606 }
607 
608 // Triangle fans test with primitive restart index at the middle.
TEST_P(TriangleFanDrawTest,DrawTriangleFanPrimitiveRestartAtMiddle)609 TEST_P(TriangleFanDrawTest, DrawTriangleFanPrimitiveRestartAtMiddle)
610 {
611     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
612 
613     std::vector<GLubyte> indices = {0, 1, 2, 3, 0xff, 0, 4, 3};
614 
615     GLBuffer indexBuffer;
616     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
617     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
618                  GL_STATIC_DRAW);
619     glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
620 
621     glDrawElements(GL_TRIANGLE_FAN, static_cast<GLsizei>(indices.size()), GL_UNSIGNED_BYTE, 0);
622 
623     EXPECT_GL_NO_ERROR();
624 
625     verifyTriangles();
626 }
627 
628 // Triangle fans test with primitive restart at begin.
TEST_P(TriangleFanDrawTest,DrawTriangleFanPrimitiveRestartAtBegin)629 TEST_P(TriangleFanDrawTest, DrawTriangleFanPrimitiveRestartAtBegin)
630 {
631     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
632 
633     // Primitive restart index is at middle, but we will use draw call which index offset=4.
634     std::vector<GLubyte> indices = {0, 1, 2, 3, 0xff, 0, 4, 3};
635 
636     GLBuffer indexBuffer;
637     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
638     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
639                  GL_STATIC_DRAW);
640     glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
641 
642     glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, 0);
643     glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE,
644                    reinterpret_cast<void *>(sizeof(indices[0]) * 4));
645 
646     EXPECT_GL_NO_ERROR();
647 
648     verifyTriangles();
649 }
650 
651 // Triangle fans test with primitive restart at end.
TEST_P(TriangleFanDrawTest,DrawTriangleFanPrimitiveRestartAtEnd)652 TEST_P(TriangleFanDrawTest, DrawTriangleFanPrimitiveRestartAtEnd)
653 {
654     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
655 
656     std::vector<GLubyte> indices = {0, 1, 2, 3, 4, 0xff};
657 
658     GLBuffer indexBuffer;
659     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
660     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
661                  GL_STATIC_DRAW);
662     glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
663 
664     glDrawElements(GL_TRIANGLE_FAN, static_cast<GLsizei>(indices.size()), GL_UNSIGNED_BYTE, 0);
665 
666     EXPECT_GL_NO_ERROR();
667 
668     verifyTriangles();
669 }
670 
671 // Triangle fans test with primitive restart enabled, but no indexed draw.
TEST_P(TriangleFanDrawTest,DrawTriangleFanPrimitiveRestartNonIndexedDraw)672 TEST_P(TriangleFanDrawTest, DrawTriangleFanPrimitiveRestartNonIndexedDraw)
673 {
674     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
675 
676     std::vector<GLubyte> indices = {0, 1, 2, 3, 4};
677 
678     GLBuffer indexBuffer;
679     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
680     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
681                  GL_STATIC_DRAW);
682     glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
683 
684     glDrawArrays(GL_TRIANGLE_FAN, 0, 5);
685 
686     EXPECT_GL_NO_ERROR();
687 
688     verifyTriangles();
689 }
690 
691 // Simple repeated draw and swap test.
TEST_P(SimpleOperationTest,DrawQuadAndSwap)692 TEST_P(SimpleOperationTest, DrawQuadAndSwap)
693 {
694     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
695 
696     for (int i = 0; i < 8; ++i)
697     {
698         drawQuad(program, "position", 0.5f, 1.0f, true);
699         ASSERT_GL_NO_ERROR();
700         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
701         swapBuffers();
702     }
703 
704     ASSERT_GL_NO_ERROR();
705 }
706 
707 // Simple indexed quad test.
TEST_P(SimpleOperationTest,DrawIndexedQuad)708 TEST_P(SimpleOperationTest, DrawIndexedQuad)
709 {
710     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
711 
712     drawIndexedQuad(program, "position", 0.5f, 1.0f, true);
713 
714     ASSERT_GL_NO_ERROR();
715     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
716 }
717 
718 // Simple repeated indexed draw and swap test.
TEST_P(SimpleOperationTest,DrawIndexedQuadAndSwap)719 TEST_P(SimpleOperationTest, DrawIndexedQuadAndSwap)
720 {
721     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
722 
723     // 32 iterations is an arbitrary number. The more iterations, the more flaky syncronization
724     // issues will reproduce consistently.
725     for (int i = 0; i < 32; ++i)
726     {
727         drawIndexedQuad(program, "position", 0.5f, 1.0f, true);
728         ASSERT_GL_NO_ERROR();
729         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
730         swapBuffers();
731     }
732 
733     ASSERT_GL_NO_ERROR();
734 }
735 
736 // Draw with a fragment uniform.
TEST_P(SimpleOperationTest,DrawQuadWithFragmentUniform)737 TEST_P(SimpleOperationTest, DrawQuadWithFragmentUniform)
738 {
739     constexpr char kFS[] =
740         "uniform mediump vec4 color;\n"
741         "void main()\n"
742         "{\n"
743         "    gl_FragColor = color;\n"
744         "}";
745     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kFS);
746 
747     GLint location = glGetUniformLocation(program, "color");
748     ASSERT_NE(-1, location);
749 
750     glUseProgram(program);
751     glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
752 
753     drawQuad(program, "position", 0.5f, 1.0f, true);
754 
755     ASSERT_GL_NO_ERROR();
756     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
757 }
758 
759 // Draw with a vertex uniform.
TEST_P(SimpleOperationTest,DrawQuadWithVertexUniform)760 TEST_P(SimpleOperationTest, DrawQuadWithVertexUniform)
761 {
762     constexpr char kVS[] =
763         "attribute vec3 position;\n"
764         "uniform vec4 color;\n"
765         "varying vec4 vcolor;\n"
766         "void main()\n"
767         "{\n"
768         "    gl_Position = vec4(position, 1);\n"
769         "    vcolor = color;\n"
770         "}";
771     constexpr char kFS[] =
772         "varying mediump vec4 vcolor;\n"
773         "void main()\n"
774         "{\n"
775         "    gl_FragColor = vcolor;\n"
776         "}";
777     ANGLE_GL_PROGRAM(program, kVS, kFS);
778 
779     const GLint location = glGetUniformLocation(program, "color");
780     ASSERT_NE(-1, location);
781 
782     glUseProgram(program);
783     glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
784 
785     drawQuad(program, "position", 0.5f, 1.0f, true);
786 
787     ASSERT_GL_NO_ERROR();
788     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
789 }
790 
791 // Draw with two uniforms.
TEST_P(SimpleOperationTest,DrawQuadWithTwoUniforms)792 TEST_P(SimpleOperationTest, DrawQuadWithTwoUniforms)
793 {
794     constexpr char kVS[] =
795         "attribute vec3 position;\n"
796         "uniform vec4 color1;\n"
797         "varying vec4 vcolor1;\n"
798         "void main()\n"
799         "{\n"
800         "    gl_Position = vec4(position, 1);\n"
801         "    vcolor1 = color1;\n"
802         "}";
803     constexpr char kFS[] =
804         "uniform mediump vec4 color2;\n"
805         "varying mediump vec4 vcolor1;\n"
806         "void main()\n"
807         "{\n"
808         "    gl_FragColor = vcolor1 + color2;\n"
809         "}";
810     ANGLE_GL_PROGRAM(program, kVS, kFS);
811 
812     const GLint location1 = glGetUniformLocation(program, "color1");
813     ASSERT_NE(-1, location1);
814 
815     const GLint location2 = glGetUniformLocation(program, "color2");
816     ASSERT_NE(-1, location2);
817 
818     glUseProgram(program);
819     glUniform4f(location1, 0.0f, 1.0f, 0.0f, 1.0f);
820     glUniform4f(location2, 1.0f, 0.0f, 0.0f, 1.0f);
821 
822     drawQuad(program, "position", 0.5f, 1.0f, true);
823 
824     ASSERT_GL_NO_ERROR();
825     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
826 }
827 
828 // Tests a shader program with more than one vertex attribute, with vertex buffers.
TEST_P(SimpleOperationTest,ThreeVertexAttributes)829 TEST_P(SimpleOperationTest, ThreeVertexAttributes)
830 {
831     constexpr char kVS[] = R"(attribute vec2 position;
832 attribute vec4 color1;
833 attribute vec4 color2;
834 varying vec4 color;
835 void main()
836 {
837     gl_Position = vec4(position, 0, 1);
838     color = color1 + color2;
839 })";
840 
841     constexpr char kFS[] = R"(precision mediump float;
842 varying vec4 color;
843 void main()
844 {
845     gl_FragColor = color;
846 }
847 )";
848 
849     ANGLE_GL_PROGRAM(program, kVS, kFS);
850 
851     glUseProgram(program);
852 
853     const GLint color1Loc = glGetAttribLocation(program, "color1");
854     const GLint color2Loc = glGetAttribLocation(program, "color2");
855     ASSERT_NE(-1, color1Loc);
856     ASSERT_NE(-1, color2Loc);
857 
858     const auto &indices = GetQuadIndices();
859 
860     // Make colored corners with red == x or 1 -x , and green = y or 1 - y.
861 
862     std::array<GLColor, 4> baseColors1 = {
863         {GLColor::black, GLColor::red, GLColor::green, GLColor::yellow}};
864     std::array<GLColor, 4> baseColors2 = {
865         {GLColor::yellow, GLColor::green, GLColor::red, GLColor::black}};
866 
867     std::vector<GLColor> colors1;
868     std::vector<GLColor> colors2;
869 
870     for (GLushort index : indices)
871     {
872         colors1.push_back(baseColors1[index]);
873         colors2.push_back(baseColors2[index]);
874     }
875 
876     GLBuffer color1Buffer;
877     glBindBuffer(GL_ARRAY_BUFFER, color1Buffer);
878     glBufferData(GL_ARRAY_BUFFER, colors1.size() * sizeof(GLColor), colors1.data(), GL_STATIC_DRAW);
879     glVertexAttribPointer(color1Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
880     glEnableVertexAttribArray(color1Loc);
881 
882     GLBuffer color2Buffer;
883     glBindBuffer(GL_ARRAY_BUFFER, color2Buffer);
884     glBufferData(GL_ARRAY_BUFFER, colors2.size() * sizeof(GLColor), colors2.data(), GL_STATIC_DRAW);
885     glVertexAttribPointer(color2Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
886     glEnableVertexAttribArray(color2Loc);
887 
888     // Draw a non-indexed quad with all vertex buffers. Should draw yellow to the entire window.
889     drawQuad(program, "position", 0.5f, 1.0f, true);
890     ASSERT_GL_NO_ERROR();
891     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::yellow);
892 }
893 
894 // Creates a 2D texture, no other operations.
TEST_P(SimpleOperationTest,CreateTexture2DNoData)895 TEST_P(SimpleOperationTest, CreateTexture2DNoData)
896 {
897     GLTexture texture;
898     glBindTexture(GL_TEXTURE_2D, texture);
899     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
900     ASSERT_GL_NO_ERROR();
901 }
902 
903 // Creates a 2D texture, no other operations.
TEST_P(SimpleOperationTest,CreateTexture2DWithData)904 TEST_P(SimpleOperationTest, CreateTexture2DWithData)
905 {
906     std::vector<GLColor> colors(16 * 16, GLColor::red);
907 
908     GLTexture texture;
909     glBindTexture(GL_TEXTURE_2D, texture);
910     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
911     ASSERT_GL_NO_ERROR();
912 }
913 
914 // Creates a cube texture, no other operations.
TEST_P(SimpleOperationTest,CreateTextureCubeNoData)915 TEST_P(SimpleOperationTest, CreateTextureCubeNoData)
916 {
917     GLTexture texture;
918     glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
919     for (GLenum cubeFace : kCubeFaces)
920     {
921         glTexImage2D(cubeFace, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
922     }
923     ASSERT_GL_NO_ERROR();
924 }
925 
926 // Creates a cube texture, no other operations.
TEST_P(SimpleOperationTest,CreateTextureCubeWithData)927 TEST_P(SimpleOperationTest, CreateTextureCubeWithData)
928 {
929     std::vector<GLColor> colors(16 * 16, GLColor::red);
930 
931     GLTexture texture;
932     glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
933     for (GLenum cubeFace : kCubeFaces)
934     {
935         glTexImage2D(cubeFace, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
936     }
937     ASSERT_GL_NO_ERROR();
938 }
939 
940 // Creates a program with a texture.
TEST_P(SimpleOperationTest,LinkProgramWithTexture)941 TEST_P(SimpleOperationTest, LinkProgramWithTexture)
942 {
943     ASSERT_NE(0u, get2DTexturedQuadProgram());
944     ASSERT_GL_NO_ERROR();
945 }
946 
947 // Creates a program with a 2D texture and renders with it.
TEST_P(SimpleOperationTest,DrawWith2DTexture)948 TEST_P(SimpleOperationTest, DrawWith2DTexture)
949 {
950     std::array<GLColor, 4> colors = {
951         {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
952 
953     GLTexture tex;
954     glBindTexture(GL_TEXTURE_2D, tex);
955     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
956     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
957     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
958 
959     draw2DTexturedQuad(0.5f, 1.0f, true);
960     ASSERT_GL_NO_ERROR();
961 
962     int w = getWindowWidth() - 2;
963     int h = getWindowHeight() - 2;
964 
965     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
966     EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
967     EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
968     EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
969 }
970 
971 template <typename T>
testDrawElementsLineLoopUsingClientSideMemory(GLenum indexType,int windowWidth,int windowHeight)972 void SimpleOperationTest::testDrawElementsLineLoopUsingClientSideMemory(GLenum indexType,
973                                                                         int windowWidth,
974                                                                         int windowHeight)
975 {
976     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
977     glUseProgram(program);
978 
979     // We expect to draw a square with these 4 vertices with a drawArray call.
980     std::vector<Vector3> vertices;
981     CreatePixelCenterWindowCoords({{32, 96}, {32, 32}, {96, 32}, {96, 96}}, windowWidth,
982                                   windowHeight, &vertices);
983 
984     // If we use these indices to draw however, we should be drawing an hourglass.
985     std::vector<T> indices{3, 2, 1, 0};
986 
987     GLint positionLocation = glGetAttribLocation(program, "position");
988     ASSERT_NE(-1, positionLocation);
989 
990     GLBuffer vertexBuffer;
991     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
992     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
993                  GL_STATIC_DRAW);
994 
995     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
996     glEnableVertexAttribArray(positionLocation);
997     glClear(GL_COLOR_BUFFER_BIT);
998     glDrawElements(GL_LINE_LOOP, 4, indexType, indices.data());
999     glDisableVertexAttribArray(positionLocation);
1000 
1001     ASSERT_GL_NO_ERROR();
1002 
1003     int quarterWidth  = windowWidth / 4;
1004     int quarterHeight = windowHeight / 4;
1005 
1006     // Bottom left
1007     EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight, GLColor::green);
1008 
1009     // Top left
1010     EXPECT_PIXEL_COLOR_EQ(quarterWidth, (quarterHeight * 3), GLColor::green);
1011 
1012     // Top right
1013     EXPECT_PIXEL_COLOR_EQ((quarterWidth * 3), (quarterHeight * 3) - 1, GLColor::green);
1014 
1015     // Verify line is closed between the 2 last vertices
1016     EXPECT_PIXEL_COLOR_EQ((quarterWidth * 2), quarterHeight, GLColor::green);
1017 }
1018 
1019 // Draw a line loop using a drawElement call and client side memory.
TEST_P(SimpleOperationTest,DrawElementsLineLoopUsingUShortClientSideMemory)1020 TEST_P(SimpleOperationTest, DrawElementsLineLoopUsingUShortClientSideMemory)
1021 {
1022     testDrawElementsLineLoopUsingClientSideMemory<GLushort>(GL_UNSIGNED_SHORT, getWindowWidth(),
1023                                                             getWindowHeight());
1024 }
1025 
1026 // Draw a line loop using a drawElement call and client side memory.
TEST_P(SimpleOperationTest,DrawElementsLineLoopUsingUByteClientSideMemory)1027 TEST_P(SimpleOperationTest, DrawElementsLineLoopUsingUByteClientSideMemory)
1028 {
1029     testDrawElementsLineLoopUsingClientSideMemory<GLubyte>(GL_UNSIGNED_BYTE, getWindowWidth(),
1030                                                            getWindowHeight());
1031 }
1032 
1033 // Creates a program with a cube texture and renders with it.
TEST_P(SimpleOperationTest,DrawWithCubeTexture)1034 TEST_P(SimpleOperationTest, DrawWithCubeTexture)
1035 {
1036     std::array<Vector2, 6 * 4> positions = {{
1037         {0, 1}, {1, 1}, {1, 2}, {0, 2} /* first face */,
1038         {1, 0}, {2, 0}, {2, 1}, {1, 1} /* second face */,
1039         {1, 1}, {2, 1}, {2, 2}, {1, 2} /* third face */,
1040         {1, 2}, {2, 2}, {2, 3}, {1, 3} /* fourth face */,
1041         {2, 1}, {3, 1}, {3, 2}, {2, 2} /* fifth face */,
1042         {3, 1}, {4, 1}, {4, 2}, {3, 2} /* sixth face */,
1043     }};
1044 
1045     const float w4 = 1.0f / 4.0f;
1046     const float h3 = 1.0f / 3.0f;
1047 
1048     // This draws a "T" shape based on the four faces of the cube. The window is divided into four
1049     // tiles horizontally and three tiles vertically (hence the w4 and h3 variable naming).
1050     for (Vector2 &pos : positions)
1051     {
1052         pos.data()[0] = pos.data()[0] * w4 * 2.0f - 1.0f;
1053         pos.data()[1] = pos.data()[1] * h3 * 2.0f - 1.0f;
1054     }
1055 
1056     const Vector3 posX(1, 0, 0);
1057     const Vector3 negX(-1, 0, 0);
1058     const Vector3 posY(0, 1, 0);
1059     const Vector3 negY(0, -1, 0);
1060     const Vector3 posZ(0, 0, 1);
1061     const Vector3 negZ(0, 0, -1);
1062 
1063     std::array<Vector3, 6 * 4> coords = {{
1064         posX, posX, posX, posX /* first face */, negX, negX, negX, negX /* second face */,
1065         posY, posY, posY, posY /* third face */, negY, negY, negY, negY /* fourth face */,
1066         posZ, posZ, posZ, posZ /* fifth face */, negZ, negZ, negZ, negZ /* sixth face */,
1067     }};
1068 
1069     const std::array<std::array<GLColor, 4>, 6> colors = {{
1070         {GLColor::red, GLColor::red, GLColor::red, GLColor::red},
1071         {GLColor::green, GLColor::green, GLColor::green, GLColor::green},
1072         {GLColor::blue, GLColor::blue, GLColor::blue, GLColor::blue},
1073         {GLColor::yellow, GLColor::yellow, GLColor::yellow, GLColor::yellow},
1074         {GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan},
1075         {GLColor::magenta, GLColor::magenta, GLColor::magenta, GLColor::magenta},
1076     }};
1077 
1078     GLTexture texture;
1079     glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
1080 
1081     for (size_t faceIndex = 0; faceIndex < kCubeFaces.size(); ++faceIndex)
1082     {
1083         glTexImage2D(kCubeFaces[faceIndex], 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1084                      colors[faceIndex].data());
1085     }
1086     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1087     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1088 
1089     constexpr char kVertexShader[] = R"(attribute vec2 pos;
1090 attribute vec3 coord;
1091 varying vec3 texCoord;
1092 void main()
1093 {
1094     gl_Position = vec4(pos, 0, 1);
1095     texCoord = coord;
1096 })";
1097 
1098     constexpr char kFragmentShader[] = R"(precision mediump float;
1099 varying vec3 texCoord;
1100 uniform samplerCube tex;
1101 void main()
1102 {
1103     gl_FragColor = textureCube(tex, texCoord);
1104 })";
1105 
1106     ANGLE_GL_PROGRAM(program, kVertexShader, kFragmentShader);
1107     GLint samplerLoc = glGetUniformLocation(program, "tex");
1108     ASSERT_EQ(samplerLoc, 0);
1109 
1110     glUseProgram(program);
1111 
1112     GLint posLoc = glGetAttribLocation(program, "pos");
1113     ASSERT_NE(-1, posLoc);
1114 
1115     GLint coordLoc = glGetAttribLocation(program, "coord");
1116     ASSERT_NE(-1, coordLoc);
1117 
1118     GLBuffer posBuffer;
1119     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
1120     glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(Vector2), positions.data(),
1121                  GL_STATIC_DRAW);
1122     glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
1123     glEnableVertexAttribArray(posLoc);
1124 
1125     GLBuffer coordBuffer;
1126     glBindBuffer(GL_ARRAY_BUFFER, coordBuffer);
1127     glBufferData(GL_ARRAY_BUFFER, coords.size() * sizeof(Vector3), coords.data(), GL_STATIC_DRAW);
1128     glVertexAttribPointer(coordLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1129     glEnableVertexAttribArray(coordLoc);
1130 
1131     auto quadIndices = GetQuadIndices();
1132     std::array<GLushort, 6 * 6> kElementsData;
1133     for (GLushort quadIndex = 0; quadIndex < 6; ++quadIndex)
1134     {
1135         for (GLushort elementIndex = 0; elementIndex < 6; ++elementIndex)
1136         {
1137             kElementsData[quadIndex * 6 + elementIndex] = quadIndices[elementIndex] + 4 * quadIndex;
1138         }
1139     }
1140 
1141     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1142     glClear(GL_COLOR_BUFFER_BIT);
1143 
1144     GLBuffer elementBuffer;
1145     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
1146     glBufferData(GL_ELEMENT_ARRAY_BUFFER, kElementsData.size() * sizeof(GLushort),
1147                  kElementsData.data(), GL_STATIC_DRAW);
1148     glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(kElementsData.size()), GL_UNSIGNED_SHORT,
1149                    nullptr);
1150     ASSERT_GL_NO_ERROR();
1151 
1152     for (int faceIndex = 0; faceIndex < 6; ++faceIndex)
1153     {
1154         int index      = faceIndex * 4;
1155         Vector2 center = (positions[index] + positions[index + 1] + positions[index + 2] +
1156                           positions[index + 3]) /
1157                          4.0f;
1158         center *= 0.5f;
1159         center += Vector2(0.5f);
1160         center *= Vector2(getWindowWidth(), getWindowHeight());
1161         EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(center.x()), static_cast<GLint>(center.y()),
1162                               colors[faceIndex][0]);
1163     }
1164 }
1165 
1166 // Tests rendering to a user framebuffer.
TEST_P(SimpleOperationTest,RenderToTexture)1167 TEST_P(SimpleOperationTest, RenderToTexture)
1168 {
1169     constexpr int kSize = 16;
1170 
1171     GLTexture texture;
1172     glBindTexture(GL_TEXTURE_2D, texture);
1173     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1174     ASSERT_GL_NO_ERROR();
1175 
1176     GLFramebuffer framebuffer;
1177     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1178     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1179     ASSERT_GL_NO_ERROR();
1180     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1181 
1182     glViewport(0, 0, kSize, kSize);
1183 
1184     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
1185     drawQuad(program, "position", 0.5f, 1.0f, true);
1186     ASSERT_GL_NO_ERROR();
1187     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1188 }
1189 
1190 // Create a simple basic Renderbuffer.
TEST_P(SimpleOperationTest,CreateRenderbuffer)1191 TEST_P(SimpleOperationTest, CreateRenderbuffer)
1192 {
1193     GLRenderbuffer renderbuffer;
1194     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
1195     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
1196     ASSERT_GL_NO_ERROR();
1197 }
1198 
1199 // Render to a simple color Renderbuffer.
TEST_P(SimpleOperationTest,RenderbufferAttachment)1200 TEST_P(SimpleOperationTest, RenderbufferAttachment)
1201 {
1202     constexpr int kSize = 16;
1203 
1204     GLRenderbuffer renderbuffer;
1205     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
1206     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
1207 
1208     GLFramebuffer framebuffer;
1209     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1210     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
1211     ASSERT_GL_NO_ERROR();
1212     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1213 
1214     glViewport(0, 0, kSize, kSize);
1215 
1216     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
1217     drawQuad(program, "position", 0.5f, 1.0f, true);
1218     ASSERT_GL_NO_ERROR();
1219     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1220 }
1221 
1222 // Tests that using desktop GL_QUADS/GL_POLYGONS enums generate the correct error.
TEST_P(SimpleOperationTest,PrimitiveModeNegativeTest)1223 TEST_P(SimpleOperationTest, PrimitiveModeNegativeTest)
1224 {
1225     // Draw a correct quad.
1226     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
1227     glUseProgram(program);
1228 
1229     GLint positionLocation = glGetAttribLocation(program, "position");
1230     ASSERT_NE(-1, positionLocation);
1231 
1232     setupQuadVertexBuffer(0.5f, 1.0f);
1233     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
1234     glEnableVertexAttribArray(positionLocation);
1235 
1236     // Tests that TRIANGLES works.
1237     glDrawArrays(GL_TRIANGLES, 0, 6);
1238     ASSERT_GL_NO_ERROR();
1239     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1240 
1241     // Tests that specific invalid enums don't work.
1242     glDrawArrays(static_cast<GLenum>(7), 0, 6);
1243     EXPECT_GL_ERROR(GL_INVALID_ENUM);
1244 
1245     glDrawArrays(static_cast<GLenum>(8), 0, 6);
1246     EXPECT_GL_ERROR(GL_INVALID_ENUM);
1247 
1248     glDrawArrays(static_cast<GLenum>(9), 0, 6);
1249     EXPECT_GL_ERROR(GL_INVALID_ENUM);
1250 }
1251 
1252 // Tests that using GL_LINES_ADJACENCY should not crash the app even if the backend doesn't support
1253 // LinesAdjacent mode.
1254 // This is to verify that the crash in crbug.com/1457840 won't happen.
TEST_P(SimpleOperationTest,PrimitiveModeLinesAdjacentNegativeTest)1255 TEST_P(SimpleOperationTest, PrimitiveModeLinesAdjacentNegativeTest)
1256 {
1257     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
1258     glUseProgram(program);
1259 
1260     GLint positionLocation = glGetAttribLocation(program, "position");
1261     ASSERT_NE(-1, positionLocation);
1262 
1263     setupQuadVertexBuffer(0.5f, 1.0f);
1264     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
1265     glEnableVertexAttribArray(positionLocation);
1266 
1267     {
1268         // Tests that TRIANGLES works.
1269         glDrawArrays(GL_TRIANGLES, 0, 6);
1270         ASSERT_GL_NO_ERROR();
1271         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1272     }
1273 
1274     {
1275         // Drawing with GL_LINES_ADJACENCY won't crash even if the backend doesn't support it.
1276         glDrawArrays(GL_LINES_ADJACENCY, 0, 6);
1277 
1278         if (IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"))
1279         {
1280             glDrawArraysInstancedANGLE(GL_LINES_ADJACENCY, 0, 6, 2);
1281         }
1282     }
1283 
1284     // Indexed draws with GL_LINES_ADJACENCY
1285     setupIndexedQuadVertexBuffer(0.5f, 1.0f);
1286     setupIndexedQuadIndexBuffer();
1287 
1288     // Clear GL error state, since ahove calls may have set GL_INVALID_ENUM.
1289     glGetError();
1290 
1291     {
1292         // Tests that TRIANGLES works.
1293         glClear(GL_COLOR_BUFFER_BIT);
1294         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
1295         ASSERT_GL_NO_ERROR();
1296         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1297     }
1298 
1299     {
1300         // Indexed drawing with GL_LINES_ADJACENCY won't crash even if the backend doesn't support
1301         // it.
1302         glDrawElements(GL_LINES_ADJACENCY, 6, GL_UNSIGNED_SHORT, nullptr);
1303         if (IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"))
1304         {
1305             glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr, 1);
1306         }
1307     }
1308 }
1309 
1310 // Tests all primitive modes, including some invalid ones, with a vertex shader that receives
1311 // no data for its vertex attributes (constant values). This is a port of the test case from
1312 // crbug.com/1457840, exercising slightly different code paths.
TEST_P(SimpleOperationTest,DrawsWithNoAttributeData)1313 TEST_P(SimpleOperationTest, DrawsWithNoAttributeData)
1314 {
1315     constexpr char kTestVertexShader[] =
1316         R"(attribute vec4 vPosition;
1317 attribute vec2 texCoord0;
1318 varying vec2 texCoord;
1319 void main() {
1320     gl_Position = vPosition;
1321     texCoord = texCoord0;
1322 })";
1323     constexpr char kTestFragmentShader[] =
1324         R"(precision mediump float;
1325 uniform sampler2D tex;
1326 uniform float divisor;
1327 varying vec2 texCoord;
1328 void main() {
1329     gl_FragData[0] = texture2DProj(tex, vec3(texCoord, divisor));
1330 })";
1331 
1332     constexpr std::array<GLenum, 12> kPrimitiveModes = {
1333         {GL_POINTS, GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP,
1334          GL_TRIANGLE_FAN,
1335 
1336          // Illegal or possibly-illegal modes
1337          GL_QUERY_RESULT, GL_LINES_ADJACENCY, GL_LINE_STRIP_ADJACENCY, GL_TRIANGLES_ADJACENCY,
1338          GL_TRIANGLE_STRIP_ADJACENCY}};
1339 
1340     ANGLE_GL_PROGRAM(program, kTestVertexShader, kTestFragmentShader);
1341     glUseProgram(program);
1342 
1343     for (GLenum mode : kPrimitiveModes)
1344     {
1345         glDrawArrays(mode, 0, 0x8866);
1346     }
1347 
1348     // If the test reaches this point then it hasn't crashed.
1349 }
1350 
1351 // Verify we don't crash when attempting to draw using GL_TRIANGLES without a program bound.
TEST_P(SimpleOperationTest31,DrawTrianglesWithoutProgramBound)1352 TEST_P(SimpleOperationTest31, DrawTrianglesWithoutProgramBound)
1353 {
1354     glDrawArrays(GL_TRIANGLES, 0, 6);
1355 }
1356 
1357 // Verify we don't crash when attempting to draw using GL_LINE_STRIP_ADJACENCY without a program
1358 // bound.
TEST_P(SimpleOperationTest31,DrawLineStripAdjacencyWithoutProgramBound)1359 TEST_P(SimpleOperationTest31, DrawLineStripAdjacencyWithoutProgramBound)
1360 {
1361     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1362 
1363     glDrawArrays(GL_LINE_STRIP_ADJACENCY, 0, 10);
1364 }
1365 
1366 // Verify instanceCount == 0 is no-op
TEST_P(SimpleOperationTest,DrawArraysZeroInstanceCountIsNoOp)1367 TEST_P(SimpleOperationTest, DrawArraysZeroInstanceCountIsNoOp)
1368 {
1369     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"));
1370 
1371     // Draw a correct green quad.
1372     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
1373     glUseProgram(program);
1374 
1375     GLint positionLocation = glGetAttribLocation(program, "position");
1376     ASSERT_NE(-1, positionLocation);
1377 
1378     setupQuadVertexBuffer(0.5f, 1.0f);
1379     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
1380     glEnableVertexAttribArray(positionLocation);
1381 
1382     // If nothing is drawn it should be red
1383     glClearColor(1.0, 0.0, 0.0, 1.0);
1384 
1385     {
1386         // Non-instanced draw should draw
1387         glClear(GL_COLOR_BUFFER_BIT);
1388         glDrawArrays(GL_TRIANGLES, 0, 6);
1389         ASSERT_GL_NO_ERROR();
1390         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1391     }
1392     {
1393         // instanceCount == 0 should be no-op
1394         glClear(GL_COLOR_BUFFER_BIT);
1395         glDrawArraysInstancedANGLE(GL_TRIANGLES, 0, 6, 0);
1396         ASSERT_GL_NO_ERROR();
1397         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1398     }
1399     {
1400         // instanceCount > 0 should draw
1401         glClear(GL_COLOR_BUFFER_BIT);
1402         glDrawArraysInstancedANGLE(GL_TRIANGLES, 0, 6, 1);
1403         ASSERT_GL_NO_ERROR();
1404         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1405     }
1406 }
1407 
1408 // Verify instanceCount == 0 is no-op
TEST_P(SimpleOperationTest,DrawElementsZeroInstanceCountIsNoOp)1409 TEST_P(SimpleOperationTest, DrawElementsZeroInstanceCountIsNoOp)
1410 {
1411     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"));
1412 
1413     // Draw a correct green quad.
1414     ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
1415     glUseProgram(program);
1416 
1417     GLint positionLocation = glGetAttribLocation(program, "position");
1418     ASSERT_NE(-1, positionLocation);
1419 
1420     setupIndexedQuadVertexBuffer(0.5f, 1.0f);
1421     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
1422     glEnableVertexAttribArray(positionLocation);
1423 
1424     setupIndexedQuadIndexBuffer();
1425 
1426     // If nothing is drawn it should be red
1427     glClearColor(1.0, 0.0, 0.0, 1.0);
1428 
1429     {
1430         // Non-instanced draw should draw
1431         glClear(GL_COLOR_BUFFER_BIT);
1432         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
1433         ASSERT_GL_NO_ERROR();
1434         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1435     }
1436     {
1437         // instanceCount == 0 should be no-op
1438         glClear(GL_COLOR_BUFFER_BIT);
1439         glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr, 0);
1440         ASSERT_GL_NO_ERROR();
1441         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1442     }
1443     {
1444         // instanceCount > 0 should draw
1445         glClear(GL_COLOR_BUFFER_BIT);
1446         glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr, 1);
1447         ASSERT_GL_NO_ERROR();
1448         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1449     }
1450 }
1451 
1452 // Test that sample coverage does not affect single sample rendering
TEST_P(SimpleOperationTest,DrawSingleSampleWithCoverage)1453 TEST_P(SimpleOperationTest, DrawSingleSampleWithCoverage)
1454 {
1455     GLint sampleBuffers = -1;
1456     glGetIntegerv(GL_SAMPLE_BUFFERS, &sampleBuffers);
1457     ASSERT_EQ(sampleBuffers, 0);
1458 
1459     GLint samples = -1;
1460     glGetIntegerv(GL_SAMPLES, &samples);
1461     ASSERT_EQ(samples, 0);
1462 
1463     glClearColor(1.0, 0.0, 1.0, 1.0);
1464     glClear(GL_COLOR_BUFFER_BIT);
1465 
1466     glEnable(GL_SAMPLE_COVERAGE);
1467     glSampleCoverage(0.0f, false);
1468 
1469     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1470     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
1471     ASSERT_GL_NO_ERROR();
1472 
1473     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1474 }
1475 
1476 // Test that sample coverage affects multi sample rendering with only one sample
TEST_P(SimpleOperationTest,DrawSingleMultiSampleWithCoverage)1477 TEST_P(SimpleOperationTest, DrawSingleMultiSampleWithCoverage)
1478 {
1479     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
1480 
1481     GLFramebuffer fbo;
1482     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1483 
1484     GLRenderbuffer rbo;
1485     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1486     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
1487     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1488     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1489 
1490     GLint samples = -1;
1491     glGetIntegerv(GL_SAMPLES, &samples);
1492     ASSERT_GT(samples, 0);
1493     ANGLE_SKIP_TEST_IF(samples != 1);
1494 
1495     glClearColor(0.0, 0.0, 1.0, 1.0);
1496     glClear(GL_COLOR_BUFFER_BIT);
1497 
1498     glEnable(GL_SAMPLE_COVERAGE);
1499     glSampleCoverage(0.0f, false);
1500 
1501     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1502     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
1503     ASSERT_GL_NO_ERROR();
1504 
1505     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1506     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1507     glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1508     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1509     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1510 }
1511 
1512 // Test that alpha-to-coverage does not affect single-sampled rendering
TEST_P(SimpleOperationTest,DrawSingleSampleWithAlphaToCoverage)1513 TEST_P(SimpleOperationTest, DrawSingleSampleWithAlphaToCoverage)
1514 {
1515     GLint sampleBuffers = -1;
1516     glGetIntegerv(GL_SAMPLE_BUFFERS, &sampleBuffers);
1517     ASSERT_EQ(sampleBuffers, 0);
1518 
1519     GLint samples = -1;
1520     glGetIntegerv(GL_SAMPLES, &samples);
1521     ASSERT_EQ(samples, 0);
1522 
1523     glClearColor(1.0, 0.0, 1.0, 1.0);
1524     glClear(GL_COLOR_BUFFER_BIT);
1525 
1526     glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1527 
1528     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1529     glUseProgram(program);
1530     glUniform4f(glGetUniformLocation(program, essl1_shaders::ColorUniform()), 0, 1, 0, 0);
1531     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
1532     ASSERT_GL_NO_ERROR();
1533 
1534     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(0, 255, 0, 0));
1535 }
1536 
1537 // Test that alpha-to-coverage affects multisampled rendering with only one sample
TEST_P(SimpleOperationTest,DrawSingleMultiSampleWithAlphaToCoverage)1538 TEST_P(SimpleOperationTest, DrawSingleMultiSampleWithAlphaToCoverage)
1539 {
1540     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
1541 
1542     GLFramebuffer fbo;
1543     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1544 
1545     GLRenderbuffer rbo;
1546     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1547     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
1548     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1549     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1550 
1551     GLint samples = -1;
1552     glGetIntegerv(GL_SAMPLES, &samples);
1553     ASSERT_GT(samples, 0);
1554     ANGLE_SKIP_TEST_IF(samples != 1);
1555 
1556     glClearColor(0.0, 0.0, 1.0, 1.0);
1557     glClear(GL_COLOR_BUFFER_BIT);
1558 
1559     glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1560 
1561     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1562     glUseProgram(program);
1563     glUniform4f(glGetUniformLocation(program, essl1_shaders::ColorUniform()), 0, 1, 0, 0);
1564     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
1565     ASSERT_GL_NO_ERROR();
1566 
1567     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1568     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1569     glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1570     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1571     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1572 }
1573 
1574 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
1575 // tests should be run against.
1576 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(
1577     SimpleOperationTest,
1578     ES3_METAL().enable(Feature::ForceBufferGPUStorage),
1579     ES3_METAL().disable(Feature::HasExplicitMemBarrier).disable(Feature::HasCheapRenderPass),
1580     WithVulkanSecondaries(ES3_VULKAN_SWIFTSHADER()));
1581 
1582 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(
1583     TriangleFanDrawTest,
1584     ES3_METAL().enable(Feature::ForceBufferGPUStorage),
1585     ES3_METAL().disable(Feature::HasExplicitMemBarrier).disable(Feature::HasCheapRenderPass));
1586 
1587 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31(SimpleOperationTest31);
1588 
1589 }  // namespace
1590