Bug 1390755 - Reorder functions in PaintThread and CompositorBridgeChild. r=mchang

MozReview-Commit-ID: 26Cbc9S0Zls

--HG--
extra : rebase_source : b9c557a8a29f9f01539d56b79b11cb5696e5e8a6
extra : histedit_source : 6717e70a114b88e693f2d390b1db15cc54b52ab1
This commit is contained in:
Ryan Hunt 2017-08-16 16:53:15 -05:00
parent f695471892
commit c2d4c1f9aa
4 changed files with 90 additions and 88 deletions

View File

@ -66,11 +66,15 @@ PaintThread::AddRef()
{
}
void
PaintThread::InitOnPaintThread()
/* static */ void
PaintThread::Start()
{
MOZ_ASSERT(!NS_IsMainThread());
sThreadId = PlatformThread::CurrentId();
PaintThread::sSingleton = new PaintThread();
if (!PaintThread::sSingleton->Init()) {
gfxCriticalNote << "Unable to start paint thread";
PaintThread::sSingleton = nullptr;
}
}
bool
@ -92,22 +96,11 @@ PaintThread::Init()
return true;
}
/* static */ void
PaintThread::Start()
void
PaintThread::InitOnPaintThread()
{
PaintThread::sSingleton = new PaintThread();
if (!PaintThread::sSingleton->Init()) {
gfxCriticalNote << "Unable to start paint thread";
PaintThread::sSingleton = nullptr;
}
}
/* static */ PaintThread*
PaintThread::Get()
{
MOZ_ASSERT(NS_IsMainThread());
return PaintThread::sSingleton.get();
MOZ_ASSERT(!NS_IsMainThread());
sThreadId = PlatformThread::CurrentId();
}
void
@ -138,12 +131,53 @@ PaintThread::ShutdownOnPaintThread()
MOZ_ASSERT(IsOnPaintThread());
}
/* static */ PaintThread*
PaintThread::Get()
{
MOZ_ASSERT(NS_IsMainThread());
return PaintThread::sSingleton.get();
}
/* static */ bool
PaintThread::IsOnPaintThread()
{
return sThreadId == PlatformThread::CurrentId();
}
void
PaintThread::PaintContents(CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aState);
// If painting asynchronously, we need to acquire the compositor bridge which
// owns the underlying MessageChannel. Otherwise we leave it null and use
// synchronous dispatch.
RefPtr<CompositorBridgeChild> cbc;
if (!gfxPrefs::LayersOMTPForceSync()) {
cbc = CompositorBridgeChild::Get();
cbc->NotifyBeginAsyncPaint(aState);
}
RefPtr<CapturedPaintState> state(aState);
RefPtr<DrawTargetCapture> capture(aState->mCapture);
RefPtr<PaintThread> self = this;
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintContents",
[self, cbc, capture, state, aCallback]() -> void
{
self->AsyncPaintContents(cbc,
state,
aCallback);
});
if (cbc) {
sThread->Dispatch(task.forget());
} else {
SyncRunnable::DispatchToThread(sThread, task);
}
}
void
PaintThread::AsyncPaintContents(CompositorBridgeChild* aBridge,
CapturedPaintState* aState,
@ -242,39 +276,5 @@ PaintThread::AsyncEndLayerTransaction(CompositorBridgeChild* aBridge,
}
}
void
PaintThread::PaintContents(CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aState);
// If painting asynchronously, we need to acquire the compositor bridge which
// owns the underlying MessageChannel. Otherwise we leave it null and use
// synchronous dispatch.
RefPtr<CompositorBridgeChild> cbc;
if (!gfxPrefs::LayersOMTPForceSync()) {
cbc = CompositorBridgeChild::Get();
cbc->NotifyBeginAsyncPaint(aState);
}
RefPtr<CapturedPaintState> state(aState);
RefPtr<DrawTargetCapture> capture(aState->mCapture);
RefPtr<PaintThread> self = this;
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintContents",
[self, cbc, capture, state, aCallback]() -> void
{
self->AsyncPaintContents(cbc,
state,
aCallback);
});
if (cbc) {
sThread->Dispatch(task.forget());
} else {
SyncRunnable::DispatchToThread(sThread, task);
}
}
} // namespace layers
} // namespace mozilla

View File

@ -67,6 +67,10 @@ public:
static void Start();
static void Shutdown();
static PaintThread* Get();
// Helper for asserts.
static bool IsOnPaintThread();
void PaintContents(CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback);
@ -90,13 +94,11 @@ public:
void Release();
void AddRef();
// Helper for asserts.
static bool IsOnPaintThread();
private:
bool Init();
void ShutdownOnPaintThread();
void InitOnPaintThread();
void AsyncPaintContents(CompositorBridgeChild* aBridge,
CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback);

View File

@ -1134,6 +1134,20 @@ CompositorBridgeChild::GetNextPipelineId()
return wr::AsPipelineId(GetNextResourceId());
}
void
CompositorBridgeChild::FlushAsyncPaints()
{
MOZ_ASSERT(NS_IsMainThread());
MonitorAutoLock lock(mPaintLock);
while (mIsWaitingForPaint) {
lock.Wait();
}
// It's now safe to free any TextureClients that were used during painting.
mTextureClientsForAsyncPaint.Clear();
}
void
CompositorBridgeChild::NotifyBeginAsyncPaint(CapturedPaintState* aState)
{
@ -1224,23 +1238,6 @@ CompositorBridgeChild::NotifyFinishedAsyncEndLayerTransaction()
}
}
void
CompositorBridgeChild::PostponeMessagesIfAsyncPainting()
{
MOZ_ASSERT(NS_IsMainThread());
MonitorAutoLock lock(mPaintLock);
MOZ_ASSERT(!mIsWaitingForPaint);
// We need to wait for async paints and the async end transaction as
// it will do texture synchronization
if (mOutstandingAsyncPaints > 0 || mOutstandingAsyncEndTransaction) {
mIsWaitingForPaint = true;
GetIPCChannel()->BeginPostponingSends();
}
}
void
CompositorBridgeChild::ResumeIPCAfterAsyncPaint()
{
@ -1261,17 +1258,20 @@ CompositorBridgeChild::ResumeIPCAfterAsyncPaint()
}
void
CompositorBridgeChild::FlushAsyncPaints()
CompositorBridgeChild::PostponeMessagesIfAsyncPainting()
{
MOZ_ASSERT(NS_IsMainThread());
MonitorAutoLock lock(mPaintLock);
while (mIsWaitingForPaint) {
lock.Wait();
}
// It's now safe to free any TextureClients that were used during painting.
mTextureClientsForAsyncPaint.Clear();
MOZ_ASSERT(!mIsWaitingForPaint);
// We need to wait for async paints and the async end transaction as
// it will do texture synchronization
if (mOutstandingAsyncPaints > 0 || mOutstandingAsyncEndTransaction) {
mIsWaitingForPaint = true;
GetIPCChannel()->BeginPostponingSends();
}
}
} // namespace layers

View File

@ -222,20 +222,15 @@ public:
wr::PipelineId GetNextPipelineId();
// Must only be called from the main thread. Notifies the CompositorBridge
// that the paint thread is going to begin painting asynchronously.
void NotifyBeginAsyncPaint(CapturedPaintState* aState);
// Must only be called from the main thread. Notifies the CompoistorBridge
// that a transaction is about to be sent, and if the paint thread is
// currently painting, to begin delaying IPC messages.
void PostponeMessagesIfAsyncPainting();
// Must only be called from the main thread. Ensures that any paints from
// previous frames have been flushed. The main thread blocks until the
// operation completes.
void FlushAsyncPaints();
// Must only be called from the main thread. Notifies the CompositorBridge
// that the paint thread is going to begin painting asynchronously.
void NotifyBeginAsyncPaint(CapturedPaintState* aState);
// Must only be called from the paint thread. Notifies the CompositorBridge
// that the paint thread has finished an asynchronous paint request.
void NotifyFinishedAsyncPaint(CapturedPaintState* aState);
@ -251,6 +246,11 @@ public:
// a given transaction and may resume sending messages.
void NotifyFinishedAsyncEndLayerTransaction();
// Must only be called from the main thread. Notifies the CompoistorBridge
// that a transaction is about to be sent, and if the paint thread is
// currently painting, to begin delaying IPC messages.
void PostponeMessagesIfAsyncPainting();
private:
// Private destructor, to discourage deletion outside of Release():
virtual ~CompositorBridgeChild();