Allow tests to run on native EGL.

Adds support for Linux and Android native EGL testing.
This can be useful for doing performance comparisons of ANGLE vs
a native GL driver. Only enabled for the trace perf tests due to
limitations in the test harness.

Bug: angleproject:4596
Change-Id: Iba6d3ccd7c1275cf095893fab824a0ea33dc3a79
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2116254
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
This commit is contained in:
Jamie Madill
2020-03-23 14:47:03 -04:00
committed by Commit Bot
parent a4b506f79e
commit 930b26417d
20 changed files with 295 additions and 128 deletions

View File

@@ -155,7 +155,8 @@ int SampleApplication::run()
configParams.depthBits = 24;
configParams.stencilBits = 8;
if (!mEGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), mPlatformParams, configParams))
if (!mEGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), angle::GLESDriverType::AngleEGL,
mPlatformParams, configParams))
{
return -1;
}

View File

@@ -68,6 +68,7 @@ enum class SearchType
};
Library *OpenSharedLibrary(const char *libraryName, SearchType searchType);
Library *OpenSharedLibraryWithExtension(const char *libraryName);
// Returns true if the process is currently being debugged.
bool IsDebuggerAttached();

View File

@@ -72,19 +72,11 @@ std::string GetHelperExecutableDir()
class PosixLibrary : public Library
{
public:
PosixLibrary(const char *libraryName, SearchType searchType)
PosixLibrary(const std::string &fullPath) : mModule(dlopen(fullPath.c_str(), RTLD_NOW))
{
std::string directory;
if (searchType == SearchType::ApplicationDir)
{
directory = GetHelperExecutableDir();
}
std::string fullPath = directory + libraryName + "." + GetSharedLibraryExtension();
mModule = dlopen(fullPath.c_str(), RTLD_NOW);
if (!mModule)
{
std::cerr << "Failed to load " << libraryName << ": " << dlerror() << std::endl;
std::cerr << "Failed to load " << fullPath << ": " << dlerror() << std::endl;
}
}
@@ -114,7 +106,19 @@ class PosixLibrary : public Library
Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
{
return new PosixLibrary(libraryName, searchType);
std::string directory;
if (searchType == SearchType::ApplicationDir)
{
directory = GetHelperExecutableDir();
}
std::string fullPath = directory + libraryName + "." + GetSharedLibraryExtension();
return new PosixLibrary(fullPath);
}
Library *OpenSharedLibraryWithExtension(const char *libraryName)
{
return new PosixLibrary(libraryName);
}
bool IsDirectory(const char *filename)

View File

@@ -41,22 +41,17 @@ class Win32Library : public Library
{
public:
Win32Library(const char *libraryName, SearchType searchType)
{
char buffer[MAX_PATH];
int ret = snprintf(buffer, MAX_PATH, "%s.%s", libraryName, GetSharedLibraryExtension());
if (ret > 0 && ret < MAX_PATH)
{
switch (searchType)
{
case SearchType::ApplicationDir:
mModule = LoadLibraryA(buffer);
mModule = LoadLibraryA(libraryName);
break;
case SearchType::SystemDir:
mModule = LoadLibraryExA(buffer, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
mModule = LoadLibraryExA(libraryName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
break;
}
}
}
~Win32Library() override
{
@@ -84,6 +79,21 @@ class Win32Library : public Library
Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
{
return new Win32Library(libraryName, searchType);
char buffer[MAX_PATH];
int ret = snprintf(buffer, MAX_PATH, "%s.%s", libraryName, GetSharedLibraryExtension());
if (ret > 0 && ret < MAX_PATH)
{
return new Win32Library(buffer, searchType);
}
else
{
fprintf(stderr, "Error loading shared library: 0x%x", ret);
return nullptr;
}
}
Library *OpenSharedLibraryWithExtension(const char *libraryName)
{
return new Win32Library(libraryName, SearchType::SystemDir);
}
} // namespace angle

View File

@@ -35,14 +35,9 @@ class UwpLibrary : public Library
public:
UwpLibrary(const char *libraryName, SearchType searchType)
{
char buffer[MAX_PATH];
int ret = snprintf(buffer, MAX_PATH, "%s.%s", libraryName, GetSharedLibraryExtension());
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wideBuffer = converter.from_bytes(buffer);
std::wstring wideBuffer = converter.from_bytes(libraryName);
if (ret > 0 && ret < MAX_PATH)
{
switch (searchType)
{
case SearchType::ApplicationDir:
@@ -53,7 +48,6 @@ class UwpLibrary : public Library
break;
}
}
}
~UwpLibrary() override
{
@@ -81,6 +75,24 @@ class UwpLibrary : public Library
Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
{
return new UwpLibrary(libraryName, searchType);
char buffer[MAX_PATH];
int ret = snprintf(buffer, MAX_PATH, "%s.%s", libraryName, GetSharedLibraryExtension());
if (ret > 0 && ret < MAX_PATH)
{
return new UwpLibrary(buffer, searchType);
}
else
{
fprintf(stderr, "Error loading shared library: 0x%x", ret);
return nullptr;
}
}
Library *OpenSharedLibraryWithExtension(const char *libraryName)
{
// SystemDir is not implemented in UWP.
fprintf(stderr, "Error loading shared library with extension.\n");
return nullptr;
}
} // namespace angle

View File

@@ -478,7 +478,7 @@ void RegisterContextCompatibilityTests()
EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE,
}};
LoadEntryPointsWithUtilLoader();
LoadEntryPointsWithUtilLoader(angle::GLESDriverType::AngleEGL);
if (eglGetPlatformDisplayEXT == nullptr)
{

View File

@@ -1108,8 +1108,8 @@ class ProgramBinariesAcrossPlatforms : public testing::TestWithParam<PlatformsWi
{
EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);
ConfigParameters configParams;
bool result = eglWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), param.eglParameters,
configParams);
bool result = eglWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), param.driver,
param.eglParameters, configParams);
if (!result)
{
EGLWindow::Delete(&eglWindow);

View File

@@ -422,8 +422,14 @@ ANGLERenderTest::ANGLERenderTest(const std::string &name, const RenderTestParams
angle::SearchType::ApplicationDir));
break;
case angle::GLESDriverType::SystemEGL:
#if defined(ANGLE_USE_UTIL_LOADER) && !defined(ANGLE_PLATFORM_WINDOWS)
mGLWindow = EGLWindow::New(testParams.majorVersion, testParams.minorVersion);
mEntryPointsLib.reset(
angle::OpenSharedLibraryWithExtension(GetNativeEGLLibraryNameWithExtension()));
#else
std::cerr << "Not implemented." << std::endl;
mSkipTest = true;
#endif // defined(ANGLE_USE_UTIL_LOADER) && !defined(ANGLE_PLATFORM_WINDOWS)
break;
case angle::GLESDriverType::SystemWGL:
#if defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
@@ -494,7 +500,8 @@ void ANGLERenderTest::SetUp()
EGLPlatformParameters withMethods = mTestParams.eglParameters;
withMethods.platformMethods = &mPlatformMethods;
if (!mGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), withMethods, mConfigParams))
if (!mGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), mTestParams.driver, withMethods,
mConfigParams))
{
mSkipTest = true;
FAIL() << "Failed initializing GL Window";

View File

@@ -78,6 +78,13 @@ ParamsT WGL(const ParamsT &in)
return out;
}
template <typename ParamsT>
ParamsT EGL(const ParamsT &in)
{
ParamsT out = in;
out.driver = angle::GLESDriverType::SystemEGL;
return out;
}
} // namespace params
#endif // TESTS_PERF_TESTS_DRAW_CALL_PERF_PARAMS_H_

View File

@@ -314,7 +314,7 @@ using P = TracePerfParams;
std::vector<P> gTestsWithID =
CombineWithValues({P()}, AllEnums<RestrictedTraceID>(), CombineTestID);
std::vector<P> gTestsWithRenderer = CombineWithFuncs(gTestsWithID, {Vulkan<P>});
std::vector<P> gTestsWithRenderer = CombineWithFuncs(gTestsWithID, {Vulkan<P>, EGL<P>});
ANGLE_INSTANTIATE_TEST_ARRAY(TracePerfTest, gTestsWithRenderer);
} // anonymous namespace

View File

@@ -279,11 +279,11 @@ GLColor32F ReadColor32F(GLint x, GLint y)
return actual;
}
void LoadEntryPointsWithUtilLoader()
void LoadEntryPointsWithUtilLoader(angle::GLESDriverType driverType)
{
#if defined(ANGLE_USE_UTIL_LOADER)
PFNEGLGETPROCADDRESSPROC getProcAddress;
ANGLETestEnvironment::GetEGLLibrary()->getAs("eglGetProcAddress", &getProcAddress);
ANGLETestEnvironment::GetDriverLibrary(driverType)->getAs("eglGetProcAddress", &getProcAddress);
ASSERT_NE(nullptr, getProcAddress);
LoadEGL(getProcAddress);
@@ -454,18 +454,13 @@ void ANGLETestBase::initOSWindow()
switch (mCurrentParams->driver)
{
case GLESDriverType::AngleEGL:
case GLESDriverType::SystemEGL:
{
mFixture->eglWindow =
EGLWindow::New(mCurrentParams->majorVersion, mCurrentParams->minorVersion);
break;
}
case GLESDriverType::SystemEGL:
{
std::cerr << "Unsupported driver." << std::endl;
break;
}
case GLESDriverType::SystemWGL:
{
// WGL tests are currently disabled.
@@ -536,10 +531,16 @@ void ANGLETestBase::ANGLETestSetUp()
if (mCurrentParams->noFixture)
{
LoadEntryPointsWithUtilLoader();
LoadEntryPointsWithUtilLoader(mCurrentParams->driver);
return;
}
if (mLastLoadedDriver.valid() && mCurrentParams->driver != mLastLoadedDriver.value())
{
LoadEntryPointsWithUtilLoader(mCurrentParams->driver);
mLastLoadedDriver = mCurrentParams->driver;
}
// Resize the window before creating the context so that the first make current
// sets the viewport and scissor box to the right size.
bool needSwap = false;
@@ -559,11 +560,13 @@ void ANGLETestBase::ANGLETestSetUp()
}
else
{
Library *driverLib = ANGLETestEnvironment::GetDriverLibrary(mCurrentParams->driver);
if (mForceNewDisplay || !mFixture->eglWindow->isDisplayInitialized())
{
mFixture->eglWindow->destroyGL();
if (!mFixture->eglWindow->initializeDisplay(mFixture->osWindow,
ANGLETestEnvironment::GetEGLLibrary(),
if (!mFixture->eglWindow->initializeDisplay(mFixture->osWindow, driverLib,
mCurrentParams->driver,
mCurrentParams->eglParameters))
{
FAIL() << "EGL Display init failed.";
@@ -574,8 +577,8 @@ void ANGLETestBase::ANGLETestSetUp()
FAIL() << "Internal parameter conflict error.";
}
if (!mFixture->eglWindow->initializeSurface(
mFixture->osWindow, ANGLETestEnvironment::GetEGLLibrary(), mFixture->configParams))
if (!mFixture->eglWindow->initializeSurface(mFixture->osWindow, driverLib,
mFixture->configParams))
{
FAIL() << "egl surface init failed.";
}
@@ -1286,9 +1289,11 @@ ANGLETestBase::ScopedIgnorePlatformMessages::~ScopedIgnorePlatformMessages()
OSWindow *ANGLETestBase::mOSWindowSingleton = nullptr;
std::map<angle::PlatformParameters, ANGLETestBase::TestFixture> ANGLETestBase::gFixtures;
Optional<EGLint> ANGLETestBase::mLastRendererType;
Optional<angle::GLESDriverType> ANGLETestBase::mLastLoadedDriver;
std::unique_ptr<Library> ANGLETestEnvironment::gEGLLibrary;
std::unique_ptr<Library> ANGLETestEnvironment::gWGLLibrary;
std::unique_ptr<Library> ANGLETestEnvironment::gAngleEGLLibrary;
std::unique_ptr<Library> ANGLETestEnvironment::gSystemEGLLibrary;
std::unique_ptr<Library> ANGLETestEnvironment::gSystemWGLLibrary;
void ANGLETestEnvironment::SetUp() {}
@@ -1297,26 +1302,58 @@ void ANGLETestEnvironment::TearDown()
ANGLETestBase::ReleaseFixtures();
}
Library *ANGLETestEnvironment::GetEGLLibrary()
// static
Library *ANGLETestEnvironment::GetDriverLibrary(angle::GLESDriverType driver)
{
#if defined(ANGLE_USE_UTIL_LOADER)
if (!gEGLLibrary)
switch (driver)
{
gEGLLibrary.reset(OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, SearchType::ApplicationDir));
case angle::GLESDriverType::AngleEGL:
return GetAngleEGLLibrary();
case angle::GLESDriverType::SystemEGL:
return GetSystemEGLLibrary();
case angle::GLESDriverType::SystemWGL:
return GetSystemWGLLibrary();
default:
return nullptr;
}
#endif // defined(ANGLE_USE_UTIL_LOADER)
return gEGLLibrary.get();
}
Library *ANGLETestEnvironment::GetWGLLibrary()
// static
Library *ANGLETestEnvironment::GetAngleEGLLibrary()
{
#if defined(ANGLE_USE_UTIL_LOADER)
if (!gAngleEGLLibrary)
{
gAngleEGLLibrary.reset(
OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, SearchType::ApplicationDir));
}
#endif // defined(ANGLE_USE_UTIL_LOADER)
return gAngleEGLLibrary.get();
}
// static
Library *ANGLETestEnvironment::GetSystemEGLLibrary()
{
#if defined(ANGLE_USE_UTIL_LOADER)
if (!gSystemEGLLibrary)
{
gSystemEGLLibrary.reset(
OpenSharedLibraryWithExtension(GetNativeEGLLibraryNameWithExtension()));
}
#endif // defined(ANGLE_USE_UTIL_LOADER)
return gSystemEGLLibrary.get();
}
// static
Library *ANGLETestEnvironment::GetSystemWGLLibrary()
{
#if defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
if (!gWGLLibrary)
if (!gSystemWGLLibrary)
{
gWGLLibrary.reset(OpenSharedLibrary("opengl32", SearchType::SystemDir));
gSystemWGLLibrary.reset(OpenSharedLibrary("opengl32", SearchType::SystemDir));
}
#endif // defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
return gWGLLibrary.get();
return gSystemWGLLibrary.get();
}
void ANGLEProcessTestArgs(int *argc, char *argv[])

View File

@@ -186,7 +186,7 @@ constexpr std::array<GLenum, 6> kCubeFaces = {
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z}};
void LoadEntryPointsWithUtilLoader();
void LoadEntryPointsWithUtilLoader(angle::GLESDriverType driver);
} // namespace angle
@@ -545,6 +545,7 @@ class ANGLETestBase
// Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan.
static Optional<EGLint> mLastRendererType;
static Optional<angle::GLESDriverType> mLastLoadedDriver;
};
template <typename Params = angle::PlatformParameters>
@@ -596,13 +597,17 @@ class ANGLETestEnvironment : public testing::Environment
void SetUp() override;
void TearDown() override;
static angle::Library *GetEGLLibrary();
static angle::Library *GetWGLLibrary();
static angle::Library *GetDriverLibrary(angle::GLESDriverType driver);
private:
static angle::Library *GetAngleEGLLibrary();
static angle::Library *GetSystemEGLLibrary();
static angle::Library *GetSystemWGLLibrary();
// For loading entry points.
static std::unique_ptr<angle::Library> gEGLLibrary;
static std::unique_ptr<angle::Library> gWGLLibrary;
static std::unique_ptr<angle::Library> gAngleEGLLibrary;
static std::unique_ptr<angle::Library> gSystemEGLLibrary;
static std::unique_ptr<angle::Library> gSystemWGLLibrary;
};
extern angle::PlatformMethods gDefaultPlatformMethods;

View File

@@ -112,7 +112,7 @@ std::ostream &operator<<(std::ostream &stream, const PlatformParameters &pp)
stream << "WGL";
break;
case GLESDriverType::SystemEGL:
stream << "GLES";
stream << "EGL";
break;
default:
stream << "Error";
@@ -769,4 +769,28 @@ PlatformParameters ES3_WGL()
{
return PlatformParameters(3, 0, GLESDriverType::SystemWGL);
}
PlatformParameters ES2_EGL()
{
return PlatformParameters(2, 0, GLESDriverType::SystemEGL);
}
PlatformParameters ES3_EGL()
{
return PlatformParameters(3, 0, GLESDriverType::SystemEGL);
}
const char *GetNativeEGLLibraryNameWithExtension()
{
#if defined(ANGLE_PLATFORM_ANDROID)
return "libEGL.so";
#elif defined(ANGLE_PLATFORM_LINUX)
return "libEGL.so.1";
#elif defined(ANGLE_PLATFORM_WINDOWS)
return "libEGL.dll";
#else
return "unknown_libegl";
#endif
}
} // namespace angle

View File

@@ -23,17 +23,6 @@
namespace angle
{
// The GLES driver type determines what shared object we use to load the GLES entry points.
// AngleEGL loads from ANGLE's version of libEGL, libGLESv2, and libGLESv1_CM.
// SystemEGL uses the system copies of libEGL, libGLESv2, and libGLESv1_CM.
// SystemWGL loads Windows GL with the GLES compatiblity extensions. See util/WGLWindow.h.
enum class GLESDriverType
{
AngleEGL,
SystemEGL,
SystemWGL,
};
struct PlatformParameters
{
PlatformParameters();
@@ -197,6 +186,11 @@ PlatformParameters ES3_METAL();
PlatformParameters ES2_WGL();
PlatformParameters ES3_WGL();
PlatformParameters ES2_EGL();
PlatformParameters ES3_EGL();
const char *GetNativeEGLLibraryNameWithExtension();
inline PlatformParameters WithNoVirtualContexts(const PlatformParameters &params)
{
PlatformParameters withNoVirtualContexts = params;

View File

@@ -14,6 +14,7 @@
#include <map>
#include "angle_gl.h"
#include "common/debug.h"
#include "common/platform.h"
#include "common/system_utils.h"
#include "common/third_party/base/anglebase/no_destructor.h"
@@ -36,7 +37,7 @@ namespace angle
{
namespace
{
bool IsANGLEConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
bool IsAngleEGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
{
std::unique_ptr<angle::Library> eglLibrary;
@@ -48,13 +49,14 @@ bool IsANGLEConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);
ConfigParameters configParams;
bool result =
eglWindow->initializeGL(osWindow, eglLibrary.get(), param.eglParameters, configParams);
eglWindow->initializeGL(osWindow, eglLibrary.get(), angle::GLESDriverType::AngleEGL,
param.eglParameters, configParams);
eglWindow->destroyGL();
EGLWindow::Delete(&eglWindow);
return result;
}
bool IsWGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
bool IsSystemWGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
{
#if defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
std::unique_ptr<angle::Library> openglLibrary(
@@ -63,7 +65,8 @@ bool IsWGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
WGLWindow *wglWindow = WGLWindow::New(param.majorVersion, param.minorVersion);
ConfigParameters configParams;
bool result =
wglWindow->initializeGL(osWindow, openglLibrary.get(), param.eglParameters, configParams);
wglWindow->initializeGL(osWindow, openglLibrary.get(), angle::GLESDriverType::SystemWGL,
param.eglParameters, configParams);
wglWindow->destroyGL();
WGLWindow::Delete(&wglWindow);
return result;
@@ -72,10 +75,24 @@ bool IsWGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
#endif // defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
}
bool IsNativeConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
bool IsSystemEGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
{
// Not yet implemented.
#if defined(ANGLE_USE_UTIL_LOADER)
std::unique_ptr<angle::Library> eglLibrary;
eglLibrary.reset(OpenSharedLibraryWithExtension(GetNativeEGLLibraryNameWithExtension()));
EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);
ConfigParameters configParams;
bool result =
eglWindow->initializeGL(osWindow, eglLibrary.get(), angle::GLESDriverType::SystemEGL,
param.eglParameters, configParams);
eglWindow->destroyGL();
EGLWindow::Delete(&eglWindow);
return result;
#else
return false;
#endif
}
bool IsAndroidDevice(const std::string &deviceName)
@@ -412,13 +429,23 @@ bool IsConfigWhitelisted(const SystemInfo &systemInfo, const PlatformParameters
return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE);
}
if (IsLinux() || IsAndroid())
{
// We do not support WGL bindings on Linux/Android. We do support system EGL.
switch (param.driver)
{
case GLESDriverType::SystemEGL:
return param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
case GLESDriverType::SystemWGL:
return false;
default:
break;
}
}
if (IsLinux())
{
// We do not support non-ANGLE bindings on Linux.
if (param.driver != GLESDriverType::AngleEGL)
{
return false;
}
ASSERT(param.driver == GLESDriverType::AngleEGL);
// Currently we support the OpenGL and Vulkan back-ends on Linux.
switch (param.getRenderer())
@@ -434,11 +461,7 @@ bool IsConfigWhitelisted(const SystemInfo &systemInfo, const PlatformParameters
if (IsAndroid())
{
// We do not support non-ANGLE bindings on Android.
if (param.driver != GLESDriverType::AngleEGL)
{
return false;
}
ASSERT(param.driver == GLESDriverType::AngleEGL);
// Nexus Android devices don't support backing 3.2 contexts
if (param.eglParameters.majorVersion == 3 && param.eglParameters.minorVersion == 2)
@@ -493,13 +516,13 @@ bool IsConfigSupported(const PlatformParameters &param)
switch (param.driver)
{
case GLESDriverType::AngleEGL:
result = IsANGLEConfigSupported(param, osWindow);
result = IsAngleEGLConfigSupported(param, osWindow);
break;
case GLESDriverType::SystemEGL:
result = IsNativeConfigSupported(param, osWindow);
result = IsSystemEGLConfigSupported(param, osWindow);
break;
case GLESDriverType::SystemWGL:
result = IsWGLConfigSupported(param, osWindow);
result = IsSystemWGLConfigSupported(param, osWindow);
break;
}

View File

@@ -15,6 +15,17 @@
namespace angle
{
struct PlatformMethods;
// The GLES driver type determines what shared object we use to load the GLES entry points.
// AngleEGL loads from ANGLE's version of libEGL, libGLESv2, and libGLESv1_CM.
// SystemEGL uses the system copies of libEGL, libGLESv2, and libGLESv1_CM.
// SystemWGL loads Windows GL with the GLES compatiblity extensions. See util/WGLWindow.h.
enum class GLESDriverType
{
AngleEGL,
SystemEGL,
SystemWGL,
};
} // namespace angle
struct EGLPlatformParameters

View File

@@ -92,10 +92,11 @@ EGLContext EGLWindow::getContext() const
bool EGLWindow::initializeGL(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &platformParams,
const ConfigParameters &configParams)
{
if (!initializeDisplay(osWindow, glWindowingLibrary, platformParams))
if (!initializeDisplay(osWindow, glWindowingLibrary, driverType, platformParams))
return false;
if (!initializeSurface(osWindow, glWindowingLibrary, configParams))
return false;
@@ -106,6 +107,7 @@ bool EGLWindow::initializeGL(OSWindow *osWindow,
bool EGLWindow::initializeDisplay(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &params)
{
#if defined(ANGLE_USE_UTIL_LOADER)
@@ -113,6 +115,7 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow,
glWindowingLibrary->getAs("eglGetProcAddress", &getProcAddress);
if (!getProcAddress)
{
fprintf(stderr, "Cannot load eglGetProcAddress\n");
return false;
}
@@ -192,7 +195,7 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow,
{
if (strstr(extensionString, "EGL_ANGLE_feature_control") == nullptr)
{
std::cout << "Missing EGL_ANGLE_feature_control.\n";
fprintf(stderr, "Missing EGL_ANGLE_feature_control.\n");
destroyGL();
return false;
}
@@ -207,7 +210,7 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow,
{
if (strstr(extensionString, "EGL_ANGLE_feature_control") == nullptr)
{
std::cout << "Missing EGL_ANGLE_feature_control.\n";
fprintf(stderr, "Missing EGL_ANGLE_feature_control.\n");
destroyGL();
return false;
}
@@ -220,17 +223,31 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow,
displayAttributes.push_back(EGL_NONE);
if (driverType == angle::GLESDriverType::SystemWGL)
return false;
if (driverType == angle::GLESDriverType::AngleEGL &&
strstr(extensionString, "EGL_ANGLE_platform_angle"))
{
mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
reinterpret_cast<void *>(osWindow->getNativeDisplay()),
&displayAttributes[0]);
}
else
{
mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
}
if (mDisplay == EGL_NO_DISPLAY)
{
fprintf(stderr, "Failed to get display: 0x%X\n", eglGetError());
destroyGL();
return false;
}
if (eglInitialize(mDisplay, &mEGLMajorVersion, &mEGLMinorVersion) == EGL_FALSE)
{
fprintf(stderr, "eglInitialize failed: 0x%X\n", eglGetError());
destroyGL();
return false;
}
@@ -269,6 +286,7 @@ bool EGLWindow::initializeSurface(OSWindow *osWindow,
bool hasPixelFormatFloat = strstr(displayExtensions, "EGL_EXT_pixel_format_float") != nullptr;
if (!hasPixelFormatFloat && mConfigParams.componentType != EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
{
fprintf(stderr, "Mising EGL_EXT_pixel_format_float.\n");
destroyGL();
return false;
}
@@ -283,7 +301,7 @@ bool EGLWindow::initializeSurface(OSWindow *osWindow,
if (!FindEGLConfig(mDisplay, configAttributes.data(), &mConfig))
{
std::cout << "Could not find a suitable EGL config!" << std::endl;
fprintf(stderr, "Could not find a suitable EGL config!\n");
destroyGL();
return false;
}
@@ -320,6 +338,7 @@ bool EGLWindow::initializeSurface(OSWindow *osWindow,
&surfaceAttributes[0]);
if (eglGetError() != EGL_SUCCESS || (mSurface == EGL_NO_SURFACE))
{
fprintf(stderr, "eglCreateWindowSurface failed: 0x%X\n", eglGetError());
destroyGL();
return false;
}
@@ -340,7 +359,7 @@ EGLContext EGLWindow::createContext(EGLContext share) const
if (mClientMajorVersion > 2 && !(mEGLMajorVersion > 1 || mEGLMinorVersion >= 5) &&
!hasKHRCreateContext)
{
std::cerr << "EGL_KHR_create_context incompatibility.\n";
fprintf(stderr, "EGL_KHR_create_context incompatibility.\n");
return EGL_NO_CONTEXT;
}
@@ -348,7 +367,7 @@ EGLContext EGLWindow::createContext(EGLContext share) const
bool hasDebug = mEGLMinorVersion >= 5;
if (mConfigParams.debug && !hasDebug)
{
std::cerr << "EGL 1.5 is required for EGL_CONTEXT_OPENGL_DEBUG.\n";
fprintf(stderr, "EGL 1.5 is required for EGL_CONTEXT_OPENGL_DEBUG.\n");
return EGL_NO_CONTEXT;
}
@@ -356,7 +375,7 @@ EGLContext EGLWindow::createContext(EGLContext share) const
strstr(displayExtensions, "EGL_ANGLE_create_context_webgl_compatibility") != nullptr;
if (mConfigParams.webGLCompatibility.valid() && !hasWebGLCompatibility)
{
std::cerr << "EGL_ANGLE_create_context_webgl_compatibility missing.\n";
fprintf(stderr, "EGL_ANGLE_create_context_webgl_compatibility missing.\n");
return EGL_NO_CONTEXT;
}
@@ -364,7 +383,7 @@ EGLContext EGLWindow::createContext(EGLContext share) const
strstr(displayExtensions, "EGL_ANGLE_create_context_extensions_enabled") != nullptr;
if (mConfigParams.extensionsEnabled.valid() && !hasCreateContextExtensionsEnabled)
{
std::cerr << "EGL_ANGLE_create_context_extensions_enabled missing.\n";
fprintf(stderr, "EGL_ANGLE_create_context_extensions_enabled missing.\n");
return EGL_NO_CONTEXT;
}
@@ -373,7 +392,7 @@ EGLContext EGLWindow::createContext(EGLContext share) const
mConfigParams.resetStrategy != EGL_NO_RESET_NOTIFICATION_EXT) &&
!hasRobustness)
{
std::cerr << "EGL_EXT_create_context_robustness missing.\n";
fprintf(stderr, "EGL_EXT_create_context_robustness missing.\n");
return EGL_NO_CONTEXT;
}
@@ -381,7 +400,7 @@ EGLContext EGLWindow::createContext(EGLContext share) const
strstr(displayExtensions, "EGL_CHROMIUM_create_context_bind_generates_resource") != nullptr;
if (!mConfigParams.bindGeneratesResource && !hasBindGeneratesResource)
{
std::cerr << "EGL_CHROMIUM_create_context_bind_generates_resource missing.\n";
fprintf(stderr, "EGL_CHROMIUM_create_context_bind_generates_resource missing.\n");
return EGL_NO_CONTEXT;
}
@@ -390,7 +409,7 @@ EGLContext EGLWindow::createContext(EGLContext share) const
if (!mConfigParams.clientArraysEnabled && !hasClientArraysExtension)
{
// Non-default state requested without the extension present
std::cerr << "EGL_ANGLE_create_context_client_arrays missing.\n";
fprintf(stderr, "EGL_ANGLE_create_context_client_arrays missing.\n");
return EGL_NO_CONTEXT;
}
@@ -398,7 +417,7 @@ EGLContext EGLWindow::createContext(EGLContext share) const
strstr(displayExtensions, "EGL_ANGLE_program_cache_control ") != nullptr;
if (mConfigParams.contextProgramCacheEnabled.valid() && !hasProgramCacheControlExtension)
{
std::cerr << "EGL_ANGLE_program_cache_control missing.\n";
fprintf(stderr, "EGL_ANGLE_program_cache_control missing.\n");
return EGL_NO_CONTEXT;
}
@@ -406,14 +425,14 @@ EGLContext EGLWindow::createContext(EGLContext share) const
strstr(displayExtensions, "EGL_KHR_create_context_no_error") != nullptr;
if (mConfigParams.noError && !hasKHRCreateContextNoError)
{
std::cerr << "EGL_KHR_create_context_no_error missing.\n";
fprintf(stderr, "EGL_KHR_create_context_no_error missing.\n");
return EGL_NO_CONTEXT;
}
eglBindAPI(EGL_OPENGL_ES_API);
if (eglGetError() != EGL_SUCCESS)
{
std::cerr << "Error on eglBindAPI.\n";
fprintf(stderr, "Error on eglBindAPI.\n");
return EGL_NO_CONTEXT;
}
@@ -426,7 +445,9 @@ EGLContext EGLWindow::createContext(EGLContext share) const
contextAttributes.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
contextAttributes.push_back(mClientMinorVersion);
if (hasDebug)
// Note that the Android loader currently doesn't handle this flag despite reporting 1.5.
// Work around this by only using the debug bit when we request a debug context.
if (hasDebug && mConfigParams.debug)
{
contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG);
contextAttributes.push_back(mConfigParams.debug ? EGL_TRUE : EGL_FALSE);
@@ -501,9 +522,9 @@ EGLContext EGLWindow::createContext(EGLContext share) const
contextAttributes.push_back(EGL_NONE);
EGLContext context = eglCreateContext(mDisplay, mConfig, share, &contextAttributes[0]);
if (eglGetError() != EGL_SUCCESS)
if (context == EGL_NO_CONTEXT)
{
std::cerr << "Error on eglCreateContext.\n";
fprintf(stderr, "eglCreateContext failed: 0x%X\n", eglGetError());
return EGL_NO_CONTEXT;
}
@@ -611,7 +632,7 @@ bool EGLWindow::makeCurrent()
if (eglMakeCurrent(mDisplay, mSurface, mSurface, mContext) == EGL_FALSE ||
eglGetError() != EGL_SUCCESS)
{
std::cerr << "Error during eglMakeCurrent.\n";
fprintf(stderr, "Error during eglMakeCurrent.\n");
return false;
}
@@ -622,7 +643,7 @@ bool EGLWindow::setSwapInterval(EGLint swapInterval)
{
if (eglSwapInterval(mDisplay, swapInterval) == EGL_FALSE || eglGetError() != EGL_SUCCESS)
{
std::cerr << "Error during eglSwapInterval.\n";
fprintf(stderr, "Error during eglSwapInterval.\n");
return false;
}

View File

@@ -69,6 +69,7 @@ class ANGLE_UTIL_EXPORT GLWindowBase : angle::NonCopyable
virtual bool initializeGL(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &platformParams,
const ConfigParameters &configParams) = 0;
virtual bool isGLInitialized() const = 0;
@@ -112,6 +113,7 @@ class ANGLE_UTIL_EXPORT EGLWindow : public GLWindowBase
// Internally initializes the Display, Surface and Context.
bool initializeGL(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &platformParams,
const ConfigParameters &configParams) override;
@@ -125,6 +127,7 @@ class ANGLE_UTIL_EXPORT EGLWindow : public GLWindowBase
// Only initializes the Display.
bool initializeDisplay(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &params);
// Only initializes the Surface.

View File

@@ -71,9 +71,15 @@ WGLWindow::~WGLWindow() {}
// Internally initializes GL resources.
bool WGLWindow::initializeGL(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &platformParams,
const ConfigParameters &configParams)
{
if (driverType != angle::GLESDriverType::SystemWGL)
{
return false;
}
glWindowingLibrary->getAs("wglGetProcAddress", &gCurrentWGLGetProcAddress);
if (!gCurrentWGLGetProcAddress)

View File

@@ -30,6 +30,7 @@ class ANGLE_UTIL_EXPORT WGLWindow : public GLWindowBase
// Internally initializes GL resources.
bool initializeGL(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &platformParams,
const ConfigParameters &configParams) override;
void destroyGL() override;