mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 08:42:13 +00:00
Bug 1386966. Coalesce OMTP drawtarget flushes until finished painting a layer. r=dvander
This commit is contained in:
parent
52ffe4157f
commit
cddef9fa41
@ -42,21 +42,13 @@ struct MOZ_STACK_CLASS AutoCapturedPaintSetup
|
||||
mTarget->SetTransform(mOldTransform);
|
||||
mTarget->SetPermitSubpixelAA(mRestorePermitsSubpixelAA);
|
||||
|
||||
// Textureclient forces a flush once we "end paint", so
|
||||
// users of this texture expect all the drawing to be complete.
|
||||
// Force a flush now.
|
||||
// TODO: This might be a performance bottleneck because
|
||||
// main thread painting only does one flush at the end of all paints
|
||||
// whereas we force a flush after each draw target paint.
|
||||
mTarget->Flush();
|
||||
|
||||
if (mBridge) {
|
||||
mBridge->NotifyFinishedAsyncPaint(mState);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<CapturedPaintState> mState;
|
||||
DrawTarget* mTarget;
|
||||
RefPtr<DrawTarget> mTarget;
|
||||
bool mRestorePermitsSubpixelAA;
|
||||
Matrix mOldTransform;
|
||||
RefPtr<CompositorBridgeChild> mBridge;
|
||||
@ -169,8 +161,53 @@ PaintThread::PaintContentsAsync(CompositorBridgeChild* aBridge,
|
||||
|
||||
// Draw all the things into the actual dest target.
|
||||
target->DrawCapturedDT(capture, Matrix());
|
||||
if (!mDrawTargetsToFlush.Contains(target)) {
|
||||
mDrawTargetsToFlush.AppendElement(target);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
self->EndAsyncPainting(cbc);
|
||||
});
|
||||
|
||||
if (cbc) {
|
||||
sThread->Dispatch(task.forget());
|
||||
} else {
|
||||
SyncRunnable::DispatchToThread(sThread, task);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PaintThread::EndAsyncPainting(CompositorBridgeChild* aBridge)
|
||||
{
|
||||
MOZ_ASSERT(IsOnPaintThread());
|
||||
// Textureclient forces a flush once we "end paint", so
|
||||
// users of this texture expect all the drawing to be complete.
|
||||
// Force a flush now.
|
||||
for (size_t i = 0; i < mDrawTargetsToFlush.Length(); i++) {
|
||||
mDrawTargetsToFlush[i]->Flush();
|
||||
}
|
||||
|
||||
mDrawTargetsToFlush.Clear();
|
||||
|
||||
if (aBridge) {
|
||||
aBridge->NotifyFinishedAsyncPaintLayer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PaintThread::PaintContents(CapturedPaintState* aState,
|
||||
PrepDrawTargetForPaintingCallback aCallback)
|
||||
|
@ -70,6 +70,11 @@ public:
|
||||
void PaintContents(CapturedPaintState* aState,
|
||||
PrepDrawTargetForPaintingCallback aCallback);
|
||||
|
||||
// To be called on the main thread. Signifies that the current
|
||||
// batch of CapturedPaintStates* for PaintContents have been recorded
|
||||
// and the main thread is finished recording this layer.
|
||||
void FinishedLayerBatch();
|
||||
|
||||
// Sync Runnables need threads to be ref counted,
|
||||
// But this thread lives through the whole process.
|
||||
// We're only temporarily using sync runnables so
|
||||
@ -87,10 +92,15 @@ private:
|
||||
void PaintContentsAsync(CompositorBridgeChild* aBridge,
|
||||
CapturedPaintState* aState,
|
||||
PrepDrawTargetForPaintingCallback aCallback);
|
||||
void EndAsyncPainting(CompositorBridgeChild* aBridge);
|
||||
|
||||
static StaticAutoPtr<PaintThread> sSingleton;
|
||||
static StaticRefPtr<nsIThread> sThread;
|
||||
static PlatformThreadId sThreadId;
|
||||
|
||||
// This shouldn't be very many elements, so a list should be fine.
|
||||
// Should only be accessed on the paint thread.
|
||||
nsTArray<RefPtr<gfx::DrawTarget>> mDrawTargetsToFlush;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -262,6 +262,8 @@ ClientPaintedLayer::PaintOffMainThread()
|
||||
|
||||
didUpdate = true;
|
||||
}
|
||||
|
||||
PaintThread::Get()->FinishedLayerBatch();
|
||||
mContentClient->EndPaint(nullptr);
|
||||
|
||||
if (didUpdate) {
|
||||
|
@ -1186,6 +1186,13 @@ CompositorBridgeChild::NotifyFinishedAsyncPaint(CapturedPaintState* aState)
|
||||
aState->mTextureClientOnWhite->DropPaintThreadRef();
|
||||
aState->mTextureClientOnWhite = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyFinishedAsyncPaintLayer()
|
||||
{
|
||||
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
// 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
|
||||
|
@ -226,10 +226,6 @@ public:
|
||||
// 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);
|
||||
|
||||
// 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.
|
||||
@ -240,6 +236,15 @@ public:
|
||||
// operation completes.
|
||||
void FlushAsyncPaints();
|
||||
|
||||
// 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);
|
||||
|
||||
// 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();
|
||||
|
||||
private:
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
virtual ~CompositorBridgeChild();
|
||||
|
Loading…
Reference in New Issue
Block a user