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 ...@@ -34,8 +34,8 @@ Dependencies
This extension is written against the wording of the OpenGL ES This extension is written against the wording of the OpenGL ES
3.1 specification. 3.1 specification.
EGL_EXT_create_context_robust_initialization is used to request a EGL_ANGLE_create_context_robust_initialization is required to request a
context supporting this extension to perform resource initialization. context that supports this extension, and resource initialization.
Overview Overview
...@@ -55,11 +55,10 @@ New Procedures and Functions ...@@ -55,11 +55,10 @@ New Procedures and Functions
New Tokens New Tokens
Accepted by the <value> parameter of GetBooleanv, GetIntegerv, Accepted by the <value> parameter of GetBooleanv, GetIntegerv,
GetFloatv, GetDoublev, and GetInteger54v: GetFloatv, GetDoublev, GetInteger64v, and IsEnabled:
CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93A7 CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93A7
Additions to Chapter 6 of the OpenGL ES 3.1 Specification (Buffer Additions to Chapter 6 of the OpenGL ES 3.1 Specification (Buffer
Objects) Objects)
...@@ -121,17 +120,18 @@ and Framebuffer Objects) ...@@ -121,17 +120,18 @@ and Framebuffer Objects)
channel of each sample; otherwise, the contents of the data store channel of each sample; otherwise, the contents of the data store
are undefined. 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, If the EGL window-system binding API is used to create a context,
the EGL_ANGLE_create_context_robust_initialization extension is the EGL_ANGLE_create_context_robust_initialization extension is
supported, and the attribute 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 EGL_TRUE when eglCreateContext is called, the resulting context
will perform robust resource initialization as described above in will perform robust resource initialization as described above in
section <section>, and the section <section>, and the
CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE
query will return GL_TRUE as described above in section 2.6.1.1. query will return GL_TRUE as described above in section 2.6.1.1.
Otherwise queries will return GL_FALSE.
Issues Issues
...@@ -140,3 +140,4 @@ Issues ...@@ -140,3 +140,4 @@ Issues
Revision History Revision History
Version 1, 2015/01/07 - first draft. Version 1, 2015/01/07 - first draft.
Version 2, 2017/03/07 - fixed EGL naming and added IsEnabled.
Name Name
EGL_ANGLE_robust_resource_initialization.txt EGL_ANGLE_create_context_robust_resource_initialization.txt
Name Strings Name Strings
EGL_ANGLE_robust_resource_intialization EGL_ANGLE_create_context_robust_resource_initialization
Contributors Contributors
...@@ -53,14 +53,14 @@ New Tokens ...@@ -53,14 +53,14 @@ New Tokens
Accepted as an attribute name in the <*attrib_list> argument to Accepted as an attribute name in the <*attrib_list> argument to
eglCreateContext: eglCreateContext:
EGL_CONTEXT_OPENGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x320F EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x320F
Additions to the EGL 1.5 Specification Additions to the EGL 1.5 Specification
Add a new section entitled "OpenGL ES Robust Resource Initialization" Add a new section entitled "OpenGL ES Robust Resource Initialization"
to section 3.7.1: 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> is set to EGL_TRUE, a context supporting <robust resource initialization>
will be created. OpenGL ES contexts must support the will be created. OpenGL ES contexts must support the
ANGLE_robust_resource_initialization extension, or equivalent core API ANGLE_robust_resource_initialization extension, or equivalent core API
...@@ -68,7 +68,7 @@ Additions to the EGL 1.5 Specification ...@@ -68,7 +68,7 @@ Additions to the EGL 1.5 Specification
This attribute is supported only for OpenGL ES contexts. If the This attribute is supported only for OpenGL ES contexts. If the
implementation does not support robust resource initialization, implementation does not support robust resource initialization,
context creation will fail. 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." is EGL_FALSE."
Issues Issues
...@@ -78,3 +78,4 @@ Issues ...@@ -78,3 +78,4 @@ Issues
Revision History Revision History
Version 1, 2015/01/07 - first draft. 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 ...@@ -517,6 +517,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSur
#define EGL_RECORDABLE_ANDROID 0x3142 #define EGL_RECORDABLE_ANDROID 0x3142
#endif /* EGL_ANDROID_recordable */ #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 #ifndef EGL_ANGLE_d3d_share_handle_client_buffer
#define EGL_ANGLE_d3d_share_handle_client_buffer 1 #define EGL_ANGLE_d3d_share_handle_client_buffer 1
......
...@@ -841,6 +841,11 @@ GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLen ...@@ -841,6 +841,11 @@ GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLen
#define GL_ANDROID_extension_pack_es31a 1 #define GL_ANDROID_extension_pack_es31a 1
#endif /* GL_ANDROID_extension_pack_es31a */ #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 #ifndef GL_ANGLE_depth_texture
#define GL_ANGLE_depth_texture 1 #define GL_ANGLE_depth_texture 1
#endif /* GL_ANGLE_depth_texture */ #endif /* GL_ANGLE_depth_texture */
...@@ -867,10 +872,10 @@ GL_APICALL GLboolean GL_APIENTRY glRequestExtensionANGLE (const GLchar *name); ...@@ -867,10 +872,10 @@ GL_APICALL GLboolean GL_APIENTRY glRequestExtensionANGLE (const GLchar *name);
#endif #endif
#endif /* GL_ANGLE_webgl_compatibility */ #endif /* GL_ANGLE_webgl_compatibility */
#ifndef GL_ANGLE_client_arrays #ifndef GL_ANGLE_robust_resource_initialization
#define GL_ANGLE_client_arrays 1 #define GL_ANGLE_robust_resource_initialization 1
#define GL_CLIENT_ARRAYS_ANGLE 0x93AA #define GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93A7
#endif /* GL_ANGLE_client_arrays */ #endif /* GL_ANGLE_robust_resource_initialization */
#ifndef GL_CHROMIUM_framebuffer_mixed_samples #ifndef GL_CHROMIUM_framebuffer_mixed_samples
#define GL_CHROMIUM_frambuffer_mixed_samples 1 #define GL_CHROMIUM_frambuffer_mixed_samples 1
......
...@@ -214,7 +214,8 @@ Extensions::Extensions() ...@@ -214,7 +214,8 @@ Extensions::Extensions()
textureNorm16(false), textureNorm16(false),
pathRendering(false), pathRendering(false),
surfacelessContext(false), surfacelessContext(false),
clientArrays(false) clientArrays(false),
robustResourceInitialization(false)
{ {
} }
...@@ -648,6 +649,7 @@ const ExtensionInfoMap &GetExtensionInfoMap() ...@@ -648,6 +649,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_CHROMIUM_path_rendering"] = esOnlyExtension(&Extensions::pathRendering); map["GL_CHROMIUM_path_rendering"] = esOnlyExtension(&Extensions::pathRendering);
map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContext); map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContext);
map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArrays); map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArrays);
map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitialization);
// clang-format on // clang-format on
return map; return map;
...@@ -1037,7 +1039,8 @@ DisplayExtensions::DisplayExtensions() ...@@ -1037,7 +1039,8 @@ DisplayExtensions::DisplayExtensions()
pixelFormatFloat(false), pixelFormatFloat(false),
surfacelessContext(false), surfacelessContext(false),
displayTextureShareGroup(false), displayTextureShareGroup(false),
createContextClientArrays(false) createContextClientArrays(false),
createContextRobustResourceInitialization(false)
{ {
} }
...@@ -1079,6 +1082,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -1079,6 +1082,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings); InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings);
InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &extensionStrings); InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &extensionStrings);
InsertExtensionString("EGL_ANGLE_create_context_client_arrays", createContextClientArrays, &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. // TODO(jmadill): Enable this when complete.
//InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings); //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
// clang-format on // clang-format on
......
...@@ -354,6 +354,9 @@ struct Extensions ...@@ -354,6 +354,9 @@ struct Extensions
// GL_ANGLE_client_arrays // GL_ANGLE_client_arrays
bool clientArrays; bool clientArrays;
// GL_ANGLE_robust_resource_initialization
bool robustResourceInitialization;
}; };
struct ExtensionInfo struct ExtensionInfo
...@@ -655,6 +658,9 @@ struct DisplayExtensions ...@@ -655,6 +658,9 @@ struct DisplayExtensions
// EGL_ANGLE_create_context_client_arrays // EGL_ANGLE_create_context_client_arrays
bool createContextClientArrays; bool createContextClientArrays;
// EGL_ANGLE_create_context_robust_resource_initialization
bool createContextRobustResourceInitialization;
}; };
struct DeviceExtensions struct DeviceExtensions
......
...@@ -204,6 +204,11 @@ bool GetClientArraysEnabled(const egl::AttributeMap &attribs) ...@@ -204,6 +204,11 @@ bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE); 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 GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
{ {
std::string labelName; std::string labelName;
...@@ -278,7 +283,8 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -278,7 +283,8 @@ Context::Context(rx::EGLImplFactory *implFactory,
initWorkarounds(); initWorkarounds();
mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs), mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs)); GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs),
GetRobustResourceInit(attribs));
mFenceNVHandleAllocator.setBaseHandle(0); mFenceNVHandleAllocator.setBaseHandle(0);
...@@ -2533,6 +2539,10 @@ void Context::initCaps(const egl::DisplayExtensions &displayExtensions) ...@@ -2533,6 +2539,10 @@ void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
// Explicitly enable GL_ANGLE_robust_client_memory // Explicitly enable GL_ANGLE_robust_client_memory
mExtensions.robustClientMemory = true; mExtensions.robustClientMemory = true;
// Determine robust resource init availability from EGL.
mExtensions.robustResourceInitialization =
displayExtensions.createContextRobustResourceInitialization;
// Apply implementation limits // Apply implementation limits
mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS); mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
mCaps.maxVertexAttribBindings = mCaps.maxVertexAttribBindings =
......
...@@ -433,6 +433,14 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign ...@@ -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 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
switch (pname) switch (pname)
{ {
......
...@@ -62,7 +62,8 @@ State::State() ...@@ -62,7 +62,8 @@ State::State()
mPrimitiveRestart(false), mPrimitiveRestart(false),
mMultiSampling(false), mMultiSampling(false),
mSampleAlphaToOne(false), mSampleAlphaToOne(false),
mFramebufferSRGB(true) mFramebufferSRGB(true),
mRobustResourceInit(false)
{ {
} }
...@@ -75,7 +76,8 @@ void State::initialize(const Caps &caps, ...@@ -75,7 +76,8 @@ void State::initialize(const Caps &caps,
const Version &clientVersion, const Version &clientVersion,
bool debug, bool debug,
bool bindGeneratesResource, bool bindGeneratesResource,
bool clientArraysEnabled) bool clientArraysEnabled,
bool robustResourceInit)
{ {
mMaxDrawBuffers = caps.maxDrawBuffers; mMaxDrawBuffers = caps.maxDrawBuffers;
mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
...@@ -214,6 +216,8 @@ void State::initialize(const Caps &caps, ...@@ -214,6 +216,8 @@ void State::initialize(const Caps &caps,
mPathStencilFunc = GL_ALWAYS; mPathStencilFunc = GL_ALWAYS;
mPathStencilRef = 0; mPathStencilRef = 0;
mPathStencilMask = std::numeric_limits<GLuint>::max(); mPathStencilMask = std::numeric_limits<GLuint>::max();
mRobustResourceInit = robustResourceInit;
} }
void State::reset(const Context *context) void State::reset(const Context *context)
...@@ -697,6 +701,8 @@ bool State::getEnableFeature(GLenum feature) const ...@@ -697,6 +701,8 @@ bool State::getEnableFeature(GLenum feature) const
return areClientArraysEnabled(); return areClientArraysEnabled();
case GL_FRAMEBUFFER_SRGB_EXT: case GL_FRAMEBUFFER_SRGB_EXT:
return getFramebufferSRGB(); return getFramebufferSRGB();
case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
return mRobustResourceInit;
default: UNREACHABLE(); return false; default: UNREACHABLE(); return false;
} }
} }
...@@ -1589,6 +1595,9 @@ void State::getBooleanv(GLenum pname, GLboolean *params) ...@@ -1589,6 +1595,9 @@ void State::getBooleanv(GLenum pname, GLboolean *params)
case GL_FRAMEBUFFER_SRGB_EXT: case GL_FRAMEBUFFER_SRGB_EXT:
*params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE; *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
break; break;
case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
*params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -45,7 +45,8 @@ class State : angle::NonCopyable ...@@ -45,7 +45,8 @@ class State : angle::NonCopyable
const Version &clientVersion, const Version &clientVersion,
bool debug, bool debug,
bool bindGeneratesResource, bool bindGeneratesResource,
bool clientArraysEnabled); bool clientArraysEnabled,
bool robustResourceInit);
void reset(const Context *context); void reset(const Context *context);
// State chunk getters // State chunk getters
...@@ -509,6 +510,9 @@ class State : angle::NonCopyable ...@@ -509,6 +510,9 @@ class State : angle::NonCopyable
// GL_EXT_sRGB_write_control // GL_EXT_sRGB_write_control
bool mFramebufferSRGB; bool mFramebufferSRGB;
// GL_ANGLE_robust_resource_intialization
bool mRobustResourceInit;
DirtyBits mDirtyBits; DirtyBits mDirtyBits;
DirtyObjects mDirtyObjects; DirtyObjects mDirtyObjects;
}; };
......
...@@ -1103,6 +1103,8 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions ...@@ -1103,6 +1103,8 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
// Contexts are virtualized so textures can be shared globally // Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true; outExtensions->displayTextureShareGroup = true;
outExtensions->createContextRobustResourceInitialization = true;
} }
gl::Error Renderer11::flush() gl::Error Renderer11::flush()
......
...@@ -464,6 +464,21 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context ...@@ -464,6 +464,21 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context
} }
break; 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: default:
return Error(EGL_BAD_ATTRIBUTE, "Unknown attribute."); return Error(EGL_BAD_ATTRIBUTE, "Unknown attribute.");
} }
......
...@@ -216,6 +216,9 @@ bool ValidCap(const Context *context, GLenum cap, bool queryOnly) ...@@ -216,6 +216,9 @@ bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
case GL_SAMPLE_MASK: case GL_SAMPLE_MASK:
return context->getClientVersion() >= Version(3, 1); return context->getClientVersion() >= Version(3, 1);
case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
return queryOnly && context->getExtensions().robustResourceInitialization;
default: default:
return false; return false;
} }
......
...@@ -78,7 +78,7 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError) ...@@ -78,7 +78,7 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
caps.maxElementIndex = 100; caps.maxElementIndex = 100;
caps.maxDrawBuffers = 1; caps.maxDrawBuffers = 1;
caps.maxColorAttachments = 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>(); NiceMock<MockTextureImpl> *textureImpl = new NiceMock<MockTextureImpl>();
EXPECT_CALL(mockFactory, createTexture(_)).WillOnce(Return(textureImpl)); EXPECT_CALL(mockFactory, createTexture(_)).WillOnce(Return(textureImpl));
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
'<(angle_path)/src/tests/gl_tests/ReadPixelsTest.cpp', '<(angle_path)/src/tests/gl_tests/ReadPixelsTest.cpp',
'<(angle_path)/src/tests/gl_tests/RendererTest.cpp', '<(angle_path)/src/tests/gl_tests/RendererTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustClientMemoryTest.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/SimpleOperationTest.cpp',
'<(angle_path)/src/tests/gl_tests/SixteenBppTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/SixteenBppTextureTest.cpp',
'<(angle_path)/src/tests/gl_tests/SRGBFramebufferTest.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() ...@@ -198,7 +198,8 @@ ANGLETest::ANGLETest()
mWidth(16), mWidth(16),
mHeight(16), mHeight(16),
mIgnoreD3D11SDKLayersWarnings(false), mIgnoreD3D11SDKLayersWarnings(false),
mQuadVertexBuffer(0) mQuadVertexBuffer(0),
mDeferContextInit(false)
{ {
mEGLWindow = mEGLWindow =
new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters); new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
...@@ -252,9 +253,14 @@ void ANGLETest::SetUp() ...@@ -252,9 +253,14 @@ void ANGLETest::SetUp()
needSwap = true; 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) if (mGLESLibrary)
...@@ -706,6 +712,16 @@ void ANGLETest::setClientArraysEnabled(bool enabled) ...@@ -706,6 +712,16 @@ void ANGLETest::setClientArraysEnabled(bool enabled)
mEGLWindow->setClientArraysEnabled(enabled); mEGLWindow->setClientArraysEnabled(enabled);
} }
void ANGLETest::setRobustResourceInit(bool enabled)
{
mEGLWindow->setRobustResourceInit(enabled);
}
void ANGLETest::setDeferContextInit(bool enabled)
{
mDeferContextInit = enabled;
}
int ANGLETest::getClientMajorVersion() const int ANGLETest::getClientMajorVersion() const
{ {
return mEGLWindow->getClientMajorVersion(); return mEGLWindow->getClientMajorVersion();
...@@ -736,11 +752,6 @@ bool ANGLETest::isMultisampleEnabled() const ...@@ -736,11 +752,6 @@ bool ANGLETest::isMultisampleEnabled() const
return mEGLWindow->isMultisample(); return mEGLWindow->isMultisample();
} }
bool ANGLETest::createEGLContext()
{
return mEGLWindow->initializeGL(mOSWindow);
}
bool ANGLETest::destroyEGLContext() bool ANGLETest::destroyEGLContext()
{ {
mEGLWindow->destroyGL(); mEGLWindow->destroyGL();
......
...@@ -238,6 +238,10 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters> ...@@ -238,6 +238,10 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
void setBindGeneratesResource(bool bindGeneratesResource); void setBindGeneratesResource(bool bindGeneratesResource);
void setVulkanLayersEnabled(bool enabled); void setVulkanLayersEnabled(bool enabled);
void setClientArraysEnabled(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 getClientMajorVersion() const;
int getClientMinorVersion() const; int getClientMinorVersion() const;
...@@ -254,7 +258,6 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters> ...@@ -254,7 +258,6 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
static OSWindow *GetOSWindow() { return mOSWindow; } static OSWindow *GetOSWindow() { return mOSWindow; }
private: private:
bool createEGLContext();
bool destroyEGLContext(); bool destroyEGLContext();
void checkD3D11SDKLayersMessages(); void checkD3D11SDKLayersMessages();
...@@ -270,6 +273,8 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters> ...@@ -270,6 +273,8 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
TestPlatformContext mPlatformContext; TestPlatformContext mPlatformContext;
bool mDeferContextInit;
static OSWindow *mOSWindow; static OSWindow *mOSWindow;
// Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan. // Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan.
......
...@@ -100,6 +100,8 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion, ...@@ -100,6 +100,8 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion,
mContext(EGL_NO_CONTEXT), mContext(EGL_NO_CONTEXT),
mClientMajorVersion(glesMajorVersion), mClientMajorVersion(glesMajorVersion),
mClientMinorVersion(glesMinorVersion), mClientMinorVersion(glesMinorVersion),
mEGLMajorVersion(0),
mEGLMinorVersion(0),
mPlatform(platform), mPlatform(platform),
mRedBits(-1), mRedBits(-1),
mGreenBits(-1), mGreenBits(-1),
...@@ -114,6 +116,7 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion, ...@@ -114,6 +116,7 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion,
mWebGLCompatibility(false), mWebGLCompatibility(false),
mBindGeneratesResource(true), mBindGeneratesResource(true),
mClientArraysEnabled(true), mClientArraysEnabled(true),
mRobustResourceInit(false),
mSwapInterval(-1) mSwapInterval(-1)
{ {
} }
...@@ -150,6 +153,13 @@ EGLContext EGLWindow::getContext() const ...@@ -150,6 +153,13 @@ EGLContext EGLWindow::getContext() const
bool EGLWindow::initializeGL(OSWindow *osWindow) bool EGLWindow::initializeGL(OSWindow *osWindow)
{ {
if (!initializeDisplayAndSurface(osWindow))
return false;
return initializeContext();
}
bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow)
{
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT")); PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
if (!eglGetPlatformDisplayEXT) if (!eglGetPlatformDisplayEXT)
{ {
...@@ -202,8 +212,7 @@ bool EGLWindow::initializeGL(OSWindow *osWindow) ...@@ -202,8 +212,7 @@ bool EGLWindow::initializeGL(OSWindow *osWindow)
return false; return false;
} }
EGLint majorVersion, minorVersion; if (eglInitialize(mDisplay, &mEGLMajorVersion, &mEGLMinorVersion) == EGL_FALSE)
if (eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_FALSE)
{ {
destroyGL(); destroyGL();
return false; return false;
...@@ -211,46 +220,6 @@ bool EGLWindow::initializeGL(OSWindow *osWindow) ...@@ -211,46 +220,6 @@ bool EGLWindow::initializeGL(OSWindow *osWindow)
const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); 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 = { std::vector<EGLint> configAttributes = {
EGL_RED_SIZE, (mRedBits >= 0) ? mRedBits : EGL_DONT_CARE, EGL_RED_SIZE, (mRedBits >= 0) ? mRedBits : EGL_DONT_CARE,
EGL_GREEN_SIZE, (mGreenBits >= 0) ? mGreenBits : EGL_DONT_CARE, EGL_GREEN_SIZE, (mGreenBits >= 0) ? mGreenBits : EGL_DONT_CARE,
...@@ -306,6 +275,63 @@ bool EGLWindow::initializeGL(OSWindow *osWindow) ...@@ -306,6 +275,63 @@ bool EGLWindow::initializeGL(OSWindow *osWindow)
return false; return false;
} }
ASSERT(mSurface != EGL_NO_SURFACE); 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; std::vector<EGLint> contextAttributes;
if (hasKHRCreateContext) if (hasKHRCreateContext)
...@@ -343,6 +369,12 @@ bool EGLWindow::initializeGL(OSWindow *osWindow) ...@@ -343,6 +369,12 @@ bool EGLWindow::initializeGL(OSWindow *osWindow)
contextAttributes.push_back(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE); contextAttributes.push_back(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE);
contextAttributes.push_back(mClientArraysEnabled ? EGL_TRUE : EGL_FALSE); 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); contextAttributes.push_back(EGL_NONE);
......
...@@ -80,6 +80,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable ...@@ -80,6 +80,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
} }
void setVulkanLayersEnabled(bool enabled) { mVulkanLayersEnabled = enabled; } void setVulkanLayersEnabled(bool enabled) { mVulkanLayersEnabled = enabled; }
void setClientArraysEnabled(bool enabled) { mClientArraysEnabled = enabled; } void setClientArraysEnabled(bool enabled) { mClientArraysEnabled = enabled; }
void setRobustResourceInit(bool enabled) { mRobustResourceInit = enabled; }
void setSwapInterval(EGLint swapInterval) { mSwapInterval = swapInterval; } void setSwapInterval(EGLint swapInterval) { mSwapInterval = swapInterval; }
static EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config); static EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config);
...@@ -103,7 +104,15 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable ...@@ -103,7 +104,15 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
bool isDebugEnabled() const { return mDebug; } bool isDebugEnabled() const { return mDebug; }
EGLint getSwapInterval() const { return mSwapInterval; } EGLint getSwapInterval() const { return mSwapInterval; }
// Internally initializes the Display, Surface and Context.
bool initializeGL(OSWindow *osWindow); bool initializeGL(OSWindow *osWindow);
// Only initializes the Display and Surface.
bool initializeDisplayAndSurface(OSWindow *osWindow);
// Only initializes the Context.
bool initializeContext();
void destroyGL(); void destroyGL();
bool isGLInitialized() const; bool isGLInitialized() const;
...@@ -115,6 +124,8 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable ...@@ -115,6 +124,8 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
EGLint mClientMajorVersion; EGLint mClientMajorVersion;
EGLint mClientMinorVersion; EGLint mClientMinorVersion;
EGLint mEGLMajorVersion;
EGLint mEGLMinorVersion;
EGLPlatformParameters mPlatform; EGLPlatformParameters mPlatform;
int mRedBits; int mRedBits;
int mGreenBits; int mGreenBits;
...@@ -129,6 +140,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable ...@@ -129,6 +140,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
bool mWebGLCompatibility; bool mWebGLCompatibility;
bool mBindGeneratesResource; bool mBindGeneratesResource;
bool mClientArraysEnabled; bool mClientArraysEnabled;
bool mRobustResourceInit;
EGLint mSwapInterval; EGLint mSwapInterval;
Optional<bool> mVulkanLayersEnabled; 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