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