mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 13:58:49 +00:00
Issue #3030 - Improve image cache entry handling.
This: - increases max image cache entry size and adjusts related parameters. - makes the cache entry timeout configurable for advanced tweaking. - adds a mechanism to keep commonly-used, small image sizes in cache longer.
This commit is contained in:
@@ -436,6 +436,7 @@ private:
|
||||
DECL_GFX_PREF(Live, "image.animated.resume-from-last-displayed", ImageAnimatedResumeFromLastDisplayed, bool, false);
|
||||
DECL_GFX_PREF(Once, "image.cache.size", ImageCacheSize, int32_t, 5*1024*1024);
|
||||
DECL_GFX_PREF(Once, "image.cache.timeweight", ImageCacheTimeWeight, int32_t, 500);
|
||||
DECL_GFX_PREF(Once, "image.cache.entry_timeout", ImageCacheEntryTimeout, int32_t, 15000);
|
||||
DECL_GFX_PREF(Live, "image.decode-immediately.enabled", ImageDecodeImmediatelyEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, true);
|
||||
DECL_GFX_PREF(Live, "image.infer-src-animation.threshold-ms", ImageInferSrcAnimationThresholdMS, uint32_t, 2000);
|
||||
|
||||
@@ -936,9 +936,9 @@ VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams, BackendTy
|
||||
// are scaled repeatedly (a rather common scenario) that can quickly exhaust
|
||||
// the cache.
|
||||
// Similar to max image size calculations, this has a max cap and size check.
|
||||
// max cap = 8000 (pixels); size check = 5% of cache
|
||||
// max cap = 8000 (pixels); size check = 10% of cache
|
||||
int32_t maxDimension = 8000;
|
||||
int32_t maxCacheElemSize = (gfxPrefs::ImageMemSurfaceCacheMaxSizeKB() * 1024) / 20;
|
||||
int32_t maxCacheElemSize = (gfxPrefs::ImageMemSurfaceCacheMaxSizeKB() * 1024) / 10;
|
||||
|
||||
bool bypassCache = bool(aParams.flags & FLAG_BYPASS_SURFACE_CACHE) ||
|
||||
// Refuse to cache animated images:
|
||||
|
||||
+43
-2
@@ -1087,7 +1087,6 @@ imgLoader::CreateNewProxyForRequest(imgRequest* aRequest,
|
||||
class imgCacheExpirationTracker final
|
||||
: public nsExpirationTracker<imgCacheEntry, 3>
|
||||
{
|
||||
enum { TIMEOUT_SECONDS = 10 };
|
||||
public:
|
||||
imgCacheExpirationTracker();
|
||||
|
||||
@@ -1096,10 +1095,46 @@ protected:
|
||||
};
|
||||
|
||||
imgCacheExpirationTracker::imgCacheExpirationTracker()
|
||||
: nsExpirationTracker<imgCacheEntry, 3>(TIMEOUT_SECONDS * 1000,
|
||||
: nsExpirationTracker<imgCacheEntry, 3>(gfxPrefs::ImageCacheEntryTimeout(),
|
||||
"imgCacheExpirationTracker")
|
||||
{ }
|
||||
|
||||
static bool
|
||||
ShouldKeepRecentlyUsedAssetInCache(imgCacheEntry* aEntry)
|
||||
{
|
||||
RefPtr<imgRequest> request = aEntry->GetRequest();
|
||||
if (!request) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* mimeType = request->GetMimeType();
|
||||
if (!mimeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Keep small, frequently reused static image assets warm a bit longer.
|
||||
if (!nsCRT::strcmp(mimeType, IMAGE_SVG_XML) ||
|
||||
!nsCRT::strcmp(mimeType, IMAGE_JPG) ||
|
||||
!nsCRT::strcmp(mimeType, IMAGE_JPEG) ||
|
||||
!nsCRT::strcmp(mimeType, IMAGE_ICO) ||
|
||||
!nsCRT::strcmp(mimeType, IMAGE_PNG) ||
|
||||
!nsCRT::strcmp(mimeType, IMAGE_WEBP)) {
|
||||
// XXX: Should we make these configurable too?
|
||||
const uint32_t kMaxWarmAssetBytes = 128 * 1024; // <= 128 kiB entries only
|
||||
const uint32_t kRecentUseGraceSeconds = 60; // keep warm for 60 s
|
||||
|
||||
if (aEntry->GetDataSize() <= kMaxWarmAssetBytes) {
|
||||
uint32_t now = SecondsFromPRTime(PR_Now());
|
||||
uint32_t touched = aEntry->GetTouchedTime();
|
||||
if (now >= touched && (now - touched) <= kRecentUseGraceSeconds) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
imgCacheExpirationTracker::NotifyExpired(imgCacheEntry* entry)
|
||||
{
|
||||
@@ -1107,6 +1142,12 @@ imgCacheExpirationTracker::NotifyExpired(imgCacheEntry* entry)
|
||||
// mechanism doesn't.
|
||||
RefPtr<imgCacheEntry> kungFuDeathGrip(entry);
|
||||
|
||||
if (ShouldKeepRecentlyUsedAssetInCache(entry)) {
|
||||
entry->Touch();
|
||||
entry->Loader()->VerifyCacheSizes();
|
||||
return;
|
||||
}
|
||||
|
||||
if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
|
||||
RefPtr<imgRequest> req = entry->GetRequest();
|
||||
if (req) {
|
||||
|
||||
@@ -152,6 +152,7 @@ public:
|
||||
private: // methods
|
||||
friend class imgLoader;
|
||||
friend class imgCacheQueue;
|
||||
friend class imgCacheExpirationTracker;
|
||||
void Touch(bool updateTime = true);
|
||||
void UpdateCache(int32_t diff = 0);
|
||||
void SetEvicted(bool evict)
|
||||
|
||||
@@ -4262,12 +4262,18 @@ pref("image.animated.decode-on-demand.batch-size", 6);
|
||||
// advancing when out of view.
|
||||
pref("image.animated.resume-from-last-displayed", true);
|
||||
|
||||
// Image cache prefs: Restart required for changes.
|
||||
|
||||
// The maximum size, in bytes, of the decoded images we cache
|
||||
pref("image.cache.size", 5242880);
|
||||
pref("image.cache.size", 26214400);
|
||||
|
||||
// A weight, from 0-1000, to place on time when comparing to size.
|
||||
// Size is given a weight of 1000 - timeweight.
|
||||
pref("image.cache.timeweight", 500);
|
||||
pref("image.cache.timeweight", 650);
|
||||
|
||||
// Time in ms before unproxied entries in the in-memory image cache are
|
||||
// considered for eviction by the expiration tracker.
|
||||
pref("image.cache.entry_timeout", 15000);
|
||||
|
||||
// Decode all images automatically on load, ignoring our normal heuristics.
|
||||
pref("image.decode-immediately.enabled", false);
|
||||
@@ -4314,7 +4320,7 @@ pref("image.mem.decode_bytes_at_a_time", 16384);
|
||||
|
||||
// Minimum timeout for expiring unused images from the surface cache, in
|
||||
// milliseconds. This controls how long we store cached temporary surfaces.
|
||||
pref("image.mem.surfacecache.min_expiration_ms", 60000); // 60s
|
||||
pref("image.mem.surfacecache.min_expiration_ms", 180000); // 180s
|
||||
|
||||
// Maximum size for the surface cache, in kilobytes.
|
||||
pref("image.mem.surfacecache.max_size_kb", 1048576); // 1GB
|
||||
@@ -4331,7 +4337,7 @@ pref("image.mem.surfacecache.size_factor", 4);
|
||||
// surface cache on memory pressure, a discard factor of 2 means to discard half
|
||||
// of the data, and so forth. The default should be a good balance for desktop
|
||||
// and laptop systems, where we never discard visible images.
|
||||
pref("image.mem.surfacecache.discard_factor", 1);
|
||||
pref("image.mem.surfacecache.discard_factor", 2);
|
||||
|
||||
// How many threads we'll use for multithreaded decoding. If < 0, will be
|
||||
// automatically determined based on the system's number of cores.
|
||||
|
||||
Reference in New Issue
Block a user