Bug 1154231 - Part 1. Reclaim cached resources when memory-pressure occurs. r=mattwoodrow

This commit is contained in:
Kan-Ru Chen 2015-04-29 11:54:04 +08:00
Родитель f47bc20645
Коммит 964162adc7
2 изменённых файлов: 50 добавлений и 4 удалений

Просмотреть файл

@ -118,6 +118,11 @@ PuppetWidget::Create(nsIWidget *aParent,
else { else {
Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, false); Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, false);
} }
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
mMemoryPressureObserver = new MemoryPressureObserver(this);
obs->AddObserver(mMemoryPressureObserver, "memory-pressure", false);
}
return NS_OK; return NS_OK;
} }
@ -153,6 +158,9 @@ PuppetWidget::Destroy()
Base::OnDestroy(); Base::OnDestroy();
Base::Destroy(); Base::Destroy();
mPaintTask.Revoke(); mPaintTask.Revoke();
if (mMemoryPressureObserver) {
mMemoryPressureObserver->Remove();
}
mChild = nullptr; mChild = nullptr;
if (mLayerManager) { if (mLayerManager) {
mLayerManager->Destroy(); mLayerManager->Destroy();
@ -175,10 +183,6 @@ PuppetWidget::Show(bool aState)
mChild->mVisible = aState; mChild->mVisible = aState;
} }
if (!mVisible && mLayerManager) {
mLayerManager->ClearCachedResources();
}
if (!wasVisible && mVisible) { if (!wasVisible && mVisible) {
Resize(mBounds.width, mBounds.height, false); Resize(mBounds.width, mBounds.height, false);
Invalidate(mBounds); Invalidate(mBounds);
@ -1037,6 +1041,35 @@ PuppetWidget::PaintTask::Run()
return NS_OK; return NS_OK;
} }
NS_IMPL_ISUPPORTS(PuppetWidget::MemoryPressureObserver, nsIObserver)
NS_IMETHODIMP
PuppetWidget::MemoryPressureObserver::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!mWidget) {
return NS_OK;
}
if (strcmp("memory-pressure", aTopic) == 0) {
if (!mWidget->mVisible && mWidget->mLayerManager) {
mWidget->mLayerManager->ClearCachedResources();
}
}
return NS_OK;
}
void
PuppetWidget::MemoryPressureObserver::Remove()
{
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(this, "memory-pressure");
}
mWidget = nullptr;
}
bool bool
PuppetWidget::NeedsPaint() PuppetWidget::NeedsPaint()
{ {

Просмотреть файл

@ -279,6 +279,18 @@ private:
PuppetWidget* mWidget; PuppetWidget* mWidget;
}; };
class MemoryPressureObserver : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
explicit MemoryPressureObserver(PuppetWidget* aWidget) : mWidget(aWidget) {}
void Remove();
private:
virtual ~MemoryPressureObserver() {}
PuppetWidget* mWidget;
};
friend class MemoryPressureObserver;
// TabChild normally holds a strong reference to this PuppetWidget // TabChild normally holds a strong reference to this PuppetWidget
// or its root ancestor, but each PuppetWidget also needs a // or its root ancestor, but each PuppetWidget also needs a
// reference back to TabChild (e.g. to delegate nsIWidget IME calls // reference back to TabChild (e.g. to delegate nsIWidget IME calls
@ -291,6 +303,7 @@ private:
nsRefPtr<PuppetWidget> mChild; nsRefPtr<PuppetWidget> mChild;
nsIntRegion mDirtyRegion; nsIntRegion mDirtyRegion;
nsRevocableEventPtr<PaintTask> mPaintTask; nsRevocableEventPtr<PaintTask> mPaintTask;
nsRefPtr<MemoryPressureObserver> mMemoryPressureObserver;
// XXX/cjones: keeping this around until we teach LayerManager to do // XXX/cjones: keeping this around until we teach LayerManager to do
// retained-content-only transactions // retained-content-only transactions
mozilla::RefPtr<DrawTarget> mDrawTarget; mozilla::RefPtr<DrawTarget> mDrawTarget;