Bug 1167235 - Part 2 - Detach DrawTarget snapshots before unlocking TextureClient. r=Bas

This commit is contained in:
Nicolas Silva 2016-07-01 10:58:13 +02:00
parent 55982c743c
commit 10809f5f78
15 changed files with 54 additions and 2 deletions

View File

@ -1175,6 +1175,17 @@ public:
return mPermitSubpixelAA;
}
/**
* Ensures that no snapshot is still pointing to this DrawTarget's surface data.
*
* This can be useful if the DrawTarget is wrapped around data that it does not
* own, and for some reason the owner of the data has to make it temporarily
* unavailable without the DrawTarget knowing about it.
* This can cause costly surface copies, so it should not be used without a
* a good reason.
*/
virtual void DetachAllSnapshots() = 0;
#ifdef USE_SKIA_GPU
virtual bool InitWithGrContext(GrContext* aGrContext,
const IntSize &aSize,

View File

@ -128,6 +128,7 @@ public:
virtual DrawTargetType GetType() const override;
virtual BackendType GetBackendType() const override;
virtual already_AddRefed<SourceSurface> Snapshot() override;
virtual void DetachAllSnapshots() override { MarkChanged(); }
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,

View File

@ -177,6 +177,8 @@ public:
virtual void SetTransform(const Matrix& aTransform) override;
virtual void DetachAllSnapshots() override { MarkSnapshotIndependent(); }
// Call to set up aContext for drawing (with the current transform, etc).
// Pass the path you're going to be using if you have one.
// Implicitly calls WillChange(aPath).

View File

@ -45,6 +45,10 @@ DrawTargetCaptureImpl::Snapshot()
return dt->Snapshot();
}
void
DrawTargetCaptureImpl::DetachAllSnapshots()
{}
#define AppendCommand(arg) new (AppendToCommandList<arg>()) arg
void

View File

@ -28,6 +28,9 @@ public:
virtual DrawTargetType GetType() const { return mRefDT->GetType(); }
virtual already_AddRefed<SourceSurface> Snapshot();
virtual void DetachAllSnapshots();
virtual IntSize GetSize() { return mSize; }
virtual void Flush() {}

View File

@ -127,6 +127,8 @@ public:
virtual void *GetNativeSurface(NativeSurfaceType aType) override { return nullptr; }
virtual void DetachAllSnapshots() override { MarkChanged(); }
bool Init(const IntSize &aSize, SurfaceFormat aFormat);
bool Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat);
uint32_t GetByteSize() const;

View File

@ -86,6 +86,13 @@ public:
bool mPatternsInitialized;
};
void
DrawTargetDual::DetachAllSnapshots()
{
mA->DetachAllSnapshots();
mB->DetachAllSnapshots();
}
void
DrawTargetDual::DrawSurface(SourceSurface *aSurface, const Rect &aDest, const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions)

View File

@ -49,7 +49,9 @@ public:
return MakeAndAddRef<SourceSurfaceDual>(mA, mB);
}
virtual IntSize GetSize() override { return mA->GetSize(); }
virtual void DetachAllSnapshots() override;
FORWARD_FUNCTION(Flush)
FORWARD_FUNCTION1(PushClip, const Path *, aPath)
FORWARD_FUNCTION1(PushClipRect, const Rect &, aRect)

View File

@ -477,6 +477,12 @@ DrawTargetRecording::Snapshot()
return retSurf.forget();
}
void
DrawTargetRecording::DetachAllSnapshots()
{
mFinalDT->DetachAllSnapshots();
}
void
DrawTargetRecording::DrawSurface(SourceSurface *aSurface,
const Rect &aDest,

View File

@ -37,6 +37,8 @@ public:
virtual already_AddRefed<SourceSurface> Snapshot() override;
virtual void DetachAllSnapshots() override;
virtual IntSize GetSize() override { return mFinalDT->GetSize(); }
/* Ensure that the DrawTarget backend has flushed all drawing operations to

View File

@ -125,6 +125,7 @@ public:
virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
virtual void SetTransform(const Matrix &aTransform) override;
virtual void *GetNativeSurface(NativeSurfaceType aType) override;
virtual void DetachAllSnapshots() override { MarkChanged(); }
bool Init(const IntSize &aSize, SurfaceFormat aFormat);
void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);

View File

@ -54,6 +54,10 @@ DrawTargetTiled::Snapshot()
return MakeAndAddRef<SnapshotTiled>(mTiles, mRect);
}
void
DrawTargetTiled::DetachAllSnapshots()
{}
// Skip the mClippedOut check since this is only used for Flush() which
// should happen even if we're clipped.
#define TILED_COMMAND(command) \

View File

@ -41,6 +41,7 @@ public:
virtual DrawTargetType GetType() const override { return mTiles[0].mDrawTarget->GetType(); }
virtual BackendType GetBackendType() const override { return mTiles[0].mDrawTarget->GetBackendType(); }
virtual already_AddRefed<SourceSurface> Snapshot() override;
virtual void DetachAllSnapshots() override;
virtual IntSize GetSize() override {
MOZ_ASSERT(mRect.width > 0 && mRect.height > 0);
return IntSize(mRect.XMost(), mRect.YMost());

View File

@ -494,7 +494,6 @@ TextureClient::Unlock()
}
if (mBorrowedDrawTarget) {
MOZ_ASSERT(mBorrowedDrawTarget->refCount() <= mExpectedDtRefs);
if (mOpenMode & OpenMode::OPEN_WRITE) {
mBorrowedDrawTarget->Flush();
if (mReadbackSink && !mData->ReadBack(mReadbackSink)) {
@ -505,6 +504,12 @@ TextureClient::Unlock()
mReadbackSink->ProcessReadback(dataSurf);
}
}
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);
mBorrowedDrawTarget = nullptr;
}

View File

@ -397,6 +397,7 @@ D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocation
void
D3D11TextureData::Deallocate(ClientIPCAllocator* aAllocator)
{
mDrawTarget = nullptr;
mTexture = nullptr;
}