diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index f538d5c28a1e..bc69cd4d8479 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -139,10 +139,10 @@ typedef struct CapturingContentInfo { mozilla::StaticRefPtr mContent; } CapturingContentInfo; -// a7ef8bb3-d628-4965-80f3-a326e089fb7f +// 1033a12a-51a2-461c-9c83-d53d0b2ac0b7 #define NS_IPRESSHELL_IID \ -{ 0xa7ef8bb3, 0xd628, 0x4965, \ - { 0x80, 0xf3, 0xa3, 0x26, 0xe0, 0x89, 0xfb, 0x7f } } +{ 0x1033a12a, 0x51a2, 0x461c, \ + { 0x9c, 0x83, 0xd5, 0x3d, 0x0b, 0x2a, 0xc0, 0xb7 } } // debug VerifyReflow flags #define VERIFY_REFLOW_ON 0x01 @@ -1551,7 +1551,8 @@ public: // Clears the current list of visible images on this presshell and replaces it // with images that are in the display list aList. 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. virtual void EnsureImageInVisibleList(nsIImageLoadingContent* aImage) = 0; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 983198ec9885..4eba5c6dddcf 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -951,6 +951,7 @@ PresShell::Init(nsIDocument* aDocument, #ifdef MOZ_XUL os->AddObserver(this, "chrome-flush-skin-caches", false); #endif + os->AddObserver(this, "memory-pressure", false); } } @@ -1137,6 +1138,7 @@ PresShell::Destroy() #ifdef MOZ_XUL os->RemoveObserver(this, "chrome-flush-skin-caches"); #endif + os->RemoveObserver(this, "memory-pressure"); } } @@ -5907,12 +5909,15 @@ PresShell::ClearVisibleImagesList(uint32_t aNonvisibleAction) } 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"); nsCOMPtr content(do_QueryInterface(aFrame->GetContent())); - if (content && aFrame->StyleVisibility()->IsVisible()) { + if (content && aFrame->StyleVisibility()->IsVisible() && + (!aRemoveOnly || content->GetVisibleCount() > 0)) { uint32_t count = mVisibleImages.Count(); mVisibleImages.PutEntry(content); if (mVisibleImages.Count() > count) { @@ -5992,7 +5997,8 @@ PresShell::MarkImagesInSubtreeVisible(nsIFrame* aFrame, const nsRect& aRect) } void -PresShell::RebuildImageVisibility(nsRect* aRect) +PresShell::RebuildImageVisibility(nsRect* aRect, + bool aRemoveOnly /* = false */) { MOZ_ASSERT(!mImageVisibilityVisited, "already visited?"); mImageVisibilityVisited = true; @@ -6011,13 +6017,19 @@ PresShell::RebuildImageVisibility(nsRect* aRect) if (aRect) { vis = *aRect; } - MarkImagesInSubtreeVisible(rootFrame, vis); + MarkImagesInSubtreeVisible(rootFrame, vis, aRemoveOnly); oldVisibleImages.EnumerateEntries(DecrementVisibleCount, nullptr); } void PresShell::UpdateImageVisibility() +{ + DoUpdateImageVisibility(/* aRemoveOnly = */ false); +} + +void +PresShell::DoUpdateImageVisibility(bool aRemoveOnly) { MOZ_ASSERT(!mPresContext || mPresContext->IsRootContentDocument(), "updating image visibility on a non-root content document?"); @@ -6036,7 +6048,7 @@ PresShell::UpdateImageVisibility() return; } - RebuildImageVisibility(); + RebuildImageVisibility(/* aRect = */ nullptr, aRemoveOnly); ClearImageVisibilityVisited(rootFrame->GetView(), true); #ifdef DEBUG_IMAGE_VISIBILITY_DISPLAY_LIST @@ -9658,6 +9670,14 @@ PresShell::Observe(nsISupports* aSubject, 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"); return NS_ERROR_FAILURE; } diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index 99b1dad70fb2..ca2f467f23d3 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -382,7 +382,8 @@ public: virtual void ScheduleImageVisibilityUpdate() 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; @@ -736,6 +737,7 @@ protected: virtual void ResumePainting() override; void UpdateImageVisibility(); + void DoUpdateImageVisibility(bool aRemoveOnly); void UpdateActivePointerState(mozilla::WidgetGUIEvent* aEvent); nsRevocableEventPtr > mUpdateImageVisibilityEvent; @@ -743,7 +745,8 @@ protected: void ClearVisibleImagesList(uint32_t aNonvisibleAction); static void ClearImageVisibilityVisited(nsView* aView, bool aClear); 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. void HandleKeyboardEvent(nsINode* aTarget,