Commit ce02f086 by Geoff Lang Committed by Commit Bot

Add an extension to share textures at the display level.

BUG=angleproject:1639 Change-Id: If9140142ebce89f33921c13d9d212c17d1894162 Reviewed-on: https://chromium-review.googlesource.com/437618Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 85334dcb
Name
ANGLE_display_texture_share_group
Name Strings
EGL_ANGLE_display_texture_share_group
Contributors
Geoff Lang, Google
Contacts
Geoff Lang, Google (geofflang 'at' google.com)
Status
Draft
Version
Version 1, February 7, 2017
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
texture objects with other contexts owned by the same display. This method
of sharing textures 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_TEXTURE_SHARE_GROUP_ANGLE 0x33AF
Additions to the EGL 1.5 Specification
Add a new section entitled "OpenGL ES Global Texture Share Groups"
to section 3.7.1:
"If the attribute EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE is set to EGL_TRUE,
a context that shares textures with other contexts owned by the same
display and created with EGL_DISPLAY_TEXTURE_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_TEXTURE_SHARE_GROUP_ANGLE.
The default value of EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE is EGL_FALSE."
Issues
None
Revision History
Version 1, 2017/02/07 - first draft.
...@@ -650,6 +650,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, E ...@@ -650,6 +650,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, E
#define EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE 0x3AAC #define EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE 0x3AAC
#endif /* EGL_ANGLE_create_context_webgl_compatibility */ #endif /* EGL_ANGLE_create_context_webgl_compatibility */
#ifndef EGL_ANGLE_display_texture_share_group
#define EGL_ANGLE_display_texture_share_group 1
#define EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE 0x3AAF
#endif /* EGL_ANGLE_display_texture_share_group */
#ifndef EGL_CHROMIUM_create_context_bind_generates_resource #ifndef EGL_CHROMIUM_create_context_bind_generates_resource
#define EGL_CHROMIUM_create_context_bind_generates_resource 1 #define EGL_CHROMIUM_create_context_bind_generates_resource 1
#define EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM 0x3AAD #define EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM 0x3AAD
......
...@@ -1032,7 +1032,8 @@ DisplayExtensions::DisplayExtensions() ...@@ -1032,7 +1032,8 @@ DisplayExtensions::DisplayExtensions()
createContextBindGeneratesResource(false), createContextBindGeneratesResource(false),
swapBuffersWithDamage(false), swapBuffersWithDamage(false),
pixelFormatFloat(false), pixelFormatFloat(false),
surfacelessContext(false) surfacelessContext(false),
displayTextureShareGroup(false)
{ {
} }
...@@ -1072,6 +1073,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -1072,6 +1073,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_EXT_swap_buffers_with_damage", swapBuffersWithDamage, &extensionStrings); InsertExtensionString("EGL_EXT_swap_buffers_with_damage", swapBuffersWithDamage, &extensionStrings);
InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings); InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings);
InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings); InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings);
InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &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
......
...@@ -646,6 +646,9 @@ struct DisplayExtensions ...@@ -646,6 +646,9 @@ struct DisplayExtensions
// EGL_KHR_surfaceless_context // EGL_KHR_surfaceless_context
bool surfacelessContext; bool surfacelessContext;
// EGL_ANGLE_display_texture_share_group
bool displayTextureShareGroup;
}; };
struct DeviceExtensions struct DeviceExtensions
......
...@@ -236,10 +236,12 @@ namespace gl ...@@ -236,10 +236,12 @@ namespace gl
Context::Context(rx::EGLImplFactory *implFactory, Context::Context(rx::EGLImplFactory *implFactory,
const egl::Config *config, const egl::Config *config,
const Context *shareContext, const Context *shareContext,
TextureManager *shareTextures,
const egl::AttributeMap &attribs, const egl::AttributeMap &attribs,
const egl::DisplayExtensions &displayExtensions) const egl::DisplayExtensions &displayExtensions)
: ValidationContext(shareContext, : ValidationContext(shareContext,
shareTextures,
GetClientVersion(attribs), GetClientVersion(attribs),
&mGLState, &mGLState,
mCaps, mCaps,
......
...@@ -61,6 +61,7 @@ class Context final : public ValidationContext ...@@ -61,6 +61,7 @@ class Context final : public ValidationContext
Context(rx::EGLImplFactory *implFactory, Context(rx::EGLImplFactory *implFactory,
const egl::Config *config, const egl::Config *config,
const Context *shareContext, const Context *shareContext,
TextureManager *shareTextures,
const egl::AttributeMap &attribs, const egl::AttributeMap &attribs,
const egl::DisplayExtensions &displayExtensions); const egl::DisplayExtensions &displayExtensions);
......
...@@ -36,10 +36,34 @@ T *AllocateOrGetSharedResourceManager(const ContextState *shareContextState, ...@@ -36,10 +36,34 @@ T *AllocateOrGetSharedResourceManager(const ContextState *shareContextState,
} }
} }
TextureManager *AllocateOrGetSharedTextureManager(const ContextState *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();
}
}
} // anonymous namespace } // anonymous namespace
ContextState::ContextState(uintptr_t contextIn, ContextState::ContextState(uintptr_t contextIn,
const ContextState *shareContextState, const ContextState *shareContextState,
TextureManager *shareTextures,
const Version &clientVersion, const Version &clientVersion,
State *stateIn, State *stateIn,
const Caps &capsIn, const Caps &capsIn,
...@@ -56,7 +80,9 @@ ContextState::ContextState(uintptr_t contextIn, ...@@ -56,7 +80,9 @@ ContextState::ContextState(uintptr_t contextIn,
mBuffers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mBuffers)), mBuffers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mBuffers)),
mShaderPrograms( mShaderPrograms(
AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mShaderPrograms)), AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mShaderPrograms)),
mTextures(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mTextures)), mTextures(AllocateOrGetSharedTextureManager(shareContextState,
shareTextures,
&ContextState::mTextures)),
mRenderbuffers( mRenderbuffers(
AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mRenderbuffers)), AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mRenderbuffers)),
mSamplers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mSamplers)), mSamplers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mSamplers)),
...@@ -85,6 +111,7 @@ const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const ...@@ -85,6 +111,7 @@ const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const
} }
ValidationContext::ValidationContext(const ValidationContext *shareContext, ValidationContext::ValidationContext(const ValidationContext *shareContext,
TextureManager *shareTextures,
const Version &clientVersion, const Version &clientVersion,
State *state, State *state,
const Caps &caps, const Caps &caps,
...@@ -94,13 +121,15 @@ ValidationContext::ValidationContext(const ValidationContext *shareContext, ...@@ -94,13 +121,15 @@ ValidationContext::ValidationContext(const ValidationContext *shareContext,
bool skipValidation) bool skipValidation)
: mState(reinterpret_cast<uintptr_t>(this), : mState(reinterpret_cast<uintptr_t>(this),
shareContext ? &shareContext->mState : nullptr, shareContext ? &shareContext->mState : nullptr,
shareTextures,
clientVersion, clientVersion,
state, state,
caps, caps,
textureCaps, textureCaps,
extensions, extensions,
limitations), limitations),
mSkipValidation(skipValidation) mSkipValidation(skipValidation),
mDisplayTextureShareGroup(shareTextures != nullptr)
{ {
} }
...@@ -673,4 +702,9 @@ bool ValidationContext::isFramebufferGenerated(GLuint framebuffer) const ...@@ -673,4 +702,9 @@ bool ValidationContext::isFramebufferGenerated(GLuint framebuffer) const
return mState.mFramebuffers->isFramebufferGenerated(framebuffer); return mState.mFramebuffers->isFramebufferGenerated(framebuffer);
} }
bool ValidationContext::usingDisplayTextureShareGroup() const
{
return mDisplayTextureShareGroup;
}
} // namespace gl } // namespace gl
...@@ -35,6 +35,7 @@ class ContextState final : public angle::NonCopyable ...@@ -35,6 +35,7 @@ class ContextState final : public angle::NonCopyable
public: public:
ContextState(uintptr_t context, ContextState(uintptr_t context,
const ContextState *shareContextState, const ContextState *shareContextState,
TextureManager *shareTextures,
const Version &clientVersion, const Version &clientVersion,
State *state, State *state,
const Caps &caps, const Caps &caps,
...@@ -55,6 +56,8 @@ class ContextState final : public angle::NonCopyable ...@@ -55,6 +56,8 @@ class ContextState final : public angle::NonCopyable
const TextureCaps &getTextureCap(GLenum internalFormat) const; const TextureCaps &getTextureCap(GLenum internalFormat) const;
bool usingDisplayTextureShareGroup() const;
private: private:
friend class Context; friend class Context;
friend class ValidationContext; friend class ValidationContext;
...@@ -81,6 +84,7 @@ class ValidationContext : angle::NonCopyable ...@@ -81,6 +84,7 @@ class ValidationContext : angle::NonCopyable
{ {
public: public:
ValidationContext(const ValidationContext *shareContext, ValidationContext(const ValidationContext *shareContext,
TextureManager *shareTextures,
const Version &clientVersion, const Version &clientVersion,
State *state, State *state,
const Caps &caps, const Caps &caps,
...@@ -115,9 +119,12 @@ class ValidationContext : angle::NonCopyable ...@@ -115,9 +119,12 @@ class ValidationContext : angle::NonCopyable
bool isRenderbufferGenerated(GLuint renderbuffer) const; bool isRenderbufferGenerated(GLuint renderbuffer) const;
bool isFramebufferGenerated(GLuint framebuffer) const; bool isFramebufferGenerated(GLuint framebuffer) const;
bool usingDisplayTextureShareGroup() const;
protected: protected:
ContextState mState; ContextState mState;
bool mSkipValidation; bool mSkipValidation;
bool mDisplayTextureShareGroup;
}; };
} // namespace gl } // namespace gl
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "libANGLE/Image.h" #include "libANGLE/Image.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/Stream.h" #include "libANGLE/Stream.h"
#include "libANGLE/ResourceManager.h"
#include "libANGLE/renderer/DisplayImpl.h" #include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/renderer/ImageImpl.h" #include "libANGLE/renderer/ImageImpl.h"
#include "third_party/trace_event/trace_event.h" #include "third_party/trace_event/trace_event.h"
...@@ -358,7 +359,8 @@ Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDe ...@@ -358,7 +359,8 @@ Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDe
mDisplayExtensionString(), mDisplayExtensionString(),
mVendorString(), mVendorString(),
mDevice(eglDevice), mDevice(eglDevice),
mPlatform(platform) mPlatform(platform),
mTextureManager(nullptr)
{ {
} }
...@@ -462,6 +464,9 @@ Error Display::initialize() ...@@ -462,6 +464,9 @@ Error Display::initialize()
ASSERT(mDevice != nullptr); ASSERT(mDevice != nullptr);
} }
ASSERT(mTextureManager == nullptr);
mTextureManager = new gl::TextureManager();
mInitialized = true; mInitialized = true;
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
...@@ -469,6 +474,12 @@ Error Display::initialize() ...@@ -469,6 +474,12 @@ Error Display::initialize()
void Display::terminate() void Display::terminate()
{ {
if (mTextureManager)
{
mTextureManager->release();
mTextureManager = nullptr;
}
makeCurrent(nullptr, nullptr, nullptr); makeCurrent(nullptr, nullptr, nullptr);
while (!mContextSet.empty()) while (!mContextSet.empty())
...@@ -673,8 +684,12 @@ Error Display::createContext(const Config *configuration, gl::Context *shareCont ...@@ -673,8 +684,12 @@ Error Display::createContext(const Config *configuration, gl::Context *shareCont
ANGLE_TRY(restoreLostDevice()); ANGLE_TRY(restoreLostDevice());
} }
gl::Context *context = bool usingDisplayTextureShareGroup =
new gl::Context(mImplementation, configuration, shareContext, attribs, mDisplayExtensions); attribs.get(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE;
gl::TextureManager *shareTextures = usingDisplayTextureShareGroup ? mTextureManager : nullptr;
gl::Context *context = new gl::Context(mImplementation, configuration, shareContext,
shareTextures, attribs, mDisplayExtensions);
ASSERT(context != nullptr); ASSERT(context != nullptr);
mContextSet.insert(context); mContextSet.insert(context);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
namespace gl namespace gl
{ {
class Context; class Context;
class TextureManager;
} }
namespace rx namespace rx
...@@ -172,6 +173,8 @@ class Display final : angle::NonCopyable ...@@ -172,6 +173,8 @@ class Display final : angle::NonCopyable
Device *mDevice; Device *mDevice;
EGLenum mPlatform; EGLenum mPlatform;
angle::LoggingAnnotator mAnnotator; angle::LoggingAnnotator mAnnotator;
gl::TextureManager *mTextureManager;
}; };
} }
......
...@@ -1099,6 +1099,9 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions ...@@ -1099,6 +1099,9 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
outExtensions->flexibleSurfaceCompatibility = true; outExtensions->flexibleSurfaceCompatibility = true;
outExtensions->directComposition = !!mDCompModule; outExtensions->directComposition = !!mDCompModule;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
} }
gl::Error Renderer11::flush() gl::Error Renderer11::flush()
......
...@@ -540,6 +540,9 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) ...@@ -540,6 +540,9 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions)
outExtensions->glRenderbufferImage = true; outExtensions->glRenderbufferImage = true;
outExtensions->flexibleSurfaceCompatibility = true; outExtensions->flexibleSurfaceCompatibility = true;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
} }
void Renderer9::startScene() void Renderer9::startScene()
......
...@@ -246,6 +246,9 @@ const FunctionsGL *DisplayCGL::getFunctionsGL() const ...@@ -246,6 +246,9 @@ const FunctionsGL *DisplayCGL::getFunctionsGL() const
void DisplayCGL::generateExtensions(egl::DisplayExtensions *outExtensions) const void DisplayCGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
{ {
outExtensions->surfacelessContext = true; outExtensions->surfacelessContext = true;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
} }
void DisplayCGL::generateCaps(egl::Caps *outCaps) const void DisplayCGL::generateCaps(egl::Caps *outCaps) const
......
...@@ -102,6 +102,9 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -102,6 +102,9 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
mEGL->hasExtension("EGL_EXT_create_context_robustness"); mEGL->hasExtension("EGL_EXT_create_context_robustness");
outExtensions->postSubBuffer = false; // Since SurfaceEGL::postSubBuffer is not implemented outExtensions->postSubBuffer = false; // Since SurfaceEGL::postSubBuffer is not implemented
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
} }
void DisplayEGL::generateCaps(egl::Caps *outCaps) const void DisplayEGL::generateCaps(egl::Caps *outCaps) const
......
...@@ -891,6 +891,9 @@ const FunctionsGL *DisplayGLX::getFunctionsGL() const ...@@ -891,6 +891,9 @@ const FunctionsGL *DisplayGLX::getFunctionsGL() const
void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const
{ {
outExtensions->createContextRobustness = mHasARBCreateContextRobustness; outExtensions->createContextRobustness = mHasARBCreateContextRobustness;
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
} }
void DisplayGLX::generateCaps(egl::Caps *outCaps) const void DisplayGLX::generateCaps(egl::Caps *outCaps) const
......
...@@ -660,6 +660,9 @@ void DisplayWGL::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -660,6 +660,9 @@ void DisplayWGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->createContextRobustness = mHasRobustness; outExtensions->createContextRobustness = mHasRobustness;
outExtensions->d3dTextureClientBuffer = mFunctionsWGL->hasExtension("WGL_NV_DX_interop2"); outExtensions->d3dTextureClientBuffer = mFunctionsWGL->hasExtension("WGL_NV_DX_interop2");
// Contexts are virtualized so textures can be shared globally
outExtensions->displayTextureShareGroup = true;
} }
void DisplayWGL::generateCaps(egl::Caps *outCaps) const void DisplayWGL::generateCaps(egl::Caps *outCaps) const
......
...@@ -427,8 +427,30 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context ...@@ -427,8 +427,30 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context
} }
break; break;
case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE:
if (!display->getExtensions().displayTextureShareGroup)
{
return Error(EGL_BAD_ATTRIBUTE,
"Attribute EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE requires "
"EGL_ANGLE_display_texture_share_group.");
}
if (value != EGL_TRUE && value != EGL_FALSE)
{
return Error(
EGL_BAD_ATTRIBUTE,
"EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE must be EGL_TRUE or EGL_FALSE.");
}
if (shareContext &&
(shareContext->usingDisplayTextureShareGroup() != (value == EGL_TRUE)))
{
return Error(EGL_BAD_ATTRIBUTE,
"All contexts within a share group must be created with the same "
"value of EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE.");
}
break;
default: default:
return Error(EGL_BAD_ATTRIBUTE); return Error(EGL_BAD_ATTRIBUTE, "Unknown attribute.");
} }
} }
......
...@@ -31,6 +31,7 @@ class MockValidationContext : public ValidationContext ...@@ -31,6 +31,7 @@ class MockValidationContext : public ValidationContext
{ {
public: public:
MockValidationContext(const ValidationContext *shareContext, MockValidationContext(const ValidationContext *shareContext,
TextureManager *shareTextures,
const Version &version, const Version &version,
State *state, State *state,
const Caps &caps, const Caps &caps,
...@@ -39,6 +40,7 @@ class MockValidationContext : public ValidationContext ...@@ -39,6 +40,7 @@ class MockValidationContext : public ValidationContext
const Limitations &limitations, const Limitations &limitations,
bool skipValidation) bool skipValidation)
: ValidationContext(shareContext, : ValidationContext(shareContext,
shareTextures,
version, version,
state, state,
caps, caps,
...@@ -97,8 +99,8 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError) ...@@ -97,8 +99,8 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
state.setDrawFramebufferBinding(framebuffer); state.setDrawFramebufferBinding(framebuffer);
state.setProgram(program); state.setProgram(program);
NiceMock<MockValidationContext> testContext(nullptr, Version(3, 0), &state, caps, textureCaps, NiceMock<MockValidationContext> testContext(nullptr, nullptr, Version(3, 0), &state, caps,
extensions, limitations, false); textureCaps, extensions, limitations, false);
// Set the expectation for the validation error here. // Set the expectation for the validation error here.
Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage); Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage);
......
...@@ -82,6 +82,128 @@ TEST_P(EGLContextSharingTest, BindTextureAfterShareContextFree) ...@@ -82,6 +82,128 @@ TEST_P(EGLContextSharingTest, BindTextureAfterShareContextFree)
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
// Tests the creation of contexts using EGL_ANGLE_display_texture_share_group
TEST_P(EGLContextSharingTest, DisplayShareGroupContextCreation)
{
EGLDisplay display = getEGLWindow()->getDisplay();
EGLConfig config = getEGLWindow()->getConfig();
const EGLint inShareGroupContextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE, EGL_NONE};
// Test creating two contexts in the global share group
mContexts[0] = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
mContexts[1] = eglCreateContext(display, config, mContexts[1], inShareGroupContextAttribs);
if (!ANGLETest::eglDisplayExtensionEnabled(display, "EGL_ANGLE_display_texture_share_group"))
{
// Make sure an error is generated and early-exit
ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
ASSERT_EQ(EGL_NO_CONTEXT, mContexts[0]);
return;
}
ASSERT_EGL_SUCCESS();
ASSERT_NE(EGL_NO_CONTEXT, mContexts[0]);
ASSERT_NE(EGL_NO_CONTEXT, mContexts[1]);
eglDestroyContext(display, mContexts[0]);
// Try creating a context that is not in the global share group but tries to share with a
// context that is
const EGLint notInShareGroupContextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE, EGL_NONE};
mContexts[1] = eglCreateContext(display, config, mContexts[1], notInShareGroupContextAttribs);
ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
ASSERT_TRUE(mContexts[1] == EGL_NO_CONTEXT);
}
// Tests the sharing of textures using EGL_ANGLE_display_texture_share_group
TEST_P(EGLContextSharingTest, DisplayShareGroupObjectSharing)
{
EGLDisplay display = getEGLWindow()->getDisplay();
if (!ANGLETest::eglDisplayExtensionEnabled(display, "EGL_ANGLE_display_texture_share_group"))
{
std::cout << "Test skipped because EGL_ANGLE_display_texture_share_group is not present."
<< std::endl;
return;
}
EGLConfig config = getEGLWindow()->getConfig();
EGLSurface surface = getEGLWindow()->getSurface();
const EGLint inShareGroupContextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE, EGL_NONE};
// Create two contexts in the global share group but not in the same context share group
mContexts[0] = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
mContexts[1] = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
ASSERT_EGL_SUCCESS();
ASSERT_NE(EGL_NO_CONTEXT, mContexts[0]);
ASSERT_NE(EGL_NO_CONTEXT, mContexts[1]);
ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
ASSERT_EGL_SUCCESS();
// Create a texture and buffer in ctx 0
GLuint textureFromCtx0 = 0;
glGenTextures(1, &textureFromCtx0);
glBindTexture(GL_TEXTURE_2D, textureFromCtx0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, 0);
ASSERT_GL_TRUE(glIsTexture(textureFromCtx0));
GLuint bufferFromCtx0 = 0;
glGenBuffers(1, &bufferFromCtx0);
glBindBuffer(GL_ARRAY_BUFFER, bufferFromCtx0);
glBufferData(GL_ARRAY_BUFFER, 1, nullptr, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
ASSERT_GL_TRUE(glIsBuffer(bufferFromCtx0));
ASSERT_GL_NO_ERROR();
// Switch to context 1 and verify that the texture is accessible but the buffer is not
ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[1]));
ASSERT_EGL_SUCCESS();
ASSERT_GL_TRUE(glIsTexture(textureFromCtx0));
ASSERT_GL_FALSE(glIsBuffer(bufferFromCtx0));
glDeleteBuffers(1, &bufferFromCtx0);
ASSERT_GL_NO_ERROR();
// Call readpixels on the texture to verify that the backend has proper support
GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureFromCtx0, 0);
GLubyte pixel[4];
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
ASSERT_GL_NO_ERROR();
glDeleteFramebuffers(1, &fbo);
glDeleteTextures(1, &textureFromCtx0);
ASSERT_GL_NO_ERROR();
ASSERT_GL_FALSE(glIsTexture(textureFromCtx0));
// Switch back to context 0 and delete the buffer
ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
ASSERT_EGL_SUCCESS();
ASSERT_GL_TRUE(glIsBuffer(bufferFromCtx0));
glDeleteBuffers(1, &bufferFromCtx0);
ASSERT_GL_NO_ERROR();
}
} // anonymous namespace } // anonymous namespace
ANGLE_INSTANTIATE_TEST(EGLContextSharingTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL()); ANGLE_INSTANTIATE_TEST(EGLContextSharingTest,
ES2_D3D9(),
ES2_D3D11(),
ES3_D3D11(),
ES2_OPENGL(),
ES3_OPENGL());
...@@ -21,6 +21,11 @@ ...@@ -21,6 +21,11 @@
#include "shader_utils.h" #include "shader_utils.h"
#include "system_utils.h" #include "system_utils.h"
#define ASSERT_GL_TRUE(a) ASSERT_EQ(static_cast<GLboolean>(GL_TRUE), (a))
#define ASSERT_GL_FALSE(a) ASSERT_EQ(static_cast<GLboolean>(GL_FALSE), (a))
#define EXPECT_GL_TRUE(a) EXPECT_EQ(static_cast<GLboolean>(GL_TRUE), (a))
#define EXPECT_GL_FALSE(a) EXPECT_EQ(static_cast<GLboolean>(GL_FALSE), (a))
#define EXPECT_GL_ERROR(err) EXPECT_EQ(static_cast<GLenum>(err), glGetError()) #define EXPECT_GL_ERROR(err) EXPECT_EQ(static_cast<GLenum>(err), glGetError())
#define EXPECT_GL_NO_ERROR() EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()) #define EXPECT_GL_NO_ERROR() EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError())
......
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