зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1425257: Introduce a global lock to protect the dependency graph between DrawTargets. r=lsalzman
This patch takes the safest route for securing modifications to the dependency graph for D2D DrawTargets. It's possible a slightly optimal approach is possible, however lock contention should be rare and I believe this is the safest and most upliftable approach. MozReview-Commit-ID: HGfSdEp2U5N
This commit is contained in:
Родитель
100be25160
Коммит
bf22a1874d
|
@ -1755,6 +1755,9 @@ protected:
|
|||
// This guards access to the singleton devices above, as well as the
|
||||
// singleton devices in DrawTargetD2D1.
|
||||
static StaticMutex mDeviceLock;
|
||||
// This synchronizes access between different D2D drawtargets and their
|
||||
// implied dependency graph.
|
||||
static StaticMutex mDTDependencyLock;
|
||||
|
||||
friend class DrawTargetD2D1;
|
||||
#endif
|
||||
|
|
|
@ -76,6 +76,7 @@ DrawTargetD2D1::~DrawTargetD2D1()
|
|||
mDC->EndDraw();
|
||||
}
|
||||
|
||||
StaticMutexAutoLock lock(Factory::mDTDependencyLock);
|
||||
// Targets depending on us can break that dependency, since we're obviously not going to
|
||||
// be modified in the future.
|
||||
for (auto iter = mDependentTargets.begin();
|
||||
|
@ -171,7 +172,8 @@ DrawTargetD2D1::Flush()
|
|||
mDC->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StaticMutexAutoLock lock(Factory::mDTDependencyLock);
|
||||
// We no longer depend on any target.
|
||||
for (TargetSet::iterator iter = mDependingOnTargets.begin();
|
||||
iter != mDependingOnTargets.end(); iter++) {
|
||||
|
@ -1285,6 +1287,8 @@ DrawTargetD2D1::MarkChanged()
|
|||
MOZ_ASSERT(!mSnapshot);
|
||||
}
|
||||
}
|
||||
|
||||
StaticMutexAutoLock lock(Factory::mDTDependencyLock);
|
||||
if (mDependentTargets.size()) {
|
||||
// Copy mDependentTargets since the Flush()es below will modify it.
|
||||
TargetSet tmpTargets = mDependentTargets;
|
||||
|
@ -1464,6 +1468,11 @@ DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern)
|
|||
void
|
||||
DrawTargetD2D1::AddDependencyOnSource(SourceSurfaceD2D1* aSource)
|
||||
{
|
||||
StaticMutexAutoLock lock(Factory::mDTDependencyLock);
|
||||
|
||||
// We grab the SnapshotLock as well, this guaranteeds aSource->mDrawTarget
|
||||
// cannot be cleared in between the if statement and the dereference.
|
||||
MutexAutoLock snapshotLock(*aSource->mSnapshotLock);
|
||||
if (aSource->mDrawTarget && !mDependingOnTargets.count(aSource->mDrawTarget)) {
|
||||
aSource->mDrawTarget->mDependentTargets.insert(this);
|
||||
mDependingOnTargets.insert(aSource->mDrawTarget);
|
||||
|
|
|
@ -222,6 +222,7 @@ StaticRefPtr<ID2D1Device> Factory::mD2D1Device;
|
|||
StaticRefPtr<IDWriteFactory> Factory::mDWriteFactory;
|
||||
bool Factory::mDWriteFactoryInitialized = false;
|
||||
StaticMutex Factory::mDeviceLock;
|
||||
StaticMutex Factory::mDTDependencyLock;
|
||||
#endif
|
||||
|
||||
DrawEventRecorder *Factory::mRecorder;
|
||||
|
|
Загрузка…
Ссылка в новой задаче