Bug 1371546 - Sync with the render thread when ShutDown() was called in main thread. r=nical, jerry

This commit is contained in:
vincentliu 2017-07-03 20:08:22 +08:00
Родитель 605fc07348
Коммит 5eb2117b57
2 изменённых файлов: 48 добавлений и 1 удалений

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

@ -7,6 +7,7 @@
#include "GeckoProfiler.h" #include "GeckoProfiler.h"
#include "RenderThread.h" #include "RenderThread.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "mtransport/runnable_utils.h"
#include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/CompositorBridgeParent.h" #include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/StaticPtr.h" #include "mozilla/StaticPtr.h"
@ -23,6 +24,7 @@ RenderThread::RenderThread(base::Thread* aThread)
: mThread(aThread) : mThread(aThread)
, mPendingFrameCountMapLock("RenderThread.mPendingFrameCountMapLock") , mPendingFrameCountMapLock("RenderThread.mPendingFrameCountMapLock")
, mRenderTextureMapLock("RenderThread.mRenderTextureMapLock") , mRenderTextureMapLock("RenderThread.mRenderTextureMapLock")
, mHasShutdown(false)
{ {
} }
@ -66,11 +68,29 @@ RenderThread::ShutDown()
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sRenderThread); MOZ_ASSERT(sRenderThread);
// TODO(nical): sync with the render thread {
MutexAutoLock lock(sRenderThread->mRenderTextureMapLock);
sRenderThread->mHasShutdown = true;
}
layers::SynchronousTask task("RenderThread");
RefPtr<Runnable> runnable = WrapRunnable(
RefPtr<RenderThread>(sRenderThread.get()),
&RenderThread::ShutDownTask,
&task);
sRenderThread->Loop()->PostTask(runnable.forget());
task.Wait();
sRenderThread = nullptr; sRenderThread = nullptr;
} }
void
RenderThread::ShutDownTask(layers::SynchronousTask* aTask)
{
layers::AutoCompleteTask complete(aTask);
MOZ_ASSERT(IsInRenderThread());
}
// static // static
MessageLoop* MessageLoop*
RenderThread::Loop() RenderThread::Loop()
@ -89,6 +109,11 @@ void
RenderThread::AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRenderer) RenderThread::AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRenderer)
{ {
MOZ_ASSERT(IsInRenderThread()); MOZ_ASSERT(IsInRenderThread());
if (mHasShutdown) {
return;
}
mRenderers[aWindowId] = Move(aRenderer); mRenderers[aWindowId] = Move(aRenderer);
MutexAutoLock lock(mPendingFrameCountMapLock); MutexAutoLock lock(mPendingFrameCountMapLock);
@ -99,6 +124,11 @@ void
RenderThread::RemoveRenderer(wr::WindowId aWindowId) RenderThread::RemoveRenderer(wr::WindowId aWindowId)
{ {
MOZ_ASSERT(IsInRenderThread()); MOZ_ASSERT(IsInRenderThread());
if (mHasShutdown) {
return;
}
mRenderers.erase(aWindowId); mRenderers.erase(aWindowId);
MutexAutoLock lock(mPendingFrameCountMapLock); MutexAutoLock lock(mPendingFrameCountMapLock);
@ -123,6 +153,10 @@ RenderThread::GetRenderer(wr::WindowId aWindowId)
void void
RenderThread::NewFrameReady(wr::WindowId aWindowId) RenderThread::NewFrameReady(wr::WindowId aWindowId)
{ {
if (mHasShutdown) {
return;
}
if (!IsInRenderThread()) { if (!IsInRenderThread()) {
Loop()->PostTask( Loop()->PostTask(
NewRunnableMethod<wr::WindowId>("wr::RenderThread::NewFrameReady", NewRunnableMethod<wr::WindowId>("wr::RenderThread::NewFrameReady",
@ -139,6 +173,10 @@ RenderThread::NewFrameReady(wr::WindowId aWindowId)
void void
RenderThread::NewScrollFrameReady(wr::WindowId aWindowId, bool aCompositeNeeded) RenderThread::NewScrollFrameReady(wr::WindowId aWindowId, bool aCompositeNeeded)
{ {
if (mHasShutdown) {
return;
}
if (!IsInRenderThread()) { if (!IsInRenderThread()) {
Loop()->PostTask(NewRunnableMethod<wr::WindowId, bool>( Loop()->PostTask(NewRunnableMethod<wr::WindowId, bool>(
"wr::RenderThread::NewScrollFrameReady", "wr::RenderThread::NewScrollFrameReady",
@ -289,6 +327,9 @@ RenderThread::RegisterExternalImage(uint64_t aExternalImageId, already_AddRefed<
{ {
MutexAutoLock lock(mRenderTextureMapLock); MutexAutoLock lock(mRenderTextureMapLock);
if (mHasShutdown) {
return;
}
MOZ_ASSERT(!mRenderTextures.GetWeak(aExternalImageId)); MOZ_ASSERT(!mRenderTextures.GetWeak(aExternalImageId));
mRenderTextures.Put(aExternalImageId, Move(aTexture)); mRenderTextures.Put(aExternalImageId, Move(aTexture));
} }
@ -297,6 +338,9 @@ void
RenderThread::UnregisterExternalImage(uint64_t aExternalImageId) RenderThread::UnregisterExternalImage(uint64_t aExternalImageId)
{ {
MutexAutoLock lock(mRenderTextureMapLock); MutexAutoLock lock(mRenderTextureMapLock);
if (mHasShutdown) {
return;
}
MOZ_ASSERT(mRenderTextures.GetWeak(aExternalImageId)); MOZ_ASSERT(mRenderTextures.GetWeak(aExternalImageId));
if (!IsInRenderThread()) { if (!IsInRenderThread()) {
// The RenderTextureHost should be released in render thread. So, post the // The RenderTextureHost should be released in render thread. So, post the

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

@ -18,6 +18,7 @@
#include "mozilla/webrender/webrender_ffi.h" #include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "mozilla/webrender/WebRenderTypes.h" #include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/layers/SynchronousTask.h"
namespace mozilla { namespace mozilla {
namespace wr { namespace wr {
@ -143,6 +144,7 @@ private:
explicit RenderThread(base::Thread* aThread); explicit RenderThread(base::Thread* aThread);
void DeferredRenderTextureHostDestroy(RefPtr<RenderTextureHost> aTexture); void DeferredRenderTextureHostDestroy(RefPtr<RenderTextureHost> aTexture);
void ShutDownTask(layers::SynchronousTask* aTask);
~RenderThread(); ~RenderThread();
@ -157,6 +159,7 @@ private:
Mutex mRenderTextureMapLock; Mutex mRenderTextureMapLock;
nsRefPtrHashtable<nsUint64HashKey, RenderTextureHost> mRenderTextures; nsRefPtrHashtable<nsUint64HashKey, RenderTextureHost> mRenderTextures;
bool mHasShutdown;
}; };
} // namespace wr } // namespace wr