Bug 1388921 Resume IPC Messages after we send sync textures. r=mattwoodrow

This commit is contained in:
Mason Chang 2017-08-14 14:27:03 -07:00
parent 444c3a179f
commit 3d88e66f5a
5 changed files with 33 additions and 26 deletions

View File

@ -172,19 +172,15 @@ void
PaintThread::FinishedLayerBatch()
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<CompositorBridgeChild> cbc;
if (!gfxPrefs::LayersOMTPForceSync()) {
cbc = CompositorBridgeChild::Get();
}
RefPtr<PaintThread> self = this;
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::EndAsyncPainting",
[self, cbc]() -> void
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::EndAsyncPaintingLayer",
[self]() -> void
{
self->EndAsyncPainting(cbc);
self->EndAsyncPaintingLayer();
});
if (cbc) {
if (!gfxPrefs::LayersOMTPForceSync()) {
sThread->Dispatch(task.forget());
} else {
SyncRunnable::DispatchToThread(sThread, task);
@ -192,7 +188,7 @@ PaintThread::FinishedLayerBatch()
}
void
PaintThread::EndAsyncPainting(CompositorBridgeChild* aBridge)
PaintThread::EndAsyncPaintingLayer()
{
MOZ_ASSERT(IsOnPaintThread());
// Textureclient forces a flush once we "end paint", so
@ -203,10 +199,6 @@ PaintThread::EndAsyncPainting(CompositorBridgeChild* aBridge)
}
mDrawTargetsToFlush.Clear();
if (aBridge) {
aBridge->NotifyFinishedAsyncPaintLayer();
}
}
void
@ -215,15 +207,20 @@ PaintThread::SynchronizePaintTextures(SyncObjectClient* aSyncObject)
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aSyncObject);
RefPtr<CompositorBridgeChild> cbc;
if (!gfxPrefs::LayersOMTPForceSync()) {
cbc = CompositorBridgeChild::Get();
}
RefPtr<SyncObjectClient> syncObject(aSyncObject);
RefPtr<PaintThread> self = this;
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::SyncTextureData",
[self, syncObject]() -> void
[self, cbc, syncObject]() -> void
{
self->SyncTextureData(syncObject);
self->SyncTextureData(cbc, syncObject);
});
if (!gfxPrefs::LayersOMTPForceSync()) {
if (cbc) {
sThread->Dispatch(task.forget());
} else {
SyncRunnable::DispatchToThread(sThread, task);
@ -231,12 +228,17 @@ PaintThread::SynchronizePaintTextures(SyncObjectClient* aSyncObject)
}
void
PaintThread::SyncTextureData(SyncObjectClient* aSyncObject)
PaintThread::SyncTextureData(CompositorBridgeChild* aBridge,
SyncObjectClient* aSyncObject)
{
MOZ_ASSERT(IsOnPaintThread());
MOZ_ASSERT(aSyncObject);
aSyncObject->Synchronize();
if (aBridge) {
aBridge->NotifyFinishedAsyncPaintTransaction();
}
}
void

View File

@ -100,8 +100,9 @@ private:
void PaintContentsAsync(CompositorBridgeChild* aBridge,
CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback);
void EndAsyncPainting(CompositorBridgeChild* aBridge);
void SyncTextureData(SyncObjectClient* aSyncObject);
void EndAsyncPaintingLayer();
void SyncTextureData(CompositorBridgeChild* aBridge,
SyncObjectClient* aSyncObject);
static StaticAutoPtr<PaintThread> sSingleton;
static StaticRefPtr<nsIThread> sThread;

View File

@ -1687,9 +1687,9 @@ SyncObjectD3D11Client::IsSyncObjectValid()
void
SyncObjectD3D11Client::Synchronize()
{
// This can be called from the paint or main thread depending on OMTP.
// We need this lock in addition to the AutoTextureLock in case we have to
// init here.
// Since this can be called from either the Paint or Main thread.
// We don't want this to race since we initialize the sync texture here
// too.
MutexAutoLock syncLock(mSyncLock);
if (!mSyncedTextures.size()) {

View File

@ -1189,15 +1189,18 @@ CompositorBridgeChild::NotifyFinishedAsyncPaint(CapturedPaintState* aState)
}
void
CompositorBridgeChild::NotifyFinishedAsyncPaintLayer()
CompositorBridgeChild::NotifyFinishedAsyncPaintTransaction()
{
MOZ_ASSERT(PaintThread::IsOnPaintThread());
MonitorAutoLock lock(mPaintLock);
// Since this should happen after ALL paints are done and
// at the end of a transaction, this should always be true.
MOZ_RELEASE_ASSERT(mOutstandingAsyncPaints == 0);
// It's possible that we painted so fast that the main thread never reached
// the code that starts delaying messages. If so, mIsWaitingForPaint will be
// false, and we can safely return.
if (mIsWaitingForPaint && mOutstandingAsyncPaints == 0) {
if (mIsWaitingForPaint) {
ResumeIPCAfterAsyncPaint();
// Notify the main thread in case it's blocking. We do this unconditionally

View File

@ -242,8 +242,9 @@ public:
// Must only be called from the paint thread. Notifies the CompositorBridge
// that the paint thread has finished ALL async requests from a given
// ClientPaintedLayer's batch.
void NotifyFinishedAsyncPaintLayer();
// transaction. We can resume IPC transactions after ALL
// async paints are done.
void NotifyFinishedAsyncPaintTransaction();
private:
// Private destructor, to discourage deletion outside of Release():