зеркало из https://github.com/mozilla/gecko-dev.git
Refactor NotifyBeginAsyncPaint logic to not be repeated (bug 1422392, r=dvander)
MozReview-Commit-ID: B8BZCxYErjv --HG-- extra : rebase_source : 17f022a10b484f5ae9ac6de9d376075c894f7226
This commit is contained in:
Родитель
98e347bbf9
Коммит
14e019993c
|
@ -51,49 +51,6 @@ CapturedBufferState::PrepareBuffer()
|
|||
(!mBufferInitialize || mBufferInitialize->CopyBuffer());
|
||||
}
|
||||
|
||||
void
|
||||
CapturedBufferState::GetTextureClients(nsTArray<RefPtr<TextureClient>>& aTextureClients)
|
||||
{
|
||||
if (mBufferFinalize) {
|
||||
if (TextureClient* source = mBufferFinalize->mSource->GetClient()) {
|
||||
aTextureClients.AppendElement(source);
|
||||
}
|
||||
if (TextureClient* sourceOnWhite = mBufferFinalize->mSource->GetClientOnWhite()) {
|
||||
aTextureClients.AppendElement(sourceOnWhite);
|
||||
}
|
||||
if (TextureClient* destination = mBufferFinalize->mDestination->GetClient()) {
|
||||
aTextureClients.AppendElement(destination);
|
||||
}
|
||||
if (TextureClient* destinationOnWhite = mBufferFinalize->mDestination->GetClientOnWhite()) {
|
||||
aTextureClients.AppendElement(destinationOnWhite);
|
||||
}
|
||||
}
|
||||
|
||||
if (mBufferUnrotate) {
|
||||
if (TextureClient* client = mBufferUnrotate->mBuffer->GetClient()) {
|
||||
aTextureClients.AppendElement(client);
|
||||
}
|
||||
if (TextureClient* clientOnWhite = mBufferUnrotate->mBuffer->GetClientOnWhite()) {
|
||||
aTextureClients.AppendElement(clientOnWhite);
|
||||
}
|
||||
}
|
||||
|
||||
if (mBufferInitialize) {
|
||||
if (TextureClient* source = mBufferInitialize->mSource->GetClient()) {
|
||||
aTextureClients.AppendElement(source);
|
||||
}
|
||||
if (TextureClient* sourceOnWhite = mBufferInitialize->mSource->GetClientOnWhite()) {
|
||||
aTextureClients.AppendElement(sourceOnWhite);
|
||||
}
|
||||
if (TextureClient* destination = mBufferInitialize->mDestination->GetClient()) {
|
||||
aTextureClients.AppendElement(destination);
|
||||
}
|
||||
if (TextureClient* destinationOnWhite = mBufferInitialize->mDestination->GetClientOnWhite()) {
|
||||
aTextureClients.AppendElement(destinationOnWhite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CapturedTiledPaintState::Copy::CopyBuffer()
|
||||
{
|
||||
|
@ -283,7 +240,7 @@ PaintThread::PrepareBuffer(CapturedBufferState* aState)
|
|||
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
||||
RefPtr<CapturedBufferState> state(aState);
|
||||
|
||||
cbc->NotifyBeginAsyncPrepareBuffer(state);
|
||||
cbc->NotifyBeginAsyncPaint(state);
|
||||
|
||||
RefPtr<PaintThread> self = this;
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PrepareBuffer",
|
||||
|
@ -316,7 +273,7 @@ PaintThread::AsyncPrepareBuffer(CompositorBridgeChild* aBridge,
|
|||
gfxCriticalNote << "Failed to prepare buffers on the paint thread.";
|
||||
}
|
||||
|
||||
aBridge->NotifyFinishedAsyncPrepareBuffer(aState);
|
||||
aBridge->NotifyFinishedAsyncPaint(aState);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -392,7 +349,7 @@ PaintThread::PaintTiledContents(CapturedTiledPaintState* aState)
|
|||
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
||||
RefPtr<CapturedTiledPaintState> state(aState);
|
||||
|
||||
cbc->NotifyBeginAsyncTiledPaint(state);
|
||||
cbc->NotifyBeginAsyncPaint(state);
|
||||
|
||||
RefPtr<PaintThread> self = this;
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintTiledContents",
|
||||
|
@ -446,7 +403,7 @@ PaintThread::AsyncPaintTiledContents(CompositorBridgeChild* aBridge,
|
|||
NS_ReleaseOnMainThreadSystemGroup("CapturePaintState::DrawTargetCapture", aState->mCapture.forget());
|
||||
}
|
||||
|
||||
aBridge->NotifyFinishedAsyncTiledPaint(aState);
|
||||
aBridge->NotifyFinishedAsyncPaint(aState);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -44,6 +44,21 @@ public:
|
|||
, mContentType(aContentType)
|
||||
{}
|
||||
|
||||
template<typename F>
|
||||
void ForEachTextureClient(F aClosure) const
|
||||
{
|
||||
aClosure(mTextureClient);
|
||||
if (mTextureClientOnWhite) {
|
||||
aClosure(mTextureClientOnWhite);
|
||||
}
|
||||
}
|
||||
|
||||
void DropTextureClients()
|
||||
{
|
||||
mTextureClient = nullptr;
|
||||
mTextureClientOnWhite = nullptr;
|
||||
}
|
||||
|
||||
nsIntRegion mRegionToDraw;
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
RefPtr<TextureClient> mTextureClientOnWhite;
|
||||
|
@ -100,7 +115,56 @@ public:
|
|||
* for the frame.
|
||||
*/
|
||||
bool PrepareBuffer();
|
||||
void GetTextureClients(nsTArray<RefPtr<TextureClient>>& aTextureClients);
|
||||
|
||||
template<typename F>
|
||||
void ForEachTextureClient(F aClosure) const
|
||||
{
|
||||
if (mBufferFinalize) {
|
||||
if (TextureClient* source = mBufferFinalize->mSource->GetClient()) {
|
||||
aClosure(source);
|
||||
}
|
||||
if (TextureClient* sourceOnWhite = mBufferFinalize->mSource->GetClientOnWhite()) {
|
||||
aClosure(sourceOnWhite);
|
||||
}
|
||||
if (TextureClient* destination = mBufferFinalize->mDestination->GetClient()) {
|
||||
aClosure(destination);
|
||||
}
|
||||
if (TextureClient* destinationOnWhite = mBufferFinalize->mDestination->GetClientOnWhite()) {
|
||||
aClosure(destinationOnWhite);
|
||||
}
|
||||
}
|
||||
|
||||
if (mBufferUnrotate) {
|
||||
if (TextureClient* client = mBufferUnrotate->mBuffer->GetClient()) {
|
||||
aClosure(client);
|
||||
}
|
||||
if (TextureClient* clientOnWhite = mBufferUnrotate->mBuffer->GetClientOnWhite()) {
|
||||
aClosure(clientOnWhite);
|
||||
}
|
||||
}
|
||||
|
||||
if (mBufferInitialize) {
|
||||
if (TextureClient* source = mBufferInitialize->mSource->GetClient()) {
|
||||
aClosure(source);
|
||||
}
|
||||
if (TextureClient* sourceOnWhite = mBufferInitialize->mSource->GetClientOnWhite()) {
|
||||
aClosure(sourceOnWhite);
|
||||
}
|
||||
if (TextureClient* destination = mBufferInitialize->mDestination->GetClient()) {
|
||||
aClosure(destination);
|
||||
}
|
||||
if (TextureClient* destinationOnWhite = mBufferInitialize->mDestination->GetClientOnWhite()) {
|
||||
aClosure(destinationOnWhite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DropTextureClients()
|
||||
{
|
||||
mBufferFinalize = Nothing();
|
||||
mBufferUnrotate = Nothing();
|
||||
mBufferInitialize = Nothing();
|
||||
}
|
||||
|
||||
Maybe<Copy> mBufferFinalize;
|
||||
Maybe<Unrotate> mBufferUnrotate;
|
||||
|
@ -158,6 +222,19 @@ public:
|
|||
, mCapture(aCapture)
|
||||
{}
|
||||
|
||||
template<typename F>
|
||||
void ForEachTextureClient(F aClosure) const
|
||||
{
|
||||
for (auto client : mClients) {
|
||||
aClosure(client);
|
||||
}
|
||||
}
|
||||
|
||||
void DropTextureClients()
|
||||
{
|
||||
mClients.clear();
|
||||
}
|
||||
|
||||
RefPtr<gfx::DrawTarget> mTargetTiled;
|
||||
RefPtr<gfx::DrawTargetCapture> mCapture;
|
||||
std::vector<Copy> mCopies;
|
||||
|
|
|
@ -1192,123 +1192,6 @@ CompositorBridgeChild::FlushAsyncPaints()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyBeginAsyncPrepareBuffer(CapturedBufferState* aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
// We must not be waiting for paints (or buffer copying) to complete yet. This
|
||||
// would imply we started a new paint without waiting for a previous one, which
|
||||
// could lead to incorrect rendering or IPDL deadlocks.
|
||||
MOZ_ASSERT(!mIsDelayingForAsyncPaints);
|
||||
|
||||
mOutstandingAsyncPaints++;
|
||||
|
||||
// Mark texture clients that they are being used for async painting, and
|
||||
// make sure we hold them alive on the main thread.
|
||||
aState->GetTextureClients(mTextureClientsForAsyncPaint);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyFinishedAsyncPrepareBuffer(CapturedBufferState* aState)
|
||||
{
|
||||
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
mOutstandingAsyncPaints--;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyBeginAsyncPaint(CapturedPaintState* aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
// We must not be waiting for paints to complete yet. This would imply we
|
||||
// started a new paint without waiting for a previous one, which could lead to
|
||||
// incorrect rendering or IPDL deadlocks.
|
||||
MOZ_ASSERT(!mIsDelayingForAsyncPaints);
|
||||
|
||||
mOutstandingAsyncPaints++;
|
||||
|
||||
// Mark texture clients that they are being used for async painting, and
|
||||
// make sure we hold them alive on the main thread.
|
||||
aState->mTextureClient->AddPaintThreadRef();
|
||||
mTextureClientsForAsyncPaint.AppendElement(aState->mTextureClient);
|
||||
if (aState->mTextureClientOnWhite) {
|
||||
aState->mTextureClientOnWhite->AddPaintThreadRef();
|
||||
mTextureClientsForAsyncPaint.AppendElement(aState->mTextureClientOnWhite);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyFinishedAsyncPaint(CapturedPaintState* aState)
|
||||
{
|
||||
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
mOutstandingAsyncPaints--;
|
||||
|
||||
// These textures should be held alive on the main thread. The ref we
|
||||
// captured should not be the final ref.
|
||||
MOZ_RELEASE_ASSERT(!aState->mTextureClient->HasOneRef());
|
||||
|
||||
// It's now safe to drop the paint thread ref we're holding, since we've
|
||||
// flushed writes to the underlying TextureData. Note that we keep the
|
||||
// main thread ref around until FlushAsyncPaints is called, lazily ensuring
|
||||
// the Release occurs on the main thread (versus a message in the event
|
||||
// loop).
|
||||
//
|
||||
// Note that we zap our ref immediately after. Otherwise, the main thread
|
||||
// could wake up when we drop the lock, and we could still be holding a ref
|
||||
// on the paint thread. If this causes TextureClient to destroy then it will
|
||||
// be destroyed on the wrong thread.
|
||||
aState->mTextureClient->DropPaintThreadRef();
|
||||
aState->mTextureClient = nullptr;
|
||||
if (aState->mTextureClientOnWhite) {
|
||||
aState->mTextureClientOnWhite->DropPaintThreadRef();
|
||||
aState->mTextureClientOnWhite = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyBeginAsyncTiledPaint(CapturedTiledPaintState* aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
// We must not be waiting for paints to complete yet. This would imply we
|
||||
// started a new paint without waiting for a previous one, which could lead to
|
||||
// incorrect rendering or IPDL deadlocks.
|
||||
MOZ_ASSERT(!mIsDelayingForAsyncPaints);
|
||||
|
||||
mOutstandingAsyncPaints++;
|
||||
|
||||
// Mark texture clients that they are being used for async painting, and
|
||||
// make sure we hold them alive on the main thread.
|
||||
for (auto& client : aState->mClients) {
|
||||
mTextureClientsForAsyncPaint.AppendElement(client);
|
||||
}
|
||||
aState->mClients.clear();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyFinishedAsyncTiledPaint(CapturedTiledPaintState* aState)
|
||||
{
|
||||
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
mOutstandingAsyncPaints--;
|
||||
|
||||
aState->mTargetTiled = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyBeginAsyncEndLayerTransaction()
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/layers/PCompositorBridgeChild.h"
|
||||
#include "mozilla/layers/TextureForwarder.h" // for TextureForwarder
|
||||
#include "mozilla/layers/PaintThread.h" // for PaintThread
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
#include "nsClassHashtable.h" // for nsClassHashtable
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
@ -45,9 +46,6 @@ class CompositorManagerChild;
|
|||
class CompositorOptions;
|
||||
class TextureClient;
|
||||
class TextureClientPool;
|
||||
class CapturedBufferState;
|
||||
class CapturedPaintState;
|
||||
class CapturedTiledPaintState;
|
||||
struct FrameMetrics;
|
||||
|
||||
class CompositorBridgeChild final : public PCompositorBridgeChild,
|
||||
|
@ -225,29 +223,45 @@ public:
|
|||
// operation completes.
|
||||
void FlushAsyncPaints();
|
||||
|
||||
// Must only be called from the main thread. Notifies the CompositorBridge
|
||||
// that the paint thread is going to begin preparing a buffer asynchronously.
|
||||
void NotifyBeginAsyncPrepareBuffer(CapturedBufferState* aState);
|
||||
|
||||
// Must only be called from the paint thread. Notifies the CompositorBridge
|
||||
// that the paint thread has finished an asynchronous buffer prepare.
|
||||
void NotifyFinishedAsyncPrepareBuffer(CapturedBufferState* aState);
|
||||
|
||||
// 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);
|
||||
template<typename CapturedState>
|
||||
void NotifyBeginAsyncPaint(CapturedState& aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
// We must not be waiting for paints or buffer copying to complete yet. This
|
||||
// would imply we started a new paint without waiting for a previous one, which
|
||||
// could lead to incorrect rendering or IPDL deadlocks.
|
||||
MOZ_ASSERT(!mIsDelayingForAsyncPaints);
|
||||
|
||||
mOutstandingAsyncPaints++;
|
||||
|
||||
// Mark texture clients that they are being used for async painting, and
|
||||
// make sure we hold them alive on the main thread.
|
||||
aState->ForEachTextureClient([this] (auto aClient) {
|
||||
aClient->AddPaintThreadRef();
|
||||
mTextureClientsForAsyncPaint.AppendElement(aClient);
|
||||
});
|
||||
}
|
||||
|
||||
// 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);
|
||||
template<typename CapturedState>
|
||||
void NotifyFinishedAsyncPaint(CapturedState& aState)
|
||||
{
|
||||
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
||||
|
||||
// Must only be called from the main thread. Notifies the CompositorBridge
|
||||
// that the paint thread is going to begin painting asynchronously.
|
||||
void NotifyBeginAsyncTiledPaint(CapturedTiledPaintState* aState);
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
mOutstandingAsyncPaints--;
|
||||
|
||||
// Must only be called from the paint thread. Notifies the CompositorBridge
|
||||
// that the paint thread has finished an asynchronous paint request.
|
||||
void NotifyFinishedAsyncTiledPaint(CapturedTiledPaintState* aState);
|
||||
aState->ForEachTextureClient([] (auto aClient) {
|
||||
aClient->DropPaintThreadRef();
|
||||
});
|
||||
aState->DropTextureClients();
|
||||
}
|
||||
|
||||
// Must only be called from the main thread. Notifies the CompositorBridge
|
||||
// that the paint thread is going to perform texture synchronization at the
|
||||
|
|
Загрузка…
Ссылка в новой задаче