Bug 1060953: Fix reference cycle between DrawTargetD2D1 and SourceSurfaceD2D1. r=jrmuizel

This commit is contained in:
Bas Schouten 2014-09-14 23:51:28 +02:00
parent b1adcf8934
commit 8c3ba1fd9c
2 changed files with 31 additions and 1 deletions

View File

@ -39,7 +39,30 @@ DrawTargetD2D1::~DrawTargetD2D1()
{
PopAllClips();
if (mSnapshot) {
// 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.
RefPtr<SourceSurfaceD2D1> deathGrip = mSnapshot;
// mSnapshot can be treated as independent of this DrawTarget since we know
// this DrawTarget won't change again.
deathGrip->MarkIndependent();
// mSnapshot will be cleared now.
}
mDC->EndDraw();
// 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();
iter != mDependentTargets.end(); iter++) {
(*iter)->mDependingOnTargets.erase(this);
}
// Our dependencies on other targets no longer matter.
for (TargetSet::iterator iter = mDependingOnTargets.begin();
iter != mDependingOnTargets.end(); iter++) {
(*iter)->mDependentTargets.erase(this);
}
}
TemporaryRef<SourceSurface>
@ -61,6 +84,13 @@ void
DrawTargetD2D1::Flush()
{
mDC->Flush();
// We no longer depend on any target.
for (TargetSet::iterator iter = mDependingOnTargets.begin();
iter != mDependingOnTargets.end(); iter++) {
(*iter)->mDependentTargets.erase(this);
}
mDependingOnTargets.clear();
}
void

View File

@ -57,7 +57,7 @@ private:
SurfaceFormat mFormat;
IntSize mSize;
RefPtr<DrawTargetD2D1> mDrawTarget;
DrawTargetD2D1* mDrawTarget;
};
class DataSourceSurfaceD2D1 : public DataSourceSurface