Commit e08a1d36 by Jamie Madill Committed by Commit Bot

Plumb robust resource init extensions.

This also cleans up a few minor glitches in the extension texts, and renames the EGL extension for consistency. It incidentally fixes a bug in our EGL init where we were checking the wrong client versions for KHR_create_context. It also implements a new feature for tests which allow them to defer Context creation until the test body. This allows tests to check for EGL extension available before trying to create a context with certain extensions. BUG=angleproject:1635 Change-Id: I9311991332c357e36214082b16f2a4a57bfa8865 Reviewed-on: https://chromium-review.googlesource.com/450920 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 146e8a1c
......@@ -34,8 +34,8 @@ Dependencies
This extension is written against the wording of the OpenGL ES
3.1 specification.
EGL_EXT_create_context_robust_initialization is used to request a
context supporting this extension to perform resource initialization.
EGL_ANGLE_create_context_robust_initialization is required to request a
context that supports this extension, and resource initialization.
Overview
......@@ -55,11 +55,10 @@ New Procedures and Functions
New Tokens
Accepted by the <value> parameter of GetBooleanv, GetIntegerv,
GetFloatv, GetDoublev, and GetInteger54v:
GetFloatv, GetDoublev, GetInteger64v, and IsEnabled:
CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93A7
Additions to Chapter 6 of the OpenGL ES 3.1 Specification (Buffer
Objects)
......@@ -121,17 +120,18 @@ and Framebuffer Objects)
channel of each sample; otherwise, the contents of the data store
are undefined.
Interactions with EGL_ANGLE_create_context_robust_resource
Interactions with EGL_ANGLE_create_context_robust_resource_initialization
If the EGL window-system binding API is used to create a context,
the EGL_ANGLE_create_context_robust_initialization extension is
supported, and the attribute
EGL_CONTEXT_OPENGL_ROBUST_INITIALIZATION_ANGLE is set to
EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE is set to
EGL_TRUE when eglCreateContext is called, the resulting context
will perform robust resource initialization as described above in
section <section>, and the
CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE
query will return GL_TRUE as described above in section 2.6.1.1.
Otherwise queries will return GL_FALSE.
Issues
......@@ -140,3 +140,4 @@ Issues
Revision History
Version 1, 2015/01/07 - first draft.
Version 2, 2017/03/07 - fixed EGL naming and added IsEnabled.
Name
EGL_ANGLE_robust_resource_initialization.txt
EGL_ANGLE_create_context_robust_resource_initialization.txt
Name Strings
EGL_ANGLE_robust_resource_intialization
EGL_ANGLE_create_context_robust_resource_initialization
Contributors
......@@ -53,14 +53,14 @@ New Tokens
Accepted as an attribute name in the <*attrib_list> argument to
eglCreateContext:
EGL_CONTEXT_OPENGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x320F
EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x320F
Additions to the EGL 1.5 Specification
Add a new section entitled "OpenGL ES Robust Resource Initialization"
to section 3.7.1:
"If the attribute EGL_CONTEXT_OPENGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE
"If the attribute EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE
is set to EGL_TRUE, a context supporting <robust resource initialization>
will be created. OpenGL ES contexts must support the
ANGLE_robust_resource_initialization extension, or equivalent core API
......@@ -68,7 +68,7 @@ Additions to the EGL 1.5 Specification
This attribute is supported only for OpenGL ES contexts. If the
implementation does not support robust resource initialization,
context creation will fail.
The default value of EGL_CONTEXT_OPENGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE
The default value of EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE
is EGL_FALSE."
Issues
......@@ -78,3 +78,4 @@ Issues
Revision History
Version 1, 2015/01/07 - first draft.
Version 2, 2017/03/01 - renamed extension and enum.
......@@ -517,6 +517,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSur
#define EGL_RECORDABLE_ANDROID 0x3142
#endif /* EGL_ANDROID_recordable */
#ifndef EGL_ANGLE_create_context_robust_resource_initialization
#define EGL_ANGLE_create_context_robust_resource_initialization 1
#define EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x320F
#endif /* EGL_ANGLE_create_context_robust_resource_initialization */
#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
#define EGL_ANGLE_d3d_share_handle_client_buffer 1
......
......@@ -841,6 +841,11 @@ GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLen
#define GL_ANDROID_extension_pack_es31a 1
#endif /* GL_ANDROID_extension_pack_es31a */
#ifndef GL_ANGLE_client_arrays
#define GL_ANGLE_client_arrays 1
#define GL_CLIENT_ARRAYS_ANGLE 0x93AA
#endif /* GL_ANGLE_client_arrays */
#ifndef GL_ANGLE_depth_texture
#define GL_ANGLE_depth_texture 1
#endif /* GL_ANGLE_depth_texture */
......@@ -867,10 +872,10 @@ GL_APICALL GLboolean GL_APIENTRY glRequestExtensionANGLE (const GLchar *name);
#endif
#endif /* GL_ANGLE_webgl_compatibility */
#ifndef GL_ANGLE_client_arrays
#define GL_ANGLE_client_arrays 1
#define GL_CLIENT_ARRAYS_ANGLE 0x93AA
#endif /* GL_ANGLE_client_arrays */
#ifndef GL_ANGLE_robust_resource_initialization
#define GL_ANGLE_robust_resource_initialization 1
#define GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93A7
#endif /* GL_ANGLE_robust_resource_initialization */
#ifndef GL_CHROMIUM_framebuffer_mixed_samples
#define GL_CHROMIUM_frambuffer_mixed_samples 1
......
......@@ -214,7 +214,8 @@ Extensions::Extensions()
textureNorm16(false),
pathRendering(false),
surfacelessContext(false),
clientArrays(false)
clientArrays(false),
robustResourceInitialization(false)
{
}
......@@ -648,6 +649,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_CHROMIUM_path_rendering"] = esOnlyExtension(&Extensions::pathRendering);
map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContext);
map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArrays);
map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitialization);
// clang-format on
return map;
......@@ -1037,7 +1039,8 @@ DisplayExtensions::DisplayExtensions()
pixelFormatFloat(false),
surfacelessContext(false),
displayTextureShareGroup(false),
createContextClientArrays(false)
createContextClientArrays(false),
createContextRobustResourceInitialization(false)
{
}
......@@ -1079,6 +1082,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings);
InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &extensionStrings);
InsertExtensionString("EGL_ANGLE_create_context_client_arrays", createContextClientArrays, &extensionStrings);
InsertExtensionString("EGL_ANGLE_create_context_robust_resource_initialization", createContextRobustResourceInitialization, &extensionStrings);
// TODO(jmadill): Enable this when complete.
//InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
// clang-format on
......
......@@ -354,6 +354,9 @@ struct Extensions
// GL_ANGLE_client_arrays
bool clientArrays;
// GL_ANGLE_robust_resource_initialization
bool robustResourceInitialization;
};
struct ExtensionInfo
......@@ -655,6 +658,9 @@ struct DisplayExtensions
// EGL_ANGLE_create_context_client_arrays
bool createContextClientArrays;
// EGL_ANGLE_create_context_robust_resource_initialization
bool createContextRobustResourceInitialization;
};
struct DeviceExtensions
......
......@@ -204,6 +204,11 @@ bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
}
bool GetRobustResourceInit(const egl::AttributeMap &attribs)
{
return (attribs.get(EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
}
std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
{
std::string labelName;
......@@ -278,7 +283,8 @@ Context::Context(rx::EGLImplFactory *implFactory,
initWorkarounds();
mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs));
GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs),
GetRobustResourceInit(attribs));
mFenceNVHandleAllocator.setBaseHandle(0);
......@@ -2533,6 +2539,10 @@ void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
// Explicitly enable GL_ANGLE_robust_client_memory
mExtensions.robustClientMemory = true;
// Determine robust resource init availability from EGL.
mExtensions.robustResourceInitialization =
displayExtensions.createContextRobustResourceInitialization;
// Apply implementation limits
mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
mCaps.maxVertexAttribBindings =
......
......@@ -433,6 +433,14 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign
}
}
if (getExtensions().robustResourceInitialization &&
pname == GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
{
*type = GL_BOOL;
*numParams = 1;
return true;
}
// Check for ES3.0+ parameter names which are also exposed as ES2 extensions
switch (pname)
{
......
......@@ -62,7 +62,8 @@ State::State()
mPrimitiveRestart(false),
mMultiSampling(false),
mSampleAlphaToOne(false),
mFramebufferSRGB(true)
mFramebufferSRGB(true),
mRobustResourceInit(false)
{
}
......@@ -75,7 +76,8 @@ void State::initialize(const Caps &caps,
const Version &clientVersion,
bool debug,
bool bindGeneratesResource,
bool clientArraysEnabled)
bool clientArraysEnabled,
bool robustResourceInit)
{
mMaxDrawBuffers = caps.maxDrawBuffers;
mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
......@@ -214,6 +216,8 @@ void State::initialize(const Caps &caps,
mPathStencilFunc = GL_ALWAYS;
mPathStencilRef = 0;
mPathStencilMask = std::numeric_limits<GLuint>::max();
mRobustResourceInit = robustResourceInit;
}
void State::reset(const Context *context)
......@@ -697,6 +701,8 @@ bool State::getEnableFeature(GLenum feature) const
return areClientArraysEnabled();
case GL_FRAMEBUFFER_SRGB_EXT:
return getFramebufferSRGB();
case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
return mRobustResourceInit;
default: UNREACHABLE(); return false;
}
}
......@@ -1589,6 +1595,9 @@ void State::getBooleanv(GLenum pname, GLboolean *params)
case GL_FRAMEBUFFER_SRGB_EXT:
*params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
break;
case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
*params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
break;
default:
UNREACHABLE();
break;
......
......@@ -45,7 +45,8 @@ class State : angle::NonCopyable
const Version &clientVersion,
bool debug,
bool bindGeneratesResource,
bool clientArraysEnabled);
bool clientArraysEnabled,
bool robustResourceInit);
void reset(const Context *context);
// State chunk getters
......@@ -509,6 +510,9 @@ class State : angle::NonCopyable
// GL_EXT_sRGB_write_control
bool mFramebufferSRGB;
// GL_ANGLE_robust_resource_intialization
bool mRobustResourceInit;
DirtyBits mDirtyBits;
DirtyObjects mDirtyObjects;
};
......
......@@ -1103,6 +1103,8 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
outExtensions->createContextRobustResourceInitialization = true;
}
gl::Error Renderer11::flush()
......
......@@ -464,6 +464,21 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context
}
break;
case EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
if (!display->getExtensions().createContextRobustResourceInitialization)
{
return Error(EGL_BAD_ATTRIBUTE,
"Attribute EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
"requires EGL_ANGLE_create_context_robust_resource_initialization.");
}
if (value != EGL_TRUE && value != EGL_FALSE)
{
return Error(EGL_BAD_ATTRIBUTE,
"EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
"either EGL_TRUE or EGL_FALSE.");
}
break;
default:
return Error(EGL_BAD_ATTRIBUTE, "Unknown attribute.");
}
......
......@@ -216,6 +216,9 @@ bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
case GL_SAMPLE_MASK:
return context->getClientVersion() >= Version(3, 1);
case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
return queryOnly && context->getExtensions().robustResourceInitialization;
default:
return false;
}
......
......@@ -78,7 +78,7 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
caps.maxElementIndex = 100;
caps.maxDrawBuffers = 1;
caps.maxColorAttachments = 1;
state.initialize(caps, extensions, Version(3, 0), false, true, true);
state.initialize(caps, extensions, Version(3, 0), false, true, true, false);
NiceMock<MockTextureImpl> *textureImpl = new NiceMock<MockTextureImpl>();
EXPECT_CALL(mockFactory, createTexture(_)).WillOnce(Return(textureImpl));
......
......@@ -67,6 +67,7 @@
'<(angle_path)/src/tests/gl_tests/ReadPixelsTest.cpp',
'<(angle_path)/src/tests/gl_tests/RendererTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustClientMemoryTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustResourceInitTest.cpp',
'<(angle_path)/src/tests/gl_tests/SimpleOperationTest.cpp',
'<(angle_path)/src/tests/gl_tests/SixteenBppTextureTest.cpp',
'<(angle_path)/src/tests/gl_tests/SRGBFramebufferTest.cpp',
......
//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RobustResourceInitTest: Tests for GL_ANGLE_robust_resource_initialization.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
namespace angle
{
class RobustResourceInitTest : public ANGLETest
{
protected:
RobustResourceInitTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
// Defer context init until the test body.
setDeferContextInit(true);
setRobustResourceInit(true);
}
};
// Context creation should fail if EGL_ANGLE_create_context_robust_resource_initialization
// is not available, and succeed otherwise.
TEST_P(RobustResourceInitTest, ExtensionInit)
{
EGLDisplay display = getEGLWindow()->getDisplay();
ASSERT_TRUE(display != EGL_NO_DISPLAY);
if (eglDisplayExtensionEnabled(display,
"EGL_ANGLE_create_context_robust_resource_initialization"))
{
// Context creation shold succeed with robust resource init enabled.
EXPECT_TRUE(getEGLWindow()->initializeContext());
// Robust resource init extension should be available.
EXPECT_TRUE(extensionEnabled("GL_ANGLE_robust_resource_initialization"));
// Querying the state value should return true.
GLboolean enabled = 0;
glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
EXPECT_GL_NO_ERROR();
EXPECT_GL_TRUE(enabled);
EXPECT_GL_TRUE(glIsEnabled(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
}
else
{
// Context creation should fail with robust resource init enabled.
EXPECT_FALSE(getEGLWindow()->initializeContext());
// Context creation should succeed with robust resource init disabled.
setRobustResourceInit(false);
ASSERT_TRUE(getEGLWindow()->initializeGL(GetOSWindow()));
// If context extension string exposed, check queries.
if (extensionEnabled("GL_ANGLE_robust_resource_initialization"))
{
GLboolean enabled = 0;
glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
EXPECT_GL_FALSE(enabled);
EXPECT_GL_FALSE(glIsEnabled(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
EXPECT_GL_NO_ERROR();
}
else
{
// Querying robust resource init should return INVALID_ENUM.
GLboolean enabled = 0;
glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
}
}
// Test queries on a normal, non-robust enabled context.
TEST_P(RobustResourceInitTest, QueriesOnNonRobustContext)
{
EGLDisplay display = getEGLWindow()->getDisplay();
ASSERT_TRUE(display != EGL_NO_DISPLAY);
if (!eglDisplayExtensionEnabled(display,
"EGL_ANGLE_create_context_robust_resource_initialization"))
{
return;
}
setRobustResourceInit(false);
EXPECT_TRUE(getEGLWindow()->initializeContext());
// If context extension string exposed, check queries.
ASSERT_TRUE(extensionEnabled("GL_ANGLE_robust_resource_initialization"));
// Querying robust resource init should return INVALID_ENUM.
GLboolean enabled = 0;
glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
EXPECT_GL_FALSE(enabled);
EXPECT_GL_FALSE(glIsEnabled(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
EXPECT_GL_NO_ERROR();
}
ANGLE_INSTANTIATE_TEST(RobustResourceInitTest,
ES2_D3D9(),
ES2_D3D11(),
ES3_D3D11(),
ES2_D3D11_FL9_3(),
ES2_OPENGL(),
ES3_OPENGL(),
ES2_OPENGLES(),
ES3_OPENGLES());
} // namespace
......@@ -198,7 +198,8 @@ ANGLETest::ANGLETest()
mWidth(16),
mHeight(16),
mIgnoreD3D11SDKLayersWarnings(false),
mQuadVertexBuffer(0)
mQuadVertexBuffer(0),
mDeferContextInit(false)
{
mEGLWindow =
new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
......@@ -252,9 +253,14 @@ void ANGLETest::SetUp()
needSwap = true;
}
if (!createEGLContext())
if (!mEGLWindow->initializeDisplayAndSurface(mOSWindow))
{
FAIL() << "egl context creation failed.";
FAIL() << "egl display or surface init failed.";
}
if (!mDeferContextInit && !mEGLWindow->initializeContext())
{
FAIL() << "GL Context init failed.";
}
if (mGLESLibrary)
......@@ -706,6 +712,16 @@ void ANGLETest::setClientArraysEnabled(bool enabled)
mEGLWindow->setClientArraysEnabled(enabled);
}
void ANGLETest::setRobustResourceInit(bool enabled)
{
mEGLWindow->setRobustResourceInit(enabled);
}
void ANGLETest::setDeferContextInit(bool enabled)
{
mDeferContextInit = enabled;
}
int ANGLETest::getClientMajorVersion() const
{
return mEGLWindow->getClientMajorVersion();
......@@ -736,11 +752,6 @@ bool ANGLETest::isMultisampleEnabled() const
return mEGLWindow->isMultisample();
}
bool ANGLETest::createEGLContext()
{
return mEGLWindow->initializeGL(mOSWindow);
}
bool ANGLETest::destroyEGLContext()
{
mEGLWindow->destroyGL();
......
......@@ -238,6 +238,10 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
void setBindGeneratesResource(bool bindGeneratesResource);
void setVulkanLayersEnabled(bool enabled);
void setClientArraysEnabled(bool enabled);
void setRobustResourceInit(bool enabled);
// Some EGL extension tests would like to defer the Context init until the test body.
void setDeferContextInit(bool enabled);
int getClientMajorVersion() const;
int getClientMinorVersion() const;
......@@ -254,7 +258,6 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
static OSWindow *GetOSWindow() { return mOSWindow; }
private:
bool createEGLContext();
bool destroyEGLContext();
void checkD3D11SDKLayersMessages();
......@@ -270,6 +273,8 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
TestPlatformContext mPlatformContext;
bool mDeferContextInit;
static OSWindow *mOSWindow;
// Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan.
......
......@@ -100,6 +100,8 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion,
mContext(EGL_NO_CONTEXT),
mClientMajorVersion(glesMajorVersion),
mClientMinorVersion(glesMinorVersion),
mEGLMajorVersion(0),
mEGLMinorVersion(0),
mPlatform(platform),
mRedBits(-1),
mGreenBits(-1),
......@@ -114,6 +116,7 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion,
mWebGLCompatibility(false),
mBindGeneratesResource(true),
mClientArraysEnabled(true),
mRobustResourceInit(false),
mSwapInterval(-1)
{
}
......@@ -150,6 +153,13 @@ EGLContext EGLWindow::getContext() const
bool EGLWindow::initializeGL(OSWindow *osWindow)
{
if (!initializeDisplayAndSurface(osWindow))
return false;
return initializeContext();
}
bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow)
{
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
if (!eglGetPlatformDisplayEXT)
{
......@@ -202,8 +212,7 @@ bool EGLWindow::initializeGL(OSWindow *osWindow)
return false;
}
EGLint majorVersion, minorVersion;
if (eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_FALSE)
if (eglInitialize(mDisplay, &mEGLMajorVersion, &mEGLMinorVersion) == EGL_FALSE)
{
destroyGL();
return false;
......@@ -211,46 +220,6 @@ bool EGLWindow::initializeGL(OSWindow *osWindow)
const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS);
// EGL_KHR_create_context is required to request a non-ES2 context.
bool hasKHRCreateContext = strstr(displayExtensions, "EGL_KHR_create_context") != nullptr;
if (majorVersion != 2 && minorVersion != 0 && !hasKHRCreateContext)
{
destroyGL();
return false;
}
bool hasWebGLCompatibility =
strstr(displayExtensions, "EGL_ANGLE_create_context_webgl_compatibility") != nullptr;
if (mWebGLCompatibility && !hasWebGLCompatibility)
{
destroyGL();
return false;
}
bool hasBindGeneratesResource =
strstr(displayExtensions, "EGL_CHROMIUM_create_context_bind_generates_resource") != nullptr;
if (!mBindGeneratesResource && !hasBindGeneratesResource)
{
destroyGL();
return false;
}
bool hasClientArraysExtension =
strstr(displayExtensions, "EGL_ANGLE_create_context_client_arrays") != nullptr;
if (!mClientArraysEnabled && !hasClientArraysExtension)
{
// Non-default state requested without the extension present
destroyGL();
return false;
}
eglBindAPI(EGL_OPENGL_ES_API);
if (eglGetError() != EGL_SUCCESS)
{
destroyGL();
return false;
}
std::vector<EGLint> configAttributes = {
EGL_RED_SIZE, (mRedBits >= 0) ? mRedBits : EGL_DONT_CARE,
EGL_GREEN_SIZE, (mGreenBits >= 0) ? mGreenBits : EGL_DONT_CARE,
......@@ -306,6 +275,63 @@ bool EGLWindow::initializeGL(OSWindow *osWindow)
return false;
}
ASSERT(mSurface != EGL_NO_SURFACE);
return true;
}
bool EGLWindow::initializeContext()
{
const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS);
// EGL_KHR_create_context is required to request a ES3+ context.
bool hasKHRCreateContext = strstr(displayExtensions, "EGL_KHR_create_context") != nullptr;
if (mClientMajorVersion > 2 && !(mEGLMajorVersion > 1 || mEGLMinorVersion >= 5) &&
!hasKHRCreateContext)
{
destroyGL();
return false;
}
bool hasWebGLCompatibility =
strstr(displayExtensions, "EGL_ANGLE_create_context_webgl_compatibility") != nullptr;
if (mWebGLCompatibility && !hasWebGLCompatibility)
{
destroyGL();
return false;
}
bool hasBindGeneratesResource =
strstr(displayExtensions, "EGL_CHROMIUM_create_context_bind_generates_resource") != nullptr;
if (!mBindGeneratesResource && !hasBindGeneratesResource)
{
destroyGL();
return false;
}
bool hasClientArraysExtension =
strstr(displayExtensions, "EGL_ANGLE_create_context_client_arrays") != nullptr;
if (!mClientArraysEnabled && !hasClientArraysExtension)
{
// Non-default state requested without the extension present
destroyGL();
return false;
}
bool hasRobustResourceInit =
strstr(displayExtensions, "EGL_ANGLE_create_context_robust_resource_initialization") !=
nullptr;
if (mRobustResourceInit && !hasRobustResourceInit)
{
// Non-default state requested without the extension present
destroyGL();
return false;
}
eglBindAPI(EGL_OPENGL_ES_API);
if (eglGetError() != EGL_SUCCESS)
{
destroyGL();
return false;
}
std::vector<EGLint> contextAttributes;
if (hasKHRCreateContext)
......@@ -343,6 +369,12 @@ bool EGLWindow::initializeGL(OSWindow *osWindow)
contextAttributes.push_back(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE);
contextAttributes.push_back(mClientArraysEnabled ? EGL_TRUE : EGL_FALSE);
}
if (hasRobustResourceInit)
{
contextAttributes.push_back(EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE);
contextAttributes.push_back(mRobustResourceInit ? EGL_TRUE : EGL_FALSE);
}
}
contextAttributes.push_back(EGL_NONE);
......
......@@ -80,6 +80,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
}
void setVulkanLayersEnabled(bool enabled) { mVulkanLayersEnabled = enabled; }
void setClientArraysEnabled(bool enabled) { mClientArraysEnabled = enabled; }
void setRobustResourceInit(bool enabled) { mRobustResourceInit = enabled; }
void setSwapInterval(EGLint swapInterval) { mSwapInterval = swapInterval; }
static EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config);
......@@ -103,7 +104,15 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
bool isDebugEnabled() const { return mDebug; }
EGLint getSwapInterval() const { return mSwapInterval; }
// Internally initializes the Display, Surface and Context.
bool initializeGL(OSWindow *osWindow);
// Only initializes the Display and Surface.
bool initializeDisplayAndSurface(OSWindow *osWindow);
// Only initializes the Context.
bool initializeContext();
void destroyGL();
bool isGLInitialized() const;
......@@ -115,6 +124,8 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
EGLint mClientMajorVersion;
EGLint mClientMinorVersion;
EGLint mEGLMajorVersion;
EGLint mEGLMinorVersion;
EGLPlatformParameters mPlatform;
int mRedBits;
int mGreenBits;
......@@ -129,6 +140,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
bool mWebGLCompatibility;
bool mBindGeneratesResource;
bool mClientArraysEnabled;
bool mRobustResourceInit;
EGLint mSwapInterval;
Optional<bool> mVulkanLayersEnabled;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment