Add extension EGL_ANGLE_display_semaphore_share_group

For sharing semaphores globally.

Bug: angleproject:4877
Change-Id: I472e0902fd04ca8350d74e6c0ae6925ee930ccf9
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2319370
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Peng Huang 2020-07-27 13:19:27 -04:00 коммит произвёл Commit Bot
Родитель 5f6f47f660
Коммит 4cf2501c67
26 изменённых файлов: 225 добавлений и 56 удалений

Просмотреть файл

@ -0,0 +1,82 @@
Name
ANGLE_display_semaphore_share_group
Name Strings
EGL_ANGLE_display_semaphore_share_group
Contributors
Peng Huang, Google
Contacts
Peng Huang, Google (penghuang 'at' google.com)
Status
Draft
Version
Version 1, July 27, 2020
Number
EGL Extension TBD
Dependencies
This extension is written against the wording of the EGL 1.5 specification.
Overview
This extension allows for the creation of OpenGL ES contexts that share
semaphore objects with other contexts owned by the same display. This method
of sharing semaphores can be used in conjuction with regular share groups.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted as an attribute name in the <*attrib_list> argument to
eglCreateContext:
EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE 0x348D
Additions to the EGL 1.5 Specification
Add a new section entitled "OpenGL ES Global Semaphore Share Groups"
to section 3.7.1:
"If the attribute EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE is set to EGL_TRUE,
a context that shares semaphores with other contexts owned by the same
display and created with EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE set to
EGL_TRUE will be created. If the share_context parameter to
eglCreateContext is not NULL, all contexts within the share group must have
been created with the same value of EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE.
The default value of EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE is EGL_FALSE."
Issues
(1) What happens to the shared semaphores when a context in the global share
group is destroyed?
RESOLOVED: When the last context in the global semaphore share group is
destroyed, all semaphores in the global semaphore share group are released. If
a new context is created in the global semaphore share group, no semaphores
will exist.
This mirrors how regular share groups work, releasing all objects when the
last context is destroyed.
Revision History
Version 1, 2020/07/27 - first draft.

Просмотреть файл

@ -319,6 +319,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithFrameTokenANGLE(EGLDisplay dpy,
#define EGL_EAGL_CONTEXT_ANGLE 0x348C
#endif
#ifndef EGL_ANGLE_display_semaphore_share_group
#define EGL_ANGLE_display_semaphore_share_group 1
#define EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE 0x348D
#endif /* EGL_ANGLE_display_semaphore_share_group */
// clang-format on
#endif // INCLUDE_EGL_EGLEXT_ANGLE_

Просмотреть файл

@ -1,6 +1,6 @@
{
"scripts/egl.xml":
"842e24514c4cfe09fba703c17a0fd292",
"4e5911cfe91274cc5112ff2f70092376",
"scripts/egl_angle_ext.xml":
"087d6a3996a91fbb0b664cac57c50c4c",
"scripts/generate_loader.py":
@ -10,7 +10,7 @@
"scripts/gl_angle_ext.xml":
"079cc4829de7ce638faf7bbf66e141ad",
"scripts/registry_xml.py":
"f45ffbc8a3c8a7144c2e98e19d1127a0",
"5d9874e9e53bde1f644808dbab945578",
"scripts/wgl.xml":
"aa96419c582af2f6673430e2847693f4",
"src/libEGL/egl_loader_autogen.cpp":

Просмотреть файл

@ -1,6 +1,6 @@
{
"scripts/egl.xml":
"842e24514c4cfe09fba703c17a0fd292",
"4e5911cfe91274cc5112ff2f70092376",
"scripts/egl_angle_ext.xml":
"087d6a3996a91fbb0b664cac57c50c4c",
"scripts/entry_point_packed_gl_enums.json":
@ -12,7 +12,7 @@
"scripts/gl_angle_ext.xml":
"079cc4829de7ce638faf7bbf66e141ad",
"scripts/registry_xml.py":
"f45ffbc8a3c8a7144c2e98e19d1127a0",
"5d9874e9e53bde1f644808dbab945578",
"scripts/wgl.xml":
"aa96419c582af2f6673430e2847693f4",
"src/libANGLE/Context_gl_1_0_autogen.h":

Просмотреть файл

@ -6,7 +6,7 @@
"scripts/gl_angle_ext.xml":
"079cc4829de7ce638faf7bbf66e141ad",
"scripts/registry_xml.py":
"f45ffbc8a3c8a7144c2e98e19d1127a0",
"5d9874e9e53bde1f644808dbab945578",
"src/libANGLE/gl_enum_utils_autogen.cpp":
"48627c0865d15bf4014327de5858d3c5",
"src/libANGLE/gl_enum_utils_autogen.h":

Просмотреть файл

@ -1,6 +1,6 @@
{
"scripts/egl.xml":
"842e24514c4cfe09fba703c17a0fd292",
"4e5911cfe91274cc5112ff2f70092376",
"scripts/egl_angle_ext.xml":
"087d6a3996a91fbb0b664cac57c50c4c",
"scripts/gen_proc_table.py":
@ -10,7 +10,7 @@
"scripts/gl_angle_ext.xml":
"079cc4829de7ce638faf7bbf66e141ad",
"scripts/registry_xml.py":
"f45ffbc8a3c8a7144c2e98e19d1127a0",
"5d9874e9e53bde1f644808dbab945578",
"scripts/wgl.xml":
"aa96419c582af2f6673430e2847693f4",
"src/libGL/proc_table_wgl_autogen.cpp":

Просмотреть файл

@ -2132,6 +2132,16 @@
<enum name="EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE"/>
</require>
</extension>
<extension name="EGL_ANGLE_display_semaphore_share_group" supported="egl">
<require>
<enum name="EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE"/>
</require>
</extension>
<extension name="EGL_ANGLE_display_texture_share_group" supported="egl">
<require>
<enum name="EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE"/>
</require>
</extension>
<extension name="EGL_ANGLE_device_d3d" supported="egl">
<require>
<enum name="EGL_D3D9_DEVICE_ANGLE"/>

Просмотреть файл

@ -124,6 +124,8 @@ supported_egl_extensions = [
"EGL_ANGLE_d3d_share_handle_client_buffer",
"EGL_ANGLE_device_creation",
"EGL_ANGLE_device_d3d",
"EGL_ANGLE_display_semaphore_share_group",
"EGL_ANGLE_display_texture_share_group",
"EGL_ANGLE_feature_control",
"EGL_ANGLE_ggp_stream_descriptor",
"EGL_ANGLE_power_preference",

Просмотреть файл

@ -1371,6 +1371,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings);
InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings);
InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &extensionStrings);
InsertExtensionString("EGL_ANGLE_display_semaphore_share_group", displaySemaphoreShareGroup, &extensionStrings);
InsertExtensionString("EGL_ANGLE_create_context_client_arrays", createContextClientArrays, &extensionStrings);
InsertExtensionString("EGL_ANGLE_program_cache_control", programCacheControl, &extensionStrings);
InsertExtensionString("EGL_ANGLE_robust_resource_initialization", robustResourceInitialization, &extensionStrings);

Просмотреть файл

@ -996,6 +996,9 @@ struct DisplayExtensions
// EGL_ANGLE_display_texture_share_group
bool displayTextureShareGroup = false;
// EGL_ANGLE_display_semaphore_share_group
bool displaySemaphoreShareGroup = false;
// EGL_ANGLE_create_context_client_arrays
bool createContextClientArrays = false;

Просмотреть файл

@ -276,6 +276,7 @@ Context::Context(egl::Display *display,
const egl::Config *config,
const Context *shareContext,
TextureManager *shareTextures,
SemaphoreManager *shareSemaphores,
MemoryProgramCache *memoryProgramCache,
const EGLenum clientType,
const egl::AttributeMap &attribs,
@ -284,6 +285,7 @@ Context::Context(egl::Display *display,
: mState(shareContext ? &shareContext->mState : nullptr,
AllocateOrGetShareGroup(display, shareContext),
shareTextures,
shareSemaphores,
&mOverlay,
clientType,
GetClientVersion(display, attribs),
@ -296,6 +298,7 @@ Context::Context(egl::Display *display,
mShared(shareContext != nullptr),
mSkipValidation(GetNoError(attribs)),
mDisplayTextureShareGroup(shareTextures != nullptr),
mDisplaySemaphoreShareGroup(shareSemaphores != nullptr),
mErrors(this),
mImplementation(display->getImplementation()
->createContext(mState, &mErrors, config, shareContext, attribs)),
@ -8059,6 +8062,11 @@ bool Context::usingDisplayTextureShareGroup() const
return mDisplayTextureShareGroup;
}
bool Context::usingDisplaySemaphoreShareGroup() const
{
return mDisplaySemaphoreShareGroup;
}
GLenum Context::getConvertedRenderbufferFormat(GLenum internalformat) const
{
if (mState.mExtensions.webglCompatibility && mState.mClientVersion.major == 2 &&

Просмотреть файл

@ -351,6 +351,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
const egl::Config *config,
const Context *shareContext,
TextureManager *shareTextures,
SemaphoreManager *shareSemaphores,
MemoryProgramCache *memoryProgramCache,
const EGLenum clientType,
const egl::AttributeMap &attribs,
@ -575,6 +576,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
bool isQueryGenerated(QueryID query) const;
bool usingDisplayTextureShareGroup() const;
bool usingDisplaySemaphoreShareGroup() const;
// Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
GLenum getConvertedRenderbufferFormat(GLenum internalformat) const;
@ -679,6 +681,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
bool mShared;
bool mSkipValidation;
bool mDisplayTextureShareGroup;
bool mDisplaySemaphoreShareGroup;
// Recorded errors
ErrorSet mErrors;

Просмотреть файл

@ -651,9 +651,11 @@ Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDe
mSurface(nullptr),
mPlatform(platform),
mTextureManager(nullptr),
mSemaphoreManager(nullptr),
mBlobCache(gl::kDefaultMaxProgramCacheMemoryBytes),
mMemoryProgramCache(mBlobCache),
mGlobalTextureShareGroupUsers(0)
mGlobalTextureShareGroupUsers(0),
mGlobalSemaphoreShareGroupUsers(0)
{}
Display::~Display()
@ -877,8 +879,10 @@ Error Display::terminate(const Thread *thread)
ANGLE_TRY(makeCurrent(thread, nullptr, nullptr, nullptr));
// The global texture manager should be deleted with the last context that uses it.
// The global texture and semaphore managers should be deleted with the last context that uses
// it.
ASSERT(mGlobalTextureShareGroupUsers == 0 && mTextureManager == nullptr);
ASSERT(mGlobalSemaphoreShareGroupUsers == 0 && mSemaphoreManager == nullptr);
while (!mImageSet.empty())
{
@ -1143,6 +1147,23 @@ Error Display::createContext(const Config *configuration,
shareTextures = mTextureManager;
}
// This display semaphore sharing will allow the first context to create the semaphore share
// group.
bool usingDisplaySemaphoreShareGroup =
attribs.get(EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE;
gl::SemaphoreManager *shareSemaphores = nullptr;
if (usingDisplaySemaphoreShareGroup)
{
ASSERT((mSemaphoreManager == nullptr) == (mGlobalSemaphoreShareGroupUsers == 0));
if (mSemaphoreManager == nullptr)
{
mSemaphoreManager = new gl::SemaphoreManager();
}
mGlobalSemaphoreShareGroupUsers++;
shareSemaphores = mSemaphoreManager;
}
gl::MemoryProgramCache *cachePointer = &mMemoryProgramCache;
// Check context creation attributes to see if we are using EGL_ANGLE_program_cache_control.
@ -1162,9 +1183,9 @@ Error Display::createContext(const Config *configuration,
}
}
gl::Context *context =
new gl::Context(this, configuration, shareContext, shareTextures, cachePointer, clientType,
attribs, mDisplayExtensions, GetClientExtensions());
gl::Context *context = new gl::Context(this, configuration, shareContext, shareTextures,
shareSemaphores, cachePointer, clientType, attribs,
mDisplayExtensions, GetClientExtensions());
if (shareContext != nullptr)
{
shareContext->setShared();
@ -1329,6 +1350,20 @@ Error Display::destroyContext(const Thread *thread, gl::Context *context)
mGlobalTextureShareGroupUsers--;
}
if (context->usingDisplaySemaphoreShareGroup())
{
ASSERT(mGlobalSemaphoreShareGroupUsers >= 1 && mSemaphoreManager != nullptr);
if (mGlobalSemaphoreShareGroupUsers == 1)
{
// If this is the last context using the global share group, destroy the global
// semaphore manager so that the semaphores can be destroyed while a context still
// exists
mSemaphoreManager->release(context);
mSemaphoreManager = nullptr;
}
mGlobalSemaphoreShareGroupUsers--;
}
ANGLE_TRY(context->onDestroy(this));
mContextSet.erase(context);
SafeDelete(context);

Просмотреть файл

@ -32,6 +32,7 @@ namespace gl
{
class Context;
class TextureManager;
class SemaphoreManager;
} // namespace gl
namespace rx
@ -302,9 +303,11 @@ class Display final : public LabeledObject,
angle::LoggingAnnotator mAnnotator;
gl::TextureManager *mTextureManager;
gl::SemaphoreManager *mSemaphoreManager;
BlobCache mBlobCache;
gl::MemoryProgramCache mMemoryProgramCache;
size_t mGlobalTextureShareGroupUsers;
size_t mGlobalSemaphoreShareGroupUsers;
angle::FrontendFeatures mFrontendFeatures;

Просмотреть файл

@ -2088,7 +2088,7 @@ void CaptureMidExecutionSetup(const gl::Context *context,
FrameCapture *frameCapture)
{
const gl::State &apiState = context->getState();
gl::State replayState(nullptr, nullptr, nullptr, nullptr, EGL_OPENGL_ES_API,
gl::State replayState(nullptr, nullptr, nullptr, nullptr, nullptr, EGL_OPENGL_ES_API,
apiState.getClientVersion(), false, true, true, true, false,
EGL_CONTEXT_PRIORITY_MEDIUM_IMG);

Просмотреть файл

@ -72,43 +72,28 @@ template <typename T>
using ContextStateMember = T *(State::*);
template <typename T>
T *AllocateOrGetSharedResourceManager(const State *shareContextState, ContextStateMember<T> member)
T *AllocateOrGetSharedResourceManager(const State *shareContextState,
ContextStateMember<T> member,
T *shareResources = nullptr)
{
if (shareContextState)
{
T *resourceManager = (*shareContextState).*member;
ASSERT(!resourceManager || resourceManager == shareResources || !shareResources);
resourceManager->addRef();
return resourceManager;
}
else if (shareResources)
{
shareResources->addRef();
return shareResources;
}
else
{
return new T();
}
}
TextureManager *AllocateOrGetSharedTextureManager(const State *shareContextState,
TextureManager *shareTextures,
ContextStateMember<TextureManager> member)
{
if (shareContextState)
{
TextureManager *textureManager = (*shareContextState).*member;
ASSERT(shareTextures == nullptr || textureManager == shareTextures);
textureManager->addRef();
return textureManager;
}
else if (shareTextures)
{
TextureManager *textureManager = shareTextures;
textureManager->addRef();
return textureManager;
}
else
{
return new TextureManager();
}
}
// TODO(https://anglebug.com/3889): Remove this helper function after blink and chromium part
// refactory done.
bool IsTextureCompatibleWithSampler(TextureType texture, TextureType sampler)
@ -308,6 +293,7 @@ ANGLE_INLINE void ActiveTexturesCache::set(ContextID contextID,
State::State(const State *shareContextState,
egl::ShareGroup *shareGroup,
TextureManager *shareTextures,
SemaphoreManager *shareSemaphores,
const OverlayType *overlay,
const EGLenum clientType,
const Version &clientVersion,
@ -325,9 +311,9 @@ State::State(const State *shareContextState,
mBufferManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mBufferManager)),
mShaderProgramManager(
AllocateOrGetSharedResourceManager(shareContextState, &State::mShaderProgramManager)),
mTextureManager(AllocateOrGetSharedTextureManager(shareContextState,
shareTextures,
&State::mTextureManager)),
mTextureManager(AllocateOrGetSharedResourceManager(shareContextState,
&State::mTextureManager,
shareTextures)),
mRenderbufferManager(
AllocateOrGetSharedResourceManager(shareContextState, &State::mRenderbufferManager)),
mSamplerManager(
@ -337,8 +323,9 @@ State::State(const State *shareContextState,
mProgramPipelineManager(new ProgramPipelineManager()),
mMemoryObjectManager(
AllocateOrGetSharedResourceManager(shareContextState, &State::mMemoryObjectManager)),
mSemaphoreManager(
AllocateOrGetSharedResourceManager(shareContextState, &State::mSemaphoreManager)),
mSemaphoreManager(AllocateOrGetSharedResourceManager(shareContextState,
&State::mSemaphoreManager,
shareSemaphores)),
mMaxDrawBuffers(0),
mMaxCombinedTextureImageUnits(0),
mDepthClearValue(0),

Просмотреть файл

@ -93,6 +93,7 @@ class State : angle::NonCopyable
State(const State *shareContextState,
egl::ShareGroup *shareGroup,
TextureManager *shareTextures,
SemaphoreManager *shareSemaphores,
const OverlayType *overlay,
const EGLenum clientType,
const Version &clientVersion,

Просмотреть файл

@ -1298,8 +1298,9 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
outExtensions->flexibleSurfaceCompatibility = true;
outExtensions->directComposition = !!mDCompModule;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// Contexts are virtualized so textures and semaphores can be shared globally
outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true;
// syncControlCHROMIUM requires direct composition.
outExtensions->syncControlCHROMIUM = outExtensions->directComposition;

Просмотреть файл

@ -591,8 +591,9 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions)
outExtensions->flexibleSurfaceCompatibility = true;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// Contexts are virtualized so textures and semaphores can be shared globally
outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true;
// D3D9 can be used without an output surface
outExtensions->surfacelessContext = true;

Просмотреть файл

@ -435,8 +435,9 @@ void DisplayCGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->surfacelessContext = true;
outExtensions->deviceQuery = true;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// Contexts are virtualized so textures and semaphores can be shared globally
outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true;
if (mSupportsGPUSwitching)
{

Просмотреть файл

@ -279,8 +279,9 @@ void DisplayEAGL::generateExtensions(egl::DisplayExtensions *outExtensions) cons
outExtensions->surfacelessContext = true;
outExtensions->deviceQuery = true;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// Contexts are virtualized so textures ans semaphores can be shared globally
outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true;
outExtensions->powerPreference = false;

Просмотреть файл

@ -616,8 +616,9 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->postSubBuffer = false; // Since SurfaceEGL::postSubBuffer is not implemented
outExtensions->presentationTime = mEGL->hasExtension("EGL_ANDROID_presentation_time");
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// Contexts are virtualized so textures and semaphores can be shared globally
outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true;
// We will fallback to regular swap if swapBuffersWithDamage isn't
// supported, so indicate support here to keep validation happy.

Просмотреть файл

@ -880,8 +880,9 @@ void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const
{
outExtensions->createContextRobustness = mHasARBCreateContextRobustness;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// Contexts are virtualized so textures ans semaphores can be shared globally
outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true;
outExtensions->surfacelessContext = true;

Просмотреть файл

@ -645,8 +645,9 @@ void DisplayWGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->querySurfacePointer = true;
outExtensions->keyedMutex = true;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
// Contexts are virtualized so textures and semaphores can be shared globally
outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true;
outExtensions->surfacelessContext = true;

Просмотреть файл

@ -195,6 +195,7 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->createContextRobustness = getRenderer()->getNativeExtensions().robustness;
outExtensions->surfaceOrientation = true;
outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true;
outExtensions->robustResourceInitialization = true;
// The Vulkan implementation will always say that EGL_KHR_swap_buffers_with_damage is supported.

Просмотреть файл

@ -1278,6 +1278,27 @@ Error ValidateCreateContext(Display *display,
}
break;
case EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE:
if (!display->getExtensions().displayTextureShareGroup)
{
return EglBadAttribute() << "Attribute "
"EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE requires "
"EGL_ANGLE_display_semaphore_share_group.";
}
if (value != EGL_TRUE && value != EGL_FALSE)
{
return EglBadAttribute() << "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE must be "
"EGL_TRUE or EGL_FALSE.";
}
if (shareContext &&
(shareContext->usingDisplaySemaphoreShareGroup() != (value == EGL_TRUE)))
{
return EglBadAttribute() << "All contexts within a share group must be "
"created with the same value of "
"EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE.";
}
break;
case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE:
if (!display->getExtensions().createContextClientArrays)
{