mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-20 22:27:31 +09:00
Issue #1354 - Clear the current context when MakeCurrent() fails.
This commit is contained in:
parent
8d600c51ed
commit
9d76eb5791
10 changed files with 81 additions and 95 deletions
|
|
@ -440,6 +440,13 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
|
||||||
{
|
{
|
||||||
MOZ_RELEASE_ASSERT(gl, "GFX: GL not initialized");
|
MOZ_RELEASE_ASSERT(gl, "GFX: GL not initialized");
|
||||||
|
|
||||||
|
if (!gl->MakeCurrent(true)) {
|
||||||
|
MOZ_ASSERT(false);
|
||||||
|
*out_failReason = { "FEATURE_FAILURE_WEBGL_MAKECURRENT",
|
||||||
|
"Failed to MakeCurrent for init." };
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Unconditionally create a new format usage authority. This is
|
// Unconditionally create a new format usage authority. This is
|
||||||
// important when restoring contexts and extensions need to add
|
// important when restoring contexts and extensions need to add
|
||||||
// formats back into the authority.
|
// formats back into the authority.
|
||||||
|
|
|
||||||
|
|
@ -578,6 +578,10 @@ GLContext::LoadFeatureSymbols(const char* prefix, bool trygl, const SymLoadStruc
|
||||||
bool
|
bool
|
||||||
GLContext::InitWithPrefixImpl(const char* prefix, bool trygl)
|
GLContext::InitWithPrefixImpl(const char* prefix, bool trygl)
|
||||||
{
|
{
|
||||||
|
// wglGetProcAddress requires a current context.
|
||||||
|
if (!MakeCurrent(true))
|
||||||
|
return false;
|
||||||
|
|
||||||
mWorkAroundDriverBugs = gfxPrefs::WorkAroundDriverBugs();
|
mWorkAroundDriverBugs = gfxPrefs::WorkAroundDriverBugs();
|
||||||
|
|
||||||
const SymLoadStruct coreSymbols[] = {
|
const SymLoadStruct coreSymbols[] = {
|
||||||
|
|
@ -714,7 +718,6 @@ GLContext::InitWithPrefixImpl(const char* prefix, bool trygl)
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
|
|
||||||
MakeCurrent();
|
|
||||||
MOZ_ASSERT(mProfile != ContextProfile::Unknown);
|
MOZ_ASSERT(mProfile != ContextProfile::Unknown);
|
||||||
|
|
||||||
uint32_t version = 0;
|
uint32_t version = 0;
|
||||||
|
|
@ -2253,13 +2256,11 @@ GLContext::MarkDestroyed()
|
||||||
mBlitHelper = nullptr;
|
mBlitHelper = nullptr;
|
||||||
mReadTexImageHelper = nullptr;
|
mReadTexImageHelper = nullptr;
|
||||||
|
|
||||||
if (MakeCurrent()) {
|
mIsDestroyed = true;
|
||||||
mTexGarbageBin->GLContextTeardown();
|
|
||||||
} else {
|
|
||||||
NS_WARNING("MakeCurrent() failed during MarkDestroyed! Skipping GL object teardown.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mSymbols.Zero();
|
mSymbols.Zero();
|
||||||
|
if (MakeCurrent(true)) {
|
||||||
|
mTexGarbageBin->GLContextTeardown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_GL_DEBUG
|
#ifdef MOZ_GL_DEBUG
|
||||||
|
|
|
||||||
|
|
@ -353,6 +353,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
bool mIsOffscreen;
|
bool mIsOffscreen;
|
||||||
bool mContextLost;
|
bool mContextLost;
|
||||||
|
bool mIsDestroyed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mVersion store the OpenGL's version, multiplied by 100. For example, if
|
* mVersion store the OpenGL's version, multiplied by 100. For example, if
|
||||||
|
|
@ -3265,7 +3266,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
return MakeCurrentImpl(aForce);
|
return MakeCurrentImpl(aForce);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Init() = 0;
|
virtual bool Init() = 0;
|
||||||
|
|
||||||
virtual bool SetupLookupFunction() = 0;
|
virtual bool SetupLookupFunction() = 0;
|
||||||
|
|
@ -3273,8 +3274,7 @@ public:
|
||||||
virtual void ReleaseSurface() {}
|
virtual void ReleaseSurface() {}
|
||||||
|
|
||||||
bool IsDestroyed() {
|
bool IsDestroyed() {
|
||||||
// MarkDestroyed will mark all these as null.
|
return mIsDestroyed;
|
||||||
return mSymbols.fUseProgram == nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLContext* GetSharedContext() { return mSharedContext; }
|
GLContext* GetSharedContext() { return mSharedContext; }
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class GLContextCGL : public GLContext
|
||||||
{
|
{
|
||||||
friend class GLContextProviderCGL;
|
friend class GLContextProviderCGL;
|
||||||
|
|
||||||
NSOpenGLContext* mContext;
|
NSOpenGLContext* const mContext;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL, override)
|
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL, override)
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ private:
|
||||||
GLXContext mContext;
|
GLXContext mContext;
|
||||||
Display* mDisplay;
|
Display* mDisplay;
|
||||||
GLXDrawable mDrawable;
|
GLXDrawable mDrawable;
|
||||||
|
Maybe<GLXDrawable> mOverrideDrawable;
|
||||||
bool mDeleteDrawable;
|
bool mDeleteDrawable;
|
||||||
bool mDoubleBuffered;
|
bool mDoubleBuffered;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,26 +83,13 @@ GLContextCGL::GLContextCGL(CreateContextFlags flags, const SurfaceCaps& caps,
|
||||||
GLContextCGL::~GLContextCGL()
|
GLContextCGL::~GLContextCGL()
|
||||||
{
|
{
|
||||||
MarkDestroyed();
|
MarkDestroyed();
|
||||||
|
[mContext release];
|
||||||
if (mContext) {
|
|
||||||
if ([NSOpenGLContext currentContext] == mContext) {
|
|
||||||
// Clear the current context before releasing. If we don't do
|
|
||||||
// this, the next time we call [NSOpenGLContext currentContext],
|
|
||||||
// "invalid context" will be printed to the console.
|
|
||||||
[NSOpenGLContext clearCurrentContext];
|
|
||||||
}
|
|
||||||
[mContext release];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GLContextCGL::Init()
|
GLContextCGL::Init()
|
||||||
{
|
{
|
||||||
if (!InitWithPrefix("gl", true))
|
return InitWithPrefix("gl", true);
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CGLContextObj
|
CGLContextObj
|
||||||
|
|
@ -114,6 +101,11 @@ GLContextCGL::GetCGLContext() const
|
||||||
bool
|
bool
|
||||||
GLContextCGL::MakeCurrentImpl(bool aForce)
|
GLContextCGL::MakeCurrentImpl(bool aForce)
|
||||||
{
|
{
|
||||||
|
if (IsDestroyed()) {
|
||||||
|
[NSOpenGLContext clearCurrentContext];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!aForce && [NSOpenGLContext currentContext] == mContext) {
|
if (!aForce && [NSOpenGLContext currentContext] == mContext) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,35 +36,24 @@ GLContextEAGL::GLContextEAGL(CreateContextFlags flags, const SurfaceCaps& caps,
|
||||||
|
|
||||||
GLContextEAGL::~GLContextEAGL()
|
GLContextEAGL::~GLContextEAGL()
|
||||||
{
|
{
|
||||||
MakeCurrent();
|
if (MakeCurrent()) {
|
||||||
|
if (mBackbufferFB) {
|
||||||
if (mBackbufferFB) {
|
fDeleteFramebuffers(1, &mBackbufferFB);
|
||||||
fDeleteFramebuffers(1, &mBackbufferFB);
|
}
|
||||||
}
|
if (mBackbufferRB) {
|
||||||
|
fDeleteRenderbuffers(1, &mBackbufferRB);
|
||||||
if (mBackbufferRB) {
|
}
|
||||||
fDeleteRenderbuffers(1, &mBackbufferRB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mLayer = nil;
|
||||||
MarkDestroyed();
|
MarkDestroyed();
|
||||||
|
[mContext release];
|
||||||
if (mLayer) {
|
|
||||||
mLayer = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mContext) {
|
|
||||||
[EAGLContext setCurrentContext:nil];
|
|
||||||
[mContext release];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GLContextEAGL::Init()
|
GLContextEAGL::Init()
|
||||||
{
|
{
|
||||||
if (!InitWithPrefix("gl", true))
|
return InitWithPrefix("gl", true);
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -120,12 +109,12 @@ GLContextEAGL::MakeCurrentImpl(bool aForce)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mContext) {
|
if (IsDestroyed()) {
|
||||||
if(![EAGLContext setCurrentContext:mContext]) {
|
[EAGLContext setCurrentContext:nil];
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
return [EAGLContext setCurrentContext:mContext];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -150,13 +150,12 @@ is_power_of_two(int v)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
DestroySurface(EGLSurface oldSurface) {
|
DestroySurface(const EGLSurface surf) {
|
||||||
if (oldSurface != EGL_NO_SURFACE) {
|
if (!surf) {
|
||||||
sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
|
// Nothing to do.
|
||||||
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
return;
|
||||||
EGL_NO_CONTEXT);
|
|
||||||
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), oldSurface);
|
|
||||||
}
|
}
|
||||||
|
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static EGLSurface
|
static EGLSurface
|
||||||
|
|
@ -223,7 +222,7 @@ GLContextEGL::~GLContextEGL()
|
||||||
sEGLLibrary.fDestroyContext(EGL_DISPLAY(), mContext);
|
sEGLLibrary.fDestroyContext(EGL_DISPLAY(), mContext);
|
||||||
sEGLLibrary.UnsetCachedCurrentContext();
|
sEGLLibrary.UnsetCachedCurrentContext();
|
||||||
|
|
||||||
mozilla::gl::DestroySurface(mSurface);
|
DestroySurface(mSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -247,12 +246,7 @@ GLContextEGL::Init()
|
||||||
if (!InitWithPrefix("gl", true))
|
if (!InitWithPrefix("gl", true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool current = MakeCurrent();
|
MOZ_ASSERT(IsCurrent());
|
||||||
if (!current) {
|
|
||||||
gfx::LogFailure(NS_LITERAL_CSTRING(
|
|
||||||
"Couldn't get device attachments for device."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static_assert(sizeof(GLint) >= sizeof(int32_t), "GLint is smaller than int32_t");
|
static_assert(sizeof(GLint) >= sizeof(int32_t), "GLint is smaller than int32_t");
|
||||||
mMaxTextureImageSize = INT32_MAX;
|
mMaxTextureImageSize = INT32_MAX;
|
||||||
|
|
@ -303,7 +297,10 @@ GLContextEGL::ReleaseTexImage()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GLContextEGL::SetEGLSurfaceOverride(EGLSurface surf) {
|
GLContextEGL::SetEGLSurfaceOverride(const EGLSurface surf) {
|
||||||
|
|
||||||
|
MOZ_ASSERT(!surf || surf != mSurface);
|
||||||
|
|
||||||
if (Screen()) {
|
if (Screen()) {
|
||||||
/* Blit `draw` to `read` if we need to, before we potentially juggle
|
/* Blit `draw` to `read` if we need to, before we potentially juggle
|
||||||
* `read` around. If we don't, we might attach a different `read`,
|
* `read` around. If we don't, we might attach a different `read`,
|
||||||
|
|
@ -314,12 +311,17 @@ GLContextEGL::SetEGLSurfaceOverride(EGLSurface surf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mSurfaceOverride = surf;
|
mSurfaceOverride = surf;
|
||||||
DebugOnly<bool> ok = MakeCurrent(true);
|
MOZ_ALWAYS_TRUE(MakeCurrent(true));
|
||||||
MOZ_ASSERT(ok);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GLContextEGL::MakeCurrentImpl(bool aForce) {
|
GLContextEGL::MakeCurrentImpl(bool aForce) {
|
||||||
|
if (IsDestroyed()) {
|
||||||
|
//Clear and exit
|
||||||
|
sEGLLibrary.fMakeCurrent(EGL_DISPLAY(), nullptr, nullptr, nullptr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool succeeded = true;
|
bool succeeded = true;
|
||||||
|
|
||||||
// Assume that EGL has the same problem as WGL does,
|
// Assume that EGL has the same problem as WGL does,
|
||||||
|
|
@ -373,7 +375,7 @@ GLContextEGL::IsCurrent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GLContextEGL::RenewSurface(nsIWidget* aWidget) {
|
GLContextEGL::RenewSurface(nsIWidget* const aWidget) {
|
||||||
if (!mOwnsContext) {
|
if (!mOwnsContext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -389,13 +391,12 @@ GLContextEGL::RenewSurface(nsIWidget* aWidget) {
|
||||||
|
|
||||||
void
|
void
|
||||||
GLContextEGL::ReleaseSurface() {
|
GLContextEGL::ReleaseSurface() {
|
||||||
if (mOwnsContext) {
|
if (!mOwnsContext) {
|
||||||
mozilla::gl::DestroySurface(mSurface);
|
return;
|
||||||
}
|
}
|
||||||
if (mSurface == mSurfaceOverride) {
|
|
||||||
mSurfaceOverride = EGL_NO_SURFACE;
|
DestroySurface(mSurface);
|
||||||
}
|
mSurface = nullptr;
|
||||||
mSurface = EGL_NO_SURFACE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -894,20 +894,12 @@ GLContextGLX::~GLContextGLX()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see bug 659842 comment 76
|
|
||||||
#ifdef DEBUG
|
|
||||||
bool success =
|
|
||||||
#endif
|
|
||||||
mGLX->xMakeCurrent(mDisplay, X11None, nullptr);
|
|
||||||
MOZ_ASSERT(success,
|
|
||||||
"glXMakeCurrent failed to release GL context before we call "
|
|
||||||
"glXDestroyContext!");
|
|
||||||
|
|
||||||
mGLX->xDestroyContext(mDisplay, mContext);
|
mGLX->xDestroyContext(mDisplay, mContext);
|
||||||
|
|
||||||
if (mDeleteDrawable) {
|
if (mDeleteDrawable) {
|
||||||
mGLX->xDestroyPixmap(mDisplay, mDrawable);
|
mGLX->xDestroyPixmap(mDisplay, mDrawable);
|
||||||
}
|
}
|
||||||
|
MOZ_ASSERT(!mOverrideDrawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -944,6 +936,10 @@ GLContextGLX::MakeCurrentImpl(bool aForce)
|
||||||
// DRI2InvalidateBuffers event before drawing. See bug 1280653.
|
// DRI2InvalidateBuffers event before drawing. See bug 1280653.
|
||||||
Unused << XPending(mDisplay);
|
Unused << XPending(mDisplay);
|
||||||
}
|
}
|
||||||
|
if (IsDestroyed()) {
|
||||||
|
MOZ_ALWAYS_TRUE(mGLX->xMakeCurrent(mDisplay, X11None, nullptr);
|
||||||
|
return false; // We did not MakeCurrent mContext, but that's what we wanted!
|
||||||
|
}
|
||||||
|
|
||||||
succeeded = mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
|
succeeded = mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
|
||||||
NS_ASSERTION(succeeded, "Failed to make GL context current!");
|
NS_ASSERTION(succeeded, "Failed to make GL context current!");
|
||||||
|
|
@ -1017,16 +1013,18 @@ GLContextGLX::GetWSIInfo(nsCString* const out) const
|
||||||
bool
|
bool
|
||||||
GLContextGLX::OverrideDrawable(GLXDrawable drawable)
|
GLContextGLX::OverrideDrawable(GLXDrawable drawable)
|
||||||
{
|
{
|
||||||
if (Screen())
|
if (Screen()) {
|
||||||
Screen()->AssureBlitted();
|
Screen()->AssureBlitted();
|
||||||
Bool result = mGLX->xMakeCurrent(mDisplay, drawable, mContext);
|
}
|
||||||
return result;
|
mOverrideDrawable = Some(drawable);
|
||||||
|
return MakeCurrent(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GLContextGLX::RestoreDrawable()
|
GLContextGLX::RestoreDrawable()
|
||||||
{
|
{
|
||||||
return mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
|
mOverrideDrawable = Nothing();
|
||||||
|
return MakeCurrent(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLContextGLX::GLContextGLX(
|
GLContextGLX::GLContextGLX(
|
||||||
|
|
|
||||||
|
|
@ -314,20 +314,17 @@ GLContextWGL::Init()
|
||||||
if (!mDC || !mContext)
|
if (!mDC || !mContext)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// see bug 929506 comment 29. wglGetProcAddress requires a current context.
|
|
||||||
if (!sWGLLib.fMakeCurrent(mDC, mContext))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SetupLookupFunction();
|
SetupLookupFunction();
|
||||||
if (!InitWithPrefix("gl", true))
|
return InitWithPrefix("gl", true);
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GLContextWGL::MakeCurrentImpl(bool aForce)
|
GLContextWGL::MakeCurrentImpl(bool aForce)
|
||||||
{
|
{
|
||||||
|
if (IsDestroyed()) {
|
||||||
|
MOZ_ALWAYS_TRUE(sWGLLib.fMakeCurrent(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
BOOL succeeded = true;
|
BOOL succeeded = true;
|
||||||
|
|
||||||
// wglGetCurrentContext seems to just pull the HGLRC out
|
// wglGetCurrentContext seems to just pull the HGLRC out
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue