Bug 705173. Make mDependentTargets weak by tracking the inverse relationship in mDependingOnTargets. In Flush(), remove dependencies on other targets. r=bas

This commit is contained in:
Robert O'Callahan 2011-11-25 15:12:40 +13:00
parent 59cd17accf
commit 7d22b4bdb5
2 changed files with 35 additions and 4 deletions

View File

@ -44,6 +44,7 @@
#include "ScaledFontDWrite.h"
#include "Logging.h"
#include "Tools.h"
#include <algorithm>
#ifndef M_PI
#define M_PI 3.14159265358979323846
@ -187,6 +188,20 @@ DrawTargetD2D::~DrawTargetD2D()
if (mTempRT) {
mTempRT->EndDraw();
}
// Targets depending on us can break that dependency, since we're obviously not going to
// be modified in the future.
for (std::vector<DrawTargetD2D*>::iterator iter = mDependentTargets.begin();
iter != mDependentTargets.end(); iter++) {
(*iter)->mDependingOnTargets.erase(
std::find((*iter)->mDependingOnTargets.begin(), (*iter)->mDependingOnTargets.end(), this));
}
// Our dependencies on other targets no longer matter.
for (std::vector<DrawTargetD2D*>::iterator iter = mDependingOnTargets.begin();
iter != mDependingOnTargets.end(); iter++) {
(*iter)->mDependentTargets.erase(
std::find((*iter)->mDependentTargets.begin(), (*iter)->mDependentTargets.end(), this));
}
}
/*
@ -218,6 +233,14 @@ DrawTargetD2D::Flush()
if (FAILED(hr)) {
gfxWarning() << "Error reported when trying to flush D2D rendertarget. Code: " << hr;
}
// We no longer depend on any target.
for (std::vector<DrawTargetD2D*>::iterator iter = mDependingOnTargets.begin();
iter != mDependingOnTargets.end(); iter++) {
(*iter)->mDependentTargets.erase(
std::find((*iter)->mDependentTargets.begin(), (*iter)->mDependentTargets.end(), this));
}
mDependingOnTargets.clear();
}
void
@ -272,6 +295,7 @@ DrawTargetD2D::DrawSurface(SourceSurface *aSurface,
if (!srcSurf->IsCopy()) {
srcSurf->mDrawTarget->mDependentTargets.push_back(this);
mDependingOnTargets.push_back(srcSurf->mDrawTarget);
}
}
break;
@ -700,6 +724,7 @@ DrawTargetD2D::CopySurface(SourceSurface *aSurface,
if (!srcSurf->IsCopy()) {
srcSurf->mDrawTarget->mDependentTargets.push_back(this);
mDependingOnTargets.push_back(srcSurf->mDrawTarget);
}
}
break;
@ -1255,11 +1280,14 @@ DrawTargetD2D::MarkChanged()
mSnapshots.clear();
}
if (mDependentTargets.size()) {
for (std::vector<RefPtr<DrawTargetD2D>>::iterator iter = mDependentTargets.begin();
iter != mDependentTargets.end(); iter++) {
// Copy mDependentTargets since the Flush()es below will modify it.
std::vector<DrawTargetD2D*> tmpTargets = mDependentTargets;
for (std::vector<DrawTargetD2D*>::iterator iter = tmpTargets.begin();
iter != tmpTargets.end(); iter++) {
(*iter)->Flush();
}
mDependentTargets.clear();
// The Flush() should have broken all dependencies on this target.
MOZ_ASSERT(!mDependentTargets.size());
}
}
@ -1655,6 +1683,7 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
if (!surf->IsCopy()) {
surf->mDrawTarget->mDependentTargets.push_back(this);
mDependingOnTargets.push_back(surf->mDrawTarget);
}
}
break;

View File

@ -198,7 +198,9 @@ private:
// surface is modified. Possibly vector is not the best choice here.
std::vector<SourceSurfaceD2DTarget*> mSnapshots;
// A list of targets we need to flush when we're modified.
std::vector<RefPtr<DrawTargetD2D>> mDependentTargets;
std::vector<DrawTargetD2D*> mDependentTargets;
// A list of targets which have this object in their mDependentTargets array
std::vector<DrawTargetD2D*> mDependingOnTargets;
// True of the current clip stack is pushed to the main RT.
bool mClipsArePushed;