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

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

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