Commit 82133763 by Geoff Lang

Vulkan: Add an unMakeCurrent for contexts.

This allows contexts to flush and update state when they are no longer going to be current. BUG=angleproject:2464 Change-Id: Ie577475a94090631a0208542b32a12a239bdeb75 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1553824Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 1ad7a072
...@@ -499,7 +499,7 @@ egl::Error Context::onDestroy(const egl::Display *display) ...@@ -499,7 +499,7 @@ egl::Error Context::onDestroy(const egl::Display *display)
mGLES1Renderer->onDestroy(this, &mState); mGLES1Renderer->onDestroy(this, &mState);
} }
ANGLE_TRY(releaseSurface(display)); ANGLE_TRY(unMakeCurrent(display));
for (auto fence : mFenceNVMap) for (auto fence : mFenceNVMap)
{ {
...@@ -605,7 +605,7 @@ egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -605,7 +605,7 @@ egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mState.setAllDirtyBits(); mState.setAllDirtyBits();
mState.setAllDirtyObjects(); mState.setAllDirtyObjects();
ANGLE_TRY(releaseSurface(display)); ASSERT(mCurrentSurface == nullptr);
Framebuffer *newDefault = nullptr; Framebuffer *newDefault = nullptr;
if (surface != nullptr) if (surface != nullptr)
...@@ -637,7 +637,7 @@ egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -637,7 +637,7 @@ egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
return angle::ResultToEGL(mImplementation->onMakeCurrent(this)); return angle::ResultToEGL(mImplementation->onMakeCurrent(this));
} }
egl::Error Context::releaseSurface(const egl::Display *display) egl::Error Context::unMakeCurrent(const egl::Display *display)
{ {
gl::Framebuffer *defaultFramebuffer = mState.mFramebufferManager->getFramebuffer(0); gl::Framebuffer *defaultFramebuffer = mState.mFramebufferManager->getFramebuffer(0);
...@@ -668,7 +668,7 @@ egl::Error Context::releaseSurface(const egl::Display *display) ...@@ -668,7 +668,7 @@ egl::Error Context::releaseSurface(const egl::Display *display)
mCurrentSurface = nullptr; mCurrentSurface = nullptr;
} }
return egl::NoError(); return angle::ResultToEGL(mImplementation->onUnMakeCurrent(this));
} }
GLuint Context::createBuffer() GLuint Context::createBuffer()
......
...@@ -301,7 +301,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -301,7 +301,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
EGLLabelKHR getLabel() const override; EGLLabelKHR getLabel() const override;
egl::Error makeCurrent(egl::Display *display, egl::Surface *surface); egl::Error makeCurrent(egl::Display *display, egl::Surface *surface);
egl::Error releaseSurface(const egl::Display *display); egl::Error unMakeCurrent(const egl::Display *display);
// These create and destroy methods are merely pass-throughs to // These create and destroy methods are merely pass-throughs to
// ResourceManager, which owns these object types // ResourceManager, which owns these object types
......
...@@ -600,7 +600,7 @@ Error Display::terminate(const Thread *thread) ...@@ -600,7 +600,7 @@ Error Display::terminate(const Thread *thread)
ANGLE_TRY(destroyContext(thread, *mContextSet.begin())); ANGLE_TRY(destroyContext(thread, *mContextSet.begin()));
} }
ANGLE_TRY(makeCurrent(nullptr, nullptr, nullptr)); ANGLE_TRY(makeCurrent(thread, nullptr, nullptr, nullptr));
// The global texture manager should be deleted with the last context that uses it. // The global texture manager should be deleted with the last context that uses it.
ASSERT(mGlobalTextureShareGroupUsers == 0 && mTextureManager == nullptr); ASSERT(mGlobalTextureShareGroupUsers == 0 && mTextureManager == nullptr);
...@@ -921,10 +921,22 @@ Error Display::createSync(const gl::Context *currentContext, ...@@ -921,10 +921,22 @@ Error Display::createSync(const gl::Context *currentContext,
return NoError(); return NoError();
} }
Error Display::makeCurrent(egl::Surface *drawSurface, Error Display::makeCurrent(const Thread *thread,
egl::Surface *drawSurface,
egl::Surface *readSurface, egl::Surface *readSurface,
gl::Context *context) gl::Context *context)
{ {
if (!mInitialized)
{
return NoError();
}
gl::Context *previousContext = thread->getContext();
if (previousContext)
{
ANGLE_TRY(previousContext->unMakeCurrent(this));
}
ANGLE_TRY(mImplementation->makeCurrent(drawSurface, readSurface, context)); ANGLE_TRY(mImplementation->makeCurrent(drawSurface, readSurface, context));
if (context != nullptr) if (context != nullptr)
...@@ -995,13 +1007,15 @@ void Display::destroyStream(egl::Stream *stream) ...@@ -995,13 +1007,15 @@ void Display::destroyStream(egl::Stream *stream)
Error Display::destroyContext(const Thread *thread, gl::Context *context) Error Display::destroyContext(const Thread *thread, gl::Context *context)
{ {
gl::Context *currentContext = thread->getContext(); gl::Context *currentContext = thread->getContext();
Surface *currentDrawSurface = thread->getCurrentDrawSurface();
Surface *currentReadSurface = thread->getCurrentReadSurface();
bool changeContextForDeletion = context != currentContext; bool changeContextForDeletion = context != currentContext;
// Make the context being deleted current during it's deletion. This allows it to delete any // Make the context being deleted current during it's deletion. This allows it to delete any
// resources it's holding. // resources it's holding.
if (changeContextForDeletion) if (changeContextForDeletion)
{ {
ANGLE_TRY(makeCurrent(nullptr, nullptr, context)); ANGLE_TRY(makeCurrent(thread, nullptr, nullptr, context));
} }
if (context->usingDisplayTextureShareGroup()) if (context->usingDisplayTextureShareGroup())
...@@ -1024,8 +1038,7 @@ Error Display::destroyContext(const Thread *thread, gl::Context *context) ...@@ -1024,8 +1038,7 @@ Error Display::destroyContext(const Thread *thread, gl::Context *context)
// Set the previous context back to current // Set the previous context back to current
if (changeContextForDeletion) if (changeContextForDeletion)
{ {
ANGLE_TRY(makeCurrent(thread->getCurrentDrawSurface(), thread->getCurrentReadSurface(), ANGLE_TRY(makeCurrent(thread, currentDrawSurface, currentReadSurface, currentContext));
currentContext));
} }
return NoError(); return NoError();
......
...@@ -114,7 +114,10 @@ class Display final : public LabeledObject, angle::NonCopyable ...@@ -114,7 +114,10 @@ class Display final : public LabeledObject, angle::NonCopyable
const AttributeMap &attribs, const AttributeMap &attribs,
Sync **outSync); Sync **outSync);
Error makeCurrent(Surface *drawSurface, Surface *readSurface, gl::Context *context); Error makeCurrent(const Thread *thread,
Surface *drawSurface,
Surface *readSurface,
gl::Context *context);
Error destroySurface(Surface *surface); Error destroySurface(Surface *surface);
void destroyImage(Image *image); void destroyImage(Image *image);
......
...@@ -109,6 +109,11 @@ void ContextImpl::stencilThenCoverStrokePathInstanced(const std::vector<gl::Path ...@@ -109,6 +109,11 @@ void ContextImpl::stencilThenCoverStrokePathInstanced(const std::vector<gl::Path
UNREACHABLE(); UNREACHABLE();
} }
angle::Result ContextImpl::onUnMakeCurrent(const gl::Context *context)
{
return angle::Result::Continue;
}
void ContextImpl::setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCache) void ContextImpl::setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCache)
{ {
mMemoryProgramCache = memoryProgramCache; mMemoryProgramCache = memoryProgramCache;
......
...@@ -154,6 +154,7 @@ class ContextImpl : public GLImplFactory ...@@ -154,6 +154,7 @@ class ContextImpl : public GLImplFactory
// Context switching // Context switching
virtual angle::Result onMakeCurrent(const gl::Context *context) = 0; virtual angle::Result onMakeCurrent(const gl::Context *context) = 0;
virtual angle::Result onUnMakeCurrent(const gl::Context *context);
// Native capabilities, unmodified by gl::Context. // Native capabilities, unmodified by gl::Context.
virtual gl::Caps getNativeCaps() const = 0; virtual gl::Caps getNativeCaps() const = 0;
......
...@@ -1003,6 +1003,14 @@ angle::Result ContextVk::onMakeCurrent(const gl::Context *context) ...@@ -1003,6 +1003,14 @@ angle::Result ContextVk::onMakeCurrent(const gl::Context *context)
updateFlipViewportDrawFramebuffer(glState); updateFlipViewportDrawFramebuffer(glState);
updateFlipViewportReadFramebuffer(glState); updateFlipViewportReadFramebuffer(glState);
invalidateDriverUniforms(); invalidateDriverUniforms();
return angle::Result::Continue;
}
angle::Result ContextVk::onUnMakeCurrent(const gl::Context *context)
{
ANGLE_TRY(flushImpl());
mCurrentWindowSurface = nullptr;
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -110,6 +110,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff ...@@ -110,6 +110,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
// Context switching // Context switching
angle::Result onMakeCurrent(const gl::Context *context) override; angle::Result onMakeCurrent(const gl::Context *context) override;
angle::Result onUnMakeCurrent(const gl::Context *context) override;
// Native capabilities, unmodified by gl::Context. // Native capabilities, unmodified by gl::Context.
gl::Caps getNativeCaps() const override; gl::Caps getNativeCaps() const override;
......
...@@ -105,11 +105,9 @@ EGLBoolean EGLAPIENTRY EGL_Terminate(EGLDisplay dpy) ...@@ -105,11 +105,9 @@ EGLBoolean EGLAPIENTRY EGL_Terminate(EGLDisplay dpy)
ANGLE_EGL_TRY_RETURN(thread, ValidateTerminate(display), "eglTerminate", ANGLE_EGL_TRY_RETURN(thread, ValidateTerminate(display), "eglTerminate",
GetDisplayIfValid(display), EGL_FALSE); GetDisplayIfValid(display), EGL_FALSE);
if (display->isValidContext(thread->getContext())) ANGLE_EGL_TRY_RETURN(thread, display->makeCurrent(thread, nullptr, nullptr, nullptr),
{ "eglTerminate", GetDisplayIfValid(display), EGL_FALSE);
SetContextCurrent(thread, nullptr); SetContextCurrent(thread, nullptr);
}
ANGLE_EGL_TRY_RETURN(thread, display->terminate(thread), "eglTerminate", ANGLE_EGL_TRY_RETURN(thread, display->terminate(thread), "eglTerminate",
GetDisplayIfValid(display), EGL_FALSE); GetDisplayIfValid(display), EGL_FALSE);
...@@ -447,15 +445,8 @@ EGLBoolean EGLAPIENTRY EGL_MakeCurrent(EGLDisplay dpy, ...@@ -447,15 +445,8 @@ EGLBoolean EGLAPIENTRY EGL_MakeCurrent(EGLDisplay dpy,
// Only call makeCurrent if the context or surfaces have changed. // Only call makeCurrent if the context or surfaces have changed.
if (previousDraw != drawSurface || previousRead != readSurface || previousContext != context) if (previousDraw != drawSurface || previousRead != readSurface || previousContext != context)
{ {
// Release the surface from the previously-current context, to allow ANGLE_EGL_TRY_RETURN(thread,
// destroyed surfaces to delete themselves. display->makeCurrent(thread, drawSurface, readSurface, context),
if (previousContext != nullptr && context != previousContext)
{
ANGLE_EGL_TRY_RETURN(thread, previousContext->releaseSurface(display), "eglMakeCurrent",
GetContextIfValid(display, context), EGL_FALSE);
}
ANGLE_EGL_TRY_RETURN(thread, display->makeCurrent(drawSurface, readSurface, context),
"eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE); "eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
SetContextCurrent(thread, context); SetContextCurrent(thread, context);
...@@ -785,17 +776,10 @@ EGLBoolean EGLAPIENTRY EGL_ReleaseThread(void) ...@@ -785,17 +776,10 @@ EGLBoolean EGLAPIENTRY EGL_ReleaseThread(void)
if (previousDraw != EGL_NO_SURFACE || previousRead != EGL_NO_SURFACE || if (previousDraw != EGL_NO_SURFACE || previousRead != EGL_NO_SURFACE ||
previousContext != EGL_NO_CONTEXT) previousContext != EGL_NO_CONTEXT)
{ {
// Release the surface from the previously-current context, to allow
// destroyed surfaces to delete themselves.
if (previousContext != nullptr && previousDisplay != EGL_NO_DISPLAY)
{
ANGLE_EGL_TRY_RETURN(thread, previousContext->releaseSurface(previousDisplay),
"eglReleaseThread", nullptr, EGL_FALSE);
}
if (previousDisplay != EGL_NO_DISPLAY) if (previousDisplay != EGL_NO_DISPLAY)
{ {
ANGLE_EGL_TRY_RETURN(thread, previousDisplay->makeCurrent(nullptr, nullptr, nullptr), ANGLE_EGL_TRY_RETURN(thread,
previousDisplay->makeCurrent(thread, nullptr, nullptr, nullptr),
"eglReleaseThread", nullptr, EGL_FALSE); "eglReleaseThread", nullptr, EGL_FALSE);
} }
......
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