Bug 1390755 - Notify the paint thread that a layer transaction is completed so it can unblock the main thread. r=mchang

MozReview-Commit-ID: 7kQHWUwek7v

--HG--
extra : rebase_source : a1837e2f3425b241b578a8903f60e43c2606cdaf
This commit is contained in:
Ryan Hunt 2017-08-16 01:04:41 -05:00
Родитель a5168688f9
Коммит c909502278
3 изменённых файлов: 30 добавлений и 23 удалений

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

@ -202,10 +202,9 @@ PaintThread::EndAsyncPaintingLayer()
}
void
PaintThread::SynchronizePaintTextures(SyncObjectClient* aSyncObject)
PaintThread::FinishedLayerTransaction(SyncObjectClient* aSyncObject)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aSyncObject);
RefPtr<CompositorBridgeChild> cbc;
if (!gfxPrefs::LayersOMTPForceSync()) {
@ -214,10 +213,10 @@ PaintThread::SynchronizePaintTextures(SyncObjectClient* aSyncObject)
RefPtr<SyncObjectClient> syncObject(aSyncObject);
RefPtr<PaintThread> self = this;
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::SyncTextureData",
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::EndAsyncLayerTransaction",
[self, cbc, syncObject]() -> void
{
self->SyncTextureData(cbc, syncObject);
self->EndAsyncLayerTransaction(cbc, syncObject);
});
if (cbc) {
@ -228,13 +227,14 @@ PaintThread::SynchronizePaintTextures(SyncObjectClient* aSyncObject)
}
void
PaintThread::SyncTextureData(CompositorBridgeChild* aBridge,
SyncObjectClient* aSyncObject)
PaintThread::EndAsyncLayerTransaction(CompositorBridgeChild* aBridge,
SyncObjectClient* aSyncObject)
{
MOZ_ASSERT(IsOnPaintThread());
MOZ_ASSERT(aSyncObject);
aSyncObject->Synchronize();
if (aSyncObject) {
aSyncObject->Synchronize();
}
if (aBridge) {
aBridge->NotifyFinishedAsyncPaintTransaction();

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

@ -75,13 +75,13 @@ public:
// and the main thread is finished recording this layer.
void FinishedLayerBatch();
// Must be called on the main thread. Tells the paint thread
// to schedule a sync textures after all async paints are done.
// NOTE: The other paint thread functions are on a per PAINT
// or per paint layer basis. This MUST be called at the end
// of a layer transaction as multiple paints can occur
// with multiple layers. We only have to do this once per transaction.
void SynchronizePaintTextures(SyncObjectClient* aSyncObject);
// Must be called on the main thread. Signifies that the current
// layer tree transaction has been finished and any async paints
// for it have been queued on the paint thread. This MUST be called
// at the end of a layer transaction as it will be used to do an optional
// texture sync and then unblock the main thread if it is waiting to paint
// a new frame.
void FinishedLayerTransaction(SyncObjectClient* aSyncObject);
// Sync Runnables need threads to be ref counted,
// But this thread lives through the whole process.
@ -101,8 +101,8 @@ private:
CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback);
void EndAsyncPaintingLayer();
void SyncTextureData(CompositorBridgeChild* aBridge,
SyncObjectClient* aSyncObject);
void EndAsyncLayerTransaction(CompositorBridgeChild* aBridge,
SyncObjectClient* aSyncObject);
static StaticAutoPtr<PaintThread> sSingleton;
static StaticRefPtr<nsIThread> sThread;

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

@ -729,18 +729,25 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
// Skip the synchronization for buffer since we also skip the painting during
// device-reset status. With OMTP, we have to wait for async paints
// before we synchronize and it's done on the paint thread.
RefPtr<SyncObjectClient> syncObject = nullptr;
if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
if (mForwarder->GetSyncObject() &&
mForwarder->GetSyncObject()->IsSyncObjectValid()) {
if (mTextureSyncOnPaintThread) {
// We have to wait for all async paints to finish to do this
PaintThread::Get()->SynchronizePaintTextures(mForwarder->GetSyncObject());
} else {
mForwarder->GetSyncObject()->Synchronize();
}
syncObject = mForwarder->GetSyncObject();
}
}
// If there were async paints queued, then we need to notify the paint thread
// that we finished queuing async paints so it can schedule a runnable after
// all async painting is finished to do a texture sync and unblock the main
// thread if it is waiting before doing a new layer transaction.
if (mTextureSyncOnPaintThread) {
MOZ_ASSERT(PaintThread::Get());
PaintThread::Get()->FinishedLayerTransaction(syncObject);
} else if (syncObject) {
syncObject->Synchronize();
}
mPhase = PHASE_FORWARD;
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(!mIsRepeatTransaction);