Bug 741319 - Delete textures using the same context used to create them, on the thread that owns that context. r=joe

This commit is contained in:
Ali Juma 2012-04-10 16:20:02 -04:00
parent 8055d345a5
commit be583b5cab
4 changed files with 29 additions and 7 deletions

View File

@ -766,7 +766,7 @@ void GLContext::ApplyFilterToBoundTexture(gfxPattern::GraphicsFilter aFilter)
BasicTextureImage::~BasicTextureImage()
{
GLContext *ctx = mGLContext;
if (ctx->IsDestroyed() || !NS_IsMainThread()) {
if (ctx->IsDestroyed() || !ctx->IsOwningThreadCurrent()) {
ctx = ctx->GetSharedContext();
}

View File

@ -554,6 +554,7 @@ public:
#endif
{
mUserData.Init();
mOwningThread = NS_GetCurrentThread();
}
virtual ~GLContext() {
@ -640,6 +641,23 @@ public:
bool IsGlobalSharedContext() { return mIsGlobalSharedContext; }
void SetIsGlobalSharedContext(bool aIsOne) { mIsGlobalSharedContext = aIsOne; }
/**
* Returns true if the thread on which this context was created is the currently
* executing thread.
*/
bool IsOwningThreadCurrent() { return NS_GetCurrentThread() == mOwningThread; }
void DispatchToOwningThread(nsIRunnable *event) {
// Before dispatching, we need to ensure we're not in the middle of
// shutting down. Dispatching runnables in the middle of shutdown
// (that is, when the main thread is no longer get-able) can cause them
// to leak. See Bug 741319, and Bug 744115.
nsCOMPtr<nsIThread> mainThread;
if (NS_SUCCEEDED(NS_GetMainThread(getter_AddRefs(mainThread)))) {
mOwningThread->Dispatch(event, NS_DISPATCH_NORMAL);
}
}
const ContextFormat& CreationFormat() { return mCreationFormat; }
const ContextFormat& ActualFormat() { return mActualFormat; }
@ -1581,6 +1599,9 @@ protected:
ContextFormat mCreationFormat;
nsRefPtr<GLContext> mSharedContext;
// The thread on which this context was created.
nsCOMPtr<nsIThread> mOwningThread;
GLContextSymbols mSymbols;
#ifdef DEBUG

View File

@ -874,7 +874,7 @@ public:
virtual ~TextureImageEGL()
{
GLContext *ctx = mGLContext;
if (ctx->IsDestroyed() || !NS_IsMainThread()) {
if (ctx->IsDestroyed() || !ctx->IsOwningThreadCurrent()) {
ctx = ctx->GetSharedContext();
}

View File

@ -83,8 +83,8 @@ public:
void
GLTexture::Allocate(GLContext *aContext)
{
NS_ASSERTION(aContext->IsGlobalSharedContext() ||
NS_IsMainThread(), "Can only allocate texture on main thread or with cx sharing");
NS_ASSERTION(aContext->IsGlobalSharedContext() || aContext->IsOwningThreadCurrent(),
"Can only allocate texture on context's owning thread or with cx sharing");
Release();
@ -122,13 +122,14 @@ GLTexture::Release()
}
if (mTexture) {
if (NS_IsMainThread() || mContext->IsGlobalSharedContext()) {
if (mContext->IsOwningThreadCurrent() || mContext->IsGlobalSharedContext()) {
mContext->MakeCurrent();
mContext->fDeleteTextures(1, &mTexture);
} else {
nsCOMPtr<nsIRunnable> runnable =
new TextureDeleter(mContext.forget(), mTexture);
NS_DispatchToMainThread(runnable);
new TextureDeleter(mContext.get(), mTexture);
mContext->DispatchToOwningThread(runnable);
mContext.forget();
}
mTexture = 0;