Bug 1062361 - Free cached tiles on memory-pressure r=nical

This commit is contained in:
Sotaro Ikeda 2014-09-04 08:27:46 -07:00
Родитель cb71cd9b96
Коммит 2899f5985d
2 изменённых файлов: 84 добавлений и 0 удалений

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

@ -40,6 +40,52 @@ namespace layers {
using namespace mozilla::gfx;
void
ClientLayerManager::MemoryPressureObserver::Destroy()
{
UnregisterMemoryPressureEvent();
mClientLayerManager = nullptr;
}
NS_IMETHODIMP
ClientLayerManager::MemoryPressureObserver::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aSomeData)
{
if (!mClientLayerManager || strcmp(aTopic, "memory-pressure")) {
return NS_OK;
}
mClientLayerManager->HandleMemoryPressure();
return NS_OK;
}
void
ClientLayerManager::MemoryPressureObserver::RegisterMemoryPressureEvent()
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_ASSERT(observerService);
if (observerService) {
observerService->AddObserver(this, "memory-pressure", false);
}
}
void
ClientLayerManager::MemoryPressureObserver::UnregisterMemoryPressureEvent()
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
observerService->RemoveObserver(this, "memory-pressure");
}
}
NS_IMPL_ISUPPORTS(ClientLayerManager::MemoryPressureObserver, nsIObserver)
ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
: mPhase(PHASE_NONE)
, mWidget(aWidget)
@ -54,6 +100,7 @@ ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
, mForwarder(new ShadowLayerForwarder)
{
MOZ_COUNT_CTOR(ClientLayerManager);
mMemoryPressureObserver = new MemoryPressureObserver(this);
}
ClientLayerManager::~ClientLayerManager()
@ -61,6 +108,7 @@ ClientLayerManager::~ClientLayerManager()
if (mTransactionIdAllocator) {
DidComposite(mLatestTransactionId);
}
mMemoryPressureObserver->Destroy();
ClearCachedResources();
// Stop receiveing AsyncParentMessage at Forwarder.
// After the call, the message is directly handled by LayerTransactionChild.
@ -622,6 +670,14 @@ ClientLayerManager::ClearCachedResources(Layer* aSubtree)
}
}
void
ClientLayerManager::HandleMemoryPressure()
{
for (size_t i = 0; i < mTexturePools.Length(); i++) {
mTexturePools[i]->ShrinkToMinimumSize();
}
}
void
ClientLayerManager::ClearLayer(Layer* aLayer)
{

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

@ -20,6 +20,7 @@
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_ABORT_IF_FALSE
#include "nsIObserver.h" // for nsIObserver
#include "nsISupportsImpl.h" // for Layer::Release, etc
#include "nsRect.h" // for nsIntRect
#include "nsTArray.h" // for nsTArray
@ -123,6 +124,8 @@ public:
// if we have one.
virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
void HandleMemoryPressure();
void SetRepeatTransaction() { mRepeatTransaction = true; }
bool GetRepeatTransaction() { return mRepeatTransaction; }
@ -235,6 +238,29 @@ protected:
TransactionPhase mPhase;
private:
// Listen memory-pressure event for ClientLayerManager
class MemoryPressureObserver MOZ_FINAL : public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
MemoryPressureObserver(ClientLayerManager* aClientLayerManager)
: mClientLayerManager(aClientLayerManager)
{
RegisterMemoryPressureEvent();
}
void Destroy();
private:
virtual ~MemoryPressureObserver() {}
void RegisterMemoryPressureEvent();
void UnregisterMemoryPressureEvent();
ClientLayerManager* mClientLayerManager;
};
/**
* Forward transaction results to the parent context.
*/
@ -304,6 +330,8 @@ private:
// indexed by gfx::SurfaceFormat
nsTArray<RefPtr<SimpleTextureClientPool> > mSimpleTilePools;
nsRefPtr<MemoryPressureObserver> mMemoryPressureObserver;
};
class ClientLayer : public ShadowableLayer