Don't assert about borrowed DT refcounts when async painting. (bug 1381393, r=mattwoodrow)

This commit is contained in:
David Anderson 2017-07-25 22:38:33 -07:00
parent 4ccde3c049
commit 3bacd995dc
5 changed files with 52 additions and 9 deletions

View File

@ -252,7 +252,12 @@ enum class OpenMode : uint8_t {
OPEN_WRITE = 0x2,
OPEN_READ_WRITE = OPEN_READ|OPEN_WRITE,
OPEN_READ_ONLY = OPEN_READ,
OPEN_WRITE_ONLY = OPEN_WRITE
OPEN_WRITE_ONLY = OPEN_WRITE,
// This is only used in conjunction with OMTP to indicate that the DrawTarget
// that is being borrowed will be painted asynchronously, and so will outlive
// the write lock.
OPEN_ASYNC_WRITE = 0x04
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(OpenMode)

View File

@ -185,7 +185,7 @@ ClientPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUp
bool
ClientPaintedLayer::PaintOffMainThread()
{
mContentClient->BeginPaint();
mContentClient->BeginAsyncPaint();
uint32_t flags = GetPaintFlags();

View File

@ -91,9 +91,16 @@ ContentClient::CreateContentClient(CompositableForwarder* aForwarder)
return MakeAndAddRef<ContentClientSingleBuffered>(aForwarder);
}
void
ContentClient::BeginAsyncPaint()
{
mInAsyncPaint = true;
}
void
ContentClient::EndPaint(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates)
{
mInAsyncPaint = false;
}
void
@ -238,6 +245,13 @@ ContentClientRemoteBuffer::BeginPaint()
}
}
void
ContentClientRemoteBuffer::BeginAsyncPaint()
{
BeginPaint();
mInAsyncPaint = true;
}
void
ContentClientRemoteBuffer::EndPaint(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates)
{
@ -349,14 +363,19 @@ ContentClientRemoteBuffer::CreateBuffer(ContentType aType,
return;
}
OpenMode mode = OpenMode::OPEN_READ_WRITE;
if (mInAsyncPaint) {
mode |= OpenMode::OPEN_ASYNC_WRITE;
}
// We just created the textures and we are about to get their draw targets
// so we have to lock them here.
DebugOnly<bool> locked = mTextureClient->Lock(OpenMode::OPEN_READ_WRITE);
DebugOnly<bool> locked = mTextureClient->Lock(mode);
MOZ_ASSERT(locked, "Could not lock the TextureClient");
*aBlackDT = mTextureClient->BorrowDrawTarget();
if (aFlags & BUFFER_COMPONENT_ALPHA) {
locked = mTextureClientOnWhite->Lock(OpenMode::OPEN_READ_WRITE);
locked = mTextureClientOnWhite->Lock(mode);
MOZ_ASSERT(locked, "Could not lock the second TextureClient for component alpha");
*aWhiteDT = mTextureClientOnWhite->BorrowDrawTarget();
@ -430,14 +449,18 @@ ContentClientRemoteBuffer::SwapBuffers(const nsIntRegion& aFrontUpdatedRegion)
bool
ContentClientRemoteBuffer::LockBuffers()
{
OpenMode mode = OpenMode::OPEN_READ_WRITE;
if (mInAsyncPaint) {
mode |= OpenMode::OPEN_ASYNC_WRITE;
}
if (mTextureClient) {
bool locked = mTextureClient->Lock(OpenMode::OPEN_READ_WRITE);
bool locked = mTextureClient->Lock(mode);
if (!locked) {
return false;
}
}
if (mTextureClientOnWhite) {
bool locked = mTextureClientOnWhite->Lock(OpenMode::OPEN_READ_WRITE);
bool locked = mTextureClientOnWhite->Lock(mode);
if (!locked) {
UnlockBuffers();
return false;
@ -553,6 +576,13 @@ ContentClientDoubleBuffered::BeginPaint()
mBufferRotation = mFrontBufferRotation;
}
void
ContentClientDoubleBuffered::BeginAsyncPaint()
{
BeginPaint();
mInAsyncPaint = true;
}
// Sync front/back buffers content
// After executing, the new back buffer has the same (interesting) pixels as
// the new front buffer, and mValidRegion et al. are correct wrt the new

View File

@ -82,7 +82,8 @@ public:
static already_AddRefed<ContentClient> CreateContentClient(CompositableForwarder* aFwd);
explicit ContentClient(CompositableForwarder* aForwarder)
: CompositableClient(aForwarder)
: CompositableClient(aForwarder),
mInAsyncPaint(false)
{}
virtual ~ContentClient()
{}
@ -103,7 +104,11 @@ public:
// call before and after painting into this content client
virtual void BeginPaint() {}
virtual void BeginAsyncPaint();
virtual void EndPaint(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates = nullptr);
protected:
bool mInAsyncPaint;
};
/**
@ -243,6 +248,7 @@ public:
* are affected by mapping/unmapping.
*/
virtual void BeginPaint() override;
virtual void BeginAsyncPaint() override;
virtual void EndPaint(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates = nullptr) override;
virtual void Updated(const nsIntRegion& aRegionToDraw,
@ -347,6 +353,7 @@ public:
virtual void SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) override;
virtual void BeginPaint() override;
virtual void BeginAsyncPaint() override;
virtual void FinalizeFrame(const nsIntRegion& aRegionToDraw) override;

View File

@ -509,7 +509,7 @@ TextureClient::Lock(OpenMode aMode)
auto format = GetFormat();
if (mIsLocked && CanExposeDrawTarget() &&
aMode == OpenMode::OPEN_READ_WRITE &&
(aMode & OpenMode::OPEN_READ_WRITE) == OpenMode::OPEN_READ_WRITE &&
NS_IsMainThread() &&
// the formats that we apparently expect, in the cairo backend. Any other
// format will trigger an assertion in GfxFormatToCairoFormat.
@ -557,7 +557,8 @@ TextureClient::Unlock()
mBorrowedDrawTarget->DetachAllSnapshots();
// If this assertion is hit, it means something is holding a strong reference
// to our DrawTarget externally, which is not allowed.
MOZ_ASSERT(mBorrowedDrawTarget->refCount() <= mExpectedDtRefs);
MOZ_ASSERT_IF(!(mOpenMode & OpenMode::OPEN_ASYNC_WRITE),
mBorrowedDrawTarget->refCount() <= mExpectedDtRefs);
mBorrowedDrawTarget = nullptr;
}