mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 666317 - Discard decoded images on a memory-pressure notification. r=joe
This commit is contained in:
parent
8968056a3a
commit
7566d381e7
@ -117,6 +117,35 @@ DiscardTracker::Remove(DiscardTrackerNode *node)
|
||||
node->prev = node->next = nsnull;
|
||||
}
|
||||
|
||||
/*
|
||||
* Discard all the images we're tracking.
|
||||
*/
|
||||
void
|
||||
DiscardTracker::DiscardAll()
|
||||
{
|
||||
if (!sInitialized)
|
||||
return;
|
||||
|
||||
// Remove the sentinel from the list so that the only elements in the list
|
||||
// which don't track an image are the head and tail.
|
||||
Remove(&sSentinel);
|
||||
|
||||
// Discard all tracked images.
|
||||
for (DiscardTrackerNode *node = sHead.next;
|
||||
node != &sTail; node = sHead.next) {
|
||||
NS_ABORT_IF_FALSE(node->curr, "empty node!");
|
||||
Remove(node);
|
||||
node->curr->Discard();
|
||||
}
|
||||
|
||||
// Add the sentinel back to the (now empty) list.
|
||||
Reset(&sSentinel);
|
||||
|
||||
// Because the sentinel is the only element in the list, the next timer event
|
||||
// would be a no-op. Disable the timer as an optimization.
|
||||
TimerOff();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the tracker.
|
||||
*/
|
||||
|
@ -76,6 +76,7 @@ class DiscardTracker
|
||||
static void Remove(struct DiscardTrackerNode *node);
|
||||
static void Shutdown();
|
||||
static void ReloadTimeout();
|
||||
static void DiscardAll();
|
||||
private:
|
||||
static nsresult Initialize();
|
||||
static nsresult TimerOn();
|
||||
|
@ -724,6 +724,7 @@ NS_IMETHODIMP
|
||||
imgCacheObserver::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aSomeData)
|
||||
{
|
||||
if (strcmp(aTopic, "memory-pressure") == 0) {
|
||||
DiscardTracker::DiscardAll();
|
||||
mLoader.MinimizeCaches();
|
||||
} else if (strcmp(aTopic, "chrome-flush-skin-caches") == 0 ||
|
||||
strcmp(aTopic, "chrome-flush-caches") == 0) {
|
||||
|
@ -49,6 +49,8 @@ _BROWSER_FILES = head.js \
|
||||
imageX2.html \
|
||||
animated.gif \
|
||||
animated2.gif \
|
||||
browser_bug666317.js \
|
||||
big.png \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_FILES)
|
||||
|
BIN
modules/libpr0n/test/browser/big.png
Normal file
BIN
modules/libpr0n/test/browser/big.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 126 KiB |
62
modules/libpr0n/test/browser/browser_bug666317.js
Normal file
62
modules/libpr0n/test/browser/browser_bug666317.js
Normal file
@ -0,0 +1,62 @@
|
||||
waitForExplicitFinish();
|
||||
|
||||
let pageSource =
|
||||
'<html><body>' +
|
||||
'<img id="testImg" src="' + TESTROOT + 'big.png">' +
|
||||
'</body></html>';
|
||||
|
||||
let oldDiscardingPref, oldTab, newTab;
|
||||
let prefBranch = Cc["@mozilla.org/preferences-service;1"]
|
||||
.getService(Ci.nsIPrefService)
|
||||
.getBranch('image.mem.');
|
||||
|
||||
function isImgDecoded() {
|
||||
let img = gBrowser.getBrowserForTab(newTab).contentWindow
|
||||
.document.getElementById('testImg');
|
||||
img.QueryInterface(Ci.nsIImageLoadingContent);
|
||||
let request = img.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
|
||||
return request.imageStatus & Ci.imgIRequest.STATUS_FRAME_COMPLETE ? true : false;
|
||||
}
|
||||
|
||||
// Ensure that the image is decoded by drawing it to a canvas.
|
||||
function forceDecodeImg() {
|
||||
let doc = gBrowser.getBrowserForTab(newTab).contentWindow.document;
|
||||
let img = doc.getElementById('testImg');
|
||||
let canvas = doc.createElement('canvas');
|
||||
let ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
}
|
||||
|
||||
function test() {
|
||||
// Enable the discarding pref.
|
||||
oldDiscardingPref = prefBranch.getBoolPref('discardable');
|
||||
prefBranch.setBoolPref('discardable', true);
|
||||
|
||||
// Create and focus a new tab.
|
||||
oldTab = gBrowser.selectedTab;
|
||||
newTab = gBrowser.addTab('data:text/html,' + pageSource);
|
||||
gBrowser.selectedTab = newTab;
|
||||
|
||||
// Run step2 after the tab loads.
|
||||
gBrowser.getBrowserForTab(newTab)
|
||||
.addEventListener("pageshow", step2 );
|
||||
}
|
||||
|
||||
function step2() {
|
||||
// Check that the image is decoded.
|
||||
forceDecodeImg();
|
||||
ok(isImgDecoded(), 'Image should initially be decoded.');
|
||||
|
||||
// Focus the old tab, then fire a memory-pressure notification. This should
|
||||
// cause the decoded image in the new tab to be discarded.
|
||||
gBrowser.selectedTab = oldTab;
|
||||
var os = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, 'memory-pressure', 'heap-minimize');
|
||||
ok(!isImgDecoded(), 'Image should be discarded.');
|
||||
|
||||
// And we're done.
|
||||
gBrowser.removeTab(newTab);
|
||||
prefBranch.setBoolPref('discardable', oldDiscardingPref);
|
||||
finish();
|
||||
}
|
Loading…
Reference in New Issue
Block a user