• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2012 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 // ANGLETest:
7 //   Implementation of common ANGLE testing fixture.
8 //
9 
10 #ifndef ANGLE_TESTS_ANGLE_TEST_H_
11 #define ANGLE_TESTS_ANGLE_TEST_H_
12 
13 #include <gtest/gtest.h>
14 #include <algorithm>
15 #include <array>
16 
17 #include "RenderDoc.h"
18 #include "angle_test_configs.h"
19 #include "angle_test_platform.h"
20 #include "common/angleutils.h"
21 #include "common/system_utils.h"
22 #include "common/vector_utils.h"
23 #include "platform/PlatformMethods.h"
24 #include "util/EGLWindow.h"
25 #include "util/shader_utils.h"
26 #include "util/util_gl.h"
27 
28 namespace angle
29 {
30 struct SystemInfo;
31 class RNG;
32 }  // namespace angle
33 
34 #define ASSERT_GL_TRUE(a) ASSERT_EQ(static_cast<GLboolean>(GL_TRUE), (a))
35 #define ASSERT_GL_FALSE(a) ASSERT_EQ(static_cast<GLboolean>(GL_FALSE), (a))
36 #define EXPECT_GL_TRUE(a) EXPECT_EQ(static_cast<GLboolean>(GL_TRUE), (a))
37 #define EXPECT_GL_FALSE(a) EXPECT_EQ(static_cast<GLboolean>(GL_FALSE), (a))
38 
39 #define EXPECT_GL_ERROR(err) EXPECT_EQ(static_cast<GLenum>(err), glGetError())
40 #define EXPECT_GL_NO_ERROR() EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError())
41 
42 #define ASSERT_GL_ERROR(err) ASSERT_EQ(static_cast<GLenum>(err), glGetError())
43 #define ASSERT_GL_NO_ERROR() ASSERT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError())
44 
45 #define EXPECT_EGL_ERROR(err) EXPECT_EQ((err), eglGetError())
46 #define EXPECT_EGL_SUCCESS() EXPECT_EGL_ERROR(EGL_SUCCESS)
47 
48 // EGLBoolean is |unsigned int| but EGL_TRUE is 0, not 0u.
49 #define ASSERT_EGL_TRUE(a) ASSERT_EQ(static_cast<EGLBoolean>(EGL_TRUE), static_cast<EGLBoolean>(a))
50 #define ASSERT_EGL_FALSE(a) \
51     ASSERT_EQ(static_cast<EGLBoolean>(EGL_FALSE), static_cast<EGLBoolean>(a))
52 #define EXPECT_EGL_TRUE(a) EXPECT_EQ(static_cast<EGLBoolean>(EGL_TRUE), static_cast<EGLBoolean>(a))
53 #define EXPECT_EGL_FALSE(a) \
54     EXPECT_EQ(static_cast<EGLBoolean>(EGL_FALSE), static_cast<EGLBoolean>(a))
55 
56 #define ASSERT_EGL_ERROR(err) ASSERT_EQ((err), eglGetError())
57 #define ASSERT_EGL_SUCCESS() ASSERT_EGL_ERROR(EGL_SUCCESS)
58 
59 #define ASSERT_GLENUM_EQ(expected, actual) \
60     ASSERT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
61 #define EXPECT_GLENUM_EQ(expected, actual) \
62     EXPECT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
63 #define ASSERT_GLENUM_NE(expected, actual) \
64     ASSERT_NE(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
65 #define EXPECT_GLENUM_NE(expected, actual) \
66     EXPECT_NE(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
67 
68 testing::AssertionResult AssertEGLEnumsEqual(const char *lhsExpr,
69                                              const char *rhsExpr,
70                                              EGLenum lhs,
71                                              EGLenum rhs);
72 
73 #define ASSERT_EGLENUM_EQ(expected, actual)                                  \
74     ASSERT_PRED_FORMAT2(AssertEGLEnumsEqual, static_cast<EGLenum>(expected), \
75                         static_cast<EGLenum>(actual))
76 #define EXPECT_EGLENUM_EQ(expected, actual)                                  \
77     EXPECT_PRED_FORMAT2(AssertEGLEnumsEqual, static_cast<EGLenum>(expected), \
78                         static_cast<EGLenum>(actual))
79 
80 #define ASSERT_GL_FRAMEBUFFER_COMPLETE(framebuffer) \
81     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(framebuffer))
82 #define EXPECT_GL_FRAMEBUFFER_COMPLETE(framebuffer) \
83     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(framebuffer))
84 
85 namespace angle
86 {
87 struct GLColorRGB
88 {
GLColorRGBGLColorRGB89     constexpr GLColorRGB() : R(0), G(0), B(0) {}
GLColorRGBGLColorRGB90     constexpr GLColorRGB(GLubyte r, GLubyte g, GLubyte b) : R(r), G(g), B(b) {}
91     GLColorRGB(const angle::Vector3 &floatColor);
92 
dataGLColorRGB93     const GLubyte *data() const { return &R; }
dataGLColorRGB94     GLubyte *data() { return &R; }
95 
96     GLubyte R, G, B;
97 
98     static const GLColorRGB black;
99     static const GLColorRGB blue;
100     static const GLColorRGB green;
101     static const GLColorRGB red;
102     static const GLColorRGB yellow;
103 };
104 
105 struct GLColorRG
106 {
GLColorRGGLColorRG107     constexpr GLColorRG() : R(0), G(0) {}
GLColorRGGLColorRG108     constexpr GLColorRG(GLubyte r, GLubyte g) : R(r), G(g) {}
109     GLColorRG(const angle::Vector2 &floatColor);
110 
dataGLColorRG111     const GLubyte *data() const { return &R; }
dataGLColorRG112     GLubyte *data() { return &R; }
113 
114     GLubyte R, G;
115 };
116 
117 struct GLColorR
118 {
GLColorRGLColorR119     constexpr GLColorR() : R(0) {}
GLColorRGLColorR120     constexpr GLColorR(GLubyte r) : R(r) {}
121     GLColorR(const float floatColor);
122 
dataGLColorR123     const GLubyte *data() const { return &R; }
dataGLColorR124     GLubyte *data() { return &R; }
125 
126     GLubyte R;
127 };
128 
129 struct GLColor
130 {
GLColorGLColor131     constexpr GLColor() : R(0), G(0), B(0), A(0) {}
GLColorGLColor132     constexpr GLColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) : R(r), G(g), B(b), A(a) {}
133     GLColor(const angle::Vector4 &floatColor);
134     GLColor(GLuint colorValue);
135 
136     angle::Vector4 toNormalizedVector() const;
137 
138     GLubyte &operator[](size_t index) { return (&R)[index]; }
139 
140     const GLubyte &operator[](size_t index) const { return (&R)[index]; }
141 
dataGLColor142     const GLubyte *data() const { return &R; }
dataGLColor143     GLubyte *data() { return &R; }
144 
145     GLuint asUint() const;
146 
147     testing::AssertionResult ExpectNear(const GLColor &expected, const GLColor &err) const;
148 
149     GLubyte R, G, B, A;
150 
151     static const GLColor black;
152     static const GLColor blue;
153     static const GLColor cyan;
154     static const GLColor green;
155     static const GLColor red;
156     static const GLColor transparentBlack;
157     static const GLColor white;
158     static const GLColor yellow;
159     static const GLColor magenta;
160 };
161 
162 struct GLColor16UI
163 {
GLColor16UIGLColor16UI164     constexpr GLColor16UI() : GLColor16UI(0, 0, 0, 0) {}
GLColor16UIGLColor16UI165     constexpr GLColor16UI(GLushort r, GLushort g, GLushort b, GLushort a) : R(r), G(g), B(b), A(a)
166     {}
167 
168     GLushort R, G, B, A;
169 };
170 
171 struct GLColor32F
172 {
GLColor32FGLColor32F173     constexpr GLColor32F() : GLColor32F(0.0f, 0.0f, 0.0f, 0.0f) {}
GLColor32FGLColor32F174     constexpr GLColor32F(GLfloat r, GLfloat g, GLfloat b, GLfloat a) : R(r), G(g), B(b), A(a) {}
175 
176     GLfloat R, G, B, A;
177 };
178 
179 static constexpr GLColor32F kFloatBlack = {0.0f, 0.0f, 0.0f, 1.0f};
180 static constexpr GLColor32F kFloatRed   = {1.0f, 0.0f, 0.0f, 1.0f};
181 static constexpr GLColor32F kFloatGreen = {0.0f, 1.0f, 0.0f, 1.0f};
182 static constexpr GLColor32F kFloatBlue  = {0.0f, 0.0f, 1.0f, 1.0f};
183 
184 // The input here for pixelPoints are the expected integer window coordinates, we add .5 to every
185 // one of them and re-scale the numbers to be between [-1,1]. Using this technique, we can make
186 // sure the rasterization stage will end up drawing pixels at the expected locations.
187 void CreatePixelCenterWindowCoords(const std::vector<Vector2> &pixelPoints,
188                                    int windowWidth,
189                                    int windowHeight,
190                                    std::vector<Vector3> *outVertices);
191 
192 // Useful to cast any type to GLubyte.
193 template <typename TR, typename TG, typename TB, typename TA>
MakeGLColor(TR r,TG g,TB b,TA a)194 GLColor MakeGLColor(TR r, TG g, TB b, TA a)
195 {
196     return GLColor(static_cast<GLubyte>(r), static_cast<GLubyte>(g), static_cast<GLubyte>(b),
197                    static_cast<GLubyte>(a));
198 }
199 
200 GLColor RandomColor(angle::RNG *rng);
201 
202 bool operator==(const GLColor &a, const GLColor &b);
203 bool operator!=(const GLColor &a, const GLColor &b);
204 std::ostream &operator<<(std::ostream &ostream, const GLColor &color);
205 GLColor ReadColor(GLint x, GLint y);
206 
207 bool operator==(const GLColorRGB &a, const GLColorRGB &b);
208 bool operator!=(const GLColorRGB &a, const GLColorRGB &b);
209 std::ostream &operator<<(std::ostream &ostream, const GLColorRGB &color);
210 
211 // Useful to cast any type to GLfloat.
212 template <typename TR, typename TG, typename TB, typename TA>
MakeGLColor32F(TR r,TG g,TB b,TA a)213 GLColor32F MakeGLColor32F(TR r, TG g, TB b, TA a)
214 {
215     return GLColor32F(static_cast<GLfloat>(r), static_cast<GLfloat>(g), static_cast<GLfloat>(b),
216                       static_cast<GLfloat>(a));
217 }
218 
219 bool operator==(const GLColor32F &a, const GLColor32F &b);
220 std::ostream &operator<<(std::ostream &ostream, const GLColor32F &color);
221 GLColor32F ReadColor32F(GLint x, GLint y);
222 
223 constexpr std::array<GLenum, 6> kCubeFaces = {
224     {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
225      GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
226      GL_TEXTURE_CUBE_MAP_NEGATIVE_Z}};
227 
228 void LoadEntryPointsWithUtilLoader(angle::GLESDriverType driver);
229 
230 }  // namespace angle
231 
232 #define EXPECT_PIXEL_EQ(x, y, r, g, b, a) \
233     EXPECT_EQ(angle::MakeGLColor(r, g, b, a), angle::ReadColor(x, y))
234 
235 #define EXPECT_PIXEL_NE(x, y, r, g, b, a) \
236     EXPECT_NE(angle::MakeGLColor(r, g, b, a), angle::ReadColor(x, y))
237 
238 #define EXPECT_PIXEL_32F_EQ(x, y, r, g, b, a) \
239     EXPECT_EQ(angle::MakeGLColor32F(r, g, b, a), angle::ReadColor32F(x, y))
240 
241 #define EXPECT_PIXEL_ALPHA_EQ(x, y, a) EXPECT_EQ(a, angle::ReadColor(x, y).A)
242 
243 #define EXPECT_PIXEL_ALPHA32F_EQ(x, y, a) EXPECT_EQ(a, angle::ReadColor32F(x, y).A)
244 
245 #define EXPECT_PIXEL_COLOR_EQ(x, y, angleColor) EXPECT_EQ(angleColor, angle::ReadColor(x, y))
246 #define EXPECT_PIXEL_COLOR_EQ_VEC2(vec2, angleColor) \
247     EXPECT_EQ(angleColor,                            \
248               angle::ReadColor(static_cast<GLint>(vec2.x()), static_cast<GLint>(vec2.y())))
249 
250 #define EXPECT_PIXEL_COLOR32F_EQ(x, y, angleColor) EXPECT_EQ(angleColor, angle::ReadColor32F(x, y))
251 
252 #define EXPECT_PIXEL_RECT_EQ(x, y, width, height, color)                                           \
253     do                                                                                             \
254     {                                                                                              \
255         std::vector<GLColor> actualColors((width) * (height));                                     \
256         glReadPixels((x), (y), (width), (height), GL_RGBA, GL_UNSIGNED_BYTE, actualColors.data()); \
257         std::vector<GLColor> expectedColors((width) * (height), color);                            \
258         EXPECT_EQ(expectedColors, actualColors);                                                   \
259     } while (0)
260 
261 #define EXPECT_PIXEL_NEAR_HELPER(x, y, r, g, b, a, abs_error, ctype, format, type) \
262     do                                                                             \
263     {                                                                              \
264         ctype pixel[4];                                                            \
265         glReadPixels((x), (y), 1, 1, format, type, pixel);                         \
266         EXPECT_GL_NO_ERROR();                                                      \
267         EXPECT_NEAR((r), pixel[0], abs_error);                                     \
268         EXPECT_NEAR((g), pixel[1], abs_error);                                     \
269         EXPECT_NEAR((b), pixel[2], abs_error);                                     \
270         EXPECT_NEAR((a), pixel[3], abs_error);                                     \
271     } while (0)
272 
273 #define EXPECT_PIXEL_EQ_HELPER(x, y, r, g, b, a, ctype, format, type) \
274     do                                                                \
275     {                                                                 \
276         ctype pixel[4];                                               \
277         glReadPixels((x), (y), 1, 1, format, type, pixel);            \
278         EXPECT_GL_NO_ERROR();                                         \
279         EXPECT_EQ((r), pixel[0]);                                     \
280         EXPECT_EQ((g), pixel[1]);                                     \
281         EXPECT_EQ((b), pixel[2]);                                     \
282         EXPECT_EQ((a), pixel[3]);                                     \
283     } while (0)
284 
285 #define EXPECT_PIXEL_NEAR(x, y, r, g, b, a, abs_error) \
286     EXPECT_PIXEL_NEAR_HELPER(x, y, r, g, b, a, abs_error, GLubyte, GL_RGBA, GL_UNSIGNED_BYTE)
287 
288 #define EXPECT_PIXEL_32F_NEAR(x, y, r, g, b, a, abs_error) \
289     EXPECT_PIXEL_NEAR_HELPER(x, y, r, g, b, a, abs_error, GLfloat, GL_RGBA, GL_FLOAT)
290 
291 #define EXPECT_PIXEL_8I(x, y, r, g, b, a) \
292     EXPECT_PIXEL_EQ_HELPER(x, y, r, g, b, a, GLbyte, GL_RGBA_INTEGER, GL_BYTE)
293 
294 #define EXPECT_PIXEL_8UI(x, y, r, g, b, a) \
295     EXPECT_PIXEL_EQ_HELPER(x, y, r, g, b, a, GLubyte, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE)
296 
297 #define EXPECT_PIXEL_16UI(x, y, r, g, b, a) \
298     EXPECT_PIXEL_EQ_HELPER(x, y, r, g, b, a, GLushort, GL_RGBA, GL_UNSIGNED_SHORT)
299 
300 #define EXPECT_PIXEL_16UI_COLOR(x, y, color) \
301     EXPECT_PIXEL_16UI(x, y, color.R, color.G, color.B, color.A)
302 
303 // TODO(jmadill): Figure out how we can use GLColor's nice printing with EXPECT_NEAR.
304 #define EXPECT_PIXEL_COLOR_NEAR(x, y, angleColor, abs_error) \
305     EXPECT_PIXEL_NEAR(x, y, angleColor.R, angleColor.G, angleColor.B, angleColor.A, abs_error)
306 
307 #define EXPECT_PIXEL_COLOR32F_NEAR(x, y, angleColor, abs_error) \
308     EXPECT_PIXEL32F_NEAR(x, y, angleColor.R, angleColor.G, angleColor.B, angleColor.A, abs_error)
309 
310 #define EXPECT_COLOR_NEAR(expected, actual, abs_error) \
311     do                                                 \
312     {                                                  \
313         EXPECT_NEAR(expected.R, actual.R, abs_error);  \
314         EXPECT_NEAR(expected.G, actual.G, abs_error);  \
315         EXPECT_NEAR(expected.B, actual.B, abs_error);  \
316         EXPECT_NEAR(expected.A, actual.A, abs_error);  \
317     } while (0)
318 #define EXPECT_PIXEL32F_NEAR(x, y, r, g, b, a, abs_error)       \
319     do                                                          \
320     {                                                           \
321         GLfloat pixel[4];                                       \
322         glReadPixels((x), (y), 1, 1, GL_RGBA, GL_FLOAT, pixel); \
323         EXPECT_GL_NO_ERROR();                                   \
324         EXPECT_NEAR((r), pixel[0], abs_error);                  \
325         EXPECT_NEAR((g), pixel[1], abs_error);                  \
326         EXPECT_NEAR((b), pixel[2], abs_error);                  \
327         EXPECT_NEAR((a), pixel[3], abs_error);                  \
328     } while (0)
329 
330 #define EXPECT_PIXEL_COLOR32F_NEAR(x, y, angleColor, abs_error) \
331     EXPECT_PIXEL32F_NEAR(x, y, angleColor.R, angleColor.G, angleColor.B, angleColor.A, abs_error)
332 
333 #define EXPECT_PIXEL_STENCIL_EQ(x, y, expected)                                    \
334     do                                                                             \
335     {                                                                              \
336         GLubyte actual;                                                            \
337         glReadPixels((x), (y), 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &actual); \
338         EXPECT_GL_NO_ERROR();                                                      \
339         EXPECT_EQ((expected), actual);                                             \
340     } while (0)
341 
342 class ANGLETestBase;
343 class EGLWindow;
344 class GLWindowBase;
345 class OSWindow;
346 class WGLWindow;
347 
348 struct TestPlatformContext final : private angle::NonCopyable
349 {
350     bool ignoreMessages        = false;
351     bool warningsAsErrors      = false;
352     ANGLETestBase *currentTest = nullptr;
353 };
354 
355 class ANGLETestBase
356 {
357   protected:
358     ANGLETestBase(const angle::PlatformParameters &params);
359     virtual ~ANGLETestBase();
360 
361   public:
362     void setWindowVisible(OSWindow *osWindow, bool isVisible);
363 
overrideWorkaroundsD3D(angle::FeaturesD3D * featuresD3D)364     virtual void overrideWorkaroundsD3D(angle::FeaturesD3D *featuresD3D) {}
overrideFeaturesVk(angle::FeaturesVk * featuresVulkan)365     virtual void overrideFeaturesVk(angle::FeaturesVk *featuresVulkan) {}
366 
367     static void ReleaseFixtures();
368 
isSwiftshader()369     bool isSwiftshader() const
370     {
371         // Renderer might be swiftshader even if local swiftshader not used.
372         return mCurrentParams->isSwiftshader() || angle::IsSwiftshaderDevice();
373     }
374 
enableDebugLayers()375     bool enableDebugLayers() const
376     {
377         return mCurrentParams->eglParameters.debugLayersEnabled != EGL_FALSE;
378     }
379 
380   protected:
381     void ANGLETestSetUp();
382     void ANGLETestPreTearDown();
383     void ANGLETestTearDown();
384 
385     virtual void swapBuffers();
386 
387     void setupQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale);
388     void setupIndexedQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale);
389     void setupIndexedQuadIndexBuffer();
390 
391     void drawQuad(GLuint program, const std::string &positionAttribName, GLfloat positionAttribZ);
392     void drawQuad(GLuint program,
393                   const std::string &positionAttribName,
394                   GLfloat positionAttribZ,
395                   GLfloat positionAttribXYScale);
396     void drawQuad(GLuint program,
397                   const std::string &positionAttribName,
398                   GLfloat positionAttribZ,
399                   GLfloat positionAttribXYScale,
400                   bool useVertexBuffer);
401     void drawQuadInstanced(GLuint program,
402                            const std::string &positionAttribName,
403                            GLfloat positionAttribZ,
404                            GLfloat positionAttribXYScale,
405                            bool useVertexBuffer,
406                            GLuint numInstances);
407     void drawPatches(GLuint program,
408                      const std::string &positionAttribName,
409                      GLfloat positionAttribZ,
410                      GLfloat positionAttribXYScale,
411                      bool useVertexBuffer);
412 
413     void drawQuadPPO(GLuint vertProgram,
414                      const std::string &positionAttribName,
415                      const GLfloat positionAttribZ,
416                      const GLfloat positionAttribXYScale);
417 
418     static std::array<angle::Vector3, 6> GetQuadVertices();
419     static std::array<GLushort, 6> GetQuadIndices();
420     static std::array<angle::Vector3, 4> GetIndexedQuadVertices();
421 
422     void drawIndexedQuad(GLuint program,
423                          const std::string &positionAttribName,
424                          GLfloat positionAttribZ);
425     void drawIndexedQuad(GLuint program,
426                          const std::string &positionAttribName,
427                          GLfloat positionAttribZ,
428                          GLfloat positionAttribXYScale);
429     void drawIndexedQuad(GLuint program,
430                          const std::string &positionAttribName,
431                          GLfloat positionAttribZ,
432                          GLfloat positionAttribXYScale,
433                          bool useBufferObject);
434 
435     void drawIndexedQuad(GLuint program,
436                          const std::string &positionAttribName,
437                          GLfloat positionAttribZ,
438                          GLfloat positionAttribXYScale,
439                          bool useBufferObject,
440                          bool restrictedRange);
441 
442     void draw2DTexturedQuad(GLfloat positionAttribZ,
443                             GLfloat positionAttribXYScale,
444                             bool useVertexBuffer);
445 
446     // The layer parameter chooses the 3D texture layer to sample from.
447     void draw3DTexturedQuad(GLfloat positionAttribZ,
448                             GLfloat positionAttribXYScale,
449                             bool useVertexBuffer,
450                             float layer);
451 
452     void setWindowWidth(int width);
453     void setWindowHeight(int height);
454     void setConfigRedBits(int bits);
455     void setConfigGreenBits(int bits);
456     void setConfigBlueBits(int bits);
457     void setConfigAlphaBits(int bits);
458     void setConfigDepthBits(int bits);
459     void setConfigStencilBits(int bits);
460     void setConfigComponentType(EGLenum componentType);
461     void setMultisampleEnabled(bool enabled);
462     void setSamples(EGLint samples);
463     void setDebugEnabled(bool enabled);
464     void setNoErrorEnabled(bool enabled);
465     void setWebGLCompatibilityEnabled(bool webglCompatibility);
466     void setExtensionsEnabled(bool extensionsEnabled);
467     void setRobustAccess(bool enabled);
468     void setBindGeneratesResource(bool bindGeneratesResource);
469     void setClientArraysEnabled(bool enabled);
470     void setRobustResourceInit(bool enabled);
471     void setContextProgramCacheEnabled(bool enabled);
472     void setContextResetStrategy(EGLenum resetStrategy);
473     void forceNewDisplay();
474 
475     // Some EGL extension tests would like to defer the Context init until the test body.
476     void setDeferContextInit(bool enabled);
477 
478     int getClientMajorVersion() const;
479     int getClientMinorVersion() const;
480 
481     GLWindowBase *getGLWindow() const;
482     EGLWindow *getEGLWindow() const;
483     int getWindowWidth() const;
484     int getWindowHeight() const;
485     bool isEmulatedPrerotation() const;
486 
487     EGLint getPlatformRenderer() const;
488 
489     void ignoreD3D11SDKLayersWarnings();
490 
491     // Allows a test to be more restrictive about platform warnings.
492     void treatPlatformWarningsAsErrors();
493 
getOSWindow()494     OSWindow *getOSWindow() { return mFixture->osWindow; }
495 
496     GLuint get2DTexturedQuadProgram();
497 
498     // Has a float uniform "u_layer" to choose the 3D texture layer.
499     GLuint get3DTexturedQuadProgram();
500 
501     class ScopedIgnorePlatformMessages : angle::NonCopyable
502     {
503       public:
504         ScopedIgnorePlatformMessages();
505         ~ScopedIgnorePlatformMessages();
506     };
507 
508     // Can be used before we get a GL context.
isGLRenderer()509     bool isGLRenderer() const
510     {
511         return mCurrentParams->getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
512     }
513 
isGLESRenderer()514     bool isGLESRenderer() const
515     {
516         return mCurrentParams->getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
517     }
518 
isD3D11Renderer()519     bool isD3D11Renderer() const
520     {
521         return mCurrentParams->getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
522     }
523 
isVulkanRenderer()524     bool isVulkanRenderer() const
525     {
526         return mCurrentParams->getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
527     }
528 
isVulkanSwiftshaderRenderer()529     bool isVulkanSwiftshaderRenderer() const
530     {
531         return mCurrentParams->getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE &&
532                mCurrentParams->isSwiftshader();
533     }
534 
isAsyncCommandQueueFeatureEnabled()535     bool isAsyncCommandQueueFeatureEnabled() const
536     {
537         return mCurrentParams->eglParameters.asyncCommandQueueFeatureVulkan == EGL_TRUE;
538     }
539 
540     bool platformSupportsMultithreading() const;
541 
isAllocateNonZeroMemoryEnabled()542     bool isAllocateNonZeroMemoryEnabled() const
543     {
544         return mCurrentParams->getAllocateNonZeroMemoryFeature() == EGL_TRUE;
545     }
546 
547     bool mIsSetUp = false;
548 
549   private:
550     void checkD3D11SDKLayersMessages();
551 
552     void drawQuad(GLuint program,
553                   const std::string &positionAttribName,
554                   GLfloat positionAttribZ,
555                   GLfloat positionAttribXYScale,
556                   bool useVertexBuffer,
557                   bool useInstancedDrawCalls,
558                   bool useTessellationPatches,
559                   GLuint numInstances);
560 
561     void initOSWindow();
562 
563     struct TestFixture
564     {
565         TestFixture();
566         ~TestFixture();
567 
568         EGLWindow *eglWindow = nullptr;
569         WGLWindow *wglWindow = nullptr;
570         OSWindow *osWindow   = nullptr;
571         ConfigParameters configParams;
572         uint32_t reuseCounter = 0;
573     };
574 
575     int mWidth;
576     int mHeight;
577 
578     bool mIgnoreD3D11SDKLayersWarnings;
579 
580     // Used for indexed quad rendering
581     GLuint mQuadVertexBuffer;
582     GLuint mQuadIndexBuffer;
583 
584     // Used for texture rendering.
585     GLuint m2DTexturedQuadProgram;
586     GLuint m3DTexturedQuadProgram;
587 
588     bool mDeferContextInit;
589     bool mAlwaysForceNewDisplay;
590     bool mForceNewDisplay;
591 
592     bool mSetUpCalled;
593     bool mTearDownCalled;
594 
595     // Usually, we use an OS Window per "fixture" (a frontend and backend combination).
596     // This allows:
597     // 1. Reusing EGL Display on Windows.
598     //    Other platforms have issues with display reuse even if a window per fixture is used.
599     // 2. Hiding only SwiftShader OS Window on Linux.
600     //    OS Windows for other backends must be visible, to allow driver to communicate with X11.
601     // However, we must use a single OS Window for all backends on Android,
602     // since test Application can have only one window.
603     static OSWindow *mOSWindowSingleton;
604 
605     static std::map<angle::PlatformParameters, TestFixture> gFixtures;
606     const angle::PlatformParameters *mCurrentParams;
607     TestFixture *mFixture;
608 
609     RenderDoc mRenderDoc;
610 
611     // Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan.
612     static Optional<EGLint> mLastRendererType;
613     static Optional<angle::GLESDriverType> mLastLoadedDriver;
614 };
615 
616 template <typename Params = angle::PlatformParameters>
617 class ANGLETestWithParam : public ANGLETestBase, public ::testing::TestWithParam<Params>
618 {
619   protected:
620     ANGLETestWithParam();
621 
testSetUp()622     virtual void testSetUp() {}
testTearDown()623     virtual void testTearDown() {}
624 
recreateTestFixture()625     void recreateTestFixture()
626     {
627         TearDown();
628         SetUp();
629     }
630 
631   private:
SetUp()632     void SetUp() final
633     {
634         ANGLETestBase::ANGLETestSetUp();
635         if (mIsSetUp)
636         {
637             testSetUp();
638         }
639     }
640 
TearDown()641     void TearDown() final
642     {
643         ANGLETestBase::ANGLETestPreTearDown();
644         if (mIsSetUp)
645         {
646             testTearDown();
647         }
648         ANGLETestBase::ANGLETestTearDown();
649     }
650 };
651 
652 template <typename Params>
ANGLETestWithParam()653 ANGLETestWithParam<Params>::ANGLETestWithParam()
654     : ANGLETestBase(std::get<angle::PlatformParameters>(this->GetParam()))
655 {}
656 
657 template <>
ANGLETestWithParam()658 inline ANGLETestWithParam<angle::PlatformParameters>::ANGLETestWithParam()
659     : ANGLETestBase(this->GetParam())
660 {}
661 
662 // Note: this hack is not necessary in C++17.  Once we switch to C++17, we can just rename
663 // ANGLETestWithParam to ANGLETest.
664 using ANGLETest = ANGLETestWithParam<>;
665 
666 class ANGLETestEnvironment : public testing::Environment
667 {
668   public:
669     void SetUp() override;
670     void TearDown() override;
671 
672     static angle::Library *GetDriverLibrary(angle::GLESDriverType driver);
673 
674   private:
675     static angle::Library *GetAngleEGLLibrary();
676     static angle::Library *GetSystemEGLLibrary();
677     static angle::Library *GetSystemWGLLibrary();
678 
679     // For loading entry points.
680     static std::unique_ptr<angle::Library> gAngleEGLLibrary;
681     static std::unique_ptr<angle::Library> gSystemEGLLibrary;
682     static std::unique_ptr<angle::Library> gSystemWGLLibrary;
683 };
684 
685 extern angle::PlatformMethods gDefaultPlatformMethods;
686 
687 #endif  // ANGLE_TESTS_ANGLE_TEST_H_
688