From 4d9d8d5d59259699150dc07602fc732eba9a1b93 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 21 Nov 2017 10:52:38 -0500 Subject: [PATCH] Bug 1416864 - Synchronize how snapshots detach in DrawTargetD2D1. r=bas --- gfx/2d/DrawTargetD2D1.cpp | 5 +++++ gfx/2d/DrawTargetD2D1.h | 1 + gfx/2d/SourceSurfaceD2D1.cpp | 6 ++++++ gfx/2d/SourceSurfaceD2D1.h | 1 + 4 files changed, 13 insertions(+) diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index 94a14e0b8d38..70188cbd60ff 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -57,6 +57,7 @@ DrawTargetD2D1::~DrawTargetD2D1() PopAllClips(); if (mSnapshot) { + MutexAutoLock lock(*mSnapshotLock); // We may hold the only reference. MarkIndependent will clear mSnapshot; // keep the snapshot object alive so it doesn't get destroyed while // MarkIndependent is running. @@ -90,6 +91,9 @@ DrawTargetD2D1::~DrawTargetD2D1() already_AddRefed DrawTargetD2D1::Snapshot() { + if (!mSnapshotLock) { + mSnapshotLock = make_shared("DrawTargetD2D1::mSnapshotLock"); + } if (mSnapshot) { RefPtr snapshot(mSnapshot); return snapshot.forget(); @@ -1274,6 +1278,7 @@ void DrawTargetD2D1::MarkChanged() { if (mSnapshot) { + MutexAutoLock lock(*mSnapshotLock); if (mSnapshot->hasOneRef()) { // Just destroy it, since no-one else knows about it. mSnapshot = nullptr; diff --git a/gfx/2d/DrawTargetD2D1.h b/gfx/2d/DrawTargetD2D1.h index 0b98657d7f65..3199eb30294e 100644 --- a/gfx/2d/DrawTargetD2D1.h +++ b/gfx/2d/DrawTargetD2D1.h @@ -280,6 +280,7 @@ private: // The latest snapshot of this surface. This needs to be told when this // target is modified. We keep it alive as a cache. RefPtr mSnapshot; + std::shared_ptr mSnapshotLock; // A list of targets we need to flush when we're modified. TargetSet mDependentTargets; // A list of targets which have this object in their mDependentTargets set diff --git a/gfx/2d/SourceSurfaceD2D1.cpp b/gfx/2d/SourceSurfaceD2D1.cpp index d4b6bc6282bb..0a1238a0f4d2 100644 --- a/gfx/2d/SourceSurfaceD2D1.cpp +++ b/gfx/2d/SourceSurfaceD2D1.cpp @@ -23,6 +23,9 @@ SourceSurfaceD2D1::SourceSurfaceD2D1(ID2D1Image *aImage, ID2D1DeviceContext *aDC mFormat = aFormat; mSize = aSize; + if (aDT) { + mSnapshotLock = aDT->mSnapshotLock; + } } SourceSurfaceD2D1::~SourceSurfaceD2D1() @@ -109,6 +112,9 @@ SourceSurfaceD2D1::EnsureRealizedBitmap() void SourceSurfaceD2D1::DrawTargetWillChange() { + MOZ_ASSERT(mSnapshotLock); + mSnapshotLock->AssertCurrentThreadOwns(); + // At this point in time this should always be true here. MOZ_ASSERT(mRealizedBitmap); diff --git a/gfx/2d/SourceSurfaceD2D1.h b/gfx/2d/SourceSurfaceD2D1.h index 7620637f8ee4..0d99a27ddea3 100644 --- a/gfx/2d/SourceSurfaceD2D1.h +++ b/gfx/2d/SourceSurfaceD2D1.h @@ -62,6 +62,7 @@ private: SurfaceFormat mFormat; IntSize mSize; DrawTargetD2D1* mDrawTarget; + std::shared_ptr mSnapshotLock; }; class DataSourceSurfaceD2D1 : public DataSourceSurface