• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // ANGLETest:
7 //   Implementation of common ANGLE testing fixture.
8 //
9 
10 #include "ANGLETest.h"
11 
12 #include "common/platform.h"
13 #include "gpu_info_util/SystemInfo.h"
14 #include "util/EGLWindow.h"
15 #include "util/OSWindow.h"
16 #include "util/test_utils.h"
17 
18 #if defined(ANGLE_PLATFORM_WINDOWS)
19 #    include <VersionHelpers.h>
20 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
21 
22 namespace angle
23 {
24 
25 const GLColorRGB GLColorRGB::black(0u, 0u, 0u);
26 const GLColorRGB GLColorRGB::blue(0u, 0u, 255u);
27 const GLColorRGB GLColorRGB::green(0u, 255u, 0u);
28 const GLColorRGB GLColorRGB::red(255u, 0u, 0u);
29 const GLColorRGB GLColorRGB::yellow(255u, 255u, 0);
30 
31 const GLColor GLColor::black            = GLColor(0u, 0u, 0u, 255u);
32 const GLColor GLColor::blue             = GLColor(0u, 0u, 255u, 255u);
33 const GLColor GLColor::cyan             = GLColor(0u, 255u, 255u, 255u);
34 const GLColor GLColor::green            = GLColor(0u, 255u, 0u, 255u);
35 const GLColor GLColor::red              = GLColor(255u, 0u, 0u, 255u);
36 const GLColor GLColor::transparentBlack = GLColor(0u, 0u, 0u, 0u);
37 const GLColor GLColor::white            = GLColor(255u, 255u, 255u, 255u);
38 const GLColor GLColor::yellow           = GLColor(255u, 255u, 0, 255u);
39 const GLColor GLColor::magenta          = GLColor(255u, 0u, 255u, 255u);
40 
41 namespace
42 {
ColorNorm(GLubyte channelValue)43 float ColorNorm(GLubyte channelValue)
44 {
45     return static_cast<float>(channelValue) / 255.0f;
46 }
47 
ColorDenorm(float colorValue)48 GLubyte ColorDenorm(float colorValue)
49 {
50     return static_cast<GLubyte>(colorValue * 255.0f);
51 }
52 
TestPlatform_logError(PlatformMethods * platform,const char * errorMessage)53 void TestPlatform_logError(PlatformMethods *platform, const char *errorMessage)
54 {
55     auto *testPlatformContext = static_cast<TestPlatformContext *>(platform->context);
56     if (testPlatformContext->ignoreMessages)
57         return;
58 
59     GTEST_NONFATAL_FAILURE_(errorMessage);
60 
61     PrintStackBacktrace();
62 }
63 
TestPlatform_logWarning(PlatformMethods * platform,const char * warningMessage)64 void TestPlatform_logWarning(PlatformMethods *platform, const char *warningMessage)
65 {
66     auto *testPlatformContext = static_cast<TestPlatformContext *>(platform->context);
67     if (testPlatformContext->ignoreMessages)
68         return;
69 
70     if (testPlatformContext->warningsAsErrors)
71     {
72         FAIL() << warningMessage;
73     }
74     else
75     {
76         std::cerr << "Warning: " << warningMessage << std::endl;
77     }
78 }
79 
TestPlatform_logInfo(PlatformMethods * platform,const char * infoMessage)80 void TestPlatform_logInfo(PlatformMethods *platform, const char *infoMessage) {}
81 
TestPlatform_overrideWorkaroundsD3D(PlatformMethods * platform,FeaturesD3D * featuresD3D)82 void TestPlatform_overrideWorkaroundsD3D(PlatformMethods *platform, FeaturesD3D *featuresD3D)
83 {
84     auto *testPlatformContext = static_cast<TestPlatformContext *>(platform->context);
85     if (testPlatformContext->currentTest)
86     {
87         testPlatformContext->currentTest->overrideWorkaroundsD3D(featuresD3D);
88     }
89 }
90 
TestPlatform_overrideFeaturesVk(PlatformMethods * platform,FeaturesVk * featuresVulkan)91 void TestPlatform_overrideFeaturesVk(PlatformMethods *platform, FeaturesVk *featuresVulkan)
92 {
93     auto *testPlatformContext = static_cast<TestPlatformContext *>(platform->context);
94     if (testPlatformContext->currentTest)
95     {
96         testPlatformContext->currentTest->overrideFeaturesVk(featuresVulkan);
97     }
98 }
99 
100 const std::array<Vector3, 6> kQuadVertices = {{
101     Vector3(-1.0f, 1.0f, 0.5f),
102     Vector3(-1.0f, -1.0f, 0.5f),
103     Vector3(1.0f, -1.0f, 0.5f),
104     Vector3(-1.0f, 1.0f, 0.5f),
105     Vector3(1.0f, -1.0f, 0.5f),
106     Vector3(1.0f, 1.0f, 0.5f),
107 }};
108 
109 const std::array<Vector3, 4> kIndexedQuadVertices = {{
110     Vector3(-1.0f, 1.0f, 0.5f),
111     Vector3(-1.0f, -1.0f, 0.5f),
112     Vector3(1.0f, -1.0f, 0.5f),
113     Vector3(1.0f, 1.0f, 0.5f),
114 }};
115 
116 constexpr std::array<GLushort, 6> kIndexedQuadIndices = {{0, 1, 2, 0, 2, 3}};
117 
GetColorName(GLColor color)118 const char *GetColorName(GLColor color)
119 {
120     if (color == GLColor::red)
121     {
122         return "Red";
123     }
124 
125     if (color == GLColor::green)
126     {
127         return "Green";
128     }
129 
130     if (color == GLColor::blue)
131     {
132         return "Blue";
133     }
134 
135     if (color == GLColor::white)
136     {
137         return "White";
138     }
139 
140     if (color == GLColor::black)
141     {
142         return "Black";
143     }
144 
145     if (color == GLColor::transparentBlack)
146     {
147         return "Transparent Black";
148     }
149 
150     if (color == GLColor::yellow)
151     {
152         return "Yellow";
153     }
154 
155     if (color == GLColor::magenta)
156     {
157         return "Magenta";
158     }
159 
160     if (color == GLColor::cyan)
161     {
162         return "Cyan";
163     }
164 
165     return nullptr;
166 }
167 
ShouldAlwaysForceNewDisplay()168 bool ShouldAlwaysForceNewDisplay()
169 {
170     // We prefer to reuse config displays. This is faster and solves a driver issue where creating
171     // many displays causes crashes. However this exposes other driver bugs on many other platforms.
172     // Conservatively enable the feature only on Windows Intel and NVIDIA for now.
173     SystemInfo *systemInfo = GetTestSystemInfo();
174     return (!systemInfo || !IsWindows() || systemInfo->hasAMDGPU());
175 }
176 }  // anonymous namespace
177 
GLColorRGB(const Vector3 & floatColor)178 GLColorRGB::GLColorRGB(const Vector3 &floatColor)
179     : R(ColorDenorm(floatColor.x())), G(ColorDenorm(floatColor.y())), B(ColorDenorm(floatColor.z()))
180 {}
181 
GLColor(const Vector4 & floatColor)182 GLColor::GLColor(const Vector4 &floatColor)
183     : R(ColorDenorm(floatColor.x())),
184       G(ColorDenorm(floatColor.y())),
185       B(ColorDenorm(floatColor.z())),
186       A(ColorDenorm(floatColor.w()))
187 {}
188 
GLColor(GLuint colorValue)189 GLColor::GLColor(GLuint colorValue) : R(0), G(0), B(0), A(0)
190 {
191     memcpy(&R, &colorValue, sizeof(GLuint));
192 }
193 
ExpectNear(const GLColor & expected,const GLColor & err) const194 testing::AssertionResult GLColor::ExpectNear(const GLColor &expected, const GLColor &err) const
195 {
196     testing::AssertionResult result(
197         abs(int(expected.R) - this->R) <= err.R && abs(int(expected.G) - this->G) <= err.G &&
198         abs(int(expected.B) - this->B) <= err.B && abs(int(expected.A) - this->A) <= err.A);
199     if (!bool(result))
200     {
201         result << "Expected " << expected << "+/-" << err << ", was " << *this;
202     }
203     return result;
204 }
205 
CreatePixelCenterWindowCoords(const std::vector<Vector2> & pixelPoints,int windowWidth,int windowHeight,std::vector<Vector3> * outVertices)206 void CreatePixelCenterWindowCoords(const std::vector<Vector2> &pixelPoints,
207                                    int windowWidth,
208                                    int windowHeight,
209                                    std::vector<Vector3> *outVertices)
210 {
211     for (Vector2 pixelPoint : pixelPoints)
212     {
213         outVertices->emplace_back(Vector3((pixelPoint[0] + 0.5f) * 2.0f / windowWidth - 1.0f,
214                                           (pixelPoint[1] + 0.5f) * 2.0f / windowHeight - 1.0f,
215                                           0.0f));
216     }
217 }
218 
toNormalizedVector() const219 Vector4 GLColor::toNormalizedVector() const
220 {
221     return Vector4(ColorNorm(R), ColorNorm(G), ColorNorm(B), ColorNorm(A));
222 }
223 
ReadColor(GLint x,GLint y)224 GLColor ReadColor(GLint x, GLint y)
225 {
226     GLColor actual;
227     glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &actual.R);
228     EXPECT_GL_NO_ERROR();
229     return actual;
230 }
231 
operator ==(const GLColor & a,const GLColor & b)232 bool operator==(const GLColor &a, const GLColor &b)
233 {
234     return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
235 }
236 
operator !=(const GLColor & a,const GLColor & b)237 bool operator!=(const GLColor &a, const GLColor &b)
238 {
239     return !(a == b);
240 }
241 
operator <<(std::ostream & ostream,const GLColor & color)242 std::ostream &operator<<(std::ostream &ostream, const GLColor &color)
243 {
244     const char *colorName = GetColorName(color);
245     if (colorName)
246     {
247         return ostream << colorName;
248     }
249 
250     ostream << "(" << static_cast<unsigned int>(color.R) << ", "
251             << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
252             << ", " << static_cast<unsigned int>(color.A) << ")";
253     return ostream;
254 }
255 
operator ==(const GLColor32F & a,const GLColor32F & b)256 bool operator==(const GLColor32F &a, const GLColor32F &b)
257 {
258     return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
259 }
260 
operator <<(std::ostream & ostream,const GLColor32F & color)261 std::ostream &operator<<(std::ostream &ostream, const GLColor32F &color)
262 {
263     ostream << "(" << color.R << ", " << color.G << ", " << color.B << ", " << color.A << ")";
264     return ostream;
265 }
266 
ReadColor32F(GLint x,GLint y)267 GLColor32F ReadColor32F(GLint x, GLint y)
268 {
269     GLColor32F actual;
270     glReadPixels((x), (y), 1, 1, GL_RGBA, GL_FLOAT, &actual.R);
271     EXPECT_GL_NO_ERROR();
272     return actual;
273 }
274 
LoadEntryPointsWithUtilLoader()275 void LoadEntryPointsWithUtilLoader()
276 {
277 #if defined(ANGLE_USE_UTIL_LOADER)
278     PFNEGLGETPROCADDRESSPROC getProcAddress;
279     ANGLETestEnvironment::GetEGLLibrary()->getAs("eglGetProcAddress", &getProcAddress);
280     ASSERT_NE(nullptr, getProcAddress);
281 
282     LoadEGL(getProcAddress);
283     LoadGLES(getProcAddress);
284 #endif  // defined(ANGLE_USE_UTIL_LOADER)
285 }
286 }  // namespace angle
287 
288 using namespace angle;
289 
290 PlatformMethods gDefaultPlatformMethods;
291 
292 namespace
293 {
294 TestPlatformContext gPlatformContext;
295 
296 // After a fixed number of iterations we reset the test window. This works around some driver bugs.
297 constexpr uint32_t kWindowReuseLimit = 50;
298 
299 constexpr char kUseConfig[]                = "--use-config=";
300 constexpr char kSeparateProcessPerConfig[] = "--separate-process-per-config";
301 
RunSeparateProcessesForEachConfig(int * argc,char * argv[])302 bool RunSeparateProcessesForEachConfig(int *argc, char *argv[])
303 {
304     std::vector<const char *> commonArgs;
305     for (int argIndex = 0; argIndex < *argc; ++argIndex)
306     {
307         if (strncmp(argv[argIndex], kSeparateProcessPerConfig, strlen(kSeparateProcessPerConfig)) !=
308             0)
309         {
310             commonArgs.push_back(argv[argIndex]);
311         }
312     }
313 
314     // Force GoogleTest init now so that we hit the test config init in angle_test_instantiate.cpp.
315     // After instantiation is finished we can gather a full list of enabled configs. Then we can
316     // iterate the list of configs to spawn a child process for each enabled config.
317     testing::InitGoogleTest(argc, argv);
318 
319     std::vector<std::string> configNames = GetAvailableTestPlatformNames();
320 
321     bool success = true;
322 
323     for (const std::string &config : configNames)
324     {
325         std::stringstream strstr;
326         strstr << kUseConfig << config;
327 
328         std::string configStr = strstr.str();
329 
330         std::vector<const char *> childArgs = commonArgs;
331         childArgs.push_back(configStr.c_str());
332 
333         ProcessHandle process(childArgs, false, false);
334         if (!process->started() || !process->finish())
335         {
336             std::cerr << "Launching child config " << config << " failed.\n";
337         }
338         else if (process->getExitCode() != 0)
339         {
340             std::cerr << "Child config " << config << " failed with exit code "
341                       << process->getExitCode() << ".\n";
342             success = false;
343         }
344     }
345     return success;
346 }
347 }  // anonymous namespace
348 
349 // static
GetQuadVertices()350 std::array<Vector3, 6> ANGLETestBase::GetQuadVertices()
351 {
352     return kQuadVertices;
353 }
354 
355 // static
GetQuadIndices()356 std::array<GLushort, 6> ANGLETestBase::GetQuadIndices()
357 {
358     return kIndexedQuadIndices;
359 }
360 
361 // static
GetIndexedQuadVertices()362 std::array<Vector3, 4> ANGLETestBase::GetIndexedQuadVertices()
363 {
364     return kIndexedQuadVertices;
365 }
366 
ANGLETestBase(const PlatformParameters & params)367 ANGLETestBase::ANGLETestBase(const PlatformParameters &params)
368     : mWidth(16),
369       mHeight(16),
370       mIgnoreD3D11SDKLayersWarnings(false),
371       mQuadVertexBuffer(0),
372       mQuadIndexBuffer(0),
373       m2DTexturedQuadProgram(0),
374       m3DTexturedQuadProgram(0),
375       mDeferContextInit(false),
376       mAlwaysForceNewDisplay(ShouldAlwaysForceNewDisplay()),
377       mForceNewDisplay(mAlwaysForceNewDisplay),
378       mSetUpCalled(false),
379       mTearDownCalled(false),
380       mCurrentParams(nullptr),
381       mFixture(nullptr)
382 {
383     // Override the default platform methods with the ANGLE test methods pointer.
384     PlatformParameters withMethods            = params;
385     withMethods.eglParameters.platformMethods = &gDefaultPlatformMethods;
386 
387     // We don't build vulkan debug layers on Mac (http://anglebug.com/4376)
388     if (IsOSX() && withMethods.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
389     {
390         withMethods.eglParameters.debugLayersEnabled = false;
391     }
392 
393     auto iter = gFixtures.find(withMethods);
394     if (iter != gFixtures.end())
395     {
396         mCurrentParams = &iter->first;
397 
398         if (!params.noFixture)
399         {
400             mFixture = &iter->second;
401             mFixture->configParams.reset();
402         }
403         return;
404     }
405 
406     TestFixture platform;
407     auto insertIter = gFixtures.emplace(withMethods, platform);
408     mCurrentParams  = &insertIter.first->first;
409 
410     if (!params.noFixture)
411     {
412         mFixture = &insertIter.first->second;
413         initOSWindow();
414     }
415 }
416 
initOSWindow()417 void ANGLETestBase::initOSWindow()
418 {
419     std::stringstream windowNameStream;
420     windowNameStream << "ANGLE Tests - " << *mCurrentParams;
421     std::string windowName = windowNameStream.str();
422 
423     if (IsAndroid())
424     {
425         // Only one window per test application on Android, shared among all fixtures
426         mFixture->osWindow = mOSWindowSingleton;
427     }
428 
429     if (!mFixture->osWindow)
430     {
431         mFixture->osWindow = OSWindow::New();
432         if (!mFixture->osWindow->initialize(windowName.c_str(), 128, 128))
433         {
434             std::cerr << "Failed to initialize OS Window.";
435         }
436 
437         if (IsAndroid())
438         {
439             // Initialize the single window on Andoird only once
440             mOSWindowSingleton = mFixture->osWindow;
441         }
442     }
443 
444     // On Linux we must keep the test windows visible. On Windows it doesn't seem to need it.
445     setWindowVisible(getOSWindow(), !IsWindows());
446 
447     switch (mCurrentParams->driver)
448     {
449         case GLESDriverType::AngleEGL:
450         {
451             mFixture->eglWindow =
452                 EGLWindow::New(mCurrentParams->majorVersion, mCurrentParams->minorVersion);
453             break;
454         }
455 
456         case GLESDriverType::SystemEGL:
457         {
458             std::cerr << "Unsupported driver." << std::endl;
459             break;
460         }
461 
462         case GLESDriverType::SystemWGL:
463         {
464             // WGL tests are currently disabled.
465             std::cerr << "Unsupported driver." << std::endl;
466             break;
467         }
468     }
469 }
470 
~ANGLETestBase()471 ANGLETestBase::~ANGLETestBase()
472 {
473     if (mQuadVertexBuffer)
474     {
475         glDeleteBuffers(1, &mQuadVertexBuffer);
476     }
477     if (mQuadIndexBuffer)
478     {
479         glDeleteBuffers(1, &mQuadIndexBuffer);
480     }
481     if (m2DTexturedQuadProgram)
482     {
483         glDeleteProgram(m2DTexturedQuadProgram);
484     }
485     if (m3DTexturedQuadProgram)
486     {
487         glDeleteProgram(m3DTexturedQuadProgram);
488     }
489 
490     if (!mSetUpCalled)
491     {
492         GTEST_NONFATAL_FAILURE_("SetUp not called.");
493     }
494 
495     if (!mTearDownCalled)
496     {
497         GTEST_NONFATAL_FAILURE_("TearDown not called.");
498     }
499 }
500 
ANGLETestSetUp()501 void ANGLETestBase::ANGLETestSetUp()
502 {
503     mSetUpCalled = true;
504 
505     gDefaultPlatformMethods.overrideWorkaroundsD3D = TestPlatform_overrideWorkaroundsD3D;
506     gDefaultPlatformMethods.overrideFeaturesVk     = TestPlatform_overrideFeaturesVk;
507     gDefaultPlatformMethods.logError               = TestPlatform_logError;
508     gDefaultPlatformMethods.logWarning             = TestPlatform_logWarning;
509     gDefaultPlatformMethods.logInfo                = TestPlatform_logInfo;
510     gDefaultPlatformMethods.context                = &gPlatformContext;
511 
512     gPlatformContext.ignoreMessages   = false;
513     gPlatformContext.warningsAsErrors = false;
514     gPlatformContext.currentTest      = this;
515 
516     // TODO(geofflang): Nexus6P generates GL errors during initialization. Suppress error messages
517     // temporarily until enough logging is in place to figure out exactly which calls generate
518     // errors.  http://crbug.com/998503
519     if (IsNexus6P())
520     {
521         gPlatformContext.ignoreMessages = true;
522     }
523 
524     if (IsWindows())
525     {
526         const auto &info = testing::UnitTest::GetInstance()->current_test_info();
527         WriteDebugMessage("Entering %s.%s\n", info->test_case_name(), info->name());
528     }
529 
530     if (mCurrentParams->noFixture)
531     {
532         LoadEntryPointsWithUtilLoader();
533         return;
534     }
535 
536     // Resize the window before creating the context so that the first make current
537     // sets the viewport and scissor box to the right size.
538     bool needSwap = false;
539     if (mFixture->osWindow->getWidth() != mWidth || mFixture->osWindow->getHeight() != mHeight)
540     {
541         if (!mFixture->osWindow->resize(mWidth, mHeight))
542         {
543             FAIL() << "Failed to resize ANGLE test window.";
544         }
545         needSwap = true;
546     }
547 
548     // WGL tests are currently disabled.
549     if (mFixture->wglWindow)
550     {
551         FAIL() << "Unsupported driver.";
552     }
553     else
554     {
555         if (mForceNewDisplay || !mFixture->eglWindow->isDisplayInitialized())
556         {
557             mFixture->eglWindow->destroyGL();
558             if (!mFixture->eglWindow->initializeDisplay(mFixture->osWindow,
559                                                         ANGLETestEnvironment::GetEGLLibrary(),
560                                                         mCurrentParams->eglParameters))
561             {
562                 FAIL() << "EGL Display init failed.";
563             }
564         }
565         else if (mCurrentParams->eglParameters != mFixture->eglWindow->getPlatform())
566         {
567             FAIL() << "Internal parameter conflict error.";
568         }
569 
570         if (!mFixture->eglWindow->initializeSurface(
571                 mFixture->osWindow, ANGLETestEnvironment::GetEGLLibrary(), mFixture->configParams))
572         {
573             FAIL() << "egl surface init failed.";
574         }
575 
576         if (!mDeferContextInit && !mFixture->eglWindow->initializeContext())
577         {
578             FAIL() << "GL Context init failed.";
579         }
580     }
581 
582     if (needSwap)
583     {
584         // Swap the buffers so that the default framebuffer picks up the resize
585         // which will allow follow-up test code to assume the framebuffer covers
586         // the whole window.
587         swapBuffers();
588     }
589 
590     // This Viewport command is not strictly necessary but we add it so that programs
591     // taking OpenGL traces can guess the size of the default framebuffer and show it
592     // in their UIs
593     glViewport(0, 0, mWidth, mHeight);
594 }
595 
ANGLETestTearDown()596 void ANGLETestBase::ANGLETestTearDown()
597 {
598     mTearDownCalled              = true;
599     gPlatformContext.currentTest = nullptr;
600 
601     if (IsWindows())
602     {
603         const testing::TestInfo *info = testing::UnitTest::GetInstance()->current_test_info();
604         WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name());
605     }
606 
607     if (mCurrentParams->noFixture)
608     {
609         return;
610     }
611 
612     swapBuffers();
613     mFixture->osWindow->messageLoop();
614 
615     if (mFixture->eglWindow)
616     {
617         checkD3D11SDKLayersMessages();
618     }
619 
620     if (mFixture->reuseCounter++ >= kWindowReuseLimit || mForceNewDisplay)
621     {
622         mFixture->reuseCounter = 0;
623         getGLWindow()->destroyGL();
624     }
625     else
626     {
627         mFixture->eglWindow->destroyContext();
628         mFixture->eglWindow->destroySurface();
629     }
630 
631     // Check for quit message
632     Event myEvent;
633     while (mFixture->osWindow->popEvent(&myEvent))
634     {
635         if (myEvent.Type == Event::EVENT_CLOSED)
636         {
637             exit(0);
638         }
639     }
640 }
641 
ReleaseFixtures()642 void ANGLETestBase::ReleaseFixtures()
643 {
644     for (auto it = gFixtures.begin(); it != gFixtures.end(); it++)
645     {
646         if (it->second.eglWindow)
647         {
648             it->second.eglWindow->destroyGL();
649         }
650     }
651 }
652 
swapBuffers()653 void ANGLETestBase::swapBuffers()
654 {
655     if (getGLWindow()->isGLInitialized())
656     {
657         getGLWindow()->swap();
658 
659         if (mFixture->eglWindow)
660         {
661             EXPECT_EGL_SUCCESS();
662         }
663     }
664 }
665 
setupQuadVertexBuffer(GLfloat positionAttribZ,GLfloat positionAttribXYScale)666 void ANGLETestBase::setupQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale)
667 {
668     if (mQuadVertexBuffer == 0)
669     {
670         glGenBuffers(1, &mQuadVertexBuffer);
671     }
672 
673     auto quadVertices = GetQuadVertices();
674     for (Vector3 &vertex : quadVertices)
675     {
676         vertex.x() *= positionAttribXYScale;
677         vertex.y() *= positionAttribXYScale;
678         vertex.z() = positionAttribZ;
679     }
680 
681     glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
682     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);
683 }
684 
setupIndexedQuadVertexBuffer(GLfloat positionAttribZ,GLfloat positionAttribXYScale)685 void ANGLETestBase::setupIndexedQuadVertexBuffer(GLfloat positionAttribZ,
686                                                  GLfloat positionAttribXYScale)
687 {
688     if (mQuadVertexBuffer == 0)
689     {
690         glGenBuffers(1, &mQuadVertexBuffer);
691     }
692 
693     auto quadVertices = kIndexedQuadVertices;
694     for (Vector3 &vertex : quadVertices)
695     {
696         vertex.x() *= positionAttribXYScale;
697         vertex.y() *= positionAttribXYScale;
698         vertex.z() = positionAttribZ;
699     }
700 
701     glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
702     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 4, quadVertices.data(), GL_STATIC_DRAW);
703 }
704 
setupIndexedQuadIndexBuffer()705 void ANGLETestBase::setupIndexedQuadIndexBuffer()
706 {
707     if (mQuadIndexBuffer == 0)
708     {
709         glGenBuffers(1, &mQuadIndexBuffer);
710     }
711 
712     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadIndexBuffer);
713     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kIndexedQuadIndices), kIndexedQuadIndices.data(),
714                  GL_STATIC_DRAW);
715 }
716 
717 // static
drawQuad(GLuint program,const std::string & positionAttribName,GLfloat positionAttribZ)718 void ANGLETestBase::drawQuad(GLuint program,
719                              const std::string &positionAttribName,
720                              GLfloat positionAttribZ)
721 {
722     drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
723 }
724 
725 // static
drawQuad(GLuint program,const std::string & positionAttribName,GLfloat positionAttribZ,GLfloat positionAttribXYScale)726 void ANGLETestBase::drawQuad(GLuint program,
727                              const std::string &positionAttribName,
728                              GLfloat positionAttribZ,
729                              GLfloat positionAttribXYScale)
730 {
731     drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, false);
732 }
733 
drawQuad(GLuint program,const std::string & positionAttribName,GLfloat positionAttribZ,GLfloat positionAttribXYScale,bool useVertexBuffer)734 void ANGLETestBase::drawQuad(GLuint program,
735                              const std::string &positionAttribName,
736                              GLfloat positionAttribZ,
737                              GLfloat positionAttribXYScale,
738                              bool useVertexBuffer)
739 {
740     drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, useVertexBuffer,
741              false, 0u);
742 }
743 
drawQuadInstanced(GLuint program,const std::string & positionAttribName,GLfloat positionAttribZ,GLfloat positionAttribXYScale,bool useVertexBuffer,GLuint numInstances)744 void ANGLETestBase::drawQuadInstanced(GLuint program,
745                                       const std::string &positionAttribName,
746                                       GLfloat positionAttribZ,
747                                       GLfloat positionAttribXYScale,
748                                       bool useVertexBuffer,
749                                       GLuint numInstances)
750 {
751     drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, useVertexBuffer,
752              true, numInstances);
753 }
754 
drawQuad(GLuint program,const std::string & positionAttribName,GLfloat positionAttribZ,GLfloat positionAttribXYScale,bool useVertexBuffer,bool useInstancedDrawCalls,GLuint numInstances)755 void ANGLETestBase::drawQuad(GLuint program,
756                              const std::string &positionAttribName,
757                              GLfloat positionAttribZ,
758                              GLfloat positionAttribXYScale,
759                              bool useVertexBuffer,
760                              bool useInstancedDrawCalls,
761                              GLuint numInstances)
762 {
763     GLint previousProgram = 0;
764     glGetIntegerv(GL_CURRENT_PROGRAM, &previousProgram);
765     if (previousProgram != static_cast<GLint>(program))
766     {
767         glUseProgram(program);
768     }
769 
770     GLint previousBuffer = 0;
771     glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &previousBuffer);
772 
773     GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
774 
775     std::array<Vector3, 6> quadVertices = GetQuadVertices();
776 
777     if (useVertexBuffer)
778     {
779         setupQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
780         glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
781         glBindBuffer(GL_ARRAY_BUFFER, previousBuffer);
782     }
783     else
784     {
785         for (Vector3 &vertex : quadVertices)
786         {
787             vertex.x() *= positionAttribXYScale;
788             vertex.y() *= positionAttribXYScale;
789             vertex.z() = positionAttribZ;
790         }
791 
792         if (previousBuffer != 0)
793         {
794             glBindBuffer(GL_ARRAY_BUFFER, 0);
795         }
796         glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
797         if (previousBuffer != 0)
798         {
799             glBindBuffer(GL_ARRAY_BUFFER, previousBuffer);
800         }
801     }
802     glEnableVertexAttribArray(positionLocation);
803 
804     if (useInstancedDrawCalls)
805     {
806         glDrawArraysInstanced(GL_TRIANGLES, 0, 6, numInstances);
807     }
808     else
809     {
810         glDrawArrays(GL_TRIANGLES, 0, 6);
811     }
812 
813     glDisableVertexAttribArray(positionLocation);
814     glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
815 
816     if (previousProgram != static_cast<GLint>(program))
817     {
818         glUseProgram(previousProgram);
819     }
820 }
821 
drawIndexedQuad(GLuint program,const std::string & positionAttribName,GLfloat positionAttribZ)822 void ANGLETestBase::drawIndexedQuad(GLuint program,
823                                     const std::string &positionAttribName,
824                                     GLfloat positionAttribZ)
825 {
826     drawIndexedQuad(program, positionAttribName, positionAttribZ, 1.0f);
827 }
828 
drawIndexedQuad(GLuint program,const std::string & positionAttribName,GLfloat positionAttribZ,GLfloat positionAttribXYScale)829 void ANGLETestBase::drawIndexedQuad(GLuint program,
830                                     const std::string &positionAttribName,
831                                     GLfloat positionAttribZ,
832                                     GLfloat positionAttribXYScale)
833 {
834     drawIndexedQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, false);
835 }
836 
drawIndexedQuad(GLuint program,const std::string & positionAttribName,GLfloat positionAttribZ,GLfloat positionAttribXYScale,bool useIndexBuffer)837 void ANGLETestBase::drawIndexedQuad(GLuint program,
838                                     const std::string &positionAttribName,
839                                     GLfloat positionAttribZ,
840                                     GLfloat positionAttribXYScale,
841                                     bool useIndexBuffer)
842 {
843     drawIndexedQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale,
844                     useIndexBuffer, false);
845 }
846 
drawIndexedQuad(GLuint program,const std::string & positionAttribName,GLfloat positionAttribZ,GLfloat positionAttribXYScale,bool useIndexBuffer,bool restrictedRange)847 void ANGLETestBase::drawIndexedQuad(GLuint program,
848                                     const std::string &positionAttribName,
849                                     GLfloat positionAttribZ,
850                                     GLfloat positionAttribXYScale,
851                                     bool useIndexBuffer,
852                                     bool restrictedRange)
853 {
854     GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
855 
856     GLint activeProgram = 0;
857     glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
858     if (static_cast<GLuint>(activeProgram) != program)
859     {
860         glUseProgram(program);
861     }
862 
863     GLuint prevCoordBinding = 0;
864     glGetIntegerv(GL_ARRAY_BUFFER_BINDING, reinterpret_cast<GLint *>(&prevCoordBinding));
865 
866     setupIndexedQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
867 
868     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
869     glEnableVertexAttribArray(positionLocation);
870     glBindBuffer(GL_ARRAY_BUFFER, prevCoordBinding);
871 
872     GLuint prevIndexBinding = 0;
873     const GLvoid *indices;
874     if (useIndexBuffer)
875     {
876         glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
877                       reinterpret_cast<GLint *>(&prevIndexBinding));
878 
879         setupIndexedQuadIndexBuffer();
880         indices = 0;
881     }
882     else
883     {
884         indices = kIndexedQuadIndices.data();
885     }
886 
887     if (!restrictedRange)
888     {
889         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
890     }
891     else
892     {
893         glDrawRangeElements(GL_TRIANGLES, 0, 3, 6, GL_UNSIGNED_SHORT, indices);
894     }
895 
896     if (useIndexBuffer)
897     {
898         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevIndexBinding);
899     }
900 
901     glDisableVertexAttribArray(positionLocation);
902     glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
903 
904     if (static_cast<GLuint>(activeProgram) != program)
905     {
906         glUseProgram(static_cast<GLuint>(activeProgram));
907     }
908 }
909 
get2DTexturedQuadProgram()910 GLuint ANGLETestBase::get2DTexturedQuadProgram()
911 {
912     if (m2DTexturedQuadProgram)
913     {
914         return m2DTexturedQuadProgram;
915     }
916 
917     constexpr char kVS[] =
918         "attribute vec2 position;\n"
919         "varying mediump vec2 texCoord;\n"
920         "void main()\n"
921         "{\n"
922         "    gl_Position = vec4(position, 0, 1);\n"
923         "    texCoord = position * 0.5 + vec2(0.5);\n"
924         "}\n";
925 
926     constexpr char kFS[] =
927         "varying mediump vec2 texCoord;\n"
928         "uniform sampler2D tex;\n"
929         "void main()\n"
930         "{\n"
931         "    gl_FragColor = texture2D(tex, texCoord);\n"
932         "}\n";
933 
934     m2DTexturedQuadProgram = CompileProgram(kVS, kFS);
935     return m2DTexturedQuadProgram;
936 }
937 
get3DTexturedQuadProgram()938 GLuint ANGLETestBase::get3DTexturedQuadProgram()
939 {
940     if (m3DTexturedQuadProgram)
941     {
942         return m3DTexturedQuadProgram;
943     }
944 
945     constexpr char kVS[] = R"(#version 300 es
946 in vec2 position;
947 out vec2 texCoord;
948 void main()
949 {
950     gl_Position = vec4(position, 0, 1);
951     texCoord = position * 0.5 + vec2(0.5);
952 })";
953 
954     constexpr char kFS[] = R"(#version 300 es
955 precision highp float;
956 
957 in vec2 texCoord;
958 out vec4 my_FragColor;
959 
960 uniform highp sampler3D tex;
961 uniform float u_layer;
962 
963 void main()
964 {
965     my_FragColor = texture(tex, vec3(texCoord, u_layer));
966 })";
967 
968     m3DTexturedQuadProgram = CompileProgram(kVS, kFS);
969     return m3DTexturedQuadProgram;
970 }
971 
draw2DTexturedQuad(GLfloat positionAttribZ,GLfloat positionAttribXYScale,bool useVertexBuffer)972 void ANGLETestBase::draw2DTexturedQuad(GLfloat positionAttribZ,
973                                        GLfloat positionAttribXYScale,
974                                        bool useVertexBuffer)
975 {
976     ASSERT_NE(0u, get2DTexturedQuadProgram());
977     drawQuad(get2DTexturedQuadProgram(), "position", positionAttribZ, positionAttribXYScale,
978              useVertexBuffer);
979 }
980 
draw3DTexturedQuad(GLfloat positionAttribZ,GLfloat positionAttribXYScale,bool useVertexBuffer,float layer)981 void ANGLETestBase::draw3DTexturedQuad(GLfloat positionAttribZ,
982                                        GLfloat positionAttribXYScale,
983                                        bool useVertexBuffer,
984                                        float layer)
985 {
986     GLuint program = get3DTexturedQuadProgram();
987     ASSERT_NE(0u, program);
988     GLint activeProgram = 0;
989     glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
990     if (static_cast<GLuint>(activeProgram) != program)
991     {
992         glUseProgram(program);
993     }
994     glUniform1f(glGetUniformLocation(program, "u_layer"), layer);
995 
996     drawQuad(program, "position", positionAttribZ, positionAttribXYScale, useVertexBuffer);
997 
998     if (static_cast<GLuint>(activeProgram) != program)
999     {
1000         glUseProgram(static_cast<GLuint>(activeProgram));
1001     }
1002 }
1003 
platformSupportsMultithreading() const1004 bool ANGLETestBase::platformSupportsMultithreading() const
1005 {
1006     return (IsOpenGLES() && IsAndroid()) || IsVulkan();
1007 }
1008 
checkD3D11SDKLayersMessages()1009 void ANGLETestBase::checkD3D11SDKLayersMessages()
1010 {
1011 #if defined(ANGLE_PLATFORM_WINDOWS)
1012     // On Windows D3D11, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages
1013     // were outputted by the test. We enable the Debug layers in Release tests as well.
1014     if (mIgnoreD3D11SDKLayersWarnings ||
1015         mFixture->eglWindow->getPlatform().renderer != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
1016         mFixture->eglWindow->getDisplay() == EGL_NO_DISPLAY)
1017     {
1018         return;
1019     }
1020 
1021     const char *extensionString = static_cast<const char *>(
1022         eglQueryString(mFixture->eglWindow->getDisplay(), EGL_EXTENSIONS));
1023     if (!extensionString)
1024     {
1025         std::cout << "Error getting extension string from EGL Window." << std::endl;
1026         return;
1027     }
1028 
1029     if (!strstr(extensionString, "EGL_EXT_device_query"))
1030     {
1031         return;
1032     }
1033 
1034     EGLAttrib device      = 0;
1035     EGLAttrib angleDevice = 0;
1036 
1037     ASSERT_EGL_TRUE(
1038         eglQueryDisplayAttribEXT(mFixture->eglWindow->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
1039     ASSERT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
1040                                             EGL_D3D11_DEVICE_ANGLE, &device));
1041     ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
1042 
1043     ID3D11InfoQueue *infoQueue = nullptr;
1044     HRESULT hr =
1045         d3d11Device->QueryInterface(__uuidof(infoQueue), reinterpret_cast<void **>(&infoQueue));
1046     if (SUCCEEDED(hr))
1047     {
1048         UINT64 numStoredD3DDebugMessages =
1049             infoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
1050 
1051         if (numStoredD3DDebugMessages > 0)
1052         {
1053             for (UINT64 i = 0; i < numStoredD3DDebugMessages; i++)
1054             {
1055                 SIZE_T messageLength = 0;
1056                 hr                   = infoQueue->GetMessage(i, nullptr, &messageLength);
1057 
1058                 if (SUCCEEDED(hr))
1059                 {
1060                     D3D11_MESSAGE *pMessage =
1061                         reinterpret_cast<D3D11_MESSAGE *>(malloc(messageLength));
1062                     infoQueue->GetMessage(i, pMessage, &messageLength);
1063 
1064                     std::cout << "Message " << i << ":"
1065                               << " " << pMessage->pDescription << "\n";
1066                     free(pMessage);
1067                 }
1068             }
1069             // Clear the queue, so that previous failures are not reported
1070             // for subsequent, otherwise passing, tests
1071             infoQueue->ClearStoredMessages();
1072 
1073             FAIL() << numStoredD3DDebugMessages
1074                    << " D3D11 SDK Layers message(s) detected! Test Failed.\n";
1075         }
1076     }
1077 
1078     SafeRelease(infoQueue);
1079 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
1080 }
1081 
setWindowWidth(int width)1082 void ANGLETestBase::setWindowWidth(int width)
1083 {
1084     mWidth = width;
1085 }
1086 
setWindowHeight(int height)1087 void ANGLETestBase::setWindowHeight(int height)
1088 {
1089     mHeight = height;
1090 }
1091 
getGLWindow() const1092 GLWindowBase *ANGLETestBase::getGLWindow() const
1093 {
1094     // WGL tests are currently disabled.
1095     assert(!mFixture->wglWindow);
1096     return mFixture->eglWindow;
1097 }
1098 
setConfigRedBits(int bits)1099 void ANGLETestBase::setConfigRedBits(int bits)
1100 {
1101     mFixture->configParams.redBits = bits;
1102 }
1103 
setConfigGreenBits(int bits)1104 void ANGLETestBase::setConfigGreenBits(int bits)
1105 {
1106     mFixture->configParams.greenBits = bits;
1107 }
1108 
setConfigBlueBits(int bits)1109 void ANGLETestBase::setConfigBlueBits(int bits)
1110 {
1111     mFixture->configParams.blueBits = bits;
1112 }
1113 
setConfigAlphaBits(int bits)1114 void ANGLETestBase::setConfigAlphaBits(int bits)
1115 {
1116     mFixture->configParams.alphaBits = bits;
1117 }
1118 
setConfigDepthBits(int bits)1119 void ANGLETestBase::setConfigDepthBits(int bits)
1120 {
1121     mFixture->configParams.depthBits = bits;
1122 }
1123 
setConfigStencilBits(int bits)1124 void ANGLETestBase::setConfigStencilBits(int bits)
1125 {
1126     mFixture->configParams.stencilBits = bits;
1127 }
1128 
setConfigComponentType(EGLenum componentType)1129 void ANGLETestBase::setConfigComponentType(EGLenum componentType)
1130 {
1131     mFixture->configParams.componentType = componentType;
1132 }
1133 
setMultisampleEnabled(bool enabled)1134 void ANGLETestBase::setMultisampleEnabled(bool enabled)
1135 {
1136     mFixture->configParams.multisample = enabled;
1137 }
1138 
setSamples(EGLint samples)1139 void ANGLETestBase::setSamples(EGLint samples)
1140 {
1141     mFixture->configParams.samples = samples;
1142 }
1143 
setDebugEnabled(bool enabled)1144 void ANGLETestBase::setDebugEnabled(bool enabled)
1145 {
1146     mFixture->configParams.debug = enabled;
1147 }
1148 
setNoErrorEnabled(bool enabled)1149 void ANGLETestBase::setNoErrorEnabled(bool enabled)
1150 {
1151     mFixture->configParams.noError = enabled;
1152 }
1153 
setWebGLCompatibilityEnabled(bool webglCompatibility)1154 void ANGLETestBase::setWebGLCompatibilityEnabled(bool webglCompatibility)
1155 {
1156     mFixture->configParams.webGLCompatibility = webglCompatibility;
1157 }
1158 
setExtensionsEnabled(bool extensionsEnabled)1159 void ANGLETestBase::setExtensionsEnabled(bool extensionsEnabled)
1160 {
1161     mFixture->configParams.extensionsEnabled = extensionsEnabled;
1162 }
1163 
setRobustAccess(bool enabled)1164 void ANGLETestBase::setRobustAccess(bool enabled)
1165 {
1166     mFixture->configParams.robustAccess = enabled;
1167 }
1168 
setBindGeneratesResource(bool bindGeneratesResource)1169 void ANGLETestBase::setBindGeneratesResource(bool bindGeneratesResource)
1170 {
1171     mFixture->configParams.bindGeneratesResource = bindGeneratesResource;
1172 }
1173 
setClientArraysEnabled(bool enabled)1174 void ANGLETestBase::setClientArraysEnabled(bool enabled)
1175 {
1176     mFixture->configParams.clientArraysEnabled = enabled;
1177 }
1178 
setRobustResourceInit(bool enabled)1179 void ANGLETestBase::setRobustResourceInit(bool enabled)
1180 {
1181     mFixture->configParams.robustResourceInit = enabled;
1182 }
1183 
setContextProgramCacheEnabled(bool enabled)1184 void ANGLETestBase::setContextProgramCacheEnabled(bool enabled)
1185 {
1186     mFixture->configParams.contextProgramCacheEnabled = enabled;
1187 }
1188 
setContextResetStrategy(EGLenum resetStrategy)1189 void ANGLETestBase::setContextResetStrategy(EGLenum resetStrategy)
1190 {
1191     mFixture->configParams.resetStrategy = resetStrategy;
1192 }
1193 
forceNewDisplay()1194 void ANGLETestBase::forceNewDisplay()
1195 {
1196     mForceNewDisplay = true;
1197 }
1198 
setDeferContextInit(bool enabled)1199 void ANGLETestBase::setDeferContextInit(bool enabled)
1200 {
1201     mDeferContextInit = enabled;
1202 }
1203 
getClientMajorVersion() const1204 int ANGLETestBase::getClientMajorVersion() const
1205 {
1206     return getGLWindow()->getClientMajorVersion();
1207 }
1208 
getClientMinorVersion() const1209 int ANGLETestBase::getClientMinorVersion() const
1210 {
1211     return getGLWindow()->getClientMinorVersion();
1212 }
1213 
getEGLWindow() const1214 EGLWindow *ANGLETestBase::getEGLWindow() const
1215 {
1216     return mFixture->eglWindow;
1217 }
1218 
getWindowWidth() const1219 int ANGLETestBase::getWindowWidth() const
1220 {
1221     return mWidth;
1222 }
1223 
getWindowHeight() const1224 int ANGLETestBase::getWindowHeight() const
1225 {
1226     return mHeight;
1227 }
1228 
isMultisampleEnabled() const1229 bool ANGLETestBase::isMultisampleEnabled() const
1230 {
1231     return mFixture->eglWindow->isMultisample();
1232 }
1233 
setWindowVisible(OSWindow * osWindow,bool isVisible)1234 void ANGLETestBase::setWindowVisible(OSWindow *osWindow, bool isVisible)
1235 {
1236     // SwiftShader windows are not required to be visible for test correctness,
1237     // moreover, making a SwiftShader window visible flaky hangs on Xvfb, so we keep them hidden.
1238     if (isSwiftshader())
1239     {
1240         return;
1241     }
1242     osWindow->setVisible(isVisible);
1243 }
1244 
1245 ANGLETestBase::TestFixture::TestFixture()  = default;
1246 ANGLETestBase::TestFixture::~TestFixture() = default;
1247 
getPlatformRenderer() const1248 EGLint ANGLETestBase::getPlatformRenderer() const
1249 {
1250     assert(mFixture->eglWindow);
1251     return mFixture->eglWindow->getPlatform().renderer;
1252 }
1253 
ignoreD3D11SDKLayersWarnings()1254 void ANGLETestBase::ignoreD3D11SDKLayersWarnings()
1255 {
1256     // Some tests may need to disable the D3D11 SDK Layers Warnings checks
1257     mIgnoreD3D11SDKLayersWarnings = true;
1258 }
1259 
treatPlatformWarningsAsErrors()1260 void ANGLETestBase::treatPlatformWarningsAsErrors()
1261 {
1262 #if defined(ANGLE_PLATFORM_WINDOWS)
1263     // Only do warnings-as-errors on 8 and above. We may fall back to the old
1264     // compiler DLL on Windows 7.
1265     gPlatformContext.warningsAsErrors = IsWindows8OrGreater();
1266 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
1267 }
1268 
ScopedIgnorePlatformMessages()1269 ANGLETestBase::ScopedIgnorePlatformMessages::ScopedIgnorePlatformMessages()
1270 {
1271     gPlatformContext.ignoreMessages = true;
1272 }
1273 
~ScopedIgnorePlatformMessages()1274 ANGLETestBase::ScopedIgnorePlatformMessages::~ScopedIgnorePlatformMessages()
1275 {
1276     gPlatformContext.ignoreMessages = false;
1277 }
1278 
1279 OSWindow *ANGLETestBase::mOSWindowSingleton = nullptr;
1280 std::map<angle::PlatformParameters, ANGLETestBase::TestFixture> ANGLETestBase::gFixtures;
1281 Optional<EGLint> ANGLETestBase::mLastRendererType;
1282 
1283 std::unique_ptr<Library> ANGLETestEnvironment::gEGLLibrary;
1284 std::unique_ptr<Library> ANGLETestEnvironment::gWGLLibrary;
1285 
SetUp()1286 void ANGLETestEnvironment::SetUp() {}
1287 
TearDown()1288 void ANGLETestEnvironment::TearDown()
1289 {
1290     ANGLETestBase::ReleaseFixtures();
1291 }
1292 
GetEGLLibrary()1293 Library *ANGLETestEnvironment::GetEGLLibrary()
1294 {
1295 #if defined(ANGLE_USE_UTIL_LOADER)
1296     if (!gEGLLibrary)
1297     {
1298         gEGLLibrary.reset(OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, SearchType::ApplicationDir));
1299     }
1300 #endif  // defined(ANGLE_USE_UTIL_LOADER)
1301     return gEGLLibrary.get();
1302 }
1303 
GetWGLLibrary()1304 Library *ANGLETestEnvironment::GetWGLLibrary()
1305 {
1306 #if defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
1307     if (!gWGLLibrary)
1308     {
1309         gWGLLibrary.reset(OpenSharedLibrary("opengl32", SearchType::SystemDir));
1310     }
1311 #endif  // defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
1312     return gWGLLibrary.get();
1313 }
1314 
ANGLEProcessTestArgs(int * argc,char * argv[])1315 void ANGLEProcessTestArgs(int *argc, char *argv[])
1316 {
1317     testing::AddGlobalTestEnvironment(new ANGLETestEnvironment());
1318 
1319     for (int argIndex = 1; argIndex < *argc; argIndex++)
1320     {
1321         if (strncmp(argv[argIndex], kUseConfig, strlen(kUseConfig)) == 0)
1322         {
1323             SetSelectedConfig(argv[argIndex] + strlen(kUseConfig));
1324         }
1325         if (strncmp(argv[argIndex], kSeparateProcessPerConfig, strlen(kSeparateProcessPerConfig)) ==
1326             0)
1327         {
1328             gSeparateProcessPerConfig = true;
1329         }
1330     }
1331 
1332     if (gSeparateProcessPerConfig)
1333     {
1334         if (IsConfigSelected())
1335         {
1336             std::cout << "Cannot use both a single test config and separate processes.\n";
1337             exit(1);
1338         }
1339 
1340         if (RunSeparateProcessesForEachConfig(argc, argv))
1341         {
1342             exit(0);
1343         }
1344         else
1345         {
1346             std::cout << "Some subprocesses failed.\n";
1347             exit(1);
1348         }
1349     }
1350 }
1351