mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Bug 1387639 Sync Textures once all async OMTP paints are done. r=mattwoodrow
This commit is contained in:
parent
517c688524
commit
a7da7e14fb
@ -9,6 +9,8 @@
|
||||
#include "base/task.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "mozilla/layers/SyncObject.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
@ -207,6 +209,35 @@ PaintThread::EndAsyncPainting(CompositorBridgeChild* aBridge)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PaintThread::SynchronizePaintTextures(SyncObjectClient* aSyncObject)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aSyncObject);
|
||||
|
||||
RefPtr<SyncObjectClient> syncObject(aSyncObject);
|
||||
RefPtr<PaintThread> self = this;
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::SyncTextureData",
|
||||
[self, syncObject]() -> void
|
||||
{
|
||||
self->SyncTextureData(syncObject);
|
||||
});
|
||||
|
||||
if (!gfxPrefs::LayersOMTPForceSync()) {
|
||||
sThread->Dispatch(task.forget());
|
||||
} else {
|
||||
SyncRunnable::DispatchToThread(sThread, task);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PaintThread::SyncTextureData(SyncObjectClient* aSyncObject)
|
||||
{
|
||||
MOZ_ASSERT(IsOnPaintThread());
|
||||
MOZ_ASSERT(aSyncObject);
|
||||
|
||||
aSyncObject->Synchronize();
|
||||
}
|
||||
|
||||
void
|
||||
PaintThread::PaintContents(CapturedPaintState* aState,
|
||||
|
@ -75,6 +75,14 @@ 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);
|
||||
|
||||
// Sync Runnables need threads to be ref counted,
|
||||
// But this thread lives through the whole process.
|
||||
// We're only temporarily using sync runnables so
|
||||
@ -93,6 +101,7 @@ private:
|
||||
CapturedPaintState* aState,
|
||||
PrepDrawTargetForPaintingCallback aCallback);
|
||||
void EndAsyncPainting(CompositorBridgeChild* aBridge);
|
||||
void SyncTextureData(SyncObjectClient* aSyncObject);
|
||||
|
||||
static StaticAutoPtr<PaintThread> sSingleton;
|
||||
static StaticRefPtr<nsIThread> sThread;
|
||||
|
@ -100,6 +100,7 @@ ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
|
||||
, mTransactionIncomplete(false)
|
||||
, mCompositorMightResample(false)
|
||||
, mNeedsComposite(false)
|
||||
, mTextureSyncOnPaintThread(false)
|
||||
, mPaintSequenceNumber(0)
|
||||
, mDeviceResetSequenceNumber(0)
|
||||
, mForwarder(new ShadowLayerForwarder(this))
|
||||
@ -358,6 +359,7 @@ ClientLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
|
||||
ClientLayer* root = ClientLayer::ToClientLayer(GetRoot());
|
||||
|
||||
mTransactionIncomplete = false;
|
||||
mTextureSyncOnPaintThread = false;
|
||||
|
||||
// Apply pending tree updates before recomputing effective
|
||||
// properties.
|
||||
@ -725,11 +727,17 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
|
||||
TimeStamp start = TimeStamp::Now();
|
||||
|
||||
// Skip the synchronization for buffer since we also skip the painting during
|
||||
// device-reset status.
|
||||
// device-reset status. With OMTP, we have to wait for async paints
|
||||
// before we synchronize and it's done on the paint thread.
|
||||
if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
|
||||
if (mForwarder->GetSyncObject() &&
|
||||
mForwarder->GetSyncObject()->IsSyncObjectValid()) {
|
||||
mForwarder->GetSyncObject()->Synchronize();
|
||||
if (mTextureSyncOnPaintThread) {
|
||||
// We have to wait for all async paints to finish to do this
|
||||
PaintThread::Get()->SynchronizePaintTextures(mForwarder->GetSyncObject());
|
||||
} else {
|
||||
mForwarder->GetSyncObject()->Synchronize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
#include "mozilla/layers/FocusTarget.h" // for FocusTarget
|
||||
#include "mozilla/layers/LayersTypes.h" // for BufferMode, LayersBackend, etc
|
||||
#include "mozilla/layers/PaintThread.h" // For PaintThread
|
||||
#include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder, etc
|
||||
#include "mozilla/layers/APZTestData.h" // for APZTestData
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
@ -158,6 +159,7 @@ public:
|
||||
bool IsRepeatTransaction() { return mIsRepeatTransaction; }
|
||||
|
||||
void SetTransactionIncomplete() { mTransactionIncomplete = true; }
|
||||
void SetNeedTextureSyncOnPaintThread() { mTextureSyncOnPaintThread = true; }
|
||||
|
||||
bool HasShadowTarget() { return !!mShadowTarget; }
|
||||
|
||||
@ -349,6 +351,7 @@ private:
|
||||
bool mTransactionIncomplete;
|
||||
bool mCompositorMightResample;
|
||||
bool mNeedsComposite;
|
||||
bool mTextureSyncOnPaintThread;
|
||||
|
||||
// An incrementing sequence number for paints.
|
||||
// Incremented in BeginTransaction(), but not for repeat transactions.
|
||||
|
@ -268,6 +268,7 @@ ClientPaintedLayer::PaintOffMainThread()
|
||||
|
||||
if (didUpdate) {
|
||||
UpdateContentClient(state);
|
||||
ClientManager()->SetNeedTextureSyncOnPaintThread();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1623,6 +1623,7 @@ SyncObjectD3D11Host::Synchronize()
|
||||
|
||||
SyncObjectD3D11Client::SyncObjectD3D11Client(SyncHandle aSyncHandle, ID3D11Device* aDevice)
|
||||
: mSyncHandle(aSyncHandle)
|
||||
, mSyncLock("SyncObjectD3D11")
|
||||
{
|
||||
if (!aDevice) {
|
||||
mDevice = DeviceManagerDx::Get()->GetContentDevice();
|
||||
@ -1678,9 +1679,19 @@ SyncObjectD3D11Client::IsSyncObjectValid()
|
||||
return true;
|
||||
}
|
||||
|
||||
// We have only 1 sync object. As a thing that somehow works,
|
||||
// we copy each of the textures that need to be synced with the compositor
|
||||
// into our sync object and only use a lock for this sync object.
|
||||
// This way, we don't have to sync every texture we send to the compositor.
|
||||
// We only have to do this once per transaction.
|
||||
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.
|
||||
MutexAutoLock syncLock(mSyncLock);
|
||||
|
||||
if (!mSyncedTextures.size()) {
|
||||
return;
|
||||
}
|
||||
|
@ -484,6 +484,7 @@ private:
|
||||
RefPtr<ID3D11Texture2D> mSyncTexture;
|
||||
RefPtr<IDXGIKeyedMutex> mKeyedMutex;
|
||||
std::vector<ID3D11Texture2D*> mSyncedTextures;
|
||||
Mutex mSyncLock;
|
||||
};
|
||||
|
||||
inline uint32_t GetMaxTextureSizeForFeatureLevel(D3D_FEATURE_LEVEL aFeatureLevel)
|
||||
|
Loading…
Reference in New Issue
Block a user