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