Bug 1171371 - On memory-pressure, remove any stale images from the visible images list. r=tn

This commit is contained in:
Seth Fowler 2015-06-04 17:37:58 -07:00
Родитель ee12c03986
Коммит 457f5493c9
3 изменённых файлов: 35 добавлений и 11 удалений

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

@ -139,10 +139,10 @@ typedef struct CapturingContentInfo {
mozilla::StaticRefPtr<nsIContent> mContent; mozilla::StaticRefPtr<nsIContent> mContent;
} CapturingContentInfo; } CapturingContentInfo;
// a7ef8bb3-d628-4965-80f3-a326e089fb7f // 1033a12a-51a2-461c-9c83-d53d0b2ac0b7
#define NS_IPRESSHELL_IID \ #define NS_IPRESSHELL_IID \
{ 0xa7ef8bb3, 0xd628, 0x4965, \ { 0x1033a12a, 0x51a2, 0x461c, \
{ 0x80, 0xf3, 0xa3, 0x26, 0xe0, 0x89, 0xfb, 0x7f } } { 0x9c, 0x83, 0xd5, 0x3d, 0x0b, 0x2a, 0xc0, 0xb7 } }
// debug VerifyReflow flags // debug VerifyReflow flags
#define VERIFY_REFLOW_ON 0x01 #define VERIFY_REFLOW_ON 0x01
@ -1551,7 +1551,8 @@ public:
// Clears the current list of visible images on this presshell and replaces it // Clears the current list of visible images on this presshell and replaces it
// with images that are in the display list aList. // with images that are in the display list aList.
virtual void RebuildImageVisibilityDisplayList(const nsDisplayList& aList) = 0; virtual void RebuildImageVisibilityDisplayList(const nsDisplayList& aList) = 0;
virtual void RebuildImageVisibility(nsRect* aRect = nullptr) = 0; virtual void RebuildImageVisibility(nsRect* aRect = nullptr,
bool aRemoveOnly = false) = 0;
// Ensures the image is in the list of visible images. // Ensures the image is in the list of visible images.
virtual void EnsureImageInVisibleList(nsIImageLoadingContent* aImage) = 0; virtual void EnsureImageInVisibleList(nsIImageLoadingContent* aImage) = 0;

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

@ -951,6 +951,7 @@ PresShell::Init(nsIDocument* aDocument,
#ifdef MOZ_XUL #ifdef MOZ_XUL
os->AddObserver(this, "chrome-flush-skin-caches", false); os->AddObserver(this, "chrome-flush-skin-caches", false);
#endif #endif
os->AddObserver(this, "memory-pressure", false);
} }
} }
@ -1137,6 +1138,7 @@ PresShell::Destroy()
#ifdef MOZ_XUL #ifdef MOZ_XUL
os->RemoveObserver(this, "chrome-flush-skin-caches"); os->RemoveObserver(this, "chrome-flush-skin-caches");
#endif #endif
os->RemoveObserver(this, "memory-pressure");
} }
} }
@ -5907,12 +5909,15 @@ PresShell::ClearVisibleImagesList(uint32_t aNonvisibleAction)
} }
void void
PresShell::MarkImagesInSubtreeVisible(nsIFrame* aFrame, const nsRect& aRect) PresShell::MarkImagesInSubtreeVisible(nsIFrame* aFrame,
const nsRect& aRect,
bool aRemoveOnly /* = false */)
{ {
MOZ_ASSERT(aFrame->PresContext()->PresShell() == this, "wrong presshell"); MOZ_ASSERT(aFrame->PresContext()->PresShell() == this, "wrong presshell");
nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(aFrame->GetContent())); nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(aFrame->GetContent()));
if (content && aFrame->StyleVisibility()->IsVisible()) { if (content && aFrame->StyleVisibility()->IsVisible() &&
(!aRemoveOnly || content->GetVisibleCount() > 0)) {
uint32_t count = mVisibleImages.Count(); uint32_t count = mVisibleImages.Count();
mVisibleImages.PutEntry(content); mVisibleImages.PutEntry(content);
if (mVisibleImages.Count() > count) { if (mVisibleImages.Count() > count) {
@ -5992,7 +5997,8 @@ PresShell::MarkImagesInSubtreeVisible(nsIFrame* aFrame, const nsRect& aRect)
} }
void void
PresShell::RebuildImageVisibility(nsRect* aRect) PresShell::RebuildImageVisibility(nsRect* aRect,
bool aRemoveOnly /* = false */)
{ {
MOZ_ASSERT(!mImageVisibilityVisited, "already visited?"); MOZ_ASSERT(!mImageVisibilityVisited, "already visited?");
mImageVisibilityVisited = true; mImageVisibilityVisited = true;
@ -6011,13 +6017,19 @@ PresShell::RebuildImageVisibility(nsRect* aRect)
if (aRect) { if (aRect) {
vis = *aRect; vis = *aRect;
} }
MarkImagesInSubtreeVisible(rootFrame, vis); MarkImagesInSubtreeVisible(rootFrame, vis, aRemoveOnly);
oldVisibleImages.EnumerateEntries(DecrementVisibleCount, nullptr); oldVisibleImages.EnumerateEntries(DecrementVisibleCount, nullptr);
} }
void void
PresShell::UpdateImageVisibility() PresShell::UpdateImageVisibility()
{
DoUpdateImageVisibility(/* aRemoveOnly = */ false);
}
void
PresShell::DoUpdateImageVisibility(bool aRemoveOnly)
{ {
MOZ_ASSERT(!mPresContext || mPresContext->IsRootContentDocument(), MOZ_ASSERT(!mPresContext || mPresContext->IsRootContentDocument(),
"updating image visibility on a non-root content document?"); "updating image visibility on a non-root content document?");
@ -6036,7 +6048,7 @@ PresShell::UpdateImageVisibility()
return; return;
} }
RebuildImageVisibility(); RebuildImageVisibility(/* aRect = */ nullptr, aRemoveOnly);
ClearImageVisibilityVisited(rootFrame->GetView(), true); ClearImageVisibilityVisited(rootFrame->GetView(), true);
#ifdef DEBUG_IMAGE_VISIBILITY_DISPLAY_LIST #ifdef DEBUG_IMAGE_VISIBILITY_DISPLAY_LIST
@ -9658,6 +9670,14 @@ PresShell::Observe(nsISupports* aSubject,
return NS_OK; return NS_OK;
} }
if (!nsCRT::strcmp(aTopic, "memory-pressure") &&
!AssumeAllImagesVisible() &&
mPresContext &&
mPresContext->IsRootContentDocument()) {
DoUpdateImageVisibility(/* aRemoveOnly = */ true);
return NS_OK;
}
NS_WARNING("unrecognized topic in PresShell::Observe"); NS_WARNING("unrecognized topic in PresShell::Observe");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }

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

@ -382,7 +382,8 @@ public:
virtual void ScheduleImageVisibilityUpdate() override; virtual void ScheduleImageVisibilityUpdate() override;
virtual void RebuildImageVisibilityDisplayList(const nsDisplayList& aList) override; virtual void RebuildImageVisibilityDisplayList(const nsDisplayList& aList) override;
virtual void RebuildImageVisibility(nsRect* aRect = nullptr) override; virtual void RebuildImageVisibility(nsRect* aRect = nullptr,
bool aRemoveOnly = false) override;
virtual void EnsureImageInVisibleList(nsIImageLoadingContent* aImage) override; virtual void EnsureImageInVisibleList(nsIImageLoadingContent* aImage) override;
@ -736,6 +737,7 @@ protected:
virtual void ResumePainting() override; virtual void ResumePainting() override;
void UpdateImageVisibility(); void UpdateImageVisibility();
void DoUpdateImageVisibility(bool aRemoveOnly);
void UpdateActivePointerState(mozilla::WidgetGUIEvent* aEvent); void UpdateActivePointerState(mozilla::WidgetGUIEvent* aEvent);
nsRevocableEventPtr<nsRunnableMethod<PresShell> > mUpdateImageVisibilityEvent; nsRevocableEventPtr<nsRunnableMethod<PresShell> > mUpdateImageVisibilityEvent;
@ -743,7 +745,8 @@ protected:
void ClearVisibleImagesList(uint32_t aNonvisibleAction); void ClearVisibleImagesList(uint32_t aNonvisibleAction);
static void ClearImageVisibilityVisited(nsView* aView, bool aClear); static void ClearImageVisibilityVisited(nsView* aView, bool aClear);
static void MarkImagesInListVisible(const nsDisplayList& aList); static void MarkImagesInListVisible(const nsDisplayList& aList);
void MarkImagesInSubtreeVisible(nsIFrame* aFrame, const nsRect& aRect); void MarkImagesInSubtreeVisible(nsIFrame* aFrame, const nsRect& aRect,
bool aRemoveOnly = false);
// Methods for dispatching KeyboardEvent and BeforeAfterKeyboardEvent. // Methods for dispatching KeyboardEvent and BeforeAfterKeyboardEvent.
void HandleKeyboardEvent(nsINode* aTarget, void HandleKeyboardEvent(nsINode* aTarget,